77 lines
3.0 KiB
GLSL
77 lines
3.0 KiB
GLSL
vec4 ReadNormal(vec2 coord) {
|
|
coord = fract(coord) * vTexCoordAM.pq + vTexCoordAM.st;
|
|
return textureGrad(normals, coord, dcdx, dcdy);
|
|
}
|
|
|
|
void GetParallaxCoord(float parallaxFade, inout vec2 newCoord, inout float parallaxDepth) {
|
|
vec2 coord = vTexCoord.st;
|
|
float invParallaxQuality = 1.0 / PARALLAX_QUALITY;
|
|
|
|
if (parallaxFade < 1.0) {
|
|
vec3 normalMap = ReadNormal(vTexCoord.st).xyz * 2.0 - 1.0;
|
|
|
|
float normalCheck = normalMap.x + normalMap.y;
|
|
float minHeight = 1.0 - invParallaxQuality;
|
|
|
|
if (viewVector.z < 0.0 && ReadNormal(vTexCoord.st).a < minHeight && normalCheck > -1.999) {
|
|
float multiplier = 0.25 * (1.0 - parallaxFade) * PARALLAX_DEPTH /
|
|
(-viewVector.z * PARALLAX_QUALITY);
|
|
vec2 interval = viewVector.xy * multiplier;
|
|
#ifdef SELF_SHADOW
|
|
float lowSurface = 0.0;
|
|
#endif
|
|
for(int i = 0; i < PARALLAX_QUALITY; i++) {
|
|
float normalA = ReadNormal(coord).a;
|
|
if (normalA < 1.0 - float(i) / PARALLAX_QUALITY) {
|
|
coord += interval;
|
|
#ifdef SELF_SHADOW
|
|
parallaxDepth = normalA;
|
|
#endif
|
|
} else break;
|
|
}
|
|
newCoord = fract(coord.st) * vTexCoordAM.pq + vTexCoordAM.st;
|
|
}
|
|
}
|
|
}
|
|
|
|
float GetParallaxShadow(float parallaxFade, vec2 coord, vec3 lightVec, mat3 tbn, float parallaxDepth, float normalDepth) {
|
|
float parallaxshadow = 1.0;
|
|
float invParallaxQuality = 1.0 / PARALLAX_QUALITY;
|
|
float minHeight = 1.0 - invParallaxQuality;
|
|
|
|
if (dist < PARALLAX_DISTANCE + 32.0) {
|
|
#ifdef PARALLAX
|
|
float heightCheck = parallaxDepth;
|
|
#else
|
|
float heightCheck = normalDepth;
|
|
#endif
|
|
|
|
if (heightCheck < minHeight) {
|
|
vec3 parallaxdir = tbn * lightVec;
|
|
parallaxdir.xy *= 0.2 * SELF_SHADOW_ANGLE * PARALLAX_DEPTH;
|
|
vec2 newvTexCoord = (coord - vTexCoordAM.st) / vTexCoordAM.pq;
|
|
float step = 1.28 / PARALLAX_QUALITY;
|
|
float height = normalDepth;
|
|
|
|
#ifdef PARALLAX
|
|
int parallaxD32 = PARALLAX_QUALITY / 32;
|
|
#endif
|
|
|
|
for(int i = 0; i < PARALLAX_QUALITY / 4; i++) {
|
|
float currentHeight = height + parallaxdir.z * step * i;
|
|
vec2 parallaxCoord = fract(newvTexCoord + parallaxdir.xy * i * step) *
|
|
vTexCoordAM.pq + vTexCoordAM.st;
|
|
float offsetHeight = textureGrad(normals, parallaxCoord, dcdx, dcdy).a;
|
|
#ifdef PARALLAX
|
|
if (i == parallaxD32) height = parallaxDepth;
|
|
#endif
|
|
parallaxshadow *= clamp(1.0 - (offsetHeight - currentHeight) * 40.0, 0.0, 1.0);
|
|
if (parallaxshadow < 0.01) break;
|
|
}
|
|
|
|
parallaxshadow = mix(parallaxshadow, 1.0, parallaxFade);
|
|
}
|
|
}
|
|
|
|
return parallaxshadow;
|
|
} |