假設在RT上去渲染一個Pixel,RT的背景顏色是B,按順序去寫顏色,先寫A1, 再寫A2,那麼最終的到的顏色
Art = (A1 Blend (A2 Blend B))
展開 :
A2 Blend B = A2 * f2 + B * f2'
A1 Blend (A2 Blend B) = A1 * f1 + (A2 * f2 + B * f2') * f1'
得到 :
Art = A1 * f1 + (A2 * f2 + B * f2') * f1' = A1 * f1 + A2 * f2 * f1' + B * f2' * f1'
令
C = A1 * f1 + A2 * f2 * f1'
T = f2' * f1'
得到 Art= C + T * B
問題來了,如果你拿一張RT渲染到 RawImage 上,按照以上的公式來推導,得到:
Bi = UI 的背景顏色
A = Art Blend Bt = Art * frt + Bt * frt' = (C + T * B) * frt + Bt * frt'
但是實際上,我們真正需要的只是想把RT上的黑色背景替換為UI的背景,再覆蓋到UI上而已,也就是
A = C + T * Bi
那我們要實現A = C + T * Bi,要怎麼做。
這裡的做法就是,把C, T 都存到RT上,當RT賦予Image的時候,再從RT上取回C,T,就可以順利地計算 A = C + T * Bi。
那怎麼才可以儲存C和T呢。
對於C的儲存,看上面的,渲染情境到RT上的情況:
C = A1 * f1 + A2 * f2 * f1' = A1 Blend ( A2 * f2 ) = A1 Blend ( A2 * f2 + B * f2') (當B = zero 的時候成立) =
A1 Blend ( A2 Blend B) (當B = zero 的時候成立)
所以,其實正常渲染情境的東西到RT上,RT的背景顏色RGB是黑色的話,RT的RGB 儲存的就是C了。
對於T的儲存,
T = f2' * f1'
可以利用RT的Alpha來儲存,Blend Op 沒有乘法操作,那麼可以 使用 ScrAlpha * Zero + DstAlpha * DstBlendFactor
並且 RT上的背景顏色的Alpha要是1.
最後給出實現:
假設一個Particle System 要渲染到 RT上,那麼 Particle System使用的Shader 應該要這樣:
BlendOp Add, Add
Blend SrcAlpha OneMinusSrcAlpha, Zero OneMinusSrcAlpha
ColorMask RGBA
那麼 RT 給到一個RawImage上,RawImage的材質用的Shader 應該要這樣 :
Blend One SrcAlpha