42 lines
1.3 KiB
GLSL
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);
|
|
}
|