mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-23 12:32:34 +00:00
58 lines
1.4 KiB
GLSL
58 lines
1.4 KiB
GLSL
|
|
// Adjust normal vector according to the normal map
|
|
|
|
#if defined(NORMALMAP)
|
|
|
|
mat3 cotangent_frame(vec3 n, vec3 p, vec2 uv);
|
|
|
|
vec3 ApplyNormalMap(vec2 texcoord)
|
|
{
|
|
#define WITH_NORMALMAP_UNSIGNED
|
|
#define WITH_NORMALMAP_GREEN_UP
|
|
//#define WITH_NORMALMAP_2CHANNEL
|
|
|
|
vec3 interpolatedNormal = normalize(vWorldNormal.xyz);
|
|
|
|
vec3 map = texture(normaltexture, texcoord).xyz;
|
|
#if defined(WITH_NORMALMAP_UNSIGNED)
|
|
map = map * 255./127. - 128./127.; // Math so "odd" because 0.5 cannot be precisely described in an unsigned format
|
|
#endif
|
|
#if defined(WITH_NORMALMAP_2CHANNEL)
|
|
map.z = sqrt(1 - dot(map.xy, map.xy));
|
|
#endif
|
|
#if defined(WITH_NORMALMAP_GREEN_UP)
|
|
map.y = -map.y;
|
|
#endif
|
|
|
|
mat3 tbn = cotangent_frame(interpolatedNormal, pixelpos.xyz, vTexCoord.st);
|
|
vec3 bumpedNormal = normalize(tbn * map);
|
|
return bumpedNormal;
|
|
}
|
|
|
|
mat3 cotangent_frame(vec3 n, vec3 p, vec2 uv)
|
|
{
|
|
// get edge vectors of the pixel triangle
|
|
vec3 dp1 = dFdx(p);
|
|
vec3 dp2 = dFdy(p);
|
|
vec2 duv1 = dFdx(uv);
|
|
vec2 duv2 = dFdy(uv);
|
|
|
|
// solve the linear system
|
|
vec3 dp2perp = cross(n, dp2); // cross(dp2, n);
|
|
vec3 dp1perp = cross(dp1, n); // cross(n, dp1);
|
|
vec3 t = dp2perp * duv1.x + dp1perp * duv2.x;
|
|
vec3 b = dp2perp * duv1.y + dp1perp * duv2.y;
|
|
|
|
// construct a scale-invariant frame
|
|
float invmax = inversesqrt(max(dot(t,t), dot(b,b)));
|
|
return mat3(t * invmax, b * invmax, n);
|
|
}
|
|
|
|
#else
|
|
|
|
vec3 ApplyNormalMap(vec2 texcoord)
|
|
{
|
|
return normalize(vWorldNormal.xyz);
|
|
}
|
|
|
|
#endif
|