1#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) && !defined(VERTEX_LIGHTING) 2 vec2 steepParallaxOffset(sampler2D parallaxMap, vec3 vViewDir,vec2 texCoord,float parallaxScale){ 3 vec2 vParallaxDirection = normalize( vViewDir.xy ); 4 5 // The length of this vector determines the furthest amount of displacement: (Ati's comment) 6 float fLength = length( vViewDir ); 7 float fParallaxLength = sqrt( fLength * fLength - vViewDir.z * vViewDir.z ) / vViewDir.z; 8 9 // Compute the actual reverse parallax displacement vector: (Ati's comment) 10 vec2 vParallaxOffsetTS = vParallaxDirection * fParallaxLength; 11 12 // Need to scale the amount of displacement to account for different height ranges 13 // in height maps. This is controlled by an artist-editable parameter: (Ati's comment) 14 parallaxScale *=0.3; 15 vParallaxOffsetTS *= parallaxScale; 16 17 vec3 eyeDir = normalize(vViewDir).xyz; 18 19 float nMinSamples = 6.0; 20 float nMaxSamples = 1000.0 * parallaxScale; 21 float nNumSamples = mix( nMinSamples, nMaxSamples, 1.0 - eyeDir.z ); //In reference shader: int nNumSamples = (int)(lerp( nMinSamples, nMaxSamples, dot( eyeDirWS, N ) )); 22 float fStepSize = 1.0 / nNumSamples; 23 float fCurrHeight = 0.0; 24 float fPrevHeight = 1.0; 25 float fNextHeight = 0.0; 26 float nStepIndex = 0.0; 27 vec2 vTexOffsetPerStep = fStepSize * vParallaxOffsetTS; 28 vec2 vTexCurrentOffset = texCoord; 29 float fCurrentBound = 1.0; 30 float fParallaxAmount = 0.0; 31 32 while ( nStepIndex < nNumSamples && fCurrHeight <= fCurrentBound ) { 33 vTexCurrentOffset -= vTexOffsetPerStep; 34 fPrevHeight = fCurrHeight; 35 36 37 #ifdef NORMALMAP_PARALLAX 38 //parallax map is stored in the alpha channel of the normal map 39 fCurrHeight = texture2DLod( parallaxMap, vTexCurrentOffset,1.0).a; 40 #else 41 //parallax map is a texture 42 fCurrHeight = texture2DLod( parallaxMap, vTexCurrentOffset,1.0).r; 43 #endif 44 45 fCurrentBound -= fStepSize; 46 nStepIndex+=1.0; 47 } 48 vec2 pt1 = vec2( fCurrentBound, fCurrHeight ); 49 vec2 pt2 = vec2( fCurrentBound + fStepSize, fPrevHeight ); 50 51 float fDelta2 = pt2.x - pt2.y; 52 float fDelta1 = pt1.x - pt1.y; 53 54 float fDenominator = fDelta2 - fDelta1; 55 56 fParallaxAmount = (pt1.x * fDelta2 - pt2.x * fDelta1 ) / fDenominator; 57 58 vec2 vParallaxOffset = vParallaxOffsetTS * (1.0 - fParallaxAmount ); 59 return texCoord - vParallaxOffset; 60 } 61 62 vec2 classicParallaxOffset(sampler2D parallaxMap, vec3 vViewDir,vec2 texCoord,float parallaxScale){ 63 float h; 64 h = texture2D(parallaxMap, texCoord).a; 65 #ifdef NORMALMAP_PARALLAX 66 //parallax map is stored in the alpha channel of the normal map 67 h = texture2D(parallaxMap, texCoord).a; 68 #else 69 //parallax map is a texture 70 h = texture2D(parallaxMap, texCoord).r; 71 #endif 72 float heightScale = parallaxScale; 73 float heightBias = heightScale* -0.6; 74 vec3 normView = normalize(vViewDir); 75 h = (h * heightScale + heightBias) * normView.z; 76 return texCoord + (h * normView.xy); 77 } 78#endif