blob: 61b9d4b8f8bc15dd2d48addda904f6fc50d45195 [file] [log] [blame]
#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) && !defined(VERTEX_LIGHTING)
vec2 steepParallaxOffset(sampler2D parallaxMap, vec3 vViewDir,vec2 texCoord,float parallaxScale){
vec2 vParallaxDirection = normalize( vViewDir.xy );
// The length of this vector determines the furthest amount of displacement: (Ati's comment)
float fLength = length( vViewDir );
float fParallaxLength = sqrt( fLength * fLength - vViewDir.z * vViewDir.z ) / vViewDir.z;
// Compute the actual reverse parallax displacement vector: (Ati's comment)
vec2 vParallaxOffsetTS = vParallaxDirection * fParallaxLength;
// Need to scale the amount of displacement to account for different height ranges
// in height maps. This is controlled by an artist-editable parameter: (Ati's comment)
parallaxScale *=0.3;
vParallaxOffsetTS *= parallaxScale;
vec3 eyeDir = normalize(vViewDir).xyz;
float nMinSamples = 6.0;
float nMaxSamples = 1000.0 * parallaxScale;
float nNumSamples = mix( nMinSamples, nMaxSamples, 1.0 - eyeDir.z ); //In reference shader: int nNumSamples = (int)(lerp( nMinSamples, nMaxSamples, dot( eyeDirWS, N ) ));
float fStepSize = 1.0 / nNumSamples;
float fCurrHeight = 0.0;
float fPrevHeight = 1.0;
float fNextHeight = 0.0;
float nStepIndex = 0.0;
vec2 vTexOffsetPerStep = fStepSize * vParallaxOffsetTS;
vec2 vTexCurrentOffset = texCoord;
float fCurrentBound = 1.0;
float fParallaxAmount = 0.0;
while ( nStepIndex < nNumSamples && fCurrHeight <= fCurrentBound ) {
vTexCurrentOffset -= vTexOffsetPerStep;
fPrevHeight = fCurrHeight;
#ifdef NORMALMAP_PARALLAX
//parallax map is stored in the alpha channel of the normal map
fCurrHeight = texture2DLod( parallaxMap, vTexCurrentOffset,1.0).a;
#else
//parallax map is a texture
fCurrHeight = texture2DLod( parallaxMap, vTexCurrentOffset,1.0).r;
#endif
fCurrentBound -= fStepSize;
nStepIndex+=1.0;
}
vec2 pt1 = vec2( fCurrentBound, fCurrHeight );
vec2 pt2 = vec2( fCurrentBound + fStepSize, fPrevHeight );
float fDelta2 = pt2.x - pt2.y;
float fDelta1 = pt1.x - pt1.y;
float fDenominator = fDelta2 - fDelta1;
fParallaxAmount = (pt1.x * fDelta2 - pt2.x * fDelta1 ) / fDenominator;
vec2 vParallaxOffset = vParallaxOffsetTS * (1.0 - fParallaxAmount );
return texCoord - vParallaxOffset;
}
vec2 classicParallaxOffset(sampler2D parallaxMap, vec3 vViewDir,vec2 texCoord,float parallaxScale){
float h;
h = texture2D(parallaxMap, texCoord).a;
#ifdef NORMALMAP_PARALLAX
//parallax map is stored in the alpha channel of the normal map
h = texture2D(parallaxMap, texCoord).a;
#else
//parallax map is a texture
h = texture2D(parallaxMap, texCoord).r;
#endif
float heightScale = parallaxScale;
float heightBias = heightScale* -0.6;
vec3 normView = normalize(vViewDir);
h = (h * heightScale + heightBias) * normView.z;
return texCoord + (h * normView.xy);
}
#endif