gpt4 book ai didi

glsl - 来自同一程序的多个输出纹理

转载 作者:行者123 更新时间:2023-12-02 14:58:24 24 4
gpt4 key购买 nike

我正在尝试学习如何利用 gl.drawBuffer() 功能从 WebGL2 中的同一程序执行多个输出。

我看了《OpenGL ES 3.0 编程指南》一书,第 11 章列出了发生多输出所需的内容。然而,着色器源代码示例非常简单,仅输出常量值。

我想知道是否有人有更好的例子?或者是否可以解释 TextureCoordinates 发生了什么变化?在普通着色器代码中,我会使用它从我的输入中查找数据值并将它们写出。现在面对多种布局,不同的TextureCoordinates如何对应每种布局呢?我的 viewPort 的尺寸会发生什么变化?对应哪个输出Texture?

以下是我理解的一些步骤:

  1. 创建一个颜色附件数组 GL_COLOR_ATTACHMENT0,...
  2. 为每个输出创建一个帧缓冲区对象
  3. 创建输出纹理
  4. 对于每个 FB:

    • 绑定(bind)帧缓冲区
    • 绑定(bind)纹理
    • 将纹理与 FBO 相关联:frameBufferTexture2D (..., color_attchment_from_step1)
  5. 调用 drawBuffers 传递颜色附件数组

在着色器内部访问这样的输出值:

layout(location = 0) out vec4 fragData0;

layout(location = 1) out vec4 fragData1;

最佳答案

你只需要一个帧缓冲对象。您将所有纹理附加到它上面。所以你的步骤是

  1. 创建帧缓冲区对象和 BindFramebuffer
  2. 创建输出纹理
  3. 对于每个纹理:
  4. 将纹理与 FBO 关联:frameBufferTexture2D(...)
  5. 创建一个颜色附件数组 GL_COLOR_ATTACHMENT0,...
  6. 调用 drawBuffers 传递颜色附件数组

function main() {
const gl = document.querySelector('canvas').getContext('webgl2');
if (!gl) {
return alert("need WebGL2");
}
const vs = `
#version 300 es
void main() {
gl_PointSize = 300.0;
gl_Position = vec4(0, 0, 0, 1);
}
`;

const fs = `
#version 300 es
precision mediump float;

layout(location = 0) out vec4 outColor0;
layout(location = 1) out vec4 outColor1;
layout(location = 2) out vec4 outColor2;
layout(location = 3) out vec4 outColor3;

void main() {
outColor0 = vec4(1, .5, .3, .7); // orange
outColor1 = vec4(.6, .5, .4, .3); // brown
outColor2 = vec4(.2, .8, .0, 1); // green
outColor3 = vec4(.3, .4, .9, .6); // blue
}
`

const program = twgl.createProgram(gl, [vs, fs]);

const textures = [];
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
for (let i = 0; i < 4; ++i) {
const tex = gl.createTexture();
textures.push(tex);
gl.bindTexture(gl.TEXTURE_2D, tex);
const width = 1;
const height = 1;
const level = 0;
gl.texImage2D(gl.TEXTURE_2D, level, gl.RGBA, width, height, 0,
gl.RGBA, gl.UNSIGNED_BYTE, null);
// attach texture to framebuffer
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i,
gl.TEXTURE_2D, tex, level);
}

// our framebuffer textures are only 1x1 pixels
gl.viewport(0, 0, 1, 1);

// tell it we want to draw to all 4 attachments
gl.drawBuffers([
gl.COLOR_ATTACHMENT0,
gl.COLOR_ATTACHMENT1,
gl.COLOR_ATTACHMENT2,
gl.COLOR_ATTACHMENT3,
]);

// draw a single point
gl.useProgram(program);
{
const offset = 0;
const count = 1
gl.drawArrays(gl.POINT, 0, 1);
}

// --- below this is not relevant to the question but just so we
// --- we can see it's working

// render the 4 textures
const fs2 = `
#version 300 es
precision mediump float;
uniform sampler2D tex[4];
out vec4 outColor;
void main() {
vec4 colors[4];

// you can't index textures with non-constant integer expressions
// in WebGL2 (you can in WebGL1 lol)
colors[0] = texture(tex[0], vec2(0));
colors[1] = texture(tex[1], vec2(0));
colors[2] = texture(tex[2], vec2(0));
colors[3] = texture(tex[3], vec2(0));

vec4 color = vec4(0);
for (int i = 0; i < 4; ++i) {
float x = gl_PointCoord.x * 4.0;
float amount = step(float(i), x) * step(x, float(i + 1));
color = mix(color, colors[i], amount);
}
outColor = vec4(color.rgb, 1);
}
`;
const prgInfo2 = twgl.createProgramInfo(gl, [vs, fs2]);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.useProgram(prgInfo2.program);
// binds all the textures and set the uniforms
twgl.setUniforms(prgInfo2, {
tex: textures,
});
gl.drawArrays(gl.POINTS, 0, 1);
}
main();
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>

关于glsl - 来自同一程序的多个输出纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51793336/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com