Self shadow on parrallax mapping
This file contains 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
#version 420 core | |
/* frame definition */ | |
uniform mat4 u_matrix_mvp; | |
uniform mat4 u_matrix_m; | |
uniform mat4 u_matrix_v; | |
uniform mat4 u_matrix_p; | |
uniform vec3 u_camera_position; | |
/* material definition */ | |
uniform sampler2D tex_albedo; | |
uniform sampler2D tex_normal; | |
uniform sampler2D tex_height; | |
in vertex_data { | |
mat3 iTBN; | |
vec3 tan_wpos; | |
vec3 tan_vpos; | |
vec2 uv; | |
} fs_in; | |
out vec4 result; | |
#define EPSILON 1e-5f | |
const float HEIGHT_SCALE = 0.05f; | |
const float AMBIENT_LIGHT = 0.15f; | |
const bool CLAMP_UVS = false; | |
const vec3 LIGHT_POS = vec3(10.f, 300.f, 50.f); | |
float parrallax_lambert(vec2 uv, vec3 ldir) | |
{ | |
vec3 normal = texture2D(tex_normal, uv).rgb; | |
normal = normalize(normal * 2.f - 1.f); | |
const float step_count = 2.f; | |
const float step_height = 1.f / step_count; | |
vec2 uv_step = (-ldir.xy * HEIGHT_SCALE) / step_count; | |
uv_step.y *= -1.f; /* because of OpenGL norm */ | |
float sample_height = texture2D(tex_height, uv).r; | |
float ray_height = sample_height + EPSILON; | |
while (sample_height < ray_height && ray_height < 1.f - EPSILON) { | |
uv += uv_step; | |
sample_height = texture2D(tex_height, uv).r; | |
ray_height += step_height; | |
} | |
ldir.y *= -1.f; /* OpenGL norm */ | |
float light = max(0.f, dot(-ldir, normal)); | |
return light; | |
if (ray_height < 1.f - EPSILON) { | |
return min(AMBIENT_LIGHT, light); | |
} | |
return light; | |
} | |
vec2 parrallax_occlusion_mapping(vec2 uv_in, vec3 vdir) | |
{ | |
const float STEP_COUNT = 10.f; | |
const float step_height = 1.f / STEP_COUNT; | |
vec2 uv_step = (vdir.xy * HEIGHT_SCALE) / STEP_COUNT; | |
uv_step.y *= -1.f; /* OpenGL norm */ | |
vec2 uv = uv_in.xy; | |
float last_sample = 0.f; | |
float current_height = 1.f; | |
float sampled_height = texture2D(tex_height, uv).r; | |
while (current_height > sampled_height) { | |
last_sample = sampled_height; | |
uv += uv_step; | |
current_height -= step_height; | |
sampled_height = texture2D(tex_height, uv).r; | |
} | |
const float l = last_sample - (current_height + step_height); | |
const float c = sampled_height - current_height; | |
const float w = c / (c - l); | |
return uv * (w) + (uv + uv_step) * (1.f - w); | |
} | |
void main() | |
{ | |
vec3 res; | |
vec3 tan_vdir = normalize(fs_in.tan_wpos - fs_in.tan_vpos); | |
vec2 p_uv = parrallax_occlusion_mapping(fs_in.uv, tan_vdir); | |
if (CLAMP_UVS && (p_uv.x > 1.f || p_uv.y > 1.f || p_uv.x < 0.f || p_uv.y < 0.f)) | |
discard; | |
vec3 p_wpos = fs_in.tan_wpos; | |
p_wpos.xy += p_uv; | |
vec3 tan_lpos = fs_in.iTBN * LIGHT_POS; | |
vec3 tan_ldir = normalize(p_wpos - tan_lpos); | |
vec3 albedo = texture2D(tex_albedo, p_uv).rgb; | |
res.rgb = albedo * parrallax_lambert(p_uv, tan_ldir); | |
result = vec4(res, 1.f); | |
} |
This file contains 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
#version 330 core | |
/* frame definition */ | |
uniform mat4 u_matrix_mvp; | |
uniform mat4 u_matrix_m; | |
uniform mat4 u_matrix_v; | |
uniform mat4 u_matrix_p; | |
uniform mat4 u_matrix_normal; | |
uniform vec3 u_camera_position; | |
in vec3 vertex; | |
in vec3 normal; | |
in vec3 tangent; | |
in vec2 uv; | |
out vertex_data { | |
mat3 iTBN; | |
vec3 tan_wpos; | |
vec3 tan_vpos; | |
vec2 uv; | |
} vs_out; | |
void main() | |
{ | |
vec3 world_position = (u_matrix_m * vec4(vertex, 1.f)).xyz; | |
vec3 bitangent = normalize(cross(normal, tangent)); | |
vec3 T = normalize(u_matrix_normal * vec4(tangent, 0.f)).xyz; | |
vec3 B = normalize(u_matrix_normal * vec4(bitangent, 0.f)).xyz; | |
vec3 N = normalize(u_matrix_normal * vec4(normal, 0.f)).xyz;; | |
vs_out.iTBN = transpose(mat3(T, B, N)); | |
vs_out.tan_wpos = vs_out.iTBN * world_position; | |
vs_out.tan_vpos = vs_out.iTBN * u_camera_position; | |
vs_out.uv = vec2(uv.x, 1.f - uv.y); | |
gl_Position = u_matrix_mvp * vec4(vertex.xyz, 1.0);; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment