diff --git a/Simple-Parallax-Occlusion-Mapping/Image.glsl b/Simple-Parallax-Occlusion-Mapping/Image.glsl new file mode 100644 index 0000000..ae4896f --- /dev/null +++ b/Simple-Parallax-Occlusion-Mapping/Image.glsl @@ -0,0 +1,79 @@ + +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); +} \ No newline at end of file diff --git a/Simple-Parallax-Occlusion-Mapping/README.md b/Simple-Parallax-Occlusion-Mapping/README.md new file mode 100644 index 0000000..eeedd9f --- /dev/null +++ b/Simple-Parallax-Occlusion-Mapping/README.md @@ -0,0 +1,6 @@ +# Simple Parallax Occlusion Mapping +![POM](https://git.teridax.de/teridax/Shadertoy-Shaders/raw/branch/main/Simple-Parallax-Occlusion-Mapping/overview.png) + +Parallax Occlusion Mapping is a way of adding 3D bumps to a flat surface, based on a heightmap. This does not actually displace the geometry +but performs a ray casting algorithm on the surface which acts a "portal" to a more detailed surface. +This Implememtation is a basic first draft and assumes the surface normal to a constant up vector. diff --git a/Simple-Parallax-Occlusion-Mapping/overview.png b/Simple-Parallax-Occlusion-Mapping/overview.png new file mode 100644 index 0000000..bea88eb Binary files /dev/null and b/Simple-Parallax-Occlusion-Mapping/overview.png differ