TerrainBlend.hlsl 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. #include "Uniforms.hlsl"
  2. #include "Samplers.hlsl"
  3. #include "Transform.hlsl"
  4. #include "ScreenPos.hlsl"
  5. #include "Lighting.hlsl"
  6. #include "Fog.hlsl"
  7. // When rendering a shadowed point light, disable specular calculations on Shader Model 2 to avoid exceeding the instruction limit
  8. #if !defined(SM3) && defined(SHADOW) && defined(POINTLIGHT)
  9. #undef SPECULAR
  10. #endif
  11. sampler2D sWeightMap0 : register(S0);
  12. sampler2D sDetailMap1 : register(S1);
  13. sampler2D sDetailMap2 : register(S2);
  14. sampler2D sDetailMap3 : register(S3);
  15. uniform float2 cDetailTiling;
  16. void VS(float4 iPos : POSITION,
  17. float3 iNormal : NORMAL,
  18. float2 iTexCoord : TEXCOORD0,
  19. #ifdef SKINNED
  20. float4 iBlendWeights : BLENDWEIGHT,
  21. int4 iBlendIndices : BLENDINDICES,
  22. #endif
  23. #ifdef INSTANCED
  24. float4x3 iModelInstance : TEXCOORD2,
  25. #endif
  26. #ifdef BILLBOARD
  27. float2 iSize : TEXCOORD1,
  28. #endif
  29. out float2 oTexCoord : TEXCOORD0,
  30. out float3 oNormal : TEXCOORD1,
  31. out float4 oWorldPos : TEXCOORD2,
  32. out float2 oDetailTexCoord : TEXCOORD3,
  33. #ifdef PERPIXEL
  34. #ifdef SHADOW
  35. out float4 oShadowPos[NUMCASCADES] : TEXCOORD4,
  36. #endif
  37. #ifdef SPOTLIGHT
  38. out float4 oSpotPos : TEXCOORD5,
  39. #endif
  40. #ifdef POINTLIGHT
  41. out float3 oCubeMaskVec : TEXCOORD5,
  42. #endif
  43. #else
  44. out float3 oVertexLight : TEXCOORD4,
  45. out float4 oScreenPos : TEXCOORD5,
  46. #endif
  47. out float4 oPos : POSITION)
  48. {
  49. float4x3 modelMatrix = iModelMatrix;
  50. float3 worldPos = GetWorldPos(modelMatrix);
  51. oPos = GetClipPos(worldPos);
  52. oNormal = GetWorldNormal(modelMatrix);
  53. oWorldPos = float4(worldPos, GetDepth(oPos));
  54. oTexCoord = GetTexCoord(iTexCoord);
  55. oDetailTexCoord = cDetailTiling * oTexCoord;
  56. #ifdef PERPIXEL
  57. // Per-pixel forward lighting
  58. float4 projWorldPos = float4(worldPos.xyz, 1.0);
  59. #ifdef SHADOW
  60. // Shadow projection: transform from world space to shadow space
  61. GetShadowPos(projWorldPos, oShadowPos);
  62. #endif
  63. #ifdef SPOTLIGHT
  64. // Spotlight projection: transform from world space to projector texture coordinates
  65. oSpotPos = mul(projWorldPos, cLightMatrices[0]);
  66. #endif
  67. #ifdef POINTLIGHT
  68. oCubeMaskVec = mul(worldPos - cLightPos.xyz, (float3x3)cLightMatrices[0]);
  69. #endif
  70. #else
  71. // Ambient & per-vertex lighting
  72. oVertexLight = GetAmbient(GetZonePos(worldPos));
  73. #ifdef NUMVERTEXLIGHTS
  74. for (int i = 0; i < NUMVERTEXLIGHTS; ++i)
  75. oVertexLight += GetVertexLight(i, worldPos, oNormal) * cVertexLights[i * 3].rgb;
  76. #endif
  77. oScreenPos = GetScreenPos(oPos);
  78. #endif
  79. }
  80. void PS(float2 iTexCoord : TEXCOORD0,
  81. float3 iNormal : TEXCOORD1,
  82. float4 iWorldPos : TEXCOORD2,
  83. float2 iDetailTexCoord : TEXCOORD3,
  84. #ifdef PERPIXEL
  85. #ifdef SHADOW
  86. float4 iShadowPos[NUMCASCADES] : TEXCOORD4,
  87. #endif
  88. #ifdef SPOTLIGHT
  89. float4 iSpotPos : TEXCOORD5,
  90. #endif
  91. #ifdef CUBEMASK
  92. float3 iCubeMaskVec : TEXCOORD5,
  93. #endif
  94. #else
  95. float3 iVertexLight : TEXCOORD4,
  96. float4 iScreenPos : TEXCOORD5,
  97. #endif
  98. #ifdef PREPASS
  99. out float4 oDepth : COLOR1,
  100. #endif
  101. #ifdef DEFERRED
  102. out float4 oAlbedo : COLOR1,
  103. out float4 oNormal : COLOR2,
  104. out float4 oDepth : COLOR3,
  105. #endif
  106. out float4 oColor : COLOR0)
  107. {
  108. // Get material diffuse albedo
  109. float3 weights = tex2D(sWeightMap0, iTexCoord).rgb;
  110. float sumWeights = weights.r + weights.g + weights.b;
  111. weights /= sumWeights;
  112. float4 diffColor = cMatDiffColor * (
  113. weights.r * tex2D(sDetailMap1, iDetailTexCoord) +
  114. weights.g * tex2D(sDetailMap2, iDetailTexCoord) +
  115. weights.b * tex2D(sDetailMap3, iDetailTexCoord)
  116. );
  117. // Get material specular albedo
  118. float3 specColor = cMatSpecColor.rgb;
  119. // Get normal
  120. float3 normal = normalize(iNormal);
  121. // Get fog factor
  122. #ifdef HEIGHTFOG
  123. float fogFactor = GetHeightFogFactor(iWorldPos.w, iWorldPos.y);
  124. #else
  125. float fogFactor = GetFogFactor(iWorldPos.w);
  126. #endif
  127. #if defined(PERPIXEL)
  128. // Per-pixel forward lighting
  129. float3 lightDir;
  130. float3 lightColor;
  131. float3 finalColor;
  132. float diff = GetDiffuse(normal, iWorldPos.xyz, lightDir);
  133. #ifdef SHADOW
  134. diff *= GetShadow(iShadowPos, iWorldPos.w);
  135. #endif
  136. #if defined(SPOTLIGHT)
  137. lightColor = iSpotPos.w > 0.0 ? tex2Dproj(sLightSpotMap, iSpotPos).rgb * cLightColor.rgb : 0.0;
  138. #elif defined(CUBEMASK)
  139. lightColor = texCUBE(sLightCubeMap, iCubeMaskVec).rgb * cLightColor.rgb;
  140. #else
  141. lightColor = cLightColor.rgb;
  142. #endif
  143. #ifdef SPECULAR
  144. float spec = GetSpecular(normal, cCameraPosPS - iWorldPos.xyz, lightDir, cMatSpecColor.a);
  145. finalColor = diff * lightColor * (diffColor.rgb + spec * specColor * cLightColor.a);
  146. #else
  147. finalColor = diff * lightColor * diffColor.rgb;
  148. #endif
  149. #ifdef AMBIENT
  150. finalColor += cAmbientColor * diffColor.rgb;
  151. finalColor += cMatEmissiveColor;
  152. oColor = float4(GetFog(finalColor, fogFactor), diffColor.a);
  153. #else
  154. oColor = float4(GetLitFog(finalColor, fogFactor), diffColor.a);
  155. #endif
  156. #elif defined(PREPASS)
  157. // Fill light pre-pass G-Buffer
  158. float specPower = cMatSpecColor.a / 255.0;
  159. oColor = float4(normal * 0.5 + 0.5, specPower);
  160. oDepth = iWorldPos.w;
  161. #elif defined(DEFERRED)
  162. // Fill deferred G-buffer
  163. float specIntensity = specColor.g;
  164. float specPower = cMatSpecColor.a / 255.0;
  165. float3 finalColor = iVertexLight * diffColor.rgb;
  166. oColor = float4(GetFog(finalColor, fogFactor), 1.0);
  167. oAlbedo = fogFactor * float4(diffColor.rgb, specIntensity);
  168. oNormal = float4(normal * 0.5 + 0.5, specPower);
  169. oDepth = iWorldPos.w;
  170. #else
  171. // Ambient & per-vertex lighting
  172. float3 finalColor = iVertexLight * diffColor.rgb;
  173. #ifdef MATERIAL
  174. // Add light pre-pass accumulation result
  175. // Lights are accumulated at half intensity. Bring back to full intensity now
  176. float4 lightInput = 2.0 * tex2Dproj(sLightBuffer, iScreenPos);
  177. float3 lightSpecColor = lightInput.a * (lightInput.rgb / GetIntensity(lightInput.rgb));
  178. finalColor += lightInput.rgb * diffColor.rgb + lightSpecColor * specColor;
  179. #endif
  180. oColor = float4(GetFog(finalColor, fogFactor), diffColor.a);
  181. #endif
  182. }