shading-standard-base.chunk 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. // Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
  2. // reference: 'moving frostbite to pbr' & UE4 BRDF.usf
  3. #include <builtin/uniforms/cc-global>
  4. #include <common/common-define>
  5. #include <common/color/gamma>
  6. #include <legacy/shadow-map-base>
  7. #include <common/data/unpack>
  8. #include <common/texture/texture-lod>
  9. #include <builtin/uniforms/cc-environment>
  10. #include <common/math/number>
  11. #include <common/lighting/functions>
  12. #if CC_USE_IBL
  13. #if CC_USE_DIFFUSEMAP
  14. #include <builtin/uniforms/cc-diffusemap>
  15. #endif
  16. #endif
  17. #if CC_USE_REFLECTION_PROBE
  18. #include <builtin/uniforms/cc-reflection-probe>
  19. #include <builtin/functionalities/probe>
  20. #endif
  21. #if CC_USE_LIGHT_PROBE
  22. #include <legacy/sh-fs>
  23. #endif
  24. float GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {
  25. vec3 NxH = cross(N, H);
  26. float OneMinusNoHSqr = dot(NxH, NxH);
  27. float a = roughness * roughness;
  28. float n = NoH * a;
  29. float p = a / max(EPSILON, OneMinusNoHSqr + n * n);
  30. return p * p;
  31. }
  32. float CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {
  33. return (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);
  34. }
  35. vec3 BRDFApprox (vec3 specular, float roughness, float NoV) {
  36. const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
  37. const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
  38. vec4 r = roughness * c0 + c1;
  39. float a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;
  40. vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;
  41. AB.y *= clamp(50.0 * specular.g, 0.0, 1.0);
  42. return max(vec3(0.0), specular * AB.x + AB.y);
  43. }
  44. #if USE_REFLECTION_DENOISE
  45. #pragma extension([GL_OES_standard_derivatives, __VERSION__ < 110])
  46. vec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity, vec2 screenUV) {
  47. #if CC_USE_IBL
  48. float mip = roughness * (mipCount - 1.0);
  49. float delta = (dot(dFdx(R), dFdy(R))) * 1000.0;
  50. float mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));
  51. #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE
  52. vec4 biased = fragTextureLod(cc_reflectionProbeCubemap, R, mip + mipBias);
  53. vec4 filtered = texture(cc_reflectionProbeCubemap, R);
  54. #elif CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_PLANAR
  55. vec4 biased = fragTextureLod(cc_reflectionProbePlanarMap, screenUV, mip + mipBias);
  56. vec4 filtered = texture(cc_reflectionProbePlanarMap, screenUV);
  57. #else
  58. vec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);
  59. vec4 filtered = texture(cc_environment, R);
  60. #endif
  61. #if CC_USE_IBL == IBL_RGBE || CC_USE_REFLECTION_PROBE != REFLECTION_PROBE_TYPE_NONE
  62. biased.rgb = unpackRGBE(biased);
  63. filtered.rgb = unpackRGBE(filtered);
  64. #else
  65. biased.rgb = SRGBToLinear(biased.rgb);
  66. filtered.rgb = SRGBToLinear(filtered.rgb);
  67. #endif
  68. return mix(biased.rgb, filtered.rgb, denoiseIntensity);
  69. #else
  70. return vec3(0.0, 0.0, 0.0);
  71. #endif
  72. }
  73. #endif
  74. struct StandardSurface {
  75. // albedo
  76. vec4 albedo;
  77. // these two need to be in the same coordinate system
  78. HIGHP_VALUE_STRUCT_DEFINE(vec3, position);
  79. vec3 normal;
  80. // emissive
  81. vec3 emissive;
  82. // light map
  83. vec4 lightmap;
  84. float lightmap_test;
  85. // PBR params
  86. float roughness;
  87. float metallic;
  88. float occlusion;
  89. float specularIntensity;
  90. #if CC_RECEIVE_SHADOW
  91. vec2 shadowBias;
  92. #endif
  93. #if CC_RECEIVE_SHADOW || CC_USE_REFLECTION_PROBE
  94. float reflectionProbeId;
  95. #endif
  96. #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_BLEND || CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_BLEND_AND_SKYBOX
  97. float reflectionProbeBlendId;
  98. float reflectionProbeBlendFactor;
  99. #endif
  100. };
  101. vec3 SampleReflectionProbe(samplerCube tex, vec3 R, float roughness, float mipCount, bool isRGBE) {
  102. vec4 envmap = fragTextureLod(tex, R, roughness * (mipCount - 1.0));
  103. if (isRGBE)
  104. return unpackRGBE(envmap);
  105. else
  106. return SRGBToLinear(envmap.rgb);
  107. }
  108. vec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {
  109. // Calculate diffuse & specular
  110. vec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);
  111. vec3 specular = mix(vec3(0.08 * s.specularIntensity), s.albedo.rgb, s.metallic);
  112. vec3 position;
  113. HIGHP_VALUE_FROM_STRUCT_DEFINED(position, s.position);
  114. vec3 N = normalize(s.normal);
  115. vec3 V = normalize(cc_cameraPos.xyz - position);
  116. vec3 L = normalize(-cc_mainLitDir.xyz);
  117. float NL = max(dot(N, L), 0.0);
  118. float shadow = 1.0;
  119. #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == CC_SHADOW_MAP
  120. if (NL > 0.0 && cc_mainLitDir.w > 0.0) {
  121. #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_CASCADED
  122. shadow = CCCSMFactorBase(position, N, s.shadowBias);
  123. #endif
  124. #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_UNIFORM
  125. shadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);
  126. #endif
  127. }
  128. #endif
  129. vec3 finalColor = vec3(0.0);
  130. #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD
  131. vec3 lightmap = s.lightmap.rgb;
  132. #if CC_USE_HDR
  133. // convert from standard camera exposure parameters to current exposure value
  134. // baked in LDR scene still regarded as exposured with standard camera parameters
  135. lightmap.rgb *= cc_exposure.w * cc_exposure.x;
  136. #endif
  137. #if CC_USE_LIGHTMAP == LIGHT_MAP_TYPE_INDIRECT_OCCLUSION
  138. shadow *= s.lightmap.a; // apply baked shadows for real-time lighting
  139. finalColor += diffuse * lightmap.rgb;
  140. #else
  141. finalColor += diffuse * lightmap.rgb * shadow; // apply real-time shadows for baked color
  142. #endif
  143. s.occlusion *= s.lightmap_test;
  144. #endif
  145. #if !CC_DISABLE_DIRECTIONAL_LIGHT
  146. float NV = max(abs(dot(N, V)), 0.0);
  147. specular = BRDFApprox(specular, s.roughness, NV);
  148. vec3 H = normalize(L + V);
  149. float NH = max(dot(N, H), 0.0);
  150. vec3 lightingColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;
  151. vec3 diffuseContrib = diffuse / PI;
  152. // Cook-Torrance Microfacet Specular BRDF
  153. vec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);
  154. vec3 dirlightContrib = (diffuseContrib + specularContrib);
  155. dirlightContrib *= shadow;
  156. finalColor += lightingColor * dirlightContrib;
  157. #endif
  158. float fAmb = max(EPSILON, 0.5 - N.y * 0.5);
  159. vec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);
  160. vec3 env = vec3(0.0), rotationDir;
  161. #if CC_USE_IBL
  162. #if CC_USE_DIFFUSEMAP && !CC_USE_LIGHT_PROBE
  163. // Diffuse reflection irradiance
  164. rotationDir = RotationVecFromAxisY(N.xyz, cc_surfaceTransform.z, cc_surfaceTransform.w);
  165. vec4 diffuseMap = texture(cc_diffuseMap, rotationDir);
  166. #if CC_USE_DIFFUSEMAP == IBL_RGBE
  167. ambDiff = unpackRGBE(diffuseMap);
  168. #else
  169. ambDiff = SRGBToLinear(diffuseMap.rgb);
  170. #endif
  171. #endif
  172. #if !CC_USE_REFLECTION_PROBE
  173. vec3 R = normalize(reflect(-V, N));
  174. rotationDir = RotationVecFromAxisY(R.xyz, cc_surfaceTransform.z, cc_surfaceTransform.w);
  175. #if USE_REFLECTION_DENOISE && !CC_IBL_CONVOLUTED
  176. env = GetEnvReflectionWithMipFiltering(rotationDir, s.roughness, cc_ambientGround.w, 0.6, vec2(0.0));
  177. #else
  178. vec4 envmap = fragTextureLod(cc_environment, rotationDir, s.roughness * (cc_ambientGround.w - 1.0));
  179. #if CC_USE_IBL == IBL_RGBE
  180. env = unpackRGBE(envmap);
  181. #else
  182. env = SRGBToLinear(envmap.rgb);
  183. #endif
  184. #endif
  185. #endif
  186. #endif
  187. float lightIntensity = cc_ambientSky.w;
  188. #if CC_USE_REFLECTION_PROBE
  189. vec4 probe = vec4(0.0);
  190. vec3 R = normalize(reflect(-V, N));
  191. #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE
  192. if(s.reflectionProbeId < 0.0){
  193. env = SampleReflectionProbe(cc_environment, R, s.roughness, cc_ambientGround.w, CC_USE_IBL == IBL_RGBE);
  194. }else{
  195. vec3 centerPos, boxHalfSize;
  196. float mipCount;
  197. GetCubeReflectionProbeData(centerPos, boxHalfSize, mipCount, s.reflectionProbeId);
  198. vec4 fixedR = CalculateBoxProjectedDirection(R, position, centerPos, boxHalfSize);
  199. env = mix(SampleReflectionProbe(cc_environment, R, s.roughness, cc_ambientGround.w, CC_USE_IBL == IBL_RGBE) * lightIntensity,
  200. SampleReflectionProbe(cc_reflectionProbeCubemap, fixedR.xyz, s.roughness, mipCount, isReflectProbeUsingRGBE(s.reflectionProbeId)), fixedR.w);
  201. }
  202. #elif CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_PLANAR
  203. if(s.reflectionProbeId < 0.0){
  204. vec2 screenUV = GetPlanarReflectScreenUV(s.position, cc_matViewProj, cc_cameraPos.w, V, R);
  205. probe = fragTextureLod(cc_reflectionProbePlanarMap, screenUV, 1.0);
  206. }else{
  207. vec4 plane;
  208. float planarReflectionDepthScale, mipCount;
  209. GetPlanarReflectionProbeData(plane, planarReflectionDepthScale, mipCount, s.reflectionProbeId);
  210. R = normalize(CalculateReflectDirection(N, V, max(abs(dot(N, V)), 0.0)));
  211. vec3 worldPosOffset = CalculatePlanarReflectPositionOnPlane(N, V, s.position, plane, cc_cameraPos.xyz, planarReflectionDepthScale);
  212. vec2 screenUV = GetPlanarReflectScreenUV(worldPosOffset, cc_matViewProj, cc_cameraPos.w, V, R);
  213. probe = fragTextureLod(cc_reflectionProbePlanarMap, screenUV, mipCount);
  214. }
  215. env = unpackRGBE(probe);
  216. #elif CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_BLEND || CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_BLEND_AND_SKYBOX
  217. if (s.reflectionProbeId < 0.0) {
  218. env = SampleReflectionProbe(cc_environment, R, s.roughness, cc_ambientGround.w, CC_USE_IBL == IBL_RGBE);
  219. } else {
  220. vec3 centerPos, boxHalfSize;
  221. float mipCount;
  222. GetCubeReflectionProbeData(centerPos, boxHalfSize, mipCount, s.reflectionProbeId);
  223. vec4 fixedR = CalculateBoxProjectedDirection(R, s.position, centerPos, boxHalfSize);
  224. env = SampleReflectionProbe(cc_reflectionProbeCubemap, fixedR.xyz, s.roughness, mipCount, isReflectProbeUsingRGBE(s.reflectionProbeId));
  225. if (s.reflectionProbeBlendId < 0.0) {
  226. vec3 skyBoxEnv = SampleReflectionProbe(cc_environment, R, s.roughness, cc_ambientGround.w, CC_USE_IBL == IBL_RGBE) * lightIntensity;
  227. #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_BLEND_AND_SKYBOX
  228. //blend with skybox
  229. env = mix(env, skyBoxEnv, s.reflectionProbeBlendFactor);
  230. #else
  231. env = mix(skyBoxEnv, env, fixedR.w);
  232. #endif
  233. }
  234. // Disable probe blend for WebGPU
  235. // else {
  236. // vec3 centerPosBlend, boxHalfSizeBlend;
  237. // float mipCountBlend;
  238. // GetBlendCubeReflectionProbeData(centerPosBlend, boxHalfSizeBlend, mipCountBlend, s.reflectionProbeBlendId);
  239. // vec4 fixedRBlend = CalculateBoxProjectedDirection(R, s.position, centerPosBlend, boxHalfSizeBlend);
  240. // vec3 probe1 = SampleReflectionProbe(cc_reflectionProbeBlendCubemap, fixedRBlend.xyz, s.roughness, mipCountBlend, isBlendReflectProbeUsingRGBE(s.reflectionProbeBlendId));
  241. // env = mix(env, probe1, s.reflectionProbeBlendFactor);
  242. // }
  243. }
  244. #endif
  245. #endif
  246. #if CC_USE_REFLECTION_PROBE
  247. //If using reflection probe, no need to multiply by the ambient light intensity.
  248. lightIntensity = s.reflectionProbeId < 0.0 ? lightIntensity : 1.0;
  249. #endif
  250. finalColor += env * lightIntensity * specular * s.occlusion;
  251. #if CC_USE_LIGHT_PROBE
  252. finalColor += SHEvaluate(N) * diffuse * s.occlusion;
  253. #endif
  254. finalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;
  255. finalColor += s.emissive;
  256. return vec4(finalColor, s.albedo.a);
  257. }