$input v_texcoord0, v_ts_light_pos, v_ts_view_pos, v_ts_frag_pos #include "../common/common.sh" SAMPLER2D(s_texColor, 0); SAMPLER2D(s_texNormal, 1); SAMPLER2D(s_texDepth, 2); uniform vec4 u_pomParam; #define u_shading_type u_pomParam.x #define u_show_diffuse_texture u_pomParam.y #define u_parallax_scale u_pomParam.z #define u_num_steps u_pomParam.w vec2 parallax_uv(vec2 uv, vec3 view_dir) { float depth_scale = float(u_parallax_scale) / 1000.0; if (u_shading_type == 2.0) { // Parallax mapping float depth = texture2D(s_texDepth, uv).r; vec2 p = view_dir.xy * (depth * depth_scale) / view_dir.z; return uv - p; } else { float layer_depth = 1.0 / float(u_num_steps); float cur_layer_depth = 0.0; vec2 delta_uv = view_dir.xy * depth_scale / (view_dir.z * u_num_steps); vec2 cur_uv = uv; float depth_from_tex = texture2D(s_texDepth, cur_uv).r; for (int i = 0; i < 32; i++) { cur_layer_depth += layer_depth; cur_uv -= delta_uv; depth_from_tex = texture2D(s_texDepth, cur_uv).r; if (depth_from_tex < cur_layer_depth) { break; } } if (u_shading_type == 3.0) { // Steep parallax mapping return cur_uv; } else { // Parallax occlusion mapping vec2 prev_uv = cur_uv + delta_uv; float next = depth_from_tex - cur_layer_depth; float prev = texture2D(s_texDepth, prev_uv).r - cur_layer_depth + layer_depth; float weight = next / (next - prev); return mix(cur_uv, prev_uv, weight); } } } void main() { vec3 light_dir = normalize(v_ts_light_pos - v_ts_frag_pos); vec3 view_dir = normalize(v_ts_view_pos - v_ts_frag_pos); // Only perturb the texture coordinates if a parallax technique is selected vec2 uv = (u_shading_type < 2.0) ? v_texcoord0 : parallax_uv(v_texcoord0, view_dir); vec3 albedo; if (u_show_diffuse_texture == 0.0) { albedo = vec3(1.0, 1.0, 1.0); } else { albedo = texture2D(s_texColor, uv).rgb; } vec3 ambient = 0.3 * albedo; vec3 normal; if (u_shading_type == 0.0) { normal = vec3(0.0, 0.0, 1.0); } else { normal.xy = texture2DBc5(s_texNormal, uv) * 2.0 - 1.0; normal.z = sqrt(1.0 - dot(normal.xy, normal.xy) ); } float diffuse = max(dot(light_dir, normal), 0.0); gl_FragColor = vec4(diffuse * albedo + ambient, 1.0); }