Shadertoy-Shaders/Simple-Parallax-Occlusion-M.../Image.glsl

79 lines
1.5 KiB
GLSL

mat2 mkrot(in float t)
{
float s = sin(t);
float c = cos(t);
return mat2(c,-s,s,c);
}
void rotCam(inout vec3 ro, inout vec3 rd)
{
mat2 a = mkrot(.4);
ro.yz *= a;
rd.yz *= a;
mat2 b = mkrot(iTime*.4);
ro.xz *= b;
rd.xz *= b;
mat2 c = mkrot(sin(iTime*.4) * .5);
ro.xy *= c;
rd.xy *= c;
}
vec2 pom(in vec2 uv, in vec3 i)
{
float y = 0.0;
float d = 2./256.;
for (int k = 0; k < 512; k++)
{
float h = textureLod(iChannel0, uv, 2.5).r;
if (abs(h - y) > 1.)
break;
y += i.y * d;
uv += i.xz * d * 1e-1;
}
return uv;
}
vec3 pomNor(in vec2 uv)
{
const vec2 eps = vec2(1e-2,0);
float t = textureLod(iChannel0, uv + eps.xy, 2.5).r;
float b = textureLod(iChannel0, uv - eps.xy, 2.5).r;
float l = textureLod(iChannel0, uv - eps.yx, 2.5).r;
float r = textureLod(iChannel0, uv + eps.yx, 2.5).r;
return normalize(vec3(r-l, 1e-1, b-t));
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = (fragCoord-.5*iResolution.xy)/iResolution.y;
vec3 s = normalize(vec3(1,1,0));
vec3 ro = vec3(0,-.1,-1);
vec3 rd = normalize(vec3(uv, 1));
rotCam(ro, rd);
vec3 col = vec3(0);
float t = -ro.y/rd.y;
vec3 p = ro + rd * t;
vec3 ap = abs(p);
if (t > 0. && max(max(ap.x,ap.y),ap.z) < .5)
{
vec2 st = pom(p.xz, rd);
vec3 n = pomNor(st);
col = texture(iChannel0, st).rgb * dot(n, s);
}
fragColor = vec4(col,1.0);
}