assimp/contrib/tinyusdz/tinyusdz-repo/examples/openglviewer/shaders/perturbed_normal.frag

43 lines
1.1 KiB
GLSL

in vec2 interpolated_uv;
in vec3 interpolated_normal;
in vec3 fragment_world_position;
uniform sampler2D normal_texture;
uniform vec3 camera_position;
out vec4 output_color;
mat3 cotangent_frame(vec3 N, vec3 p, vec2 uv)
{
vec3 dp1 = dFdx( p );
vec3 dp2 = dFdy( p );
vec2 duv1 = dFdx( uv );
vec2 duv2 = dFdy( uv );
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;
float invmax = inversesqrt(max(dot(T,T), dot(B,B)));
return mat3( T * invmax, B * invmax, N );
}
// Perturb normal, see http://www.thetenthplanet.de/archives/1180
vec3 perturb_normal(vec3 N, vec3 V)
{
vec3 sampled_normal_map = texture(normal_texture, interpolated_uv).xyz * 255.f/127.f - 128.f/127.f;
sampled_normal_map.y = - sampled_normal_map.y;
mat3 TBN = cotangent_frame(N, -V, interpolated_uv);
return normalize(TBN * sampled_normal_map);
}
void main()
{
vec3 v = normalize(camera_position - fragment_world_position);
vec3 n = perturb_normal(normalize(interpolated_normal), v);
output_color = vec4(n, 1.0f);
}