swwmgz_m/shaders/glsl/Envmask.fp

48 lines
1.9 KiB
GLSL

// basic texture + masked equirectangular envmap + gradient rim
// allows for up to three different layers of environment mapping (RGB mask)
#define RECIPROCAL_PI2 0.15915494
// keeping this as a define while using vec3 uniforms for the parameters
// ensures that we only need to compile three versions of this material shader
// (at least, because I don't know for sure how VKDoom handles this stuff)
#ifndef ENV_LAYERS
#define ENV_LAYERS 1
#endif
#define ENV_TWOLAYER ((ENV_LAYERS == 2) || (ENV_LAYERS == 3))
#define ENV_THREELAYER (ENV_LAYERS == 3)
void SetupMaterial( inout Material mat )
{
vec4 base = getTexel(vTexCoord.st);
vec4 mask = texture(masktex,vTexCoord.st);
vec3 norm = normalize(vWorldNormal.xyz);
vec3 eye = normalize(uCameraPos.xyz-pixelpos.xyz);
vec3 rvec = normalize(reflect(eye,norm));
vec2 uv = vec2(atan(rvec.z,rvec.x)*RECIPROCAL_PI2+.5,asin(rvec.y)*RECIPROCAL_PI2+.5);
vec2 uv2 = vec2(atan(rvec.z,abs(rvec.x))*RECIPROCAL_PI2+.5,asin(rvec.y)*RECIPROCAL_PI2+.5);
vec2 dTdx = dFdx(uv2);
vec2 dTdy = dFdy(uv2);
float rf = 1.-abs(dot(eye,norm));
vec3 envcol = textureGrad(envtex,uv,dTdx,dTdy).rgb*EnvFact.x;
float rim = smoothstep(RimStep.x,1.,rf);
vec3 rimcol = textureLod(rimtex,vec2(.25+.5*rim,.5),0.).rgb;
envcol = mix(envcol,rimcol,rim*RimFact.x);
mat.Base = vec4(base.rgb+envcol*mask.x,base.a);
#if ( ENV_TWOLAYER )
envcol = textureGrad(envtex2,uv,dTdx,dTdy).rgb*EnvFact.y;
rim = smoothstep(RimStep.y,1.,rf);
rimcol = textureLod(rimtex2,vec2(.25+.5*rim,.5),0.).rgb;
envcol = mix(envcol,rimcol,rim*RimFact.y);
mat.Base.rgb += envcol*mask.y;
#endif
#if ( ENV_THREELAYER )
envcol = textureGrad(envtex3,uv,dTdx,dTdy).rgb*EnvFact.z;
rim = smoothstep(RimStep.z,1.,rf);
rimcol = textureLod(rimtex3,vec2(.25+.5*rim,.5),0.).rgb;
envcol = mix(envcol,rimcol,rim*RimFact.z);
mat.Base.rgb += envcol*mask.z;
#endif
mat.Normal = ApplyNormalMap(vTexCoord.st);
mat.Bright = texture(brighttexture,vTexCoord.st);
}