Created
February 4, 2020 07:56
-
-
Save msomeone/0918f7b1944d058920d8e280cfd75e8b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
vec3 ndc2world(mat4 inv_proj, mat4 inv_view, vec3 ndc_pos) | |
{ | |
vec4 v = inv_proj * vec4(ndc_pos, 1.); | |
v.xyz /= v.w; // view space | |
vec4 w = inv_view * vec4(v.xyz, 1.); // world space, camera relative (origin = camera position) | |
return w.xyz; | |
//return v.xyz; | |
} | |
// Try reconstructing normal accurately from depth buffer. | |
// input DepthBuffer: stores linearized depth in range (0, 1). | |
// 5 taps on each direction: | z | x | * | y | w |, '*' denotes the center sample. | |
vec3 ReconstructNormal(sampler2D DepthBuffer, vec2 ndc0, vec2 uv0, vec2 texel_size, mat4 inv_proj, mat4 inv_view) | |
{ | |
float depth = (textureLod(DepthBuffer, uv0, 0.).x); | |
vec4 H, H0; | |
H0.x = textureLod(DepthBuffer, uv0 - vec2(1. / texel_size.x, 0.), .0).x; | |
H0.y = textureLod(DepthBuffer, uv0 + vec2(1. / texel_size.x, 0.), .0).x; | |
H0.z = textureLod(DepthBuffer, uv0 - vec2(2. / texel_size.x, 0.), .0).x; | |
H0.w = textureLod(DepthBuffer, uv0 + vec2(2. / texel_size.x, 0.), .0).x; | |
H.x = (H0.x); | |
H.y = (H0.y); | |
H.z = (H0.z); | |
H.w = (H0.w); | |
//vec2 he = abs(H.xy * H.zw / (2. * H.zw - H.xy) - depth); | |
vec2 he = vec2( | |
abs((2. * H.x - H.z) - depth), // line eq. solutions for (x0 + 2), x0 = x0(z_tap) | |
abs((2. * H.y - H.w) - depth) | |
); | |
vec3 hDeriv; | |
if (he.x > he.y) | |
{ // Calculate horizontal derivative of world position from taps | z | x | | |
vec3 tap_x_wp = ndc2world(inv_proj, inv_view, vec3(ndc0 - vec2(1. / texel_size.x, 0.) * 2., H0.x)); | |
vec3 tap_z_wp = ndc2world(inv_proj, inv_view, vec3(ndc0 - vec2(2. / texel_size.x, 0.) * 2., H0.z)); | |
hDeriv = tap_x_wp - tap_z_wp; // may ignore 1./dx = 2., who cares if we gona normalize anyway | |
} | |
else | |
{// Calculate horizontal derivative of world position from taps | y | w | | |
vec3 tap_y_wp = ndc2world(inv_proj, inv_view, vec3(ndc0 + vec2(0., 1. / texel_size.x) * 2., H0.y)); | |
vec3 tap_w_wp = ndc2world(inv_proj, inv_view, vec3(ndc0 + vec2(0., 2. / texel_size.x) * 2., H0.w)); | |
hDeriv = tap_w_wp - tap_y_wp; | |
} | |
vec4 V, V0; | |
V0.x = textureLod(DepthBuffer, uv0 - vec2(0., 1. / texel_size.y), .0).x; | |
V0.y = textureLod(DepthBuffer, uv0 + vec2(0., 1. / texel_size.y), .0).x; | |
V0.z = textureLod(DepthBuffer, uv0 - vec2(0., 2. / texel_size.y), .0).x; | |
V0.w = textureLod(DepthBuffer, uv0 + vec2(0., 2. / texel_size.y), .0).x; | |
V.x = (V0.x); | |
V.y = (V0.y); | |
V.z = (V0.z); | |
V.w = (V0.w); | |
//vec2 ve = abs(V.xy * V.zw / (2. * V.zw - V.xy) - depth); | |
vec2 ve = vec2( // line eq. solutions for (y0 + 2), y0 = y0(z_tap) | |
abs((2. * V.x - V.z) - depth), | |
abs((2. * V.y - V.w) - depth) | |
); | |
vec3 vDeriv; | |
if (ve.x > ve.y) | |
{ // Calculate vertical derivative of world position from taps | z | x | | |
vec3 tap_x_wp = ndc2world(inv_proj, inv_view, vec3(ndc0 - vec2(0., 1. / texel_size.y) * 2., V0.x)); | |
vec3 tap_z_wp = ndc2world(inv_proj, inv_view, vec3(ndc0 - vec2(0., 2. / texel_size.y) * 2., V0.z)); | |
vDeriv = tap_x_wp - tap_z_wp; | |
} | |
else | |
{ // Calculate vertical derivative of world position from taps | y | w | | |
vec3 tap_y_wp = ndc2world(inv_proj, inv_view, vec3(ndc0 + vec2(0., 1. / texel_size.y) * 2., V0.y)); | |
vec3 tap_w_wp = ndc2world(inv_proj, inv_view, vec3(ndc0 + vec2(0., 2. / texel_size.y) * 2., V0.w)); | |
vDeriv = tap_w_wp - tap_y_wp; | |
} | |
return normalize(cross(hDeriv, vDeriv)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment