1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#version 330 core
in VS_OUT {
vec3 frag_pos;
vec2 tex_coords;
vec3 tangent_light_pos;
vec3 tangent_view_pos;
vec3 tangent_frag_pos;
} fs_in;
out vec4 frag_color;
uniform sampler2D diffuse_texture;
uniform sampler2D normal_map;
uniform sampler2D depth_map;
uniform float hscale;
vec2 parallax_mapping(vec2 tex_coords, vec3 view_dir)
{
float h;
vec2 p, r;
h = texture(depth_map, tex_coords).r;
p = view_dir.xy/view_dir.z*h*hscale;
r = tex_coords-p;
return r;
}
vec2 step_parallax_mapping(vec2 tex_coords, vec3 view_dir)
{
float minsteps, maxsteps, nsteps, step, dstep, depth;
vec2 p, cur_tex_coords, dtex_coords;
minsteps = 8.0;
maxsteps = 32.0;
nsteps = mix(maxsteps, minsteps, max(dot(vec3(0.0, 0.0, 1.0), view_dir), 0.0));
dstep = 1.0/nsteps;
step = 0.0;
p = view_dir.xy*hscale;
dtex_coords = p/nsteps;
cur_tex_coords = tex_coords;
depth = texture(depth_map, cur_tex_coords).r;
while (step < depth) {
cur_tex_coords -= dtex_coords;
depth = texture(depth_map, cur_tex_coords).r;
step += dstep;
}
return cur_tex_coords;
}
vec2 parallax_occlusion_mapping(vec2 tex_coords, vec3 view_dir)
{
float minsteps, maxsteps, nsteps, step, dstep, depth,
after_depth, before_depth, weight;
vec2 p, cur_tex_coords, dtex_coords, prev_tex_coords, result;
minsteps = 8.0;
maxsteps = 32.0;
nsteps = mix(maxsteps, minsteps, max(dot(vec3(0.0, 0.0, 1.0), view_dir), 0.0));
dstep = 1.0/nsteps;
step = 0.0;
p = view_dir.xy*hscale;
dtex_coords = p/nsteps;
cur_tex_coords = tex_coords;
depth = texture(depth_map, cur_tex_coords).r;
while (step < depth) {
cur_tex_coords -= dtex_coords;
depth = texture(depth_map, cur_tex_coords).r;
step += dstep;
}
prev_tex_coords = cur_tex_coords+dtex_coords;
after_depth = depth-step;
before_depth = texture(depth_map, prev_tex_coords).r-step+dstep;
weight = after_depth/(after_depth-before_depth);
result = prev_tex_coords*weight+cur_tex_coords*(1.0-weight);
return result;
}
void main(void)
{
vec3 color, light_color,
normal, view_dir, halfway_dir, light_dir,
ambient, diffuse, specular, result;
vec2 tex_coords;
float diff, spec;
view_dir = normalize(fs_in.tangent_view_pos-fs_in.tangent_frag_pos);
tex_coords = parallax_occlusion_mapping(fs_in.tex_coords, view_dir);
if ((tex_coords.x > 1.0) || (tex_coords.y > 1.0) || (tex_coords.x < 0.0) || (tex_coords.y < 0.0))
discard;
color = vec3(texture(diffuse_texture, tex_coords));
normal = vec3(texture(normal_map, tex_coords));
normal = normalize((normal*2.0)-1.0);
light_color = vec3(1.0);
ambient = vec3(0.01);
light_dir = normalize(fs_in.tangent_light_pos-fs_in.tangent_frag_pos);
diff = max(dot(light_dir, normal), 0.0);
diffuse = diff*light_color;
halfway_dir = normalize(light_dir+view_dir);
spec = pow(max(dot(halfway_dir, normal), 0.0), 64.0);
specular = spec*light_color;
result = (ambient+diffuse+specular)*color;
frag_color = vec4(result, 1.0);
}
|