我试图了解渲染到特定纹理 mipmap 级别的正确方法。
在下面的示例中,我尝试将青色渲染为 .mipmap 级别 1 texture
。如果我在通话中将级别从1
更改为,画布将按预期显示青色。但是我不明白为什么这里只有级别有效,因为 WebGL 2/OpenGL ES 3 规范支持非零级别。0
framebufferTexture2D
0
我还尝试过显式分离级别 0(绑定到null
)和各种其他组合(即使用texImage2D
而不是texStorage2D
),但似乎没有一个组合呈现到 mipmap 级别。
const
canvas = document.createElement('canvas'),
gl = canvas.getContext('webgl2'),
triangle = new Float32Array([ 0, 0, 2, 0, 0, 2 ]);
texture = gl.createTexture(),
framebuffer = gl.createFramebuffer(),
size = 100,
vertex = createShader(gl.VERTEX_SHADER, `#version 300 es
precision mediump float;
uniform sampler2D sampler;
layout(location = 0) in vec2 position;
out vec4 color;
void main() {
color = textureLod(sampler, position, 0.5);
gl_Position = vec4(position * 2. - 1., 0, 1);
}`
),
fragment = createShader(gl.FRAGMENT_SHADER, `#version 300 es
precision mediump float;
in vec4 color;
out vec4 fragColor;
void main() {
fragColor = color;
}`
),
program = gl.createProgram();
canvas.width = canvas.height = size;
document.body.appendChild(canvas);
gl.viewport(0, 0, size, size);
gl.attachShader(program, vertex);
gl.attachShader(program, fragment);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error('program');
}
gl.useProgram(program);
// Create a big triangle
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, triangle, gl.STATIC_DRAW);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(0);
// Create a texture with mipmap levels 0 (base) and 1
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texStorage2D(gl.TEXTURE_2D, 2, gl.RGB8, 2, 2);
// Setup framebuffer to render to texture level 1, clear to cyan
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
texture,
1 // Switching this to `0` will work fine
);
const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (status !== gl.FRAMEBUFFER_COMPLETE) {
console.error(status);
}
gl.clearColor(0, 1, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// Detach framebuffer, clear to red
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.clearColor(1, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw the triangle
gl.drawArrays(gl.TRIANGLES, 0, 3);
// Some utility functions to cleanup the above code
function createShader(type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.log(gl.getShaderInfoLog(shader));
}
return shader;
}
我希望我在设置中做错了什么,但我找不到很多这样的例子。