【发布时间】:2019-11-16 19:10:33
【问题描述】:
我需要在梯形多边形上绘制部分纹理。 (老式的假 3D 赛车游戏,道路是由这些梯形组成的,我想在它们上应用纹理。)
但是纹理看起来是错误的,就像形成梯形的两个三角形中的每一个都是平行四边形的一半,它们各自具有不同的水平倾斜,而不是全局透视变换。
寻找解决方案我发现这个问题很常见,原因是两个三角形不相等并且着色器是二维的。根据我的发现,尤其是这个答案:https://stackoverflow.com/a/25239021/3666866,我试图修复我的着色器。但它并没有改变任何东西......
My shaders : (copied from webglfundamentals.com, edited according to https://stackoverflow.com/a/25239021/3666866)
<script id="3d-vertex-shader" type="x-shader/x-vertex">
attribute vec4 a_position ;
//attribute vec2 a_texcoord ;
attribute vec4 a_texcoord ;
uniform mat4 u_matrix ;
//varying vec2 v_texcoord ;
varying vec4 v_texcoord ;
void main() {
gl_Position = u_matrix * a_position ;
v_texcoord = a_texcoord ;
}
</script>
<script id="3d-fragment-shader" type="x-shader/x-fragment">
precision mediump float ;
//varying vec2 v_texcoord ;
varying vec4 v_texcoord ;
uniform sampler2D u_texture ;
void main() {
//gl_FragColor = texture2D(u_texture, v_texcoord) ;
gl_FragColor = texture2DProj( u_texture , v_texcoord ) ;
}
</script>
code :
gl_.positionLocation = gl.getAttribLocation( gl_.program, "a_position" );
gl_.texcoordLocation = gl.getAttribLocation( gl_.program, "a_texcoord" );
gl.matrixLocation = gl.getUniformLocation( gl_.program, "u_matrix" );
gl.textureLocation = gl.getUniformLocation( gl_.program, "u_texture" );
gl_.positionBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, gl_.positionBuffer );
var positions = new Float32Array(
[
-1.5, -0.5, 0.5,
1.5, -0.5, 0.5,
-0.5, 0.5, 0.5,
-0.5, 0.5, 0.5,
1.5, -0.5, 0.5,
0.5, 0.5, 0.5,
]);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
gl_.texcoordBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, gl_.texcoordBuffer );
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(
[
0.25, 0 ,
0.5 , 0 ,
0.25, 0.5,
0.25, 0.5,
0.5 , 0 ,
0.5 , 0.5,
]),
gl.STATIC_DRAW);
The render code :
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.bindBuffer( gl.ARRAY_BUFFER, positionBuffer );
gl.vertexAttribPointer(positionLocation,3,gl.FLOAT,false,0,0);
gl.enableVertexAttribArray( texcoordLocation );
gl.bindBuffer( gl.ARRAY_BUFFER, texcoordBuffer );
gl.vertexAttribPointer(texcoordLocation,3,gl.FLOAT,false,0,0);
let projectionMatrix = m4.perspective( fieldOfViewRadians, aspect, 1, 2000);
let viewProjectionMatrix = m4.multiply( projectionMatrix, viewMatrix );
let matrix = m4.xRotate( viewProjectionMatrix, modelXRotationRadians );
gl.uniformMatrix4fv( matrixLocation , false , viewProjectionMatrix );
gl.uniform1i( textureLocation , 0 );
gl.drawArrays(gl.TRIANGLES, 0, 6 * 1 );
哪里出错了?
【问题讨论】:
-
只是好奇。什么是老式假 3D 赛车游戏的例子?我之所以问,是因为我在想象像 Outrun 或 Power Drift 这样的缩放四边形,但我不记得哪些游戏使用了梯形。
-
至于您的代码,您没有显示纹理坐标,但您链接到的答案使用 3d 纹理坐标,但您上面的代码将
2传递给gl.vertexAttribPointer以获得纹理坐标,所以您不将 3d 纹理坐标传递给着色器。 -
我没有很好地解释自己。我不能使用旧游戏相同的扫描线技巧,这就是为什么我想使用梯形,结果应该看起来很相似(我希望)。我把它改成了 3 但 id 没有效果。
-
您链接到的示例使用 3D 纹理坐标,但您仅使用 2D 纹理坐标。您需要为每个纹理坐标添加正确的第三个坐标,就像您链接到的答案一样。
标签: webgl shader projection-matrix