mame/3rdparty/bgfx/examples/33-pom/fs_pom.sc

97 lines
2.2 KiB
Scala

$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);
}