WebGL 着色器不遵循形状方向
WebGL shaders not respecting shape orientation
我是 WebGL 的新手,我正在修改我在网上找到的现有项目以满足我的需要。
我的相机是等距的,我正在渲染两个立方体。我想在 'ground' 上有一个无限网格,就像在许多 3d 编辑器中一样。
您可以在下面看到网格不是无限的(我知道这是因为顶点只从 -1 到 1),而且它的方向不正确。它直接在屏幕上呈现,而不是考虑发送到 GPU 的变换矩阵。
由于涉及到三个相互关联的程序(2个shader,加上JS),不知道是哪里出了问题。这是最相关的代码;该项目很大,所以如果您需要查看其他内容,请告诉我:
let vertices = [
1.0, 1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, -1.0, 0.0
];
let bufferObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
let attribute = shader.position; // getAttribLocation(..., 'position')
gl.bindBuffer(gl.ARRAY_BUFFER, vertices);
gl.enableVertexAttribArray(attribute);
gl.vertexAttribPointer(attribute, 3, gl.FLOAT, false, 0, 0); // size of 3 is the only one that renders the quad
// this rotates the plane to be along the 'ground' - even without this, it stands up, and the grid still doesn't respect the orientation
(new Matrix()).rotateX(90).sendToGpu(gl, shader.model); // getUniformLocation(..., 'model')
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); // 4 vertices
顶点着色器:
attribute vec4 position;
attribute vec2 uv;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
varying vec2 vUv;
void main()
{
vUv = uv;
gl_Position = projection * view * model * position;
}
片段着色器:
precision mediump float;
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
vec2 offset = vec2(0, 0);
vec2 pitch = vec2(32, 32);
void main()
{
float lX = gl_FragCoord.x / resolution.x;
float lY = gl_FragCoord.y / resolution.y;
float scaleFactor = 10000.0;
float offX = (scaleFactor * offset[0]) + gl_FragCoord.x;
float offY = (scaleFactor * offset[1]) + (1.0 - gl_FragCoord.y);
if (int(mod(offX, pitch[0])) == 0 || int(mod(offY, pitch[1])) == 0)
{
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.2);
}
else
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 0.1);
}
}
有人能给我指出正确的方向吗?
根据纹理坐标 (vUv
) 而不是 gl_FragCoord.xy
.
生成网格
添加纹理坐标属性:
let vertices = [
// x y z u v
1.0, 1.0, 0.0, 1.0, 0.0,
-1.0, 1.0, 0.0, 0.0, 0.0,
1.0, -1.0, 0.0, 1.0, 1.0,
-1.0, -1.0, 0.0 0.0, 1.0,
];
let bufferObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, vertices);
let attribute = shader.position; // getAttribLocation(..., 'position')
gl.enableVertexAttribArray(attribute);
gl.vertexAttribPointer(attribute, 3, gl.FLOAT, false, 5*4, 0);
let attribute_uv = gl.getAttribLocation(..., 'uv')
gl.enableVertexAttribArray(attribute_uv);
gl.vertexAttribPointer(attribute_uv, 2, gl.FLOAT, false, 5*4, 3*4);
在片段着色器中将 offX
和 offY
设置为 vUV
而不是 gl_FragCoord.xy
:
// [...]
varying vec2 vUv;
void main()
{
// float offX = (scaleFactor * offset[0]) + gl_FragCoord.x;
// float offY = (scaleFactor * offset[1]) + (1.0 - gl_FragCoord.y);
float scaleFactor = 32.0*8.0;
float offX = scaleFactor * vUv.x;
float offY = scaleFactor * vUv.y;
// [...]
}
我是 WebGL 的新手,我正在修改我在网上找到的现有项目以满足我的需要。
我的相机是等距的,我正在渲染两个立方体。我想在 'ground' 上有一个无限网格,就像在许多 3d 编辑器中一样。
您可以在下面看到网格不是无限的(我知道这是因为顶点只从 -1 到 1),而且它的方向不正确。它直接在屏幕上呈现,而不是考虑发送到 GPU 的变换矩阵。
由于涉及到三个相互关联的程序(2个shader,加上JS),不知道是哪里出了问题。这是最相关的代码;该项目很大,所以如果您需要查看其他内容,请告诉我:
let vertices = [
1.0, 1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, -1.0, 0.0
];
let bufferObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
let attribute = shader.position; // getAttribLocation(..., 'position')
gl.bindBuffer(gl.ARRAY_BUFFER, vertices);
gl.enableVertexAttribArray(attribute);
gl.vertexAttribPointer(attribute, 3, gl.FLOAT, false, 0, 0); // size of 3 is the only one that renders the quad
// this rotates the plane to be along the 'ground' - even without this, it stands up, and the grid still doesn't respect the orientation
(new Matrix()).rotateX(90).sendToGpu(gl, shader.model); // getUniformLocation(..., 'model')
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); // 4 vertices
顶点着色器:
attribute vec4 position;
attribute vec2 uv;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
varying vec2 vUv;
void main()
{
vUv = uv;
gl_Position = projection * view * model * position;
}
片段着色器:
precision mediump float;
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
vec2 offset = vec2(0, 0);
vec2 pitch = vec2(32, 32);
void main()
{
float lX = gl_FragCoord.x / resolution.x;
float lY = gl_FragCoord.y / resolution.y;
float scaleFactor = 10000.0;
float offX = (scaleFactor * offset[0]) + gl_FragCoord.x;
float offY = (scaleFactor * offset[1]) + (1.0 - gl_FragCoord.y);
if (int(mod(offX, pitch[0])) == 0 || int(mod(offY, pitch[1])) == 0)
{
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.2);
}
else
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 0.1);
}
}
有人能给我指出正确的方向吗?
根据纹理坐标 (vUv
) 而不是 gl_FragCoord.xy
.
添加纹理坐标属性:
let vertices = [
// x y z u v
1.0, 1.0, 0.0, 1.0, 0.0,
-1.0, 1.0, 0.0, 0.0, 0.0,
1.0, -1.0, 0.0, 1.0, 1.0,
-1.0, -1.0, 0.0 0.0, 1.0,
];
let bufferObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, vertices);
let attribute = shader.position; // getAttribLocation(..., 'position')
gl.enableVertexAttribArray(attribute);
gl.vertexAttribPointer(attribute, 3, gl.FLOAT, false, 5*4, 0);
let attribute_uv = gl.getAttribLocation(..., 'uv')
gl.enableVertexAttribArray(attribute_uv);
gl.vertexAttribPointer(attribute_uv, 2, gl.FLOAT, false, 5*4, 3*4);
在片段着色器中将 offX
和 offY
设置为 vUV
而不是 gl_FragCoord.xy
:
// [...]
varying vec2 vUv;
void main()
{
// float offX = (scaleFactor * offset[0]) + gl_FragCoord.x;
// float offY = (scaleFactor * offset[1]) + (1.0 - gl_FragCoord.y);
float scaleFactor = 32.0*8.0;
float offX = scaleFactor * vUv.x;
float offY = scaleFactor * vUv.y;
// [...]
}