DBuffer.hlsl 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. #ifndef UNIVERSAL_DBUFFER_INCLUDED
  2. #define UNIVERSAL_DBUFFER_INCLUDED
  3. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  4. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl"
  5. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
  6. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DecalInput.hlsl"
  7. #if (defined(_DBUFFER_MRT1) || defined(_DBUFFER_MRT2) || defined(_DBUFFER_MRT3)) && !defined(_SURFACE_TYPE_TRANSPARENT)
  8. #define _DBUFFER
  9. #endif
  10. #define DBufferType0 half4
  11. #define DBufferType1 half4
  12. #define DBufferType2 half4
  13. #if defined(_DBUFFER_MRT3)
  14. #define OUTPUT_DBUFFER(NAME) \
  15. out DBufferType0 MERGE_NAME(NAME, 0) : SV_Target0, \
  16. out DBufferType1 MERGE_NAME(NAME, 1) : SV_Target1, \
  17. out DBufferType2 MERGE_NAME(NAME, 2) : SV_Target2
  18. #define DECLARE_DBUFFER_TEXTURE(NAME) \
  19. TEXTURE2D_X_HALF(MERGE_NAME(NAME, 0)); \
  20. TEXTURE2D_X_HALF(MERGE_NAME(NAME, 1)); \
  21. TEXTURE2D_X_HALF(MERGE_NAME(NAME, 2));
  22. #define FETCH_DBUFFER(NAME, TEX, unCoord2) \
  23. DBufferType0 MERGE_NAME(NAME, 0) = LOAD_TEXTURE2D_X(MERGE_NAME(TEX, 0), unCoord2); \
  24. DBufferType1 MERGE_NAME(NAME, 1) = LOAD_TEXTURE2D_X(MERGE_NAME(TEX, 1), unCoord2); \
  25. DBufferType2 MERGE_NAME(NAME, 2) = LOAD_TEXTURE2D_X(MERGE_NAME(TEX, 2), unCoord2);
  26. #define ENCODE_INTO_DBUFFER(DECAL_SURFACE_DATA, NAME) EncodeIntoDBuffer(DECAL_SURFACE_DATA, MERGE_NAME(NAME,0), MERGE_NAME(NAME,1), MERGE_NAME(NAME,2))
  27. #define DECODE_FROM_DBUFFER(NAME, DECAL_SURFACE_DATA) DecodeFromDBuffer(MERGE_NAME(NAME,0), MERGE_NAME(NAME,1), MERGE_NAME(NAME,2), DECAL_SURFACE_DATA)
  28. #elif defined(_DBUFFER_MRT2)
  29. #define OUTPUT_DBUFFER(NAME) \
  30. out DBufferType0 MERGE_NAME(NAME, 0) : SV_Target0, \
  31. out DBufferType1 MERGE_NAME(NAME, 1) : SV_Target1
  32. #define DECLARE_DBUFFER_TEXTURE(NAME) \
  33. TEXTURE2D_X_HALF(MERGE_NAME(NAME, 0)); \
  34. TEXTURE2D_X_HALF(MERGE_NAME(NAME, 1));
  35. #define FETCH_DBUFFER(NAME, TEX, unCoord2) \
  36. DBufferType0 MERGE_NAME(NAME, 0) = LOAD_TEXTURE2D_X(MERGE_NAME(TEX, 0), unCoord2); \
  37. DBufferType1 MERGE_NAME(NAME, 1) = LOAD_TEXTURE2D_X(MERGE_NAME(TEX, 1), unCoord2);
  38. #define ENCODE_INTO_DBUFFER(DECAL_SURFACE_DATA, NAME) EncodeIntoDBuffer(DECAL_SURFACE_DATA, MERGE_NAME(NAME,0), MERGE_NAME(NAME,1))
  39. #define DECODE_FROM_DBUFFER(NAME, DECAL_SURFACE_DATA) DecodeFromDBuffer(MERGE_NAME(NAME,0), MERGE_NAME(NAME,1), DECAL_SURFACE_DATA)
  40. #else
  41. #define OUTPUT_DBUFFER(NAME) \
  42. out DBufferType0 MERGE_NAME(NAME, 0) : SV_Target0
  43. #define DECLARE_DBUFFER_TEXTURE(NAME) \
  44. TEXTURE2D_X_HALF(MERGE_NAME(NAME, 0));
  45. #define FETCH_DBUFFER(NAME, TEX, unCoord2) \
  46. DBufferType0 MERGE_NAME(NAME, 0) = LOAD_TEXTURE2D_X(MERGE_NAME(TEX, 0), unCoord2);
  47. #define ENCODE_INTO_DBUFFER(DECAL_SURFACE_DATA, NAME) EncodeIntoDBuffer(DECAL_SURFACE_DATA, MERGE_NAME(NAME,0))
  48. #define DECODE_FROM_DBUFFER(NAME, DECAL_SURFACE_DATA) DecodeFromDBuffer(MERGE_NAME(NAME,0), DECAL_SURFACE_DATA)
  49. #endif
  50. void EncodeIntoDBuffer(DecalSurfaceData surfaceData
  51. , out DBufferType0 outDBuffer0
  52. #if defined(_DBUFFER_MRT2) || defined(_DBUFFER_MRT3)
  53. , out DBufferType1 outDBuffer1
  54. #endif
  55. #if defined(_DBUFFER_MRT3)
  56. , out DBufferType2 outDBuffer2
  57. #endif
  58. )
  59. {
  60. outDBuffer0 = surfaceData.baseColor;
  61. #if defined(_DBUFFER_MRT2) || defined(_DBUFFER_MRT3)
  62. outDBuffer1 = half4(surfaceData.normalWS.xyz * 0.5 + 0.5, surfaceData.normalWS.w);
  63. #endif
  64. #if defined(_DBUFFER_MRT3)
  65. outDBuffer2 = half4(surfaceData.metallic, surfaceData.occlusion, surfaceData.smoothness, surfaceData.MAOSAlpha);
  66. #endif
  67. }
  68. void DecodeFromDBuffer(
  69. DBufferType0 inDBuffer0
  70. #if defined(_DBUFFER_MRT2) || defined(_DBUFFER_MRT3)
  71. , DBufferType1 inDBuffer1
  72. #endif
  73. #if defined(_DBUFFER_MRT3) || defined(DECALS_4RT)
  74. , DBufferType2 inDBuffer2
  75. #endif
  76. , out DecalSurfaceData surfaceData
  77. )
  78. {
  79. ZERO_INITIALIZE(DecalSurfaceData, surfaceData);
  80. surfaceData.baseColor = inDBuffer0;
  81. #if defined(_DBUFFER_MRT2) || defined(_DBUFFER_MRT3)
  82. // Use (254.0 / 255.0) instead of 0.5 to allow to encode 0 perfectly (encode as 127)
  83. // Range goes from -0.99607 to 1.0039
  84. surfaceData.normalWS.xyz = inDBuffer1.xyz * 2.0 - (254.0 / 255.0);
  85. surfaceData.normalWS.w = inDBuffer1.w;
  86. #endif
  87. #if defined(_DBUFFER_MRT3)
  88. surfaceData.metallic = inDBuffer2.x;
  89. surfaceData.occlusion = inDBuffer2.y;
  90. surfaceData.smoothness = inDBuffer2.z;
  91. surfaceData.MAOSAlpha = inDBuffer2.w;
  92. #endif
  93. }
  94. DECLARE_DBUFFER_TEXTURE(_DBufferTexture);
  95. void ApplyDecal(float4 positionCS,
  96. inout half3 baseColor,
  97. inout half3 specularColor,
  98. inout half3 normalWS,
  99. inout half metallic,
  100. inout half occlusion,
  101. inout half smoothness)
  102. {
  103. FETCH_DBUFFER(DBuffer, _DBufferTexture, int2(positionCS.xy));
  104. DecalSurfaceData decalSurfaceData;
  105. DECODE_FROM_DBUFFER(DBuffer, decalSurfaceData);
  106. // using alpha compositing https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch23.html, mean weight of 1 is neutral
  107. // Note: We only test weight (i.e decalSurfaceData.xxx.w is < 1.0) if it can save something
  108. baseColor.xyz = baseColor.xyz * decalSurfaceData.baseColor.w + decalSurfaceData.baseColor.xyz;
  109. #if defined(_DBUFFER_MRT2) || defined(_DBUFFER_MRT3)
  110. // Always test the normal as we can have decompression artifact
  111. if (decalSurfaceData.normalWS.w < 1.0)
  112. {
  113. normalWS.xyz = normalize(normalWS.xyz * decalSurfaceData.normalWS.w + decalSurfaceData.normalWS.xyz);
  114. }
  115. #endif
  116. #if defined(_DBUFFER_MRT3)
  117. #ifdef _SPECULAR_SETUP
  118. if (decalSurfaceData.MAOSAlpha.x < 1.0)
  119. {
  120. half3 decalSpecularColor = ComputeFresnel0((decalSurfaceData.baseColor.w < 1.0) ? decalSurfaceData.baseColor.xyz : half3(1.0, 1.0, 1.0), decalSurfaceData.metallic, DEFAULT_SPECULAR_VALUE);
  121. specularColor = specularColor * decalSurfaceData.MAOSAlpha + decalSpecularColor * (1.0f - decalSurfaceData.MAOSAlpha);
  122. }
  123. #else
  124. metallic = metallic * decalSurfaceData.MAOSAlpha + decalSurfaceData.metallic;
  125. #endif
  126. occlusion = occlusion * decalSurfaceData.MAOSAlpha + decalSurfaceData.occlusion;
  127. smoothness = smoothness * decalSurfaceData.MAOSAlpha + decalSurfaceData.smoothness;
  128. #endif
  129. }
  130. void ApplyDecalToBaseColor(float4 positionCS, inout half3 baseColor)
  131. {
  132. FETCH_DBUFFER(DBuffer, _DBufferTexture, int2(positionCS.xy));
  133. DecalSurfaceData decalSurfaceData;
  134. DECODE_FROM_DBUFFER(DBuffer, decalSurfaceData);
  135. // using alpha compositing https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch23.html, mean weight of 1 is neutral
  136. // Note: We only test weight (i.e decalSurfaceData.xxx.w is < 1.0) if it can save something
  137. baseColor.xyz = baseColor.xyz * decalSurfaceData.baseColor.w + decalSurfaceData.baseColor.xyz;
  138. }
  139. void ApplyDecalToBaseColorAndNormal(float4 positionCS, inout half3 baseColor, inout half3 normalWS)
  140. {
  141. half3 specular = 0;
  142. half metallic = 0;
  143. half occlusion = 0;
  144. half smoothness = 0;
  145. ApplyDecal(positionCS,
  146. baseColor,
  147. specular,
  148. normalWS,
  149. metallic,
  150. occlusion,
  151. smoothness);
  152. }
  153. void ApplyDecalToSurfaceData(float4 positionCS, inout SurfaceData surfaceData, inout InputData inputData)
  154. {
  155. #ifdef _SPECULAR_SETUP
  156. half metallic = 0;
  157. ApplyDecal(positionCS,
  158. surfaceData.albedo,
  159. surfaceData.specular,
  160. inputData.normalWS,
  161. metallic,
  162. surfaceData.occlusion,
  163. surfaceData.smoothness);
  164. #else
  165. half3 specular = 0;
  166. ApplyDecal(positionCS,
  167. surfaceData.albedo,
  168. specular,
  169. inputData.normalWS,
  170. surfaceData.metallic,
  171. surfaceData.occlusion,
  172. surfaceData.smoothness);
  173. #endif
  174. }
  175. #endif // UNIVERSAL_DBUFFER_INCLUDED