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

Glsl 来自同一程序的多个输出纹理,glsl,webgl2,Glsl,Webgl2,我正在尝试学习如何利用gl.drawBuffer的功能在WebGL2中从同一个程序执行多个输出 我看了《OpenGL ES 3.0编程指南》一书,第11章列出了进行多输出所需的内容。但是,着色器源示例仅输出常量值非常简单 我想知道是否有人有更好的例子?或者,如果有人能解释纹理坐标发生了什么变化?在普通着色器代码中,我将使用它从输入中查找数据值并写出它们。现在面对多个布局,纹理坐标的变化如何对应每个布局?视口的尺寸会发生什么变化?这与哪个输出纹理相对应 以下是我理解它们的一些步骤: 创建颜色附件数

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

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

我想知道是否有人有更好的例子?或者,如果有人能解释纹理坐标发生了什么变化?在普通着色器代码中,我将使用它从输入中查找数据值并写出它们。现在面对多个布局,纹理坐标的变化如何对应每个布局?视口的尺寸会发生什么变化?这与哪个输出纹理相对应

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

创建颜色附件数组GL_Color_ATTACHMENT0。。。 为每个输出创建帧缓冲区对象 创建输出纹理 对于每个FB:

绑定帧缓冲区 黏结结构 将纹理与FBO关联:frameBufferTexture2D…,来自步骤1的颜色 调用drawBuffers传递颜色附件数组

在着色器内部,访问如下输出值:

layout(location = 0) out vec4 fragData0;

layout(location = 1) out vec4 fragData1;

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

