PBRDeferred.hlsl 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include "Uniforms.hlsl"
  2. #include "Samplers.hlsl"
  3. #include "Transform.hlsl"
  4. #include "ScreenPos.hlsl"
  5. #include "Lighting.hlsl"
  6. #include "Constants.hlsl"
  7. #include "PBR.hlsl"
  8. #line 9
  9. void VS(float4 iPos : POSITION,
  10. #ifdef DIRLIGHT
  11. out float2 oScreenPos : TEXCOORD0,
  12. #else
  13. out float4 oScreenPos : TEXCOORD0,
  14. #endif
  15. out float3 oFarRay : TEXCOORD1,
  16. #ifdef ORTHO
  17. out float3 oNearRay : TEXCOORD2,
  18. #endif
  19. out float4 oPos : OUTPOSITION)
  20. {
  21. float4x3 modelMatrix = iModelMatrix;
  22. float3 worldPos = GetWorldPos(modelMatrix);
  23. oPos = GetClipPos(worldPos);
  24. #ifdef DIRLIGHT
  25. oScreenPos = GetScreenPosPreDiv(oPos);
  26. oFarRay = GetFarRay(oPos);
  27. #ifdef ORTHO
  28. oNearRay = GetNearRay(oPos);
  29. #endif
  30. #else
  31. oScreenPos = GetScreenPos(oPos);
  32. oFarRay = GetFarRay(oPos) * oPos.w;
  33. #ifdef ORTHO
  34. oNearRay = GetNearRay(oPos) * oPos.w;
  35. #endif
  36. #endif
  37. }
  38. void PS(
  39. #ifdef DIRLIGHT
  40. float2 iScreenPos : TEXCOORD0,
  41. #else
  42. float4 iScreenPos : TEXCOORD0,
  43. #endif
  44. float3 iFarRay : TEXCOORD1,
  45. #ifdef ORTHO
  46. float3 iNearRay : TEXCOORD2,
  47. #endif
  48. float2 iFragPos : VPOS,
  49. out float4 oColor : OUTCOLOR0)
  50. {
  51. // If rendering a directional light quad, optimize out the w divide
  52. #ifdef DIRLIGHT
  53. float3 depth = Sample2DLod0(DepthBuffer, iScreenPos).r;
  54. #ifdef HWDEPTH
  55. depth = ReconstructDepth(depth);
  56. #endif
  57. #ifdef ORTHO
  58. float3 worldPos = lerp(iNearRay, iFarRay, depth);
  59. #else
  60. float3 worldPos = iFarRay * depth;
  61. #endif
  62. const float4 albedoInput = Sample2DLod0(AlbedoBuffer, iScreenPos);
  63. const float4 normalInput = Sample2DLod0(NormalBuffer, iScreenPos);
  64. const float4 specularInput = Sample2DLod0(SpecMap, iScreenPos);
  65. #else
  66. float depth = Sample2DProj(DepthBuffer, iScreenPos).r;
  67. #ifdef HWDEPTH
  68. depth = ReconstructDepth(depth);
  69. #endif
  70. #ifdef ORTHO
  71. float3 worldPos = lerp(iNearRay, iFarRay, depth) / iScreenPos.w;
  72. #else
  73. float3 worldPos = iFarRay * depth / iScreenPos.w;
  74. #endif
  75. const float4 albedoInput = Sample2DProj(AlbedoBuffer, iScreenPos);
  76. const float4 normalInput = Sample2DProj(NormalBuffer, iScreenPos);
  77. const float4 specularInput = Sample2DProj(SpecMap, iScreenPos);
  78. #endif
  79. // Position acquired via near/far ray is relative to camera. Bring position to world space
  80. float3 eyeVec = -worldPos;
  81. worldPos += cCameraPosPS;
  82. float3 normal = normalInput.rgb;
  83. const float roughness = length(normal);
  84. normal = normalize(normal);
  85. const float3 specColor = specularInput.rgb;
  86. const float4 projWorldPos = float4(worldPos, 1.0);
  87. float3 lightDir;
  88. float atten = 1;
  89. #if defined(DIRLIGHT)
  90. atten = GetAtten(normal, worldPos, lightDir);
  91. #elif defined(SPOTLIGHT)
  92. atten = GetAttenSpot(normal, worldPos, lightDir);
  93. #else
  94. atten = GetAttenPoint(normal, worldPos, lightDir);
  95. #endif
  96. float shadow = 1;
  97. #ifdef SHADOW
  98. shadow *= GetShadowDeferred(projWorldPos, normal, depth);
  99. #endif
  100. #if defined(SPOTLIGHT)
  101. const float4 spotPos = mul(projWorldPos, cLightMatricesPS[0]);
  102. const float3 lightColor = spotPos.w > 0.0 ? Sample2DProj(LightSpotMap, spotPos).rgb * cLightColor.rgb : 0.0;
  103. #elif defined(CUBEMASK)
  104. const float3 lightColor = texCUBE(sLightCubeMap, mul(worldPos - cLightPosPS.xyz, (float3x3)cLightMatricesPS[0])).rgb * cLightColor.rgb;
  105. #else
  106. const float3 lightColor = cLightColor.rgb;
  107. #endif
  108. const float3 toCamera = normalize(eyeVec);
  109. const float3 lightVec = normalize(lightDir);
  110. const float ndl = clamp(abs(dot(normal, lightVec)), M_EPSILON, 1.0);
  111. float3 BRDF = GetBRDF(worldPos, lightDir, lightVec, toCamera, normal, roughness, albedoInput.rgb, specColor);
  112. oColor.a = 1;
  113. oColor.rgb = BRDF * lightColor * shadow * atten / M_PI;
  114. }