WebGL - 加载纹理时出现问题
WebGL - Problems Loading a Texture
我正在尝试创建纹理(到处都是灰色)并使用 WebGL 将其渲染为 canvas。
我在这里尝试过:
function tryToDraw() {
vertexShaderCode = `#version 100
precision mediump float;
attribute vec2 vertex_attrib;
void main (void)
{
gl_Position = vec4 (vertex_attrib, 0.0, 1.0) ;
}
`;
fragmentShaderCode = `#version 100
precision mediump float;
uniform sampler2D myTexture;
void main (void) {
vec2 texcoord = gl_FragCoord.xy / 1024.0;
gl_FragColor = vec4(texture2D (myTexture, texcoord).rgb, 1.0);
}
`;
var canvas = document.getElementById('waves_canvas');
var gl = canvas.getContext('webgl');
var program = gl.createProgram();
var textureArr = new Uint8Array(1024 * 1024 * 3).fill(128);
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderCode);
gl.compileShader(vertexShader);
gl.attachShader(program, vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderCode);
gl.compileShader(fragmentShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.validateProgram(program);
console.log(gl.getProgramParameter(program, gl.VALIDATE_STATUS));
gl.useProgram(program);
var location = gl.getUniformLocation(program, 'myTexture');
gl.uniform1i(location, 0);
var texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1024, 1024, 0, gl.RGB, gl.UNSIGNED_BYTE, textureArr);
var vertexPositions = new Float32Array([-1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0]);
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertexPositions, gl.STATIC_DRAW);
var vPosAttrLoc = gl.getAttribLocation(program, 'vertex_attrib');
gl.enableVertexAttribArray(vPosAttrLoc);
gl.vertexAttribPointer(vPosAttrLoc, 2, gl.FLOAT, false, 2 * vertexPositions.BYTES_PER_ELEMENT, null);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
tryToDraw();
<canvas id="waves_canvas"></canvas>
我对在WebGL中加载纹理的理解是,我们按照以下过程加载纹理:
- 我们通过使用
gl.uniform1i(gl.getUniformLocation(program, 'myTexture'), 0)
. 指定我们为 uniform sampler2D
使用的纹理单元
- 我们使用
gl.createTexture()
创建纹理。
- 然后我们使用
GL.activeTexture
选择要加载到的纹理单元。
- 我们使用
GL.bindTexture
. 将刚刚创建的纹理绑定到纹理单元
- 我们使用
GL.texImage2D
加载纹理。
我已经尝试在上面的 JSFiddle 中实现它,但我认为纹理加载不正确。我期待看到一个灰屏 (128,128,128),这应该是我加载的纹理,但是我看到的只是黑屏。
有谁知道我加载纹理是否正确?
当我 运行 您在 Chrome 中的代码时,我在 JavaScript 控制台中收到此警告
[.WebGL-0x7f9d4101ce00]RENDER WARNING: texture bound to texture unit 0 is not renderable. It might be non-power-of-2 or have incompatible texture filtering (maybe)?
您的纹理没有 mip,因此您需要通过调用 gl.generateMipmap(gl.TEXTURE_2D)
创建 mip,或者您需要通过调用 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
来设置过滤以便不需要 mip
见this
function tryToDraw() {
vertexShaderCode = `#version 100
precision mediump float;
attribute vec2 vertex_attrib;
void main (void)
{
gl_Position = vec4 (vertex_attrib, 0.0, 1.0) ;
}
`;
fragmentShaderCode = `#version 100
precision mediump float;
uniform sampler2D myTexture;
void main (void) {
vec2 texcoord = gl_FragCoord.xy / 1024.0;
gl_FragColor = vec4(texture2D (myTexture, texcoord).rgb, 1.0);
}
`;
var canvas = document.getElementById('waves_canvas');
var gl = canvas.getContext('webgl');
var program = gl.createProgram();
var textureArr = new Uint8Array(1024 * 1024 * 3).fill(128);
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderCode);
gl.compileShader(vertexShader);
gl.attachShader(program, vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderCode);
gl.compileShader(fragmentShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.validateProgram(program);
console.log(gl.getProgramParameter(program, gl.VALIDATE_STATUS));
gl.useProgram(program);
var location = gl.getUniformLocation(program, 'myTexture');
gl.uniform1i(location, 0);
var texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1024, 1024, 0, gl.RGB, gl.UNSIGNED_BYTE, textureArr);
var vertexPositions = new Float32Array([-1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0]);
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertexPositions, gl.STATIC_DRAW);
var vPosAttrLoc = gl.getAttribLocation(program, 'vertex_attrib');
gl.enableVertexAttribArray(vPosAttrLoc);
gl.vertexAttribPointer(vPosAttrLoc, 2, gl.FLOAT, false, 2 * vertexPositions.BYTES_PER_ELEMENT, null);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
tryToDraw();
<canvas id="waves_canvas"></canvas>
下次请使用snippet。
我正在尝试创建纹理(到处都是灰色)并使用 WebGL 将其渲染为 canvas。
我在这里尝试过:
function tryToDraw() {
vertexShaderCode = `#version 100
precision mediump float;
attribute vec2 vertex_attrib;
void main (void)
{
gl_Position = vec4 (vertex_attrib, 0.0, 1.0) ;
}
`;
fragmentShaderCode = `#version 100
precision mediump float;
uniform sampler2D myTexture;
void main (void) {
vec2 texcoord = gl_FragCoord.xy / 1024.0;
gl_FragColor = vec4(texture2D (myTexture, texcoord).rgb, 1.0);
}
`;
var canvas = document.getElementById('waves_canvas');
var gl = canvas.getContext('webgl');
var program = gl.createProgram();
var textureArr = new Uint8Array(1024 * 1024 * 3).fill(128);
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderCode);
gl.compileShader(vertexShader);
gl.attachShader(program, vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderCode);
gl.compileShader(fragmentShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.validateProgram(program);
console.log(gl.getProgramParameter(program, gl.VALIDATE_STATUS));
gl.useProgram(program);
var location = gl.getUniformLocation(program, 'myTexture');
gl.uniform1i(location, 0);
var texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1024, 1024, 0, gl.RGB, gl.UNSIGNED_BYTE, textureArr);
var vertexPositions = new Float32Array([-1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0]);
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertexPositions, gl.STATIC_DRAW);
var vPosAttrLoc = gl.getAttribLocation(program, 'vertex_attrib');
gl.enableVertexAttribArray(vPosAttrLoc);
gl.vertexAttribPointer(vPosAttrLoc, 2, gl.FLOAT, false, 2 * vertexPositions.BYTES_PER_ELEMENT, null);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
tryToDraw();
<canvas id="waves_canvas"></canvas>
我对在WebGL中加载纹理的理解是,我们按照以下过程加载纹理:
- 我们通过使用
gl.uniform1i(gl.getUniformLocation(program, 'myTexture'), 0)
. 指定我们为 - 我们使用
gl.createTexture()
创建纹理。 - 然后我们使用
GL.activeTexture
选择要加载到的纹理单元。 - 我们使用
GL.bindTexture
. 将刚刚创建的纹理绑定到纹理单元
- 我们使用
GL.texImage2D
加载纹理。
uniform sampler2D
使用的纹理单元
我已经尝试在上面的 JSFiddle 中实现它,但我认为纹理加载不正确。我期待看到一个灰屏 (128,128,128),这应该是我加载的纹理,但是我看到的只是黑屏。
有谁知道我加载纹理是否正确?
当我 运行 您在 Chrome 中的代码时,我在 JavaScript 控制台中收到此警告
[.WebGL-0x7f9d4101ce00]RENDER WARNING: texture bound to texture unit 0 is not renderable. It might be non-power-of-2 or have incompatible texture filtering (maybe)?
您的纹理没有 mip,因此您需要通过调用 gl.generateMipmap(gl.TEXTURE_2D)
创建 mip,或者您需要通过调用 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
见this
function tryToDraw() {
vertexShaderCode = `#version 100
precision mediump float;
attribute vec2 vertex_attrib;
void main (void)
{
gl_Position = vec4 (vertex_attrib, 0.0, 1.0) ;
}
`;
fragmentShaderCode = `#version 100
precision mediump float;
uniform sampler2D myTexture;
void main (void) {
vec2 texcoord = gl_FragCoord.xy / 1024.0;
gl_FragColor = vec4(texture2D (myTexture, texcoord).rgb, 1.0);
}
`;
var canvas = document.getElementById('waves_canvas');
var gl = canvas.getContext('webgl');
var program = gl.createProgram();
var textureArr = new Uint8Array(1024 * 1024 * 3).fill(128);
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderCode);
gl.compileShader(vertexShader);
gl.attachShader(program, vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderCode);
gl.compileShader(fragmentShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.validateProgram(program);
console.log(gl.getProgramParameter(program, gl.VALIDATE_STATUS));
gl.useProgram(program);
var location = gl.getUniformLocation(program, 'myTexture');
gl.uniform1i(location, 0);
var texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1024, 1024, 0, gl.RGB, gl.UNSIGNED_BYTE, textureArr);
var vertexPositions = new Float32Array([-1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0]);
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertexPositions, gl.STATIC_DRAW);
var vPosAttrLoc = gl.getAttribLocation(program, 'vertex_attrib');
gl.enableVertexAttribArray(vPosAttrLoc);
gl.vertexAttribPointer(vPosAttrLoc, 2, gl.FLOAT, false, 2 * vertexPositions.BYTES_PER_ELEMENT, null);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
tryToDraw();
<canvas id="waves_canvas"></canvas>
下次请使用snippet。