standard-common.chunk 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #include <common/lighting/brdf>
  2. #include <common/lighting/functions>
  3. vec3 CalculateDirectDiffuse(in LightingIntermediateData lightingData, in vec4 lightSourceColorAndIntensity)
  4. {
  5. vec3 irradiance = vec3(lightingData.NoLSat) * lightSourceColorAndIntensity.rgb * lightSourceColorAndIntensity.w;
  6. return irradiance * DiffuseCoefficient_EnergyConservation;
  7. }
  8. vec3 CalculateDirectSpecular(in LightingIntermediateData lightingData, in vec4 lightSourceColorAndIntensity)
  9. {
  10. vec3 irradiance = vec3(lightingData.NoLSat) * lightSourceColorAndIntensity.rgb * lightSourceColorAndIntensity.w;
  11. float roughness = lightingData.specularParam;
  12. #if CC_SURFACES_LIGHTING_ANISOTROPIC
  13. float rT, rB;
  14. GetAnisotropicRoughness(roughness, lightingData.anisotropyShape, rT, rB);
  15. float calcSpec = D_GGXAniso(rT, rB, lightingData.NoHSat, lightingData.H, lightingData.T, lightingData.B);
  16. #else
  17. #if CC_SURFACES_USE_LEGACY_COMPATIBLE_LIGHTING
  18. float calcSpec = (roughness * 0.25 + 0.25) * D_GGXMobile(roughness, lightingData.NoHSat);
  19. #else
  20. float calcSpec = D_GGX(roughness, lightingData.NoHSat);
  21. #endif
  22. #endif
  23. return irradiance * calcSpec;
  24. }
  25. #if CC_SURFACES_LIGHTING_ANISOTROPIC && CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT
  26. vec3 EnvAnisotropicReflection(samplerCube tex, vec3 R, float roughness, float mipCount, float anisotropyShape, vec3 V, vec3 N, vec3 T, vec3 B) {
  27. R = normalize(R);
  28. float integratedBRDF = 0.0;
  29. vec3 envSpec = vec3(0.0);
  30. // One direction sample count
  31. const int SAMPLE_STEP_COUNT = CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT;
  32. float sampleAngleRange = PI * abs(anisotropyShape);
  33. vec3 anisoDirection = anisotropyShape < 0.0 ? T : B;
  34. vec3 ROnNormalPlane = normalize(R - anisoDirection * dot(R, anisoDirection));
  35. //ROnTangentPlane = R; //for example: cross-style
  36. vec3 stepOffset = normalize(ROnNormalPlane - N) * (sampleAngleRange / float(SAMPLE_STEP_COUNT * 2));
  37. for (int i = -SAMPLE_STEP_COUNT; i <= SAMPLE_STEP_COUNT; ++i)
  38. {
  39. float rT, rB;
  40. GetAnisotropicRoughness(roughness, anisotropyShape, rT, rB);
  41. #if CC_IBL_CONVOLUTED
  42. float coef = abs(float(i)) / float(SAMPLE_STEP_COUNT) * float(SAMPLE_STEP_COUNT);
  43. #else
  44. float coef = pow(abs(float(i)) / float(SAMPLE_STEP_COUNT), 1.3) * float(SAMPLE_STEP_COUNT);
  45. #endif
  46. vec3 H = normalize(N + stepOffset * sign(float(i)) * coef);
  47. vec3 L = reflect(-V, H);
  48. float NoHSat = saturate(dot(N, H));
  49. float calcSpec = D_GGXAniso(rT, rB, NoHSat, H, T, B);
  50. envSpec += calcSpec * EnvReflection(tex, L, roughness, mipCount);
  51. integratedBRDF += calcSpec;
  52. }
  53. envSpec /= integratedBRDF;
  54. return envSpec;
  55. }
  56. #endif
  57. // for skybox IBL
  58. vec3 SampleEnvironmentSpecular(samplerCube tex, in LightingIntermediateData lightingData, float mipCount)
  59. {
  60. vec3 envSpec = vec3(0.0);
  61. float roughness = lightingData.specularParam;
  62. #if CC_SURFACES_LIGHTING_ANISOTROPIC && !CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT
  63. vec3 R = GetAnisotropicReflect(roughness, lightingData.anisotropyShape, lightingData.V, lightingData.N, lightingData.T, lightingData.B);
  64. #else
  65. vec3 R = CalculateReflectDirection(lightingData.N, lightingData.V, lightingData.NoV);
  66. #endif
  67. #if CC_SURFACES_LIGHTING_ANISOTROPIC && CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT
  68. envSpec = EnvAnisotropicReflection(tex, R, roughness, mipCount, lightingData.anisotropyShape, lightingData.V, lightingData.N, lightingData.T, lightingData.B);
  69. #else
  70. #if CC_SURFACES_USE_REFLECTION_DENOISE && !CC_IBL_CONVOLUTED
  71. envSpec = EnvReflectionWithMipFiltering(normalize(R), roughness, mipCount, 0.6);
  72. #else
  73. envSpec = EnvReflection(tex, R, roughness, mipCount);
  74. #endif
  75. #endif
  76. return envSpec;
  77. }
  78. // for reflection probe
  79. vec3 SampleEnvironmentSpecular(samplerCube tex, in LightingIntermediateData lightingData, float mipCount, vec3 worldPos, vec3 cubeCenterPos, vec3 boxHalfSize, bool isRGBE)
  80. {
  81. vec3 envSpec = vec3(0.0);
  82. float roughness = lightingData.specularParam;
  83. #if CC_SURFACES_LIGHTING_ANISOTROPIC && !CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT
  84. vec3 R = GetAnisotropicReflect(roughness, lightingData.anisotropyShape, lightingData.V, lightingData.N, lightingData.T, lightingData.B);
  85. #else
  86. vec3 R = CalculateReflectDirection(lightingData.N, lightingData.V, lightingData.NoV);
  87. #endif
  88. vec4 fixedR = CalculateBoxProjectedDirection(R, worldPos, cubeCenterPos, boxHalfSize);
  89. R = fixedR.xyz;
  90. vec3 envmap = SampleEnvironmentSpecular(cc_environment, lightingData, cc_ambientGround.w).xyz * cc_ambientSky.w;
  91. #if CC_SURFACES_LIGHTING_ANISOTROPIC && CC_SURFACES_LIGHTING_ANISOTROPIC_ENVCONVOLUTION_COUNT
  92. envSpec = EnvAnisotropicReflection(tex, fixedR.xyz, roughness, mipCount, lightingData.anisotropyShape, lightingData.V, lightingData.N, lightingData.T, lightingData.B);
  93. #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE
  94. envSpec = mix(envmap, envSpec, fixedR.w);
  95. #endif
  96. #else
  97. #if CC_SURFACES_USE_REFLECTION_DENOISE && !CC_IBL_CONVOLUTED
  98. envSpec = EnvReflectionWithMipFiltering(normalize(R), roughness, mipCount, 0.6);
  99. #else
  100. envSpec = EnvReflectionOfReflectionProbe(tex, R, roughness, mipCount, isRGBE);
  101. #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE
  102. envSpec = mix(envmap, envSpec, fixedR.w);
  103. #endif
  104. #endif
  105. #endif
  106. return envSpec;
  107. }
  108. vec3 CalculateEnvironmentDiffuse(in LightingIntermediateData lightingData, float lightIntensity)
  109. {
  110. // Hemisphere Lighting
  111. float fAmb = max(EPSILON, 0.5 - lightingData.N.y * 0.5);
  112. vec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);
  113. // Diffuse Map
  114. #if CC_USE_IBL
  115. #if CC_USE_DIFFUSEMAP && !CC_USE_LIGHT_PROBE
  116. // Diffuse irradiance
  117. vec3 rotationDir = RotationVecFromAxisY(lightingData.N, cc_surfaceTransform.z, cc_surfaceTransform.w);
  118. vec4 diffuseMap = texture(cc_diffuseMap, rotationDir);
  119. #if CC_USE_DIFFUSEMAP == IBL_RGBE
  120. ambDiff = unpackRGBE(diffuseMap);
  121. #else
  122. ambDiff = SRGBToLinear(diffuseMap.rgb);
  123. #endif
  124. #endif
  125. #endif
  126. ambDiff.rgb *= lightIntensity;
  127. // Probe
  128. #if CC_USE_LIGHT_PROBE
  129. ambDiff.rgb += SHEvaluate(lightingData.N);
  130. #endif
  131. return ambDiff.rgb;
  132. }
  133. vec3 CalculateEnvironmentSpecular(in LightingIntermediateData lightingData, float lightIntensity)
  134. {
  135. vec3 envSpec = vec3(0.0);
  136. #if CC_USE_REFLECTION_PROBE
  137. vec3 worldPos;
  138. HIGHP_VALUE_FROM_STRUCT_DEFINED(worldPos, lightingData.worldPosition);
  139. #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE
  140. if(FSInput_reflectionProbeId < 0.0){
  141. envSpec = SampleEnvironmentSpecular(cc_environment, lightingData, cc_ambientGround.w);
  142. }else{
  143. vec3 centerPos, boxHalfSize;
  144. float mipCount;
  145. GetCubeReflectionProbeData(centerPos, boxHalfSize, mipCount, FSInput_reflectionProbeId);
  146. envSpec = SampleEnvironmentSpecular(cc_reflectionProbeCubemap, lightingData, mipCount, worldPos, centerPos, boxHalfSize, isReflectProbeUsingRGBE(FSInput_reflectionProbeId));
  147. }
  148. #elif CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_PLANAR
  149. vec3 R = normalize(CalculateReflectDirection(lightingData.N, lightingData.V, lightingData.NoV));
  150. if(FSInput_reflectionProbeId < 0.0){
  151. vec2 screenUV = GetPlanarReflectScreenUV(worldPos, cc_matViewProj, cc_cameraPos.w, lightingData.V, R);
  152. envSpec = unpackRGBE(fragTextureLod(cc_reflectionProbePlanarMap, screenUV, 1.0)).xyz;
  153. }else{
  154. vec4 plane;
  155. float planarReflectionDepthScale, mipCount;
  156. GetPlanarReflectionProbeData(plane, planarReflectionDepthScale, mipCount, FSInput_reflectionProbeId);
  157. vec3 worldPosOffset = CalculatePlanarReflectPositionOnPlane(lightingData.N, lightingData.V, worldPos, plane, cc_cameraPos.xyz, planarReflectionDepthScale);
  158. vec2 screenUV = GetPlanarReflectScreenUV(worldPosOffset, cc_matViewProj, cc_cameraPos.w, lightingData.V, R);
  159. envSpec = unpackRGBE(fragTextureLod(cc_reflectionProbePlanarMap, screenUV, mipCount)).xyz;
  160. }
  161. #elif CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_BLEND || CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_BLEND_AND_SKYBOX
  162. if(FSInput_reflectionProbeId < 0.0){
  163. envSpec = SampleEnvironmentSpecular(cc_environment, lightingData, cc_ambientGround.w);
  164. }else{
  165. vec3 centerPos, boxHalfSize;
  166. float mipCount;
  167. GetCubeReflectionProbeData(centerPos, boxHalfSize, mipCount, FSInput_reflectionProbeId);
  168. envSpec = SampleEnvironmentSpecular(cc_reflectionProbeCubemap, lightingData, mipCount, worldPos, centerPos, boxHalfSize, isReflectProbeUsingRGBE(FSInput_reflectionProbeId));
  169. float blendFactor = 0.0;
  170. #if USE_INSTANCING
  171. blendFactor = FSInput_reflectionProbeData.x;
  172. #else
  173. blendFactor = cc_reflectionProbeBlendData1.w;
  174. #endif
  175. if(FSInput_reflectionProbeBlendId < 0.0)
  176. {
  177. vec3 skyBoxEnv = SampleEnvironmentSpecular(cc_environment, lightingData, cc_ambientGround.w).rgb * lightIntensity;
  178. #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_BLEND_AND_SKYBOX
  179. //blend with skybox
  180. envSpec = mix(envSpec, skyBoxEnv, blendFactor);
  181. #else
  182. vec3 R = normalize(CalculateReflectDirection(lightingData.N, lightingData.V, lightingData.NoV));
  183. vec4 fixedR = CalculateBoxProjectedDirection(R, worldPos, centerPos, boxHalfSize);
  184. envSpec = mix(skyBoxEnv, envSpec, fixedR.w);
  185. #endif
  186. }
  187. // Disable probe blend for WebGPU
  188. // else {
  189. // vec3 centerPosBlend, boxHalfSizeBlend;
  190. // float mipCountBlend;
  191. // GetBlendCubeReflectionProbeData(centerPosBlend, boxHalfSizeBlend, mipCountBlend, FSInput_reflectionProbeBlendId);
  192. // vec3 probeBlend = SampleEnvironmentSpecular(cc_reflectionProbeBlendCubemap, lightingData, mipCountBlend, worldPos, centerPosBlend, boxHalfSizeBlend, isBlendReflectProbeUsingRGBE(FSInput_reflectionProbeBlendId));
  193. // envSpec = mix(envSpec, probeBlend, blendFactor);
  194. // }
  195. }
  196. #endif
  197. #elif CC_USE_IBL
  198. envSpec = SampleEnvironmentSpecular(cc_environment, lightingData, cc_ambientGround.w);
  199. #endif
  200. #if CC_USE_REFLECTION_PROBE
  201. //If using reflection probe, no need to multiply by the ambient light intensity.
  202. lightIntensity = FSInput_reflectionProbeId < 0.0 ? lightIntensity : 1.0;
  203. #endif
  204. return envSpec * lightIntensity;
  205. }