创建帧缓冲区对象并绑定帧缓冲区 创建输出纹理 对于每个纹理: 将纹理与FBO关联:frameBufferTexture2D。。。 创建颜色附件数组GL_Color_ATTACHMENT0。。。 调用drawBuffers传递颜色附件数组 主要功能{ const gl=document.querySelector'canvas.getContext'webgl2'; 如果!德国劳埃德船级社{ 返回警报需要WebGL2; } 常数vs=` 300版es 真空总管{ gl_PointSize=300.0; gl_位置=向量40,0,0,1; } `; 常数fs=` 300版es 精密中泵浮子; layoutlocation=0输出向量4输出颜色0; layoutlocation=1输出向量4输出颜色1; layoutlocation=2输出向量4输出颜色2; layoutlocation=3输出向量4输出颜色3; 真空总管{ outColor0=vec41.5.3.7;//橙色 outColor1=vec4.6.5.4.3;//棕色 outColor2=vec4.2、.8、.0、1;//绿色 outColor3=vec4.3、.4、.9、.6;//蓝色 } ` const program=twgl.createProgramgl[vs,fs]; 常量纹理=[]; const fb=gl.createFramebuffer; gl.bindframebuffer gl.FRAMEBUFFER,fb; 对于设i=0;i<4;++i{ 常量tex=gl.createTexture; 纹理.pushtex; gl.bindTexturegl.TEXTURE_2D,tex; 常数宽度=1; 常数高度=1; 常数级=0; gl.texImage2Dgl.TEXTURE_2D,标高,gl.RGBA,宽度,高度,0, gl.RGBA,gl.UNSIGNED_字节,null; //将纹理附加到帧缓冲区 gl.framebufferTexture2Dgl.FRAMEBUFFER,gl.COLOR_附件0+i, gl.TEXTURE_2D、tex、level; } //我们的帧缓冲区纹理只有1x1像素 总图视口0,0,1,1; //告诉它我们要绘制所有4个附件 德国劳埃德船级社[ gl.COLOR_附件0, gl.COLOR_附件1, gl.COLOR_附件2, gl.COLOR_附件3, ]; //画一个点 gl.useprogrammProgram; { 常数偏移=0; 常数计数=1 gl.drawArraysgl.POINT,0,1; } //-下面这与问题无关,但我们仅此而已 //-我们可以看到它在工作 //渲染4个纹理 常数fs2=` 300版es 精密中泵浮子; 均匀取样器2d-tex[4]; 外显vec4外显色; 真空总管{ vec4颜色[4]; //不能使用非常量整数表达式索引纹理 //在WebGL2中,您可以在WebGL1 lol中 颜色[0]=texturetex[0],向量20; 颜色[1]=texturetex[1],vec20; 颜色[2]=texturetex[2],vec20; 颜色[3]=texturetex[3],vec20; vec4颜色=vec40; 对于int i=0;i<4;++i{ 浮点x=gl_PointCoord.x*4.0; 浮动金额=逐步浮动i,x*stepx,浮动i+1; 颜色=混合颜色,颜色[i],数量; } outColor=vec4color.rgb,1; } `; const prgInfo2=twgl.createProgramInfogl[vs,fs2]; gl.bindframebuffer gl.FRAMEBUFFER,空; gl.viewport0,0,gl.canvas.width,gl.canvas.height; gl.useProgramprgInfo2.program; //绑定所有纹理并设置制服 twgl.setUniformsprgInfo2{ 特克斯:纹理, }; gl.drawArraysgl.POINTS,0,1; } 主要的
您只需要一个帧缓冲区对象。将所有纹理都附加到它。所以你的步骤是

创建帧缓冲区对象并绑定帧缓冲区 创建输出纹理 对于每个纹理: 将纹理与FBO关联:frameBufferTexture2D。。。 创建颜色附件数组GL_Color_ATTACHMENT0。。。 调用drawBuffers传递颜色附件数组 主要功能{ const gl=document.querySelector'canvas.getContext'webgl2'; 如果!德国劳埃德船级社{ 返回警报需要WebGL2; } 常数vs=` 300版es 真空总管{ gl_PointSize=300.0; gl_位置=向量40,0,0,1; } `; 常数fs=` 300版es 精密中泵浮子; layoutlocation=0输出向量4输出颜色0; layoutlocation=1输出向量4输出颜色1; layoutlocation=2输出向量4输出颜色2; layoutlocation=3输出向量4输出颜色3; 真空总管{ outColor0=vec41.5.3.7;//橙色 outColor1=vec4.6.5.4.3;//棕色 outColor2=vec4.2、.8、.0、1;//绿色 outColor3=vec4.3、.4、.9、.6;//蓝色 } ` const program=twgl.createProgramgl[vs,fs]; 常量纹理=[]; const fb=gl.createFramebuffer; gl.bindframebuffer gl.FRAMEBUFFER,fb; 对于let i=0;i<4++我{ 常量tex=gl.createTexture; 纹理.pushtex; gl.bindTexturegl.TEXTURE_2D,tex; 常数宽度=1; 常数高度=1; 常数级=0; gl.texImage2Dgl.TEXTURE_2D,标高,gl.RGBA,宽度,高度,0, gl.RGBA,gl.UNSIGNED_字节,null; //将纹理附加到帧缓冲区 gl.framebufferTexture2Dgl.FRAMEBUFFER,gl.COLOR_附件0+i, gl.TEXTURE_2D、tex、level; } //我们的帧缓冲区纹理只有1x1像素 总图视口0,0,1,1; //告诉它我们要绘制所有4个附件 德国劳埃德船级社[ gl.COLOR_附件0, gl.COLOR_附件1, gl.COLOR_附件2, gl.COLOR_附件3, ]; //画一个点 gl.useprogrammProgram; { 常数偏移=0; 常数计数=1 gl.drawArraysgl.POINT,0,1; } //-下面这与问题无关,但我们仅此而已 //-我们可以看到它在工作 //渲染4个纹理 常数fs2=` 300版es 精密中泵浮子; 均匀取样器2d-tex[4]; 外显vec4外显色; 真空总管{ vec4颜色[4]; //不能使用非常量整数表达式索引纹理 //在WebGL2中,您可以在WebGL1 lol中 颜色[0]=texturetex[0],向量20; 颜色[1]=texturetex[1],vec20; 颜色[2]=texturetex[2],vec20; 颜色[3]=texturetex[3],vec20; vec4颜色=vec40; 对于int i=0;i<4;++i{ 浮点x=gl_PointCoord.x*4.0; 浮动金额=逐步浮动i,x*stepx,浮动i+1; 颜色=混合颜色,颜色[i],数量; } outColor=vec4color.rgb,1; } `; const prgInfo2=twgl.createProgramInfogl[vs,fs2]; gl.bindframebuffer gl.FRAMEBUFFER,空; gl.viewport0,0,gl.canvas.width,gl.canvas.height; gl.useProgramprgInfo2.program; //绑定所有纹理并设置制服 twgl.setUniformsprgInfo2{ 特克斯:纹理, }; gl.drawArraysgl.POINTS,0,1; } 主要的
非常感谢@gman。我仍然要问的问题是:所有的纹理都需要相同的大小吗?看起来这是输出不同颜色的一个很好的解决方案,但对于输出任意大小的纹理可能没有多大用处。如果可能的话,我需要不同的纹理坐标输入变量来传递给我的片段源。除此之外,缩放是如何工作的?我想目前我是通过设置gl.viewport0,0,width,height来设置比例的,这就是我如何知道当在片段着色器中得到不同的vTexCoords时,我必须将s和t乘以X和Y上的比例才能得到逻辑坐标。因此,如果允许输出纹理具有不同的大小,我还需要不同的比例因子作为输入?附加到同一帧缓冲区的纹理不能有不同的大小。它们必须是相同的尺寸。我也不确定texcoords和viewport有什么关系。在大多数着色器中,2不相关。此外,您还可以创建自己的属性,这样您的属性不仅限于一组texcoords,甚至不必有纹理coords。再次感谢您的澄清。我正在尝试这样做,但我需要在第一次绘制后附加另一个纹理。我注意到您将帧缓冲区绑定为NULL。我不能那样做。但是,如果我只调用gl.framebufferTexture2D,我会得到一个FRAMEBUFFER\u complete\u DIMENSIONS状态。在进行多重输出后,如何重置FB?非常感谢@gman。我仍然要问的问题是:所有的纹理都需要相同的大小吗?看起来这是输出不同颜色的一个很好的解决方案,但对于输出任意大小的纹理可能没有多大用处。如果可能的话,我需要不同的纹理坐标输入变量来传递给我的片段源。除此之外,缩放是如何工作的?我想目前我是通过设置gl.viewport0,0,width,height来设置比例的,这就是我如何知道当在片段着色器中得到不同的vTexCoords时,我必须将s和t乘以X和Y上的比例才能得到逻辑坐标。因此,如果允许输出纹理具有不同的大小,我还需要不同的比例因子作为输入?附加到同一帧缓冲区的纹理不能有不同的大小。它们必须是相同的尺寸。我也不确定texcoords和viewport有什么关系。在大多数着色器中,2不相关。此外,您还可以创建自己的属性,这样您的属性就不局限于一组texcoords,甚至不需要
我需要纹理坐标。再次感谢您的澄清。我正在尝试这样做,但是我需要在第一次绘制后附加另一个纹理。我注意到您将帧缓冲区绑定为NULL。我不能那样做。但是,如果我只调用gl.framebufferTexture2D,我会得到一个FRAMEBUFFER\u complete\u DIMENSIONS状态。在进行多重输出后,如何重置FB?谢谢