# HG changeset patch # User Leonard Ritter # Date 1645260740 -3600 # Sat Feb 19 09:52:20 2022 +0100 # Node ID ef01c3ccf70920891a986aa97025097af5fb0acf # Parent e0122ef2d1f882869b220eabf65d06114b6876ac * VVF: fixed smooth normals diff --git a/testing/test_cascade_dmc_cc_vvf.sc b/testing/test_cascade_dmc_cc_vvf.sc --- a/testing/test_cascade_dmc_cc_vvf.sc +++ b/testing/test_cascade_dmc_cc_vvf.sc @@ -50,7 +50,7 @@ POST_TRANSFORM := false # true is worse OCCLUSION_CULLING := false FOG := false -USE_FLAT_SHADING := false +USE_FLAT_SHADING := true BALANCE_QUADS := true USE_COMPLEX_SURFACE := false HIGH_QUALITY_FEATURES := true @@ -82,8 +82,8 @@ let MAX_SECTOR_LOD_I = 2 let SECTOR_GROUP_SIZE = (1 << MAX_SECTOR_LOD_I) -#let SUBDIVIDE_RADIUS = 6 -let SUBDIVIDE_RADIUS = 4 +let SUBDIVIDE_RADIUS = 6 +#let SUBDIVIDE_RADIUS = 4 let SUBDIVIDE_SCALE = 12 MAX_CASCADE_DEPTH := 6 # MAX_WORLD_LOD_I - MAX_SECTOR_LOD_I @@ -136,6 +136,15 @@ BLEND+Z = 16:u32 BLEND-Z = 32:u32 +# corner planes +let + MASK_PLANE-X = 0x01010101 + MASK_PLANE+X = 0x10101010 + MASK_PLANE-Y = 0x00110011 + MASK_PLANE+Y = 0x11001100 + MASK_PLANE-Z = 0x00001111 + MASK_PLANE+Z = 0x11110000 + struct Sector plain key : u32 flags : u32 # six face bits indicating where the next highest LOD level is @@ -467,8 +476,25 @@ q1 := (c + w) * 2.0 - 1.0 ? ((abs q0) < (abs q1)) q0 q1 -fn triangle-area (A B C) - (length (cross (B - A) (C - A))) / 2.0 +inline triangle-area-normal (v1 v2 v3) + if 1 + cross + (v2 - v1) . xyz + (v3 - v1) . xyz + else + let a b = + (v2 - v1) . xyz + (v3 - v1) . xyz + * + cross (normalize a) (normalize b) + length (cross a b) + +inline triangle-normal (v1 v2 v3) + normalize (triangle-area-normal v1 v2 v3) + +# triangle area * 2 +inline triangle-areax2 (v1 v2 v3) + length (triangle-area-normal v1 v2 v3) fn trimix (v p) # corner weights of cube in [-1..1]³ domain @@ -1099,13 +1125,6 @@ NATIVE_LANE_WIDTH := 64 -fn normal (v1 v2 v3) - cross - normalize - (v3 - v1) . xyz - normalize - (v2 - v1) . xyz - inline swapnormal (v n) Vertex v.pos (vec4 n 0) @@ -1125,8 +1144,8 @@ let ofs = (atomicAdd vertex-out.count 6) entries := vertex-out.entries static-if USE_FLAT_SHADING - n0 := (normal v00.pos v10.pos v11.pos) - n1 := (normal v11.pos v01.pos v00.pos) + n0 := (triangle-normal v00.pos v10.pos v11.pos) + n1 := (triangle-normal v11.pos v01.pos v00.pos) #n1 := (normal v00.pos v11.pos v01.pos) entries @ (ofs + 0) = (swapnormal v00 n0) @@ -1153,8 +1172,8 @@ BLEND-Z = 32:u32 fn lod-skirt? (p sector-flags) - MIND := SECTOR_GROUP_SIZE // 2 - MAXD := SECTOR_GROUP_SIZE + MIND := 2 + MAXD := SECTOR_GROUP_SIZE - 2 predicate-flags := | ? (p.x >= MAXD) BLEND+X 0:u32 @@ -1209,7 +1228,6 @@ local cflags = 0:u32 for i in (range 0 8) let x y z = (i & 1) ((i >> 1) & 1) ((i >> 2) & 1) - #d := (((x ^ y ^ z) & 1) * 2 - 1) as f32 delta := (ivec3 x y z) wpos := gpos + delta let wpos lod = @@ -1233,37 +1251,72 @@ _ (gpos >> 1) (lod + 1) 2.0 (1.0 - (vec3 (gpos & 1)) * 2.0) else _ gpos lod 1.0 (vec3 0.0) + + local cflags = 0:u32 + for i in (range 0 8) + let x y z = (i & 1) ((i >> 1) & 1) ((i >> 2) & 1) + delta := (ivec3 x y z) + wpos := vpos + delta + let vx cf = + unpack-vvf (texelFetch smp-world wpos vlod) + cflags |= ((cf & 1) << (i as u32)) + cflags := (deref cflags) + inline fetch (offset) let vx = static-if BLOCKY_WORLD (vec3 0) else _ (unpack-vvf (texelFetch smp-world (vpos + offset) vlod)) () - vx := vx + (vec3 offset) * 2.0 - vx := vx * vscale + voffset - let vc v-x v+x v-y v+y v-z v+z = - fetch (ivec3 0) - fetch (ivec3 1 0 0) - fetch (ivec3 -1 0 0) - fetch (ivec3 0 1 0) - fetch (ivec3 0 -1 0) - fetch (ivec3 0 0 1) - fetch (ivec3 0 0 -1) - inline edgeweight (mask) - m := (cflags & mask) - ? ((m != mask) & (m != 0)) 1.0 0.0 - let nvert = - + - (vec4 (v+x - vc) 1) * (edgeweight 0x10101010) - (vec4 (vc - v-x) 1) * (edgeweight 0x01010101) - (vec4 (v+y - vc) 1) * (edgeweight 0x11001100) - (vec4 (vc - v-y) 1) * (edgeweight 0x00110011) - (vec4 (v+z - vc) 1) * (edgeweight 0x11110000) - (vec4 (vc - v-z) 1) * (edgeweight 0x00001111) - normal := nvert.xyz / nvert.w + vx + (vec3 offset) * 2.0 + + let v000 = (fetch (ivec3 0 0 0)) + + ### compute vertex normal + + inline edgebits (a b) + (cflags >> a as u32) & 1, (cflags >> b as u32) & 1 + + inline edge (a b) + let u v = (edgebits a b) + (u != v), (u == 0) + + local normal_accum = (vec3 0) + inline collect-plane (Du fpermute u v) + Dv := (Du + 1) % 3 + Dw := (Du + 2) % 3 + i0 := (u << Du) | (v << Dv) + i1 := i0 ^ (1 << Dw) + let set? flip? = (edge i0 i1) + if set? + flip? := flip? ^ ((u ^ v) == 1) + v00 := v000 + let du dv = (u * 2 - 1) (v * 2 - 1) + v01 := (fetch (fpermute du 0)) + v10 := (fetch (fpermute 0 dv)) + #v11 := (fetch (fpermute du dv)) + n1 := (triangle-area-normal v00 v01 v10) + #n2 := (triangle-area-normal v11 v10 v00) + + #normal_accum += (n1 + n2) * (? flip? -1.0 1.0) + normal_accum += n1 * (? flip? -1.0 1.0) + ; + + for u v in (dim 2 2) + collect-plane 0 # XY + inline (du dv) (ivec3 du dv 0) + \ u v + collect-plane 1 # YZ + inline (du dv) (ivec3 0 du dv) + \ u v + collect-plane 2 # ZX + inline (du dv) (ivec3 dv 0 du) + \ u v + vertexlod := lod as f32 + (? llod? 0.5 0.0) + vertex := v000 * vscale + voffset cell-vertex @ idx = - vec4 vc vertexlod - cell-normal @ idx = normal + vec4 vertex vertexlod + cell-normal @ idx = (normalize normal_accum) ; ; barrier; @@ -1283,22 +1336,19 @@ dpos := lpos + offset idx := (id2svindex dpos) v := (copy (cell-vertex @ idx)) - transform-vertex v dpos + _ (transform-vertex v.xyz dpos) (copy (cell-normal @ idx)) local verts : (array vec4 7) + local norms : (array vec4 7) local n = 0 va-map inline (i) verts @ i = (vec4 0) + norms @ i = (vec4 0) va-range 7 let C00- C00+ C0-0 C0+0 C-00 C+00 C000 = (va-range 7) - let v000 = (getvertex (ivec3 0 0 0)) - #inline check-edge (IDX ofs mask) - x := (cflags & mask) - if ((x != mask) & ((x ^ mask) != mask)) - m := (v000 + (getvertex ofs)) - w @ C00- = (vec4 m 2) + let v000 n000 = (getvertex (ivec3 0 0 0)) inline edgebits (a b) (cflags >> a as u32) & 1, (cflags >> b as u32) & 1 @@ -1316,18 +1366,22 @@ let set? flip? = (edge i0 i1) if set? v00 := v000 + n00 := n000 let du dv = (u * 2 - 1) (v * 2 - 1) - v01 := (getvertex (fpermute du 0)) - v10 := (getvertex (fpermute 0 dv)) - v11 := (getvertex (fpermute du dv)) - # face vertices - fv := ((v00 + v01 + v10 + v11) / 4) - # edge vertices - ev01 := (v00 + v01) / 2 - ev10 := (v00 + v10) / 2 - verts @ C000 += (vec4 (fv + ev01 + ev10) 3) - verts @ (Du * 2 + u) += (vec4 (fv + ev01) 2) - verts @ (Dv * 2 + v) += (vec4 (fv + ev10) 2) + let v01 n01 = (getvertex (fpermute du 0)) + let v10 n10 = (getvertex (fpermute 0 dv)) + let v11 n11 = (getvertex (fpermute du dv)) + inline compute-verts (verts v00 v01 v10 v11) + # face vertices + fv := ((v00 + v01 + v10 + v11) / 4) + # edge vertices + ev01 := (v00 + v01) / 2 + ev10 := (v00 + v10) / 2 + verts @ C000 += (vec4 (fv + ev01 + ev10) 3) + verts @ (Du * 2 + u) += (vec4 (fv + ev01) 2) + verts @ (Dv * 2 + v) += (vec4 (fv + ev10) 2) + compute-verts verts v00 v01 v10 v11 + compute-verts norms n00 n01 n10 n11 n += 1 ; @@ -1351,28 +1405,33 @@ if set? flip? := flip? ^ ((u ^ v) == 1) v00 := v000 + n00 := n000 let du dv = (u * 2 - 1) (v * 2 - 1) - v01 := (getvertex (fpermute du 0)) - v10 := (getvertex (fpermute 0 dv)) - v11 := (getvertex (fpermute du dv)) - # face vertices - fv := (v00 + v01 + v10 + v11) / 4 - # edge vertices - ev01 := (copy (verts @ (Du * 2 + u))) - ev01 := ev01.xyz / ev01.w - ev10 := (copy (verts @ (Dv * 2 + v))) - ev10 := ev10.xyz / ev10.w - # center vertex - cv := (copy (verts @ C000)) - cv := cv.xyz / cv.w - let ev01 ev10 = - if flip? (_ ev10 ev01) - else (_ ev01 ev10) + let v01 n01 = (getvertex (fpermute du 0)) + let v10 n10 = (getvertex (fpermute 0 dv)) + let v11 n11 = (getvertex (fpermute du dv)) + inline compute-quad (verts v00 v01 v10 v11) + # face vertices + fv := (v00 + v01 + v10 + v11) / 4 + # edge vertices + ev01 := (copy (verts @ (Du * 2 + u))) + ev01 := ev01.xyz / ev01.w + ev10 := (copy (verts @ (Dv * 2 + v))) + ev10 := ev10.xyz / ev10.w + # center vertex + cv := (copy (verts @ C000)) + cv := cv.xyz / cv.w + let ev01 ev10 = + if flip? (_ ev10 ev01) + else (_ ev01 ev10) + _ cv ev01 ev10 fv + let v0 v1 v2 v3 = (compute-quad verts v00 v01 v10 v11) + let n0 n1 n2 n3 = (compute-quad norms n00 n01 n10 n11) generate-quad - Vertex (vec4 cv 1) (vec4 0) - Vertex (vec4 ev01 1) (vec4 0) - Vertex (vec4 ev10 1) (vec4 0) - Vertex (vec4 fv 1) (vec4 0) + Vertex (vec4 v0 1) (vec4 n0 0) + Vertex (vec4 v1 1) (vec4 n1 0) + Vertex (vec4 v2 1) (vec4 n2 0) + Vertex (vec4 v3 1) (vec4 n3 0) build-plane 0 # XY inline (du dv) (ivec3 du dv 0)