1
0
Fork 0
fgdata/Shaders/HDR/normalmap.glsl
Fernando García Liñán 10cd3fb8c4 HDR: Normal mapping without precomputed tangents
Also tidy up model and terrain shaders. Inputs and outputs to vertex and
fragment shaders are now interface blocks.
2023-04-17 05:09:24 +02:00

42 lines
1.3 KiB
GLSL

#version 330 core
uniform sampler2D normal_tex;
uniform int normalmap_dds = 0;
/*
* Create a cotangent frame without a pre-computed tangent basis.
* "Normal Mapping Without Precomputed Tangents" by Christian Schüler (2013).
* http://www.thetenthplanet.de/archives/1180
*/
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(dp2, N);
vec3 dp1perp = 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);
}
/*
* Perturb the interpolated vertex normal N according to a normal map.
* V is the view vector (eye to vertex, not normalized). Both N and V must be
* in the same space.
*/
vec3 perturb_normal(vec3 N, vec3 V, vec2 texcoord)
{
vec3 normal = texture(normal_tex, texcoord).rgb * 2.0 - 1.0;
if (normalmap_dds > 0) {
// DDS has flipped normals
normal = -normal;
}
mat3 TBN = cotangent_frame(N, V, texcoord);
return normalize(TBN * normal);
}