我正在为unity3d编写着色器。着色器使用多个渲染目标来渲染后处理效果。
但是,我遇到了一个有趣的问题。
当Unity3d在direct3d模式下运行时,默认情况下,所有标准着色器仅将数据写入第一个颜色缓冲区(即索引为0)。也就是说,如果我将3个颜色缓冲区附加到相机,则调用Camera.Render
索引为0的颜色缓冲区将包含渲染的场景,并且所有其他缓冲区将保持不变,除非某些着色器专门在其中写入。我的着色器利用了这种行为(我使用索引为1和2的缓冲区来积累后期处理效果所需的数据)。
但是,在OpenGL模式下,标准的unity3d着色器立即写入所有颜色缓冲区。即,如果我将多个渲染缓冲区附加到摄像机,则调用Camera.Render
所有3个缓冲区将包含渲染场景的副本。
这在OpenGL模式下破坏了我的着色器。
我该如何解决?我需要一次性渲染整个场景,只有具有特定着色器的对象才应修改其他颜色缓冲区。
我需要一劳永逸地渲染场景,因为使用图层蒙版会导致团结一致地重新计算所有灯光的投影仪阴影,因此我需要正确的阴影。
建议?
可悲的是,事实证明“不写入渲染目标之一”是opengl中未记录的行为。标准单位着色器在为正向渲染路径编译时会产生gl_FragData[0] = ...;
分配并仅写入一个缓冲区,这会触发未记录的行为并导致混乱。
为了解决该问题,我需要使数据显式地统一写入标准着色器中的其他渲染目标中。不幸的是,这无法完成,因为没有“入口”可以“钩住”标准着色器并将其他数据写入其他颜色缓冲区。与之最接近的是“ finalcolor”修饰符,但实际上它不允许通过CG着色器写入其他缓冲区(这要求其他数据来自片段着色器,而表面着色器无法访问该片段着色器),只能修改一种颜色。
我决定重写着色器的一部分(因此它不会触发OpenGL中未记录的行为),并放弃了在效果中使用统一阴影贴图支持。据我所知,除了修改统一引擎(需要“特殊安排”和访问源代码)或用我自己的整个照明系统替代之外,没有其他选择。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句