Nav apraksta
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

ShaderPassDecal.hlsl 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. #if (SHADERPASS != SHADERPASS_DEPTHONLY) && (SHADERPASS != SHADERPASS_DBUFFER_PROJECTOR) && (SHADERPASS != SHADERPASS_DBUFFER_MESH) && (SHADERPASS != SHADERPASS_FORWARD_EMISSIVE_PROJECTOR) && (SHADERPASS != SHADERPASS_FORWARD_EMISSIVE_MESH) && (SHADERPASS != SHADERPASS_DECAL_SCREEN_SPACE_PROJECTOR) && (SHADERPASS != SHADERPASS_DECAL_SCREEN_SPACE_MESH) && (SHADERPASS != SHADERPASS_DECAL_GBUFFER_PROJECTOR) && (SHADERPASS != SHADERPASS_DECAL_GBUFFER_MESH)
  2. #error SHADERPASS_is_not_correctly_define
  3. #endif
  4. #if !defined(SHADERPASS)
  5. #error SHADERPASS_is_not_define
  6. #endif
  7. #if (SHADERPASS == SHADERPASS_DBUFFER_PROJECTOR) || (SHADERPASS == SHADERPASS_FORWARD_EMISSIVE_PROJECTOR) || (SHADERPASS == SHADERPASS_DECAL_SCREEN_SPACE_PROJECTOR) || (SHADERPASS == SHADERPASS_DECAL_GBUFFER_PROJECTOR)
  8. #define DECAL_PROJECTOR
  9. #endif
  10. #if (SHADERPASS == SHADERPASS_DBUFFER_MESH) || (SHADERPASS == SHADERPASS_FORWARD_EMISSIVE_MESH) || (SHADERPASS == SHADERPASS_DECAL_SCREEN_SPACE_MESH) || (SHADERPASS == SHADERPASS_DECAL_GBUFFER_MESH)
  11. #define DECAL_MESH
  12. #endif
  13. #if (SHADERPASS == SHADERPASS_DBUFFER_PROJECTOR) || (SHADERPASS == SHADERPASS_DBUFFER_MESH)
  14. #define DECAL_DBUFFER
  15. #endif
  16. #if (SHADERPASS == SHADERPASS_DECAL_SCREEN_SPACE_PROJECTOR) || (SHADERPASS == SHADERPASS_DECAL_SCREEN_SPACE_MESH)
  17. #define DECAL_SCREEN_SPACE
  18. #endif
  19. #if (SHADERPASS == SHADERPASS_DECAL_GBUFFER_PROJECTOR) || (SHADERPASS == SHADERPASS_DECAL_GBUFFER_MESH)
  20. #define DECAL_GBUFFER
  21. #endif
  22. #if (SHADERPASS == SHADERPASS_FORWARD_EMISSIVE_PROJECTOR) || (SHADERPASS == SHADERPASS_FORWARD_EMISSIVE_MESH)
  23. #define DECAL_FORWARD_EMISSIVE
  24. #endif
  25. #if ((!defined(_MATERIAL_AFFECTS_NORMAL) && defined(_MATERIAL_AFFECTS_ALBEDO)) || (defined(_MATERIAL_AFFECTS_NORMAL) && defined(_MATERIAL_AFFECTS_NORMAL_BLEND))) && (defined(DECAL_SCREEN_SPACE) || defined(DECAL_GBUFFER))
  26. #define DECAL_RECONSTRUCT_NORMAL
  27. #elif defined(DECAL_ANGLE_FADE)
  28. #define DECAL_LOAD_NORMAL
  29. #endif
  30. #ifdef _DECAL_LAYERS
  31. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareRenderingLayerTexture.hlsl"
  32. #endif
  33. #if defined(DECAL_LOAD_NORMAL)
  34. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl"
  35. #endif
  36. #if defined(DECAL_PROJECTOR) || defined(DECAL_RECONSTRUCT_NORMAL)
  37. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
  38. #endif
  39. #ifdef DECAL_MESH
  40. #include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DecalMeshBiasTypeEnum.cs.hlsl"
  41. #endif
  42. #ifdef DECAL_RECONSTRUCT_NORMAL
  43. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/NormalReconstruction.hlsl"
  44. #endif
  45. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl"
  46. void MeshDecalsPositionZBias(inout Varyings input)
  47. {
  48. #if UNITY_REVERSED_Z
  49. input.positionCS.z -= _DecalMeshDepthBias;
  50. #else
  51. input.positionCS.z += _DecalMeshDepthBias;
  52. #endif
  53. }
  54. void InitializeInputData(Varyings input, float3 positionWS, half3 normalWS, half3 viewDirectionWS, out InputData inputData)
  55. {
  56. inputData = (InputData)0;
  57. inputData.positionWS = positionWS;
  58. inputData.normalWS = normalWS;
  59. inputData.viewDirectionWS = viewDirectionWS;
  60. #if defined(VARYINGS_NEED_SHADOW_COORD) && defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  61. inputData.shadowCoord = input.shadowCoord;
  62. #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
  63. inputData.shadowCoord = TransformWorldToShadowCoord(positionWS);
  64. #else
  65. inputData.shadowCoord = float4(0, 0, 0, 0);
  66. #endif
  67. #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT
  68. inputData.fogCoord = InitializeInputDataFog(float4(positionWS, 1.0), input.fogFactorAndVertexLight.x);
  69. inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;
  70. #endif
  71. #if defined(VARYINGS_NEED_DYNAMIC_LIGHTMAP_UV) && defined(DYNAMICLIGHTMAP_ON)
  72. inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV.xy, half3(input.sh), normalWS);
  73. #if defined(VARYINGS_NEED_STATIC_LIGHTMAP_UV)
  74. inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV);
  75. #endif
  76. #elif defined(VARYINGS_NEED_STATIC_LIGHTMAP_UV)
  77. #if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2))
  78. inputData.bakedGI = SAMPLE_GI(input.sh,
  79. GetAbsolutePositionWS(inputData.positionWS),
  80. inputData.normalWS,
  81. inputData.viewDirectionWS,
  82. input.positionCS.xy,
  83. input.probeOcclusion,
  84. inputData.shadowMask);
  85. #else
  86. inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, half3(input.sh), normalWS);
  87. #if defined(VARYINGS_NEED_STATIC_LIGHTMAP_UV)
  88. inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV);
  89. #endif
  90. #endif
  91. #endif
  92. #if defined(DEBUG_DISPLAY)
  93. #if defined(VARYINGS_NEED_DYNAMIC_LIGHTMAP_UV) && defined(DYNAMICLIGHTMAP_ON)
  94. inputData.dynamicLightmapUV = input.dynamicLightmapUV.xy;
  95. #endif
  96. #if defined(VARYINGS_NEED_STATIC_LIGHTMAP_UV) && defined(LIGHTMAP_ON)
  97. inputData.staticLightmapUV = input.staticLightmapUV;
  98. #elif defined(VARYINGS_NEED_SH)
  99. inputData.vertexSH = input.sh;
  100. #endif
  101. #endif
  102. inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
  103. }
  104. void GetSurface(DecalSurfaceData decalSurfaceData, inout SurfaceData surfaceData)
  105. {
  106. surfaceData.albedo = decalSurfaceData.baseColor.rgb;
  107. surfaceData.metallic = saturate(decalSurfaceData.metallic);
  108. surfaceData.specular = 0;
  109. surfaceData.smoothness = saturate(decalSurfaceData.smoothness);
  110. surfaceData.occlusion = decalSurfaceData.occlusion;
  111. surfaceData.emission = decalSurfaceData.emissive;
  112. surfaceData.alpha = saturate(decalSurfaceData.baseColor.w);
  113. surfaceData.clearCoatMask = 0;
  114. surfaceData.clearCoatSmoothness = 1;
  115. }
  116. PackedVaryings Vert(Attributes inputMesh)
  117. {
  118. Varyings output = (Varyings)0;
  119. UNITY_SETUP_INSTANCE_ID(inputMesh);
  120. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  121. #ifdef DECAL_MESH
  122. if (_DecalMeshBiasType == DECALMESHDEPTHBIASTYPE_VIEW_BIAS) // TODO: Check performance of branch
  123. {
  124. float3 viewDirectionOS = GetObjectSpaceNormalizeViewDir(inputMesh.positionOS);
  125. inputMesh.positionOS += viewDirectionOS * (_DecalMeshViewBias);
  126. }
  127. output = BuildVaryings(inputMesh);
  128. if (_DecalMeshBiasType == DECALMESHDEPTHBIASTYPE_DEPTH_BIAS) // TODO: Check performance of branch
  129. {
  130. MeshDecalsPositionZBias(output);
  131. }
  132. #else
  133. output = BuildVaryings(inputMesh);
  134. #endif
  135. #if defined(VARYINGS_NEED_STATIC_LIGHTMAP_UV)
  136. OUTPUT_LIGHTMAP_UV(inputMesh.uv1, unity_LightmapST, output.staticLightmapUV);
  137. #endif
  138. #if defined(VARYINGS_NEED_DYNAMIC_LIGHTMAP_UV) && defined(DYNAMICLIGHTMAP_ON)
  139. output.dynamicLightmapUV.xy = inputMesh.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
  140. #endif
  141. #if defined(VARYINGS_NEED_SH) && !defined(LIGHTMAP_ON)
  142. output.sh = float3(SampleSHVertex(half3(output.normalWS)));
  143. #endif
  144. PackedVaryings packedOutput = (PackedVaryings)0;
  145. packedOutput = PackVaryings(output);
  146. return packedOutput;
  147. }
  148. void Frag(PackedVaryings packedInput,
  149. #if defined(DECAL_DBUFFER)
  150. OUTPUT_DBUFFER(outDBuffer)
  151. #elif defined(DECAL_SCREEN_SPACE)
  152. out half4 outColor : SV_Target0
  153. #elif defined(DECAL_GBUFFER)
  154. out FragmentOutput fragmentOutput
  155. #elif defined(DECAL_FORWARD_EMISSIVE)
  156. out half4 outEmissive : SV_Target0
  157. #elif defined(SCENEPICKINGPASS)
  158. out float4 outColor : SV_Target0
  159. #else
  160. #error SHADERPASS_is_not_correctly_define
  161. #endif
  162. )
  163. {
  164. #ifdef SCENEPICKINGPASS
  165. outColor = _SelectionID;
  166. #else
  167. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
  168. UNITY_SETUP_INSTANCE_ID(packedInput);
  169. Varyings input = UnpackVaryings(packedInput);
  170. half angleFadeFactor = 1.0;
  171. float2 positionCS = input.positionCS.xy;
  172. // Only screen space needs flip logic, other passes do not setup needed properties so we skip here
  173. #if defined(DECAL_SCREEN_SPACE)
  174. TransformScreenUV(positionCS, _ScreenSize.y);
  175. #endif
  176. #ifdef _DECAL_LAYERS
  177. #ifdef _RENDER_PASS_ENABLED
  178. uint surfaceRenderingLayer = DecodeMeshRenderingLayer(LOAD_FRAMEBUFFER_X_INPUT(GBUFFER4, positionCS.xy).r);
  179. #else
  180. uint surfaceRenderingLayer = LoadSceneRenderingLayer(positionCS.xy);
  181. #endif
  182. uint projectorRenderingLayer = uint(UNITY_ACCESS_INSTANCED_PROP(Decal, _DecalLayerMaskFromDecal));
  183. // This is simple trick to clip if there is no matching layers
  184. // Part (surfaceRenderingLayer & projectorRenderingLayer) will produce 0, 1, 2 ...
  185. // Finally we subtract with small value to remmap only zero to negative value
  186. clip((surfaceRenderingLayer & projectorRenderingLayer) - 0.1);
  187. #endif
  188. #if defined(DECAL_PROJECTOR)
  189. #if UNITY_REVERSED_Z
  190. #if _RENDER_PASS_ENABLED
  191. float depth = LOAD_FRAMEBUFFER_X_INPUT(GBUFFER3, positionCS.xy).x;
  192. #else
  193. float depth = LoadSceneDepth(positionCS.xy);
  194. #endif
  195. #else
  196. #if _RENDER_PASS_ENABLED
  197. float depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, LOAD_FRAMEBUFFER_X_INPUT(GBUFFER3, positionCS.xy));
  198. #else
  199. // Adjust z to match NDC for OpenGL
  200. float depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, LoadSceneDepth(positionCS.xy));
  201. #endif
  202. #endif
  203. #endif
  204. #if defined(DECAL_RECONSTRUCT_NORMAL)
  205. #if defined(_DECAL_NORMAL_BLEND_HIGH)
  206. half3 normalWS = half3(ReconstructNormalTap9(positionCS.xy));
  207. #elif defined(_DECAL_NORMAL_BLEND_MEDIUM)
  208. half3 normalWS = half3(ReconstructNormalTap5(positionCS.xy));
  209. #else
  210. half3 normalWS = half3(ReconstructNormalDerivative(input.positionCS.xy));
  211. #endif
  212. #elif defined(DECAL_LOAD_NORMAL)
  213. half3 normalWS = half3(LoadSceneNormals(positionCS.xy));
  214. #endif
  215. float2 positionSS = input.positionCS.xy * _ScreenSize.zw;
  216. #if defined(SUPPORTS_FOVEATED_RENDERING_NON_UNIFORM_RASTER)
  217. UNITY_BRANCH if (_FOVEATED_RENDERING_NON_UNIFORM_RASTER)
  218. {
  219. positionSS = RemapFoveatedRenderingNonUniformToLinearCS(input.positionCS.xy, true) * _ScreenSize.zw;
  220. }
  221. #endif
  222. #ifdef DECAL_PROJECTOR
  223. float3 positionWS = ComputeWorldSpacePosition(positionSS, depth, UNITY_MATRIX_I_VP);
  224. #ifdef VARYINGS_NEED_POSITION_WS
  225. input.positionWS = positionWS;
  226. #endif
  227. // Transform from relative world space to decal space (DS) to clip the decal
  228. float3 positionDS = TransformWorldToObject(positionWS);
  229. positionDS = positionDS * float3(1.0, -1.0, 1.0);
  230. // call clip as early as possible
  231. float clipValue = 0.5 - Max3(abs(positionDS).x, abs(positionDS).y, abs(positionDS).z);
  232. clip(clipValue);
  233. float2 texCoord = positionDS.xz + float2(0.5, 0.5);
  234. #ifdef VARYINGS_NEED_TEXCOORD0
  235. input.texCoord0.xy = texCoord;
  236. #endif
  237. #ifdef VARYINGS_NEED_TEXCOORD1
  238. input.texCoord1.xy = texCoord;
  239. #endif
  240. #ifdef VARYINGS_NEED_TEXCOORD2
  241. input.texCoord2.xy = texCoord;
  242. #endif
  243. #ifdef VARYINGS_NEED_TEXCOORD3
  244. input.texCoord3.xy = texCoord;
  245. #endif
  246. #ifdef DECAL_ANGLE_FADE
  247. // Check if this decal projector require angle fading
  248. half4x4 normalToWorld = UNITY_ACCESS_INSTANCED_PROP(Decal, _NormalToWorld);
  249. half2 angleFade = half2(normalToWorld[1][3], normalToWorld[2][3]);
  250. if (angleFade.y < 0.0f) // if angle fade is enabled
  251. {
  252. half3 decalNormal = half3(normalToWorld[0].z, normalToWorld[1].z, normalToWorld[2].z);
  253. half dotAngle = dot(normalWS, decalNormal);
  254. // See equation in DecalCreateDrawCallSystem.cs - simplified to a madd mul add here
  255. angleFadeFactor = saturate(angleFade.x + angleFade.y * (dotAngle * (dotAngle - 2.0)));
  256. }
  257. #endif
  258. #else // Decal mesh
  259. float3 positionWS = input.positionWS.xyz;
  260. #endif
  261. half3 viewDirectionWS = GetWorldSpaceNormalizeViewDir(positionWS);
  262. DecalSurfaceData surfaceData;
  263. GetSurfaceData(input, input.positionCS, angleFadeFactor, surfaceData);
  264. #if defined(DECAL_DBUFFER)
  265. ENCODE_INTO_DBUFFER(surfaceData, outDBuffer);
  266. #elif defined(DECAL_SCREEN_SPACE)
  267. // Blend normal with background
  268. #ifdef DECAL_RECONSTRUCT_NORMAL
  269. surfaceData.normalWS.xyz = normalize(lerp(normalWS.xyz, surfaceData.normalWS.xyz, surfaceData.normalWS.w));
  270. #endif
  271. InputData inputData;
  272. InitializeInputData(input, positionWS, surfaceData.normalWS.xyz, viewDirectionWS, inputData);
  273. SurfaceData surface = (SurfaceData)0;
  274. GetSurface(surfaceData, surface);
  275. half4 color = UniversalFragmentPBR(inputData, surface);
  276. color.rgb = MixFog(color.rgb, inputData.fogCoord);
  277. outColor = color;
  278. #elif defined(DECAL_GBUFFER)
  279. // Need to reconstruct normal here for inputData.bakedGI, but also save off surfaceData.normalWS for correct GBuffer blending
  280. half3 normalToPack = surfaceData.normalWS.xyz;
  281. #ifdef DECAL_RECONSTRUCT_NORMAL
  282. surfaceData.normalWS.xyz = normalize(lerp(normalWS.xyz, surfaceData.normalWS.xyz, surfaceData.normalWS.w));
  283. #endif
  284. InputData inputData;
  285. InitializeInputData(input, positionWS, surfaceData.normalWS.xyz, viewDirectionWS, inputData);
  286. SurfaceData surface = (SurfaceData)0;
  287. GetSurface(surfaceData, surface);
  288. BRDFData brdfData;
  289. InitializeBRDFData(surface.albedo, surface.metallic, 0, surface.smoothness, surface.alpha, brdfData);
  290. // Skip GI if there is no abledo
  291. #ifdef _MATERIAL_AFFECTS_ALBEDO
  292. Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask);
  293. MixRealtimeAndBakedGI(mainLight, surfaceData.normalWS.xyz, inputData.bakedGI, inputData.shadowMask);
  294. half3 color = GlobalIllumination(brdfData, inputData.bakedGI, surface.occlusion, surfaceData.normalWS.xyz, inputData.viewDirectionWS);
  295. #else
  296. half3 color = 0;
  297. #endif
  298. // We can not use usual GBuffer functions (etc. BRDFDataToGbuffer) as we use alpha for blending
  299. #pragma warning (disable : 3578) // The output value isn't completely initialized.
  300. half3 packedNormalWS = PackNormal(normalToPack);
  301. fragmentOutput.GBuffer0 = half4(surfaceData.baseColor.rgb, surfaceData.baseColor.a);
  302. fragmentOutput.GBuffer1 = 0;
  303. fragmentOutput.GBuffer2 = half4(packedNormalWS, surfaceData.normalWS.a);
  304. fragmentOutput.GBuffer3 = half4(surfaceData.emissive + color, surfaceData.baseColor.a);
  305. #if OUTPUT_SHADOWMASK
  306. fragmentOutput.GBuffer4 = inputData.shadowMask; // will have unity_ProbesOcclusion value if subtractive lighting is used (baked)
  307. #endif
  308. #pragma warning (default : 3578) // Restore output value isn't completely initialized.
  309. #elif defined(DECAL_FORWARD_EMISSIVE)
  310. // Emissive need to be pre-exposed
  311. outEmissive.rgb = surfaceData.emissive * GetCurrentExposureMultiplier();
  312. outEmissive.a = surfaceData.baseColor.a;
  313. #else
  314. #endif
  315. #endif
  316. }