mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-24 02:11:14 +00:00
59 lines
1.4 KiB
Text
59 lines
1.4 KiB
Text
|
|
||
|
// 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
|