Core.hlsl 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #ifndef UNIVERSAL_PIPELINE_CORE_INCLUDED
  2. #define UNIVERSAL_PIPELINE_CORE_INCLUDED
  3. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
  4. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl"
  5. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl"
  6. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
  7. #if !defined(SHADER_HINT_NICE_QUALITY)
  8. #if defined(SHADER_API_MOBILE) || defined(SHADER_API_SWITCH)
  9. #define SHADER_HINT_NICE_QUALITY 0
  10. #else
  11. #define SHADER_HINT_NICE_QUALITY 1
  12. #endif
  13. #endif
  14. // Shader Quality Tiers in Universal.
  15. // SRP doesn't use Graphics Settings Quality Tiers.
  16. // We should expose shader quality tiers in the pipeline asset.
  17. // Meanwhile, it's forced to be:
  18. // High Quality: Non-mobile platforms or shader explicit defined SHADER_HINT_NICE_QUALITY
  19. // Medium: Mobile aside from GLES2
  20. // Low: GLES2
  21. #if SHADER_HINT_NICE_QUALITY
  22. #define SHADER_QUALITY_HIGH
  23. #elif defined(SHADER_API_GLES)
  24. #define SHADER_QUALITY_LOW
  25. #else
  26. #define SHADER_QUALITY_MEDIUM
  27. #endif
  28. #ifndef BUMP_SCALE_NOT_SUPPORTED
  29. #define BUMP_SCALE_NOT_SUPPORTED !SHADER_HINT_NICE_QUALITY
  30. #endif
  31. struct VertexPositionInputs
  32. {
  33. float3 positionWS; // World space position
  34. float3 positionVS; // View space position
  35. float4 positionCS; // Homogeneous clip space position
  36. float4 positionNDC;// Homogeneous normalized device coordinates
  37. };
  38. struct VertexNormalInputs
  39. {
  40. real3 tangentWS;
  41. real3 bitangentWS;
  42. float3 normalWS;
  43. };
  44. VertexPositionInputs GetVertexPositionInputs(float3 positionOS)
  45. {
  46. VertexPositionInputs input;
  47. input.positionWS = TransformObjectToWorld(positionOS);
  48. input.positionVS = TransformWorldToView(input.positionWS);
  49. input.positionCS = TransformWorldToHClip(input.positionWS);
  50. float4 ndc = input.positionCS * 0.5f;
  51. input.positionNDC.xy = float2(ndc.x, ndc.y * _ProjectionParams.x) + ndc.w;
  52. input.positionNDC.zw = input.positionCS.zw;
  53. return input;
  54. }
  55. VertexNormalInputs GetVertexNormalInputs(float3 normalOS)
  56. {
  57. VertexNormalInputs tbn;
  58. tbn.tangentWS = real3(1.0, 0.0, 0.0);
  59. tbn.bitangentWS = real3(0.0, 1.0, 0.0);
  60. tbn.normalWS = TransformObjectToWorldNormal(normalOS);
  61. return tbn;
  62. }
  63. VertexNormalInputs GetVertexNormalInputs(float3 normalOS, float4 tangentOS)
  64. {
  65. VertexNormalInputs tbn;
  66. // mikkts space compliant. only normalize when extracting normal at frag.
  67. real sign = tangentOS.w * GetOddNegativeScale();
  68. tbn.normalWS = TransformObjectToWorldNormal(normalOS);
  69. tbn.tangentWS = TransformObjectToWorldDir(tangentOS.xyz);
  70. tbn.bitangentWS = cross(tbn.normalWS, tbn.tangentWS) * sign;
  71. return tbn;
  72. }
  73. #if UNITY_REVERSED_Z
  74. #if SHADER_API_OPENGL || SHADER_API_GLES || SHADER_API_GLES3
  75. //GL with reversed z => z clip range is [near, -far] -> should remap in theory but dont do it in practice to save some perf (range is close enough)
  76. #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) max(-(coord), 0)
  77. #else
  78. //D3d with reversed Z => z clip range is [near, 0] -> remapping to [0, far]
  79. //max is required to protect ourselves from near plane not being correct/meaningfull in case of oblique matrices.
  80. #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) max(((1.0-(coord)/_ProjectionParams.y)*_ProjectionParams.z),0)
  81. #endif
  82. #elif UNITY_UV_STARTS_AT_TOP
  83. //D3d without reversed z => z clip range is [0, far] -> nothing to do
  84. #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) (coord)
  85. #else
  86. //Opengl => z clip range is [-near, far] -> should remap in theory but dont do it in practice to save some perf (range is close enough)
  87. #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) (coord)
  88. #endif
  89. float3 GetCameraPositionWS()
  90. {
  91. return _WorldSpaceCameraPos;
  92. }
  93. float4 GetScaledScreenParams()
  94. {
  95. return _ScaledScreenParams;
  96. }
  97. void AlphaDiscard(real alpha, real cutoff, real offset = 0.0h)
  98. {
  99. #ifdef _ALPHATEST_ON
  100. clip(alpha - cutoff + offset);
  101. #endif
  102. }
  103. // A word on normalization of normals:
  104. // For better quality normals should be normalized before and after
  105. // interpolation.
  106. // 1) In vertex, skinning or blend shapes might vary significantly the lenght of normal.
  107. // 2) In fragment, because even outputting unit-length normals interpolation can make it non-unit.
  108. // 3) In fragment when using normal map, because mikktspace sets up non orthonormal basis.
  109. // However we will try to balance performance vs quality here as also let users configure that as
  110. // shader quality tiers.
  111. // Low Quality Tier: Normalize either per-vertex or per-pixel depending if normalmap is sampled.
  112. // Medium Quality Tier: Always normalize per-vertex. Normalize per-pixel only if using normal map
  113. // High Quality Tier: Normalize in both vertex and pixel shaders.
  114. real3 NormalizeNormalPerVertex(real3 normalWS)
  115. {
  116. #if defined(SHADER_QUALITY_LOW) && defined(_NORMALMAP)
  117. return normalWS;
  118. #else
  119. return normalize(normalWS);
  120. #endif
  121. }
  122. real3 NormalizeNormalPerPixel(real3 normalWS)
  123. {
  124. #if defined(SHADER_QUALITY_HIGH) || defined(_NORMALMAP)
  125. return normalize(normalWS);
  126. #else
  127. return normalWS;
  128. #endif
  129. }
  130. // TODO: A similar function should be already available in SRP lib on master. Use that instead
  131. float4 ComputeScreenPos(float4 positionCS)
  132. {
  133. float4 o = positionCS * 0.5f;
  134. o.xy = float2(o.x, o.y * _ProjectionParams.x) + o.w;
  135. o.zw = positionCS.zw;
  136. return o;
  137. }
  138. real ComputeFogFactor(float z)
  139. {
  140. float clipZ_01 = UNITY_Z_0_FAR_FROM_CLIPSPACE(z);
  141. #if defined(FOG_LINEAR)
  142. // factor = (end-z)/(end-start) = z * (-1/(end-start)) + (end/(end-start))
  143. float fogFactor = saturate(clipZ_01 * unity_FogParams.z + unity_FogParams.w);
  144. return real(fogFactor);
  145. #elif defined(FOG_EXP) || defined(FOG_EXP2)
  146. // factor = exp(-(density*z)^2)
  147. // -density * z computed at vertex
  148. return real(unity_FogParams.x * clipZ_01);
  149. #else
  150. return 0.0h;
  151. #endif
  152. }
  153. real ComputeFogIntensity(real fogFactor)
  154. {
  155. real fogIntensity = 0.0h;
  156. #if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
  157. #if defined(FOG_EXP)
  158. // factor = exp(-density*z)
  159. // fogFactor = density*z compute at vertex
  160. fogIntensity = saturate(exp2(-fogFactor));
  161. #elif defined(FOG_EXP2)
  162. // factor = exp(-(density*z)^2)
  163. // fogFactor = density*z compute at vertex
  164. fogIntensity = saturate(exp2(-fogFactor * fogFactor));
  165. #elif defined(FOG_LINEAR)
  166. fogIntensity = fogFactor;
  167. #endif
  168. #endif
  169. return fogIntensity;
  170. }
  171. half3 MixFogColor(real3 fragColor, real3 fogColor, real fogFactor)
  172. {
  173. #if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
  174. real fogIntensity = ComputeFogIntensity(fogFactor);
  175. fragColor = lerp(fogColor, fragColor, fogIntensity);
  176. #endif
  177. return fragColor;
  178. }
  179. half3 MixFog(real3 fragColor, real fogFactor)
  180. {
  181. return MixFogColor(fragColor, unity_FogColor.rgb, fogFactor);
  182. }
  183. // Stereo-related bits
  184. #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
  185. #define SLICE_ARRAY_INDEX unity_StereoEyeIndex
  186. #define TEXTURE2D_X TEXTURE2D_ARRAY
  187. #define TEXTURE2D_X_PARAM TEXTURE2D_ARRAY_PARAM
  188. #define TEXTURE2D_X_ARGS TEXTURE2D_ARRAY_ARGS
  189. #define TEXTURE2D_X_HALF TEXTURE2D_ARRAY_HALF
  190. #define TEXTURE2D_X_FLOAT TEXTURE2D_ARRAY_FLOAT
  191. #define LOAD_TEXTURE2D_X(textureName, unCoord2) LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, SLICE_ARRAY_INDEX)
  192. #define LOAD_TEXTURE2D_X_LOD(textureName, unCoord2, lod) LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, SLICE_ARRAY_INDEX, lod)
  193. #define SAMPLE_TEXTURE2D_X(textureName, samplerName, coord2) SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, SLICE_ARRAY_INDEX)
  194. #define SAMPLE_TEXTURE2D_X_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, SLICE_ARRAY_INDEX, lod)
  195. #define GATHER_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, SLICE_ARRAY_INDEX)
  196. #define GATHER_RED_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_RED_TEXTURE2D(textureName, samplerName, float3(coord2, SLICE_ARRAY_INDEX))
  197. #define GATHER_GREEN_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_GREEN_TEXTURE2D(textureName, samplerName, float3(coord2, SLICE_ARRAY_INDEX))
  198. #define GATHER_BLUE_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_BLUE_TEXTURE2D(textureName, samplerName, float3(coord2, SLICE_ARRAY_INDEX))
  199. #else
  200. #define SLICE_ARRAY_INDEX 0
  201. #define TEXTURE2D_X TEXTURE2D
  202. #define TEXTURE2D_X_PARAM TEXTURE2D_PARAM
  203. #define TEXTURE2D_X_ARGS TEXTURE2D_ARGS
  204. #define TEXTURE2D_X_HALF TEXTURE2D_HALF
  205. #define TEXTURE2D_X_FLOAT TEXTURE2D_FLOAT
  206. #define LOAD_TEXTURE2D_X LOAD_TEXTURE2D
  207. #define LOAD_TEXTURE2D_X_LOD LOAD_TEXTURE2D_LOD
  208. #define SAMPLE_TEXTURE2D_X SAMPLE_TEXTURE2D
  209. #define SAMPLE_TEXTURE2D_X_LOD SAMPLE_TEXTURE2D_LOD
  210. #define GATHER_TEXTURE2D_X GATHER_TEXTURE2D
  211. #define GATHER_RED_TEXTURE2D_X GATHER_RED_TEXTURE2D
  212. #define GATHER_GREEN_TEXTURE2D_X GATHER_GREEN_TEXTURE2D
  213. #define GATHER_BLUE_TEXTURE2D_X GATHER_BLUE_TEXTURE2D
  214. #endif
  215. #if defined(UNITY_SINGLE_PASS_STEREO)
  216. float2 TransformStereoScreenSpaceTex(float2 uv, float w)
  217. {
  218. // TODO: RVS support can be added here, if Universal decides to support it
  219. float4 scaleOffset = unity_StereoScaleOffset[unity_StereoEyeIndex];
  220. return uv.xy * scaleOffset.xy + scaleOffset.zw * w;
  221. }
  222. float2 UnityStereoTransformScreenSpaceTex(float2 uv)
  223. {
  224. return TransformStereoScreenSpaceTex(saturate(uv), 1.0);
  225. }
  226. #else
  227. #define UnityStereoTransformScreenSpaceTex(uv) uv
  228. #endif // defined(UNITY_SINGLE_PASS_STEREO)
  229. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Deprecated.hlsl"
  230. #endif