SubsurfaceScatteringShader.js 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. console.warn( "THREE.SubsurfaceScatteringShader: As part of the transition to ES6 Modules, the files in 'examples/js' were deprecated in May 2020 (r117) and will be deleted in December 2020 (r124). You can find more information about developing using ES6 Modules in https://threejs.org/docs/index.html#manual/en/introduction/Import-via-modules." );
  2. /**
  3. * @author daoshengmu / http://dsmu.me/
  4. *
  5. * ------------------------------------------------------------------------------------------
  6. * Subsurface Scattering shader
  7. * Based on GDC 2011 – Approximating Translucency for a Fast, Cheap and Convincing Subsurface Scattering Look
  8. * https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/
  9. *------------------------------------------------------------------------------------------
  10. */
  11. function replaceAll( string, find, replace ) {
  12. return string.split( find ).join( replace );
  13. }
  14. var meshphong_frag_head = THREE.ShaderChunk[ "meshphong_frag" ].slice( 0, THREE.ShaderChunk[ "meshphong_frag" ].indexOf( 'void main() {' ) );
  15. var meshphong_frag_body = THREE.ShaderChunk[ "meshphong_frag" ].slice( THREE.ShaderChunk[ "meshphong_frag" ].indexOf( 'void main() {' ) );
  16. THREE.SubsurfaceScatteringShader = {
  17. uniforms: THREE.UniformsUtils.merge( [
  18. THREE.ShaderLib[ "phong" ].uniforms,
  19. {
  20. "thicknessMap": { value: null },
  21. "thicknessColor": { value: new THREE.Color( 0xffffff ) },
  22. "thicknessDistortion": { value: 0.1 },
  23. "thicknessAmbient": { value: 0.0 },
  24. "thicknessAttenuation": { value: 0.1 },
  25. "thicknessPower": { value: 2.0 },
  26. "thicknessScale": { value: 10.0 }
  27. }
  28. ] ),
  29. vertexShader: [
  30. "#define USE_UV",
  31. THREE.ShaderChunk[ "meshphong_vert" ],
  32. ].join( "\n" ),
  33. fragmentShader: [
  34. "#define USE_UV",
  35. "#define SUBSURFACE",
  36. meshphong_frag_head,
  37. "uniform sampler2D thicknessMap;",
  38. "uniform float thicknessPower;",
  39. "uniform float thicknessScale;",
  40. "uniform float thicknessDistortion;",
  41. "uniform float thicknessAmbient;",
  42. "uniform float thicknessAttenuation;",
  43. "uniform vec3 thicknessColor;",
  44. "void RE_Direct_Scattering(const in IncidentLight directLight, const in vec2 uv, const in GeometricContext geometry, inout ReflectedLight reflectedLight) {",
  45. " vec3 thickness = thicknessColor * texture2D(thicknessMap, uv).r;",
  46. " vec3 scatteringHalf = normalize(directLight.direction + (geometry.normal * thicknessDistortion));",
  47. " float scatteringDot = pow(saturate(dot(geometry.viewDir, -scatteringHalf)), thicknessPower) * thicknessScale;",
  48. " vec3 scatteringIllu = (scatteringDot + thicknessAmbient) * thickness;",
  49. " reflectedLight.directDiffuse += scatteringIllu * thicknessAttenuation * directLight.color;",
  50. "}",
  51. meshphong_frag_body.replace( "#include <lights_fragment_begin>",
  52. replaceAll(
  53. THREE.ShaderChunk[ 'lights_fragment_begin' ],
  54. 'RE_Direct( directLight, geometry, material, reflectedLight );',
  55. [
  56. "RE_Direct( directLight, geometry, material, reflectedLight );",
  57. "#if defined( SUBSURFACE ) && defined( USE_UV )",
  58. " RE_Direct_Scattering(directLight, vUv, geometry, reflectedLight);",
  59. "#endif",
  60. ].join( "\n" )
  61. ),
  62. ),
  63. ].join( "\n" ),
  64. };