#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); }