Dies ist das Repository meines kleinen Portfolios.
Im Hintergrund läuft eine Planetensimulation, geschrieben in JavaScript und Three.js.
Die zu sehenden Texturen stammen von:
https://www.solarsystemscope.com/textures/
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.
88 lines
2.8 KiB
88 lines
2.8 KiB
import { |
|
Color, |
|
ShaderChunk, |
|
ShaderLib, |
|
UniformsUtils |
|
} from 'three'; |
|
|
|
/** |
|
* ------------------------------------------------------------------------------------------ |
|
* 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 = ShaderChunk[ 'meshphong_frag' ].slice( 0, ShaderChunk[ 'meshphong_frag' ].indexOf( 'void main() {' ) ); |
|
const meshphong_frag_body = ShaderChunk[ 'meshphong_frag' ].slice( ShaderChunk[ 'meshphong_frag' ].indexOf( 'void main() {' ) ); |
|
|
|
const SubsurfaceScatteringShader = { |
|
|
|
uniforms: UniformsUtils.merge( [ |
|
ShaderLib[ 'phong' ].uniforms, |
|
{ |
|
'thicknessMap': { value: null }, |
|
'thicknessColor': { value: new 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', |
|
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( |
|
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' ), |
|
|
|
}; |
|
|
|
export { SubsurfaceScatteringShader };
|
|
|