You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
2.8 KiB
50 lines
2.8 KiB
2 years ago
|
( function () {
|
||
|
|
||
|
/**
|
||
|
* ------------------------------------------------------------------------------------------
|
||
|
* Subsurface Scattering shader
|
||
|
* Based on GDC 2011 – Approximating Translucency for a Fast, Cheap and Convincing Subsurface Scattering Look
|
||
|
* https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/
|
||
|
*------------------------------------------------------------------------------------------
|
||
|
*/
|
||
|
|
||
|
function replaceAll( string, find, replace ) {
|
||
|
|
||
|
return string.split( find ).join( replace );
|
||
|
|
||
|
}
|
||
|
|
||
|
const meshphong_frag_head = THREE.ShaderChunk[ 'meshphong_frag' ].slice( 0, THREE.ShaderChunk[ 'meshphong_frag' ].indexOf( 'void main() {' ) );
|
||
|
const meshphong_frag_body = THREE.ShaderChunk[ 'meshphong_frag' ].slice( THREE.ShaderChunk[ 'meshphong_frag' ].indexOf( 'void main() {' ) );
|
||
|
const SubsurfaceScatteringShader = {
|
||
|
uniforms: THREE.UniformsUtils.merge( [ THREE.ShaderLib[ 'phong' ].uniforms, {
|
||
|
'thicknessMap': {
|
||
|
value: null
|
||
|
},
|
||
|
'thicknessColor': {
|
||
|
value: new THREE.Color( 0xffffff )
|
||
|
},
|
||
|
'thicknessDistortion': {
|
||
|
value: 0.1
|
||
|
},
|
||
|
'thicknessAmbient': {
|
||
|
value: 0.0
|
||
|
},
|
||
|
'thicknessAttenuation': {
|
||
|
value: 0.1
|
||
|
},
|
||
|
'thicknessPower': {
|
||
|
value: 2.0
|
||
|
},
|
||
|
'thicknessScale': {
|
||
|
value: 10.0
|
||
|
}
|
||
|
} ] ),
|
||
|
vertexShader: [ '#define USE_UV', THREE.ShaderChunk[ 'meshphong_vert' ] ].join( '\n' ),
|
||
|
fragmentShader: [ '#define USE_UV', '#define SUBSURFACE', meshphong_frag_head, 'uniform sampler2D thicknessMap;', 'uniform float thicknessPower;', 'uniform float thicknessScale;', 'uniform float thicknessDistortion;', 'uniform float thicknessAmbient;', 'uniform float thicknessAttenuation;', 'uniform vec3 thicknessColor;', 'void RE_Direct_Scattering(const in IncidentLight directLight, const in vec2 uv, const in GeometricContext geometry, inout ReflectedLight reflectedLight) {', ' vec3 thickness = thicknessColor * texture2D(thicknessMap, uv).r;', ' vec3 scatteringHalf = normalize(directLight.direction + (geometry.normal * thicknessDistortion));', ' float scatteringDot = pow(saturate(dot(geometry.viewDir, -scatteringHalf)), thicknessPower) * thicknessScale;', ' vec3 scatteringIllu = (scatteringDot + thicknessAmbient) * thickness;', ' reflectedLight.directDiffuse += scatteringIllu * thicknessAttenuation * directLight.color;', '}', meshphong_frag_body.replace( '#include <lights_fragment_begin>', replaceAll( THREE.ShaderChunk[ 'lights_fragment_begin' ], 'RE_Direct( directLight, geometry, material, reflectedLight );', [ 'RE_Direct( directLight, geometry, material, reflectedLight );', '#if defined( SUBSURFACE ) && defined( USE_UV )', ' RE_Direct_Scattering(directLight, vUv, geometry, reflectedLight);', '#endif' ].join( '\n' ) ) ) ].join( '\n' )
|
||
|
};
|
||
|
|
||
|
THREE.SubsurfaceScatteringShader = SubsurfaceScatteringShader;
|
||
|
|
||
|
} )();
|