shading-toon.chunk 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
  2. #include <builtin/uniforms/cc-global>
  3. #include <common/common-define>
  4. #include <common/data/packing>
  5. struct ToonSurface {
  6. vec4 baseColor;
  7. vec4 specular;
  8. // these two need to be in the same coordinate system
  9. HIGHP_VALUE_STRUCT_DEFINE(vec3, position);
  10. vec3 normal;
  11. // shading params
  12. vec3 shade1;
  13. vec3 shade2;
  14. vec3 emissive;
  15. float baseStep;
  16. float baseFeather;
  17. float shadeStep;
  18. float shadeFeather;
  19. float shadowCover;
  20. #if CC_RECEIVE_SHADOW
  21. vec2 shadowBias;
  22. #endif
  23. };
  24. // Inspired by UTS2, (C)UTJ/UCL
  25. #if CC_FORWARD_ADD
  26. #include <legacy/lighting>
  27. vec4 CCToonShading (ToonSurface s) {
  28. vec3 position;
  29. HIGHP_VALUE_FROM_STRUCT_DEFINED(position, s.position);
  30. vec3 V = normalize(cc_cameraPos.xyz - position);
  31. vec3 N = normalize(s.normal);
  32. float specularWeight = 1.0 - pow(s.specular.a, 5.0);
  33. vec3 finalColor = vec3(0.0);
  34. for (int i = 0; i < LIGHTS_PER_PASS; i++) {
  35. // lighting
  36. vec3 SLU = IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w) ? -cc_lightDir[i].xyz : cc_lightPos[i].xyz - position;
  37. vec3 SL = normalize(SLU);
  38. vec3 SH = normalize(SL + V);
  39. float SNL = 0.5 * dot(N, SL) + 0.5;
  40. float SNH = 0.5 * dot(N, SH) + 0.5;
  41. vec3 diffuse = mix(s.shade1, s.shade2,
  42. clamp(1.0 + (s.shadeStep - s.shadeFeather - SNL) / s.shadeFeather, 0.0, 1.0));
  43. diffuse = mix(s.baseColor.rgb, diffuse,
  44. clamp(1.0 + (s.baseStep - s.baseFeather - SNL) / s.baseFeather, 0.0, 1.0));
  45. float specularMask = step(specularWeight, SNH);
  46. vec3 specular = s.specular.rgb * specularMask;
  47. // attenuations
  48. float illum = 1.0;
  49. float att = 1.0;
  50. if (IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w)) {
  51. att = GetOutOfRange(position, cc_lightPos[i].xyz, cc_lightDir[i].xyz, cc_lightSizeRangeAngle[i].xyz, cc_lightBoundingSizeVS[i].xyz);
  52. } else {
  53. float distSqr = dot(SLU, SLU);
  54. float litRadius = cc_lightSizeRangeAngle[i].x;
  55. float litRadiusSqr = litRadius * litRadius;
  56. illum = (IS_POINT_LIGHT(cc_lightPos[i].w) || IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w)) ? 1.0 : litRadiusSqr / max(litRadiusSqr , distSqr);
  57. float attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);
  58. attRadiusSqrInv *= attRadiusSqrInv;
  59. att = GetDistAtt(distSqr, attRadiusSqrInv);
  60. if (IS_SPOT_LIGHT(cc_lightPos[i].w)) {
  61. float cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);
  62. float cosOuter = cc_lightSizeRangeAngle[i].z;
  63. float litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);
  64. float litAngleOffset = -cosOuter * litAngleScale;
  65. att *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);
  66. }
  67. }
  68. finalColor += SNL * cc_lightColor[i].rgb * cc_lightColor[i].a * illum * att * s.baseStep * (diffuse + specular);
  69. }
  70. return vec4(finalColor, 0.0);
  71. }
  72. #else
  73. #if CC_RECEIVE_SHADOW
  74. #include <legacy/shadow-map-fs>
  75. #endif
  76. vec4 CCToonShading (ToonSurface s) {
  77. vec3 position;
  78. HIGHP_VALUE_FROM_STRUCT_DEFINED(position, s.position);
  79. vec3 V = normalize(cc_cameraPos.xyz - position);
  80. vec3 N = normalize(s.normal);
  81. vec3 L = normalize(-cc_mainLitDir.xyz);
  82. float NL = 0.5 * dot(N, L) + 0.5;
  83. float NH = 0.5 * dot(normalize(V + L), N) + 0.5;
  84. vec3 lightColor = cc_mainLitColor.rgb * cc_mainLitColor.w * s.baseStep;
  85. vec3 diffuse = mix(s.shade1, s.shade2,
  86. clamp(1.0 + (s.shadeStep - s.shadeFeather - NL) / s.shadeFeather, 0.0, 1.0));
  87. diffuse = mix(s.baseColor.rgb, diffuse,
  88. clamp(1.0 + (s.baseStep - s.baseFeather - NL) / s.baseFeather, 0.0, 1.0));
  89. float specularWeight = 1.0 - pow(s.specular.a, 5.0);
  90. float specularMask = step(specularWeight + EPSILON_LOWP, NH);
  91. vec3 specular = s.specular.rgb * specularMask;
  92. vec3 dirlightContrib = diffuse + specular;
  93. float shadow = 1.0;
  94. #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == CC_SHADOW_MAP
  95. if(s.shadowCover < NL && cc_mainLitDir.w > 0.0) {
  96. #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_CASCADED
  97. shadow = CCCSMFactorBase(position, N, s.shadowBias);
  98. #endif
  99. #if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_UNIFORM
  100. shadow = CCShadowFactorBase(CC_SHADOW_POSITION, N, s.shadowBias);
  101. #endif
  102. }
  103. #endif
  104. dirlightContrib *= shadow;
  105. vec3 finalColor = lightColor * dirlightContrib;
  106. // TODO: no ambient, no IBL for now
  107. finalColor += s.emissive;
  108. return vec4(finalColor, s.baseColor.a);
  109. }
  110. #endif