写入纹理GLSL

时间:2014-11-24 22:35:07

标签: c++ opengl glsl texture-mapping render-to-texture

我希望能够(在片段着色器中)将一个纹理添加到另一个纹理。现在我有投射纹理,并希望扩展它。

这是我到目前为止所拥有的:

我还绘制了viewfrustum,蓝色/灰色测试图像沿着该视图投影到恒定旋转的几何体上。

我的顶点着色器:

    ProjTexCoord = ProjectorMatrix * ModelTransform * raw_pos;

My Fragment Shader:

vec4 diffuse = texture(texture1, vs_st);
vec4 projTexColor = textureProj(texture2, ProjTexCoord);
vec4 shaded = diffuse; // max(intensity * diffuse, ambient); -- no shadows for now
    if (ProjTexCoord[0] > 0.0 || 
        ProjTexCoord[1] > 0.0 ||
        ProjTexCoord[0] < ProjTexCoord[2] || 
        ProjTexCoord[1] < ProjTexCoord[2]){
        diffuse = shaded;
    }else if(dot(n, projector_aim) < 0 ){
        diffuse = projTexColor;
    }else{
        diffuse = shaded;
    }

我想要实现的目标:

例如,当用户按下按钮时,我希望蓝色/灰色纹理写入球体上的灰色纹理,然后用旋转。想象一下,它可以拍摄一张照片&#34;或者在球体顶部绘画,以便在按下按钮后蓝色/灰色纹理与球体一起旋转。

当片段着色器对每个像素进行操作时,应该可以逐个像素地从一个纹理复制到另一个纹理,但我不知道如何,我可能在谷歌搜索错误的东西。

我如何在技术上实现这一目标?什么方法最通用?非常感谢您的建议,如果需要更多代码,请告知我们。

2 个答案:

答案 0 :(得分:2)

为了清楚起见,您希望将贴花烘焙到您的球体的灰色纹理中。

在绘制另一个对象时写入灰色纹理的麻烦是它不是一对一的。您可能正在向同一个纹素写入两次或更多次,或者单个片段可能需要在灰色纹理中写入多个纹素。听起来很有吸引力,因为你已经拥有了一个地方的所有坐标,但我不会这样做。

我首先创建一个纹理,其中包含灰色纹理中每个纹素的对象空间位置。这是关键,因此当您单击时可以渲染到灰色纹理(使用FBO)并知道每个纹素在当前视图中的位置或投影纹理的视图。可能存在边缘情况,其中相同的纹理位出现在多个三角形上。您可以通过使用纹理坐标作为顶点位置将球体渲染为灰色纹理来实现此目的。你可能需要一个浮点纹理,下面的图像可能不是球体的纹理映射,但是它可以用于演示:P。

enter image description here

因此,当您单击时,可以在启用了Alpha混合的情况下将全屏四边形渲染为灰色纹理。使用灰色纹理对象空间位置,每个片段计算蓝色纹理投影内的图像空间位置。丢弃纹理外部的碎片,并对内部碎片进行采样/混合。

enter image description here

答案 1 :(得分:0)

我认为你过于复杂了。

  • 写入经典着色器内的纹理(即不是计算着色器)仅针对最新硬件和最新的OpenGL版本和扩展实现。
  • 如果使用错误,可能会非常慢。它很容易引入管道停顿和CPU-GPU同步点
  • 像素着色器可能会成为一个非常缓慢的无法维护的分支和纹理提取混乱。
  • 所有这些混乱都将针对每一帧的每一个像素进行

解决方案:KISS

  • 只需在CPU端更新纹理即可。
  • 写入纹理,用所需内容替换部分
  • 更新只需要在您需要时进行一次。数据会一直存在,直到您重写它为止(每帧甚至一次,但每次更改请求只需一次)
  • 像素着色器是简单的死脑:没有分支,一个纹理
  • 要获得目标像素,请实施光线拾取(无论如何,对于任何非平凡的交​​互式3D图形程序,您都需要它)

P.S。 &#34;一切都应尽可能简单,但不能简单。&#34;艾尔伯特爱因斯坦。