CTI_Internal-DeferredReflections.shader 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. Shader "Hidden/CTI/Internal-DeferredReflections" {
  2. Properties {
  3. _SrcBlend ("", Float) = 1
  4. _DstBlend ("", Float) = 1
  5. }
  6. SubShader {
  7. // Calculates reflection contribution from a single probe (rendered as cubes) or default reflection (rendered as full screen quad)
  8. Pass {
  9. ZWrite Off
  10. ZTest LEqual
  11. Blend [_SrcBlend] [_DstBlend]
  12. CGPROGRAM
  13. #pragma target 3.0
  14. #pragma vertex vert_deferred
  15. #pragma fragment frag
  16. #include "UnityCG.cginc"
  17. #include "UnityDeferredLibrary.cginc"
  18. #include "UnityStandardUtils.cginc"
  19. #include "UnityStandardBRDF.cginc"
  20. #include "UnityPBSLighting.cginc"
  21. sampler2D _CameraGBufferTexture0;
  22. sampler2D _CameraGBufferTexture1;
  23. sampler2D _CameraGBufferTexture2;
  24. half3 distanceFromAABB(half3 p, half3 aabbMin, half3 aabbMax)
  25. {
  26. return max(max(p - aabbMax, aabbMin - p), half3(0.0, 0.0, 0.0));
  27. }
  28. half4 frag (unity_v2f_deferred i) : SV_Target
  29. {
  30. // Stripped from UnityDeferredCalculateLightParams, refactor into function ?
  31. i.ray = i.ray * (_ProjectionParams.z / i.ray.z);
  32. float2 uv = i.uv.xy / i.uv.w;
  33. // read depth and reconstruct world position
  34. float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv);
  35. depth = Linear01Depth (depth);
  36. float4 viewPos = float4(i.ray * depth,1);
  37. float3 worldPos = mul (unity_CameraToWorld, viewPos).xyz;
  38. half4 gbuffer0 = tex2D (_CameraGBufferTexture0, uv);
  39. half4 gbuffer1 = tex2D (_CameraGBufferTexture1, uv);
  40. half4 gbuffer2 = tex2D (_CameraGBufferTexture2, uv);
  41. // Check for translucent material
  42. half TransMat = floor(gbuffer2.a * 3 + 0.5f) == 2 ? 1 : 0;
  43. // Rewrite specColor if needed
  44. half3 specColor = (TransMat == 1)? gbuffer1.rrr : gbuffer1.rgb;
  45. half oneMinusRoughness = gbuffer1.a;
  46. half3 worldNormal = gbuffer2.rgb * 2 - 1;
  47. worldNormal = normalize(worldNormal);
  48. float3 eyeVec = normalize(worldPos - _WorldSpaceCameraPos);
  49. half oneMinusReflectivity = 1 - SpecularStrength(specColor.rgb);
  50. half occlusion = gbuffer0.a;
  51. half3 worldNormalRefl = reflect(eyeVec, worldNormal);
  52. float blendDistance = unity_SpecCube1_ProbePosition.w; // will be set to blend distance for this probe
  53. #if UNITY_SPECCUBE_BOX_PROJECTION
  54. // For box projection, use expanded bounds as they are rendered; otherwise
  55. // box projection artifacts when outside of the box.
  56. float4 boxMin = unity_SpecCube0_BoxMin - float4(blendDistance,blendDistance,blendDistance,0);
  57. float4 boxMax = unity_SpecCube0_BoxMax + float4(blendDistance,blendDistance,blendDistance,0);
  58. half3 worldNormal0 = BoxProjectedCubemapDirection (worldNormalRefl, worldPos, unity_SpecCube0_ProbePosition, boxMin, boxMax);
  59. #else
  60. half3 worldNormal0 = worldNormalRefl;
  61. #endif
  62. Unity_GlossyEnvironmentData g;
  63. g.roughness = 1 - oneMinusRoughness;
  64. g.reflUVW = worldNormal0;
  65. half3 env0 = Unity_GlossyEnvironment (UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, g);
  66. UnityLight light;
  67. light.color = 0;
  68. light.dir = 0;
  69. light.ndotl = 0;
  70. UnityIndirect ind;
  71. ind.diffuse = 0;
  72. ind.specular = env0 * occlusion;
  73. half3 rgb = UNITY_BRDF_PBS (0, specColor, oneMinusReflectivity, oneMinusRoughness, worldNormal, -eyeVec, light, ind).rgb;
  74. // Calculate falloff value, so reflections on the edges of the probe would gradually blend to previous reflection.
  75. // Also this ensures that pixels not located in the reflection probe AABB won't
  76. // accidentally pick up reflections from this probe.
  77. half3 distance = distanceFromAABB(worldPos, unity_SpecCube0_BoxMin.xyz, unity_SpecCube0_BoxMax.xyz);
  78. half falloff = saturate(1.0 - length(distance)/blendDistance);
  79. return half4(rgb, falloff);
  80. }
  81. ENDCG
  82. }
  83. // Adds reflection buffer to the lighting buffer
  84. Pass
  85. {
  86. ZWrite Off
  87. ZTest Always
  88. Blend [_SrcBlend] [_DstBlend]
  89. CGPROGRAM
  90. #pragma target 3.0
  91. #pragma vertex vert
  92. #pragma fragment frag
  93. #pragma multi_compile ___ UNITY_HDR_ON
  94. #include "UnityCG.cginc"
  95. sampler2D _CameraReflectionsTexture;
  96. struct v2f {
  97. float2 uv : TEXCOORD0;
  98. float4 pos : SV_POSITION;
  99. };
  100. v2f vert (float4 vertex : POSITION)
  101. {
  102. v2f o;
  103. o.pos = UnityObjectToClipPos(vertex);
  104. o.uv = ComputeScreenPos (o.pos).xy;
  105. return o;
  106. }
  107. half4 frag (v2f i) : SV_Target
  108. {
  109. half4 c = tex2D (_CameraReflectionsTexture, i.uv);
  110. #ifdef UNITY_HDR_ON
  111. return float4(c.rgb, 0.0f);
  112. #else
  113. return float4(exp2(-c.rgb), 0.0f);
  114. #endif
  115. }
  116. ENDCG
  117. }
  118. }
  119. Fallback Off
  120. }