2015-05-09 71 views
3

我正在爲unity3d編寫着色器。着色器使用多個渲染目標來呈現後期處理效果。Unity3d,多個渲染目標 - Direct3D/OpenGl中的不同行爲

但是,我遇到了一個有趣的問題。

當Unity3d運行在Direct3D模式,默認情況下所有的標準着色器將數據寫入到僅第一顏色緩衝液(即,具有索引0)。即如果我將3個顏色緩衝區添加到相機,請撥打Camera.Render帶索引0的顏色緩衝區將包含渲染場景,除非某些着色器專門寫入,否則所有其他緩衝區都將保持不變。我的着色器利用這種行爲(我使用緩衝區索引1和2來累積後期處理效果所需的數據)。

然而,在OpenGL模式下的標準unity3d着色器中的所有顏色緩衝區寫一次。即如果我將多個渲染緩衝區附加到相機上,請致電Camera.Render,所有3個緩衝區都將包含渲染場景的副本。

這打破了我在OpenGL模式下的着色器。

我該如何解決這個問題?我需要一次渲染整個場景,只有具有特定着色器的對象才能修改其他顏色緩衝區。

我需要渲染的場景一氣呵成,因爲使用圖層蒙版,使團結重新計算投影陰影的所有燈光,我需要的陰影是正確的。

建議?

+0

您是否嘗試過在相機上手動操作命令緩衝區? http://docs.unity3d.com/ScriptReference/Camera.GetCommandBuffers.html –

+0

@MaxYankov:不,如果你更具體,它會有所幫助。我發現我可以在那裏插入額外的命令,但我不知道我該怎麼處理緩衝區。我不記得D3D/OGL是否在任何地方記錄默認的MRT行爲。基本上,如果着色器只寫入第一個緩衝區,則在D3D上,二級緩衝區不變。在OGL上他們從第一緩衝區接收信息的副本。這是標準的統一着色器。 – SigTerm

+0

我希望我可以更具體一些,但我認爲我沒有足夠的經驗。但是,如果我遇到這個問題,這是我可以挖掘的地方。 –

回答

1

可悲的是,事實證明,「不寫入渲染目標之一」,是在OpenGL無證行爲。當爲正向渲染路徑編譯時,標準統一着色器產生gl_FragData[0] = ...;賦值並且只寫入一個緩衝區,這會觸發未記錄的行爲並導致混亂。

爲了解決這個問題,我需要作出統一寫入數據明確納入標準着色器附加渲染目標。不幸的是,這是無法完成的,因爲沒有「入口點」來「掛鉤」標準着色器並將其他數據寫入其他顏色緩衝區。最接近的是"finalcolor"修飾符,但它實際上不允許通過CG着色器寫入額外的緩衝區(這需要額外的數據來自片段着色器,這是從表面着色器不可訪問的),但只能修改一種顏色。

我決定重寫着色器的一部分(所以它不會引發在OpenGL無證行爲),並放棄了其在效合一陰影貼圖的支持。據我所知,沒有其他選擇沒有修改統一引擎(需要「特殊安排」和源代碼訪問)或用我自己的替換整個照明系統。