shading-standard-additive.chunk 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
  2. #include <legacy/lighting>
  3. #if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0
  4. vec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {
  5. vec3 position;
  6. HIGHP_VALUE_FROM_STRUCT_DEFINED(position, s.position);
  7. // Calculate diffuse & specular
  8. vec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);
  9. vec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);
  10. vec3 diffuseContrib = diffuse / PI;
  11. vec3 N = normalize(s.normal);
  12. vec3 V = normalize(cc_cameraPos.xyz - position);
  13. float NV = max(abs(dot(N, V)), 0.0);
  14. specular = BRDFApprox(specular, s.roughness, NV);
  15. vec3 finalColor = vec3(0.0);
  16. int numLights = CC_PIPELINE_TYPE == CC_PIPELINE_TYPE_FORWARD ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);
  17. for (int i = 0; i < LIGHTS_PER_PASS; i++) {
  18. if (i >= numLights) break;
  19. // lighting
  20. vec3 SLU = IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w) ? -cc_lightDir[i].xyz : cc_lightPos[i].xyz - position;
  21. vec3 SL = normalize(SLU);
  22. vec3 SH = normalize(SL + V);
  23. float SNL = max(dot(N, SL), 0.0);
  24. float SNH = max(dot(N, SH), 0.0);
  25. vec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);
  26. // attenuations
  27. float illum = 1.0;
  28. float att = 1.0;
  29. if (IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w)) {
  30. att = GetOutOfRange(position, cc_lightPos[i].xyz, cc_lightDir[i].xyz, cc_lightSizeRangeAngle[i].xyz, cc_lightBoundingSizeVS[i].xyz);
  31. } else {
  32. float distSqr = dot(SLU, SLU);
  33. float litRadius = cc_lightSizeRangeAngle[i].x;
  34. float litRadiusSqr = litRadius * litRadius;
  35. illum = (IS_POINT_LIGHT(cc_lightPos[i].w) || IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w)) ? 1.0 : litRadiusSqr / max(litRadiusSqr, distSqr);
  36. float attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);
  37. attRadiusSqrInv *= attRadiusSqrInv;
  38. att = GetDistAtt(distSqr, attRadiusSqrInv);
  39. if (IS_SPOT_LIGHT(cc_lightPos[i].w)) {
  40. float cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);
  41. float cosOuter = cc_lightSizeRangeAngle[i].z;
  42. float strength = clamp(cc_lightBoundingSizeVS[i].w, 0.0, 1.0);
  43. float litAngleScale = 1.0 / max(0.001, mix(cosInner, 1.0, strength) - cosOuter);
  44. float litAngleOffset = -cosOuter * litAngleScale;
  45. att *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);
  46. }
  47. }
  48. // shadows
  49. float shadow = 1.0;
  50. #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == CC_SHADOW_MAP
  51. if (IS_SPOT_LIGHT(cc_lightPos[i].w) && cc_lightSizeRangeAngle[i].w > 0.0) {
  52. shadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);
  53. }
  54. #endif
  55. finalColor += SNL * cc_lightColor[i].rgb * shadow * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);
  56. }
  57. return vec4(finalColor, 0.0);
  58. }
  59. #endif