Ich versuche, den richtigen Ansatz zu verstehen, auf eine bestimmte Textur Mipmap-Ebene zu rendern.Rendern Textur mipmap Ebene
Im folgenden Beispiel versuche ich, die Farbe Cyan auf Mipmap Level 1 von texture
zu rendern. Wenn ich die Ebene von 1
zu 0
in dem Aufruf framebufferTexture2D
ändere, zeigt die Zeichenfläche Cyan wie erwartet an. Allerdings verstehe ich nicht, warum nur die Ebene 0
hier funktioniert, da in der WebGL 2/OpenGL ES 3-Spezifikation Nicht-Null-Ebenen unterstützt werden.
ich auch explizit versucht habe Abnehmen 0 (Bindung an null
) und verschiedene andere Kombinationen (das heißt mit texImage2D
statt texStorage2D
), aber keine der Kombinationen scheinen die Mipmapstufe zu machen.
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;
}
erwarte ich, dass ich etwas falsch im Setup mache, aber ich habe nicht in der Lage gewesen, dies viele Beispiele zu finden.
verwende ich in meiner Frage geklärt haben sollte, dass keiner dieser Arbeit auch nicht. Ich habe 0,5 da drin gelassen, als ich die Frage gepostet habe, weil es zumindest etwas außer Schwarz anzeigen sollte, wenn es zwischen den zwei Ebenen interpoliert. – grovesNL
aktualisierte Antwort .. – gman
hinzugefügt ein weiteres Problem mit 'Status' – gman