From 49cda13e509c6b15f69f72df70e608e3d2b9a75a Mon Sep 17 00:00:00 2001 From: mars Date: Sat, 7 May 2022 18:37:49 -0600 Subject: [PATCH] Add initial oct_encoding.wgsl --- shaders/oct_encoding.wgsl | 52 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 shaders/oct_encoding.wgsl diff --git a/shaders/oct_encoding.wgsl b/shaders/oct_encoding.wgsl new file mode 100644 index 0000000..201cd09 --- /dev/null +++ b/shaders/oct_encoding.wgsl @@ -0,0 +1,52 @@ +struct TangentFrame { + normal: vec3; + tangent: vec3; +}; + +// https://knarkowicz.wordpress.com/2014/04/16/octahedron-normal-vector-encoding/?like_comment=12 +fn oct_norm_wrap(v: vec2) -> vec2 { + return (1.0 - abs(v.yx)) * select(vec2(-1.0), vec2(1.0), v.xy >= vec2(0.0)); +} + +fn oct_norm_encode(n: vec3) -> vec2 { + let ml = (abs(n.x) + abs(n.y) + abs(n.z)); // ml = manhattan length + let n = n / ml; + let v = select(oct_norm_wrap(n.xy), n.xy, n.z >= 0.0); + return fma(v, vec2(0.5), vec2(0.5)); +} + +fn oct_norm_decode(f: vec2) -> vec3 { + let f = fma(f, vec2(2.0), vec2(-1.0)); + let n = vec3(f.xy, 1.0 - abs(f.x) - abs(f.y)); + let t = vec2(clamp(-n.z, 0.0, 1.0)); + let nxy = n.xy + select(t, -t, n.xy >= vec2(0.0)); + return normalize(vec3(nxy, n.z)); +} + +fn tan_frame_encode(tf: TangentFrame) -> u32 { + return u32(0); // TODO +} + +fn tan_frame_decode(i: u32) -> TangentFrame { + let n = i & u32(0xffff); + let nx = n >> u32(8); + let ny = n & u32(0xff); + let n = vec2(f32(nx), f32(ny)) / 255.0; + + let t = i >> u32(16); + let tx = t >> u32(8); + let ty = t & u32(0xff); + let t = vec2(f32(tx), f32(ty)) / 255.0; + + var tf: TangentFrame; + tf.normal = oct_norm_decode(n); + tf.tangent = oct_norm_decode(n); + return tf; +} + +fn tan_frame_transform(i: u32, transform: mat4x4) -> u32 { + var tf = tan_frame_decode(i); + tf.normal = (transform * vec4(tf.normal, 0.0)).xyz; + tf.tangent = (transform * vec4(tf.tangent, 0.0)).xyz; + return tan_frame_encode(tf); +}