mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-03 17:59:55 +02:00
184 lines
5.1 KiB
JavaScript
184 lines
5.1 KiB
JavaScript
// Parallax Occlusion shaders from
|
|
// http://sunandblackcat.com/tipFullView.php?topicid=28
|
|
// No tangent-space transforms logic based on
|
|
// http://mmikkelsen3d.blogspot.sk/2012/02/parallaxpoc-mapping-and-no-tangent.html
|
|
|
|
THREE.ParallaxShader = {
|
|
// Ordered from fastest to best quality.
|
|
modes: {
|
|
none: 'NO_PARALLAX',
|
|
basic: 'USE_BASIC_PARALLAX',
|
|
steep: 'USE_STEEP_PARALLAX',
|
|
occlusion: 'USE_OCLUSION_PARALLAX', // a.k.a. POM
|
|
relief: 'USE_RELIEF_PARALLAX'
|
|
},
|
|
|
|
uniforms: {
|
|
'bumpMap': { value: null },
|
|
'map': { value: null },
|
|
'parallaxScale': { value: null },
|
|
'parallaxMinLayers': { value: null },
|
|
'parallaxMaxLayers': { value: null }
|
|
},
|
|
|
|
vertexShader: [
|
|
'varying vec2 vUv;',
|
|
'varying vec3 vViewPosition;',
|
|
'varying vec3 vNormal;',
|
|
|
|
'void main() {',
|
|
|
|
' vUv = uv;',
|
|
' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',
|
|
' vViewPosition = -mvPosition.xyz;',
|
|
' vNormal = normalize( normalMatrix * normal );',
|
|
' gl_Position = projectionMatrix * mvPosition;',
|
|
|
|
'}'
|
|
|
|
].join( '\n' ),
|
|
|
|
fragmentShader: [
|
|
'uniform sampler2D bumpMap;',
|
|
'uniform sampler2D map;',
|
|
|
|
'uniform float parallaxScale;',
|
|
'uniform float parallaxMinLayers;',
|
|
'uniform float parallaxMaxLayers;',
|
|
|
|
'varying vec2 vUv;',
|
|
'varying vec3 vViewPosition;',
|
|
'varying vec3 vNormal;',
|
|
|
|
'#ifdef USE_BASIC_PARALLAX',
|
|
|
|
' vec2 parallaxMap( in vec3 V ) {',
|
|
|
|
' float initialHeight = texture2D( bumpMap, vUv ).r;',
|
|
|
|
// No Offset Limitting: messy, floating output at grazing angles.
|
|
//"vec2 texCoordOffset = parallaxScale * V.xy / V.z * initialHeight;",
|
|
|
|
// Offset Limiting
|
|
' vec2 texCoordOffset = parallaxScale * V.xy * initialHeight;',
|
|
' return vUv - texCoordOffset;',
|
|
|
|
' }',
|
|
|
|
'#else',
|
|
|
|
' vec2 parallaxMap( in vec3 V ) {',
|
|
|
|
// Determine number of layers from angle between V and N
|
|
' float numLayers = mix( parallaxMaxLayers, parallaxMinLayers, abs( dot( vec3( 0.0, 0.0, 1.0 ), V ) ) );',
|
|
|
|
' float layerHeight = 1.0 / numLayers;',
|
|
' float currentLayerHeight = 0.0;',
|
|
// Shift of texture coordinates for each iteration
|
|
' vec2 dtex = parallaxScale * V.xy / V.z / numLayers;',
|
|
|
|
' vec2 currentTextureCoords = vUv;',
|
|
|
|
' float heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;',
|
|
|
|
// while ( heightFromTexture > currentLayerHeight )
|
|
// Infinite loops are not well supported. Do a "large" finite
|
|
// loop, but not too large, as it slows down some compilers.
|
|
' for ( int i = 0; i < 30; i += 1 ) {',
|
|
' if ( heightFromTexture <= currentLayerHeight ) {',
|
|
' break;',
|
|
' }',
|
|
' currentLayerHeight += layerHeight;',
|
|
// Shift texture coordinates along vector V
|
|
' currentTextureCoords -= dtex;',
|
|
' heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;',
|
|
' }',
|
|
|
|
' #ifdef USE_STEEP_PARALLAX',
|
|
|
|
' return currentTextureCoords;',
|
|
|
|
' #elif defined( USE_RELIEF_PARALLAX )',
|
|
|
|
' vec2 deltaTexCoord = dtex / 2.0;',
|
|
' float deltaHeight = layerHeight / 2.0;',
|
|
|
|
// Return to the mid point of previous layer
|
|
' currentTextureCoords += deltaTexCoord;',
|
|
' currentLayerHeight -= deltaHeight;',
|
|
|
|
// Binary search to increase precision of Steep Parallax Mapping
|
|
' const int numSearches = 5;',
|
|
' for ( int i = 0; i < numSearches; i += 1 ) {',
|
|
|
|
' deltaTexCoord /= 2.0;',
|
|
' deltaHeight /= 2.0;',
|
|
' heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;',
|
|
// Shift along or against vector V
|
|
' if( heightFromTexture > currentLayerHeight ) {', // Below the surface
|
|
|
|
' currentTextureCoords -= deltaTexCoord;',
|
|
' currentLayerHeight += deltaHeight;',
|
|
|
|
' } else {', // above the surface
|
|
|
|
' currentTextureCoords += deltaTexCoord;',
|
|
' currentLayerHeight -= deltaHeight;',
|
|
|
|
' }',
|
|
|
|
' }',
|
|
' return currentTextureCoords;',
|
|
|
|
' #elif defined( USE_OCLUSION_PARALLAX )',
|
|
|
|
' vec2 prevTCoords = currentTextureCoords + dtex;',
|
|
|
|
// Heights for linear interpolation
|
|
' float nextH = heightFromTexture - currentLayerHeight;',
|
|
' float prevH = texture2D( bumpMap, prevTCoords ).r - currentLayerHeight + layerHeight;',
|
|
|
|
// Proportions for linear interpolation
|
|
' float weight = nextH / ( nextH - prevH );',
|
|
|
|
// Interpolation of texture coordinates
|
|
' return prevTCoords * weight + currentTextureCoords * ( 1.0 - weight );',
|
|
|
|
' #else', // NO_PARALLAX
|
|
|
|
' return vUv;',
|
|
|
|
' #endif',
|
|
|
|
' }',
|
|
'#endif',
|
|
|
|
'vec2 perturbUv( vec3 surfPosition, vec3 surfNormal, vec3 viewPosition ) {',
|
|
|
|
' vec2 texDx = dFdx( vUv );',
|
|
' vec2 texDy = dFdy( vUv );',
|
|
|
|
' vec3 vSigmaX = dFdx( surfPosition );',
|
|
' vec3 vSigmaY = dFdy( surfPosition );',
|
|
' vec3 vR1 = cross( vSigmaY, surfNormal );',
|
|
' vec3 vR2 = cross( surfNormal, vSigmaX );',
|
|
' float fDet = dot( vSigmaX, vR1 );',
|
|
|
|
' vec2 vProjVscr = ( 1.0 / fDet ) * vec2( dot( vR1, viewPosition ), dot( vR2, viewPosition ) );',
|
|
' vec3 vProjVtex;',
|
|
' vProjVtex.xy = texDx * vProjVscr.x + texDy * vProjVscr.y;',
|
|
' vProjVtex.z = dot( surfNormal, viewPosition );',
|
|
|
|
' return parallaxMap( vProjVtex );',
|
|
'}',
|
|
|
|
'void main() {',
|
|
|
|
' vec2 mapUv = perturbUv( -vViewPosition, normalize( vNormal ), normalize( vViewPosition ) );',
|
|
' gl_FragColor = texture2D( map, mapUv );',
|
|
|
|
'}'
|
|
|
|
].join( '\n' )
|
|
|
|
};
|