No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Debugging3D.hlsl 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. #ifndef UNIVERSAL_DEBUGGING3D_INCLUDED
  2. #define UNIVERSAL_DEBUGGING3D_INCLUDED
  3. // Ensure that we always include "DebuggingCommon.hlsl" even if we don't use it - saves extraneous includes elsewhere...
  4. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/DebuggingCommon.hlsl"
  5. #if defined(DEBUG_DISPLAY)
  6. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl"
  7. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl"
  8. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl"
  9. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
  10. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl"
  11. #define TERRAIN_STREAM_INFO float4(0.0f, 0.0f, float(6 | (4 << 4)), 0.0f) // 0-15 are reserved for per-texture codes (use "6" to indicate terrain); per-material code "4" signifies "warnings/issues"
  12. #define SETUP_DEBUG_TEXTURE_DATA(inputData, uv) SetupDebugDataTexture(inputData, TRANSFORM_TEX(uv.xy, unity_MipmapStreaming_DebugTex), unity_MipmapStreaming_DebugTex_TexelSize, unity_MipmapStreaming_DebugTex_MipInfo, unity_MipmapStreaming_DebugTex_StreamInfo, unity_MipmapStreaming_DebugTex)
  13. #define SETUP_DEBUG_TEXTURE_DATA_NO_UV(inputData) SetupDebugDataTexture(inputData, float2(0.0f, 0.0f), unity_MipmapStreaming_DebugTex_TexelSize, unity_MipmapStreaming_DebugTex_MipInfo, unity_MipmapStreaming_DebugTex_StreamInfo, unity_MipmapStreaming_DebugTex)
  14. #define SETUP_DEBUG_TEXTURE_DATA_FOR_TEX(inputData, uv, texture) SetupDebugDataTexture(inputData, uv, texture##_TexelSize, texture##_MipInfo, texture##_StreamInfo, texture)
  15. #define SETUP_DEBUG_TEXTURE_DATA_FOR_TERRAIN(inputData) SetupDebugDataTerrain(inputData)
  16. void SetupDebugDataTexture(inout InputData inputData, float2 uv, float4 texelSize, float4 mipInfo, float4 streamInfo, TEXTURE2D(tex))
  17. {
  18. inputData.uv = uv;
  19. inputData.texelSize = texelSize;
  20. inputData.mipInfo = mipInfo;
  21. inputData.streamInfo = streamInfo;
  22. inputData.mipCount = GetMipCount(TEXTURE2D_ARGS(tex, sampler_PointClamp));
  23. inputData.originalColor = 0.0f;
  24. if (_DebugMipInfoMode != DEBUGMIPINFOMODE_NONE)
  25. {
  26. inputData.originalColor = SAMPLE_TEXTURE2D(tex, sampler_LinearRepeat, uv).xyz;
  27. }
  28. }
  29. void SetupDebugDataBrdf(inout InputData inputData, half3 brdfDiffuse, half3 brdfSpecular)
  30. {
  31. inputData.brdfDiffuse = brdfDiffuse;
  32. inputData.brdfSpecular = brdfSpecular;
  33. }
  34. void SetupDebugDataTerrain(inout InputData inputData)
  35. {
  36. // TERRAIN_STREAM_INFO: no streamInfo will have been set (no MeshRenderer); set status to "6" to reflect in the debug status that this is a terrain
  37. // also, set the per-material status to "4" to indicate warnings
  38. inputData.streamInfo = TERRAIN_STREAM_INFO;
  39. }
  40. bool UpdateSurfaceAndInputDataForDebug(inout SurfaceData surfaceData, inout InputData inputData)
  41. {
  42. bool changed = false;
  43. if (_DebugLightingMode == DEBUGLIGHTINGMODE_LIGHTING_WITHOUT_NORMAL_MAPS || _DebugLightingMode == DEBUGLIGHTINGMODE_LIGHTING_WITH_NORMAL_MAPS)
  44. {
  45. surfaceData.albedo = 1;
  46. surfaceData.emission = 0;
  47. surfaceData.specular = 0;
  48. surfaceData.occlusion = 1;
  49. surfaceData.clearCoatMask = 0;
  50. surfaceData.clearCoatSmoothness = 1;
  51. surfaceData.metallic = 0;
  52. surfaceData.smoothness = 0;
  53. changed = true;
  54. }
  55. else if (_DebugLightingMode == DEBUGLIGHTINGMODE_REFLECTIONS || _DebugLightingMode == DEBUGLIGHTINGMODE_REFLECTIONS_WITH_SMOOTHNESS)
  56. {
  57. surfaceData.albedo = 0;
  58. surfaceData.emission = 0;
  59. surfaceData.occlusion = 1;
  60. surfaceData.clearCoatMask = 0;
  61. surfaceData.clearCoatSmoothness = 1;
  62. surfaceData.specular = 1;
  63. surfaceData.metallic = 0;
  64. if (_DebugLightingMode == DEBUGLIGHTINGMODE_REFLECTIONS)
  65. {
  66. surfaceData.smoothness = 1;
  67. }
  68. changed = true;
  69. }
  70. if (_DebugLightingMode == DEBUGLIGHTINGMODE_LIGHTING_WITHOUT_NORMAL_MAPS || _DebugLightingMode == DEBUGLIGHTINGMODE_REFLECTIONS)
  71. {
  72. const half3 normalTS = half3(0, 0, 1);
  73. #if defined(_NORMALMAP)
  74. inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld);
  75. #else
  76. inputData.normalWS = inputData.normalWS;
  77. #endif
  78. surfaceData.normalTS = normalTS;
  79. changed = true;
  80. }
  81. return changed;
  82. }
  83. bool CalculateValidationMetallic(half3 albedo, half metallic, inout half4 debugColor)
  84. {
  85. if (metallic < _DebugValidateMetallicMinValue)
  86. {
  87. debugColor = _DebugValidateBelowMinThresholdColor;
  88. }
  89. else if (metallic > _DebugValidateMetallicMaxValue)
  90. {
  91. debugColor = _DebugValidateAboveMaxThresholdColor;
  92. }
  93. else
  94. {
  95. half luminance = Luminance(albedo);
  96. debugColor = half4(luminance, luminance, luminance, 1);
  97. }
  98. return true;
  99. }
  100. bool CalculateValidationColorForDebug(in InputData inputData, in SurfaceData surfaceData, inout half4 debugColor)
  101. {
  102. switch(_DebugMaterialValidationMode)
  103. {
  104. case DEBUGMATERIALVALIDATIONMODE_NONE:
  105. return false;
  106. case DEBUGMATERIALVALIDATIONMODE_ALBEDO:
  107. return CalculateValidationAlbedo(surfaceData.albedo, debugColor);
  108. case DEBUGMATERIALVALIDATIONMODE_METALLIC:
  109. return CalculateValidationMetallic(surfaceData.albedo, surfaceData.metallic, debugColor);
  110. default:
  111. return TryGetDebugColorInvalidMode(debugColor);
  112. }
  113. }
  114. bool CalculateColorForDebugMaterial(in InputData inputData, in SurfaceData surfaceData, inout half4 debugColor)
  115. {
  116. // Debug materials...
  117. switch(_DebugMaterialMode)
  118. {
  119. case DEBUGMATERIALMODE_NONE:
  120. return false;
  121. case DEBUGMATERIALMODE_ALBEDO:
  122. debugColor = half4(surfaceData.albedo, 1);
  123. return true;
  124. case DEBUGMATERIALMODE_SPECULAR:
  125. debugColor = half4(surfaceData.specular, 1);
  126. return true;
  127. case DEBUGMATERIALMODE_ALPHA:
  128. debugColor = half4(surfaceData.alpha.rrr, 1);
  129. return true;
  130. case DEBUGMATERIALMODE_SMOOTHNESS:
  131. debugColor = half4(surfaceData.smoothness.rrr, 1);
  132. return true;
  133. case DEBUGMATERIALMODE_AMBIENT_OCCLUSION:
  134. debugColor = half4(surfaceData.occlusion.rrr, 1);
  135. return true;
  136. case DEBUGMATERIALMODE_EMISSION:
  137. debugColor = half4(surfaceData.emission, 1);
  138. return true;
  139. case DEBUGMATERIALMODE_NORMAL_WORLD_SPACE:
  140. debugColor = half4(inputData.normalWS.xyz * 0.5 + 0.5, 1);
  141. return true;
  142. case DEBUGMATERIALMODE_NORMAL_TANGENT_SPACE:
  143. debugColor = half4(surfaceData.normalTS.xyz * 0.5 + 0.5, 1);
  144. return true;
  145. case DEBUGMATERIALMODE_METALLIC:
  146. debugColor = half4(surfaceData.metallic.rrr, 1);
  147. return true;
  148. default:
  149. return TryGetDebugColorInvalidMode(debugColor);
  150. }
  151. }
  152. bool CalculateColorForDebugMipmapStreaming(in InputData inputData, in SurfaceData surfaceData, inout half4 debugColor)
  153. {
  154. return CalculateColorForDebugMipmapStreaming(inputData.mipCount, inputData.positionCS.xy, inputData.texelSize, inputData.uv, inputData.mipInfo, inputData.streamInfo, inputData.originalColor, debugColor);
  155. }
  156. bool CalculateColorForDebug(in InputData inputData, in SurfaceData surfaceData, inout half4 debugColor)
  157. {
  158. if (CalculateColorForDebugSceneOverride(debugColor))
  159. {
  160. return true;
  161. }
  162. else if (CalculateColorForDebugMipmapStreaming(inputData, surfaceData, debugColor))
  163. {
  164. return true;
  165. }
  166. else if (CalculateColorForDebugMaterial(inputData, surfaceData, debugColor))
  167. {
  168. return true;
  169. }
  170. else if (CalculateValidationColorForDebug(inputData, surfaceData, debugColor))
  171. {
  172. return true;
  173. }
  174. else
  175. {
  176. return false;
  177. }
  178. }
  179. half3 CalculateDebugShadowCascadeColor(in InputData inputData)
  180. {
  181. float3 positionWS = inputData.positionWS;
  182. half cascadeIndex = ComputeCascadeIndex(positionWS);
  183. switch (uint(cascadeIndex))
  184. {
  185. case 0: return kDebugColorShadowCascade0.rgb;
  186. case 1: return kDebugColorShadowCascade1.rgb;
  187. case 2: return kDebugColorShadowCascade2.rgb;
  188. case 3: return kDebugColorShadowCascade3.rgb;
  189. default: return kDebugColorBlack.rgb;
  190. }
  191. }
  192. half4 CalculateDebugLightingComplexityColor(in InputData inputData, in SurfaceData surfaceData)
  193. {
  194. #if USE_FORWARD_PLUS
  195. int numLights = URP_FP_DIRECTIONAL_LIGHTS_COUNT;
  196. uint entityIndex;
  197. ClusterIterator it = ClusterInit(inputData.normalizedScreenSpaceUV, inputData.positionWS, 0);
  198. [loop] while (ClusterNext(it, entityIndex))
  199. {
  200. numLights++;
  201. }
  202. it = ClusterInit(inputData.normalizedScreenSpaceUV, inputData.positionWS, 1);
  203. [loop] while (ClusterNext(it, entityIndex))
  204. {
  205. numLights++;
  206. }
  207. #else
  208. // Assume a main light and add 1 to the additional lights.
  209. int numLights = GetAdditionalLightsCount() + 1;
  210. #endif
  211. const uint2 tileSize = uint2(32,32);
  212. const uint maxLights = 9;
  213. const float opacity = 0.8f;
  214. uint2 pixelCoord = uint2(inputData.normalizedScreenSpaceUV * _ScreenParams.xy);
  215. half3 base = surfaceData.albedo;
  216. half4 overlay = half4(OverlayHeatMap(pixelCoord, tileSize, numLights, maxLights, opacity));
  217. uint2 tileCoord = (float2)pixelCoord / tileSize;
  218. uint2 offsetInTile = pixelCoord - tileCoord * tileSize;
  219. bool border = any(offsetInTile == 0 || offsetInTile == tileSize.x - 1);
  220. if (border)
  221. overlay = half4(1, 1, 1, 0.4f);
  222. return half4(lerp(base.rgb, overlay.rgb, overlay.a), 1);
  223. }
  224. bool CanDebugOverrideOutputColor(inout InputData inputData, inout SurfaceData surfaceData, inout BRDFData brdfData, inout half4 debugColor)
  225. {
  226. if (_DebugMaterialMode == DEBUGMATERIALMODE_LIGHTING_COMPLEXITY)
  227. {
  228. debugColor = CalculateDebugLightingComplexityColor(inputData, surfaceData);
  229. return true;
  230. }
  231. else if (_DebugLightingMode == DEBUGLIGHTINGMODE_GLOBAL_ILLUMINATION)
  232. {
  233. debugColor = half4(inputData.bakedGI, surfaceData.alpha);
  234. return true;
  235. }
  236. else
  237. {
  238. debugColor = half4(0, 0, 0, 1);
  239. if (_DebugLightingMode == DEBUGLIGHTINGMODE_SHADOW_CASCADES)
  240. {
  241. surfaceData.albedo = CalculateDebugShadowCascadeColor(inputData);
  242. }
  243. else
  244. {
  245. if (UpdateSurfaceAndInputDataForDebug(surfaceData, inputData))
  246. {
  247. // If we've modified any data we'll need to re-sample the GI to ensure that everything works correctly...
  248. #if defined(DYNAMICLIGHTMAP_ON)
  249. inputData.bakedGI = SAMPLE_GI(inputData.staticLightmapUV, inputData.dynamicLightmapUV.xy, inputData.vertexSH, inputData.normalWS);
  250. #elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2))
  251. inputData.bakedGI = SAMPLE_GI(inputData.vertexSH,
  252. GetAbsolutePositionWS(inputData.positionWS),
  253. inputData.normalWS,
  254. inputData.viewDirectionWS,
  255. inputData.positionCS.xy,
  256. inputData.probeOcclusion,
  257. inputData.shadowMask);
  258. #else
  259. inputData.bakedGI = SAMPLE_GI(inputData.staticLightmapUV, inputData.vertexSH, inputData.normalWS);
  260. #endif
  261. }
  262. }
  263. // Update the BRDF data following any changes to the input/surface above...
  264. InitializeBRDFData(surfaceData, brdfData);
  265. return CalculateColorForDebug(inputData, surfaceData, debugColor);
  266. }
  267. }
  268. bool CanDebugOverrideOutputColor(inout InputData inputData, inout SurfaceData surfaceData, inout half4 debugColor)
  269. {
  270. if (_DebugMaterialMode == DEBUGMATERIALMODE_LIGHTING_COMPLEXITY)
  271. {
  272. debugColor = CalculateDebugLightingComplexityColor(inputData, surfaceData);
  273. return true;
  274. }
  275. else if (_DebugLightingMode == DEBUGLIGHTINGMODE_GLOBAL_ILLUMINATION)
  276. {
  277. debugColor = half4(inputData.bakedGI, surfaceData.alpha);
  278. return true;
  279. }
  280. else
  281. {
  282. if (_DebugLightingMode == DEBUGLIGHTINGMODE_SHADOW_CASCADES)
  283. {
  284. surfaceData.albedo = CalculateDebugShadowCascadeColor(inputData);
  285. }
  286. else
  287. {
  288. if (UpdateSurfaceAndInputDataForDebug(surfaceData, inputData))
  289. {
  290. // If we've modified any data we'll need to re-sample the GI to ensure that everything works correctly...
  291. #if defined(DYNAMICLIGHTMAP_ON)
  292. inputData.bakedGI = SAMPLE_GI(inputData.staticLightmapUV, inputData.dynamicLightmapUV.xy, inputData.vertexSH, inputData.normalWS);
  293. #elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2))
  294. inputData.bakedGI = SAMPLE_GI(inputData.vertexSH,
  295. GetAbsolutePositionWS(inputData.positionWS),
  296. inputData.normalWS,
  297. inputData.viewDirectionWS,
  298. inputData.positionCS.xy,
  299. inputData.probeOcclusion,
  300. inputData.shadowMask);
  301. #else
  302. inputData.bakedGI = SAMPLE_GI(inputData.staticLightmapUV, inputData.vertexSH, inputData.normalWS);
  303. #endif
  304. }
  305. }
  306. return CalculateColorForDebug(inputData, surfaceData, debugColor);
  307. }
  308. }
  309. #else
  310. // When "DEBUG_DISPLAY" isn't defined this macro does nothing - there's no debug-data to set-up...
  311. #define SETUP_DEBUG_TEXTURE_DATA(inputData, uv)
  312. #define SETUP_DEBUG_TEXTURE_DATA_NO_UV(inputData)
  313. #define SETUP_DEBUG_TEXTURE_DATA_FOR_TEX(inputData, uv, texture)
  314. #define SETUP_DEBUG_TEXTURE_DATA_FOR_TERRAIN(inputData)
  315. #endif
  316. #endif