【问题标题】:unity3d, multiple render targets - different behavior in Direct3D/OpenGlunity3d,多个渲染目标 - Direct3D/OpenGl 中的不同行为
【发布时间】:2015-05-09 15:41:08
【问题描述】:

我正在为 unity3d 编写着色器。着色器使用多个渲染目标来渲染后期处理效果。

但是,我遇到了有趣的问题。

当 Unity3d 在 direct3d 模式下运行时,默认情况下,所有标准着色器仅将数据写入第一个颜色缓冲区(即索引为 0)。 IE。如果我将 3 个颜色缓冲区附加到相机,调用 Camera.Render 索引为 0 的颜色缓冲区将包含渲染场景,并且所有其他缓冲区将保持不变,除非某些着色器专门写入它们。我的着色器利用了这种行为(我使用索引为 1 和 2 的缓冲区来积累后期处理效果所需的数据)。

但是,在 OpenGL 模式下,标准 unity3d 着色器一次写入所有颜色缓冲区。 IE。如果我将多个渲染缓冲区附加到相机,请调用 Camera.Render 所有 3 个缓冲区将包含渲染场景的副本。

这会破坏我在 OpenGL 模式下的着色器。

我该如何解决这个问题?我需要一次性渲染整个场景,并且只有具有特定着色器的对象才能修改额外的颜色缓冲区。

我需要一次性渲染场景,因为使用图层蒙版会导致统一重新计算所有灯光的投影仪阴影,并且我需要正确的阴影。

建议?

【问题讨论】:

  • 您是否尝试过手动操作相机上的命令缓冲区? docs.unity3d.com/ScriptReference/Camera.GetCommandBuffers.html
  • @MaxYankov:不,如果你更具体一些会有所帮助。我看到我可以在那里插入其他命令,但我不确定我应该对缓冲区做什么。我不完全记得 D3D/OGL 是否在任何地方记录了默认的 MRT 行为。基本上,在 D3D 上,如果着色器仅写入第一个缓冲区,则二级缓冲区不会受到影响。在 OGL 上,他们从第一个缓冲区接收信息副本。那是标准的统一着色器。
  • 我希望我能更具体一些,但我认为我在这方面的经验不够。但是,如果我遇到这个问题,我会在这里挖掘。
  • @MaxYankov:我的意思是,我不知道任何 gl 命令会改变其他颜色缓冲区的默认行为。
  • @MaxYankov: :-\ 好的。明天我会检查 GL 规范,但我怀疑我会发现任何有用的东西。问题是统一并不能让我精确控制渲染的内容、时间和方式。因此,如果我开始使用图层,它会重新计算所有可见光的阴影贴图,从而导致阴影消失。如果它允许我指定一些对象应该使用它们的默认着色器绘制,则替换着色器可以工作。而且,当然没有可用于统一个人的Camera.Render 的源代码。叹息。

标签: opengl unity3d directx shader cg


【解决方案1】:

遗憾的是,事实证明“不写入渲染目标之一”是 opengl 中未记录的行为。标准的统一着色器在为前向渲染路径编译时会产生gl_FragData[0] = ...; 分配并仅写入一个缓冲区,这会触发未记录的行为并导致混乱。

为了解决这个问题,我需要统一将数据明确写入标准着色器中的其他渲染目标。不幸的是,这无法做到,因为没有“入口点”来“挂钩”标准着色器并将附加数据写入其他颜色缓冲区。最接近的是"finalcolor"修饰符,但它实际上不允许通过CG着色器写入额外的缓冲区(这需要额外的数据来自片段着色器,表面着色器无法访问),只能修改一种颜色。

我决定重写着色器的一部分(这样它就不会在 OpenGL 中触发未记录的行为)并放弃在效果中支持统一阴影贴图。据我所知,除了修改统一引擎(需要“特殊安排”和源代码访问)或用我自己的替换整个照明系统之外,没有其他选择。

【讨论】:

    猜你喜欢
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多