e0122ef2d1f8 — Leonard Ritter 9 months ago
* improved LOD skirts
1 files changed, 121 insertions(+), 58 deletions(-)

M testing/test_cascade_dmc_cc_vvf.sc
M testing/test_cascade_dmc_cc_vvf.sc +121 -58
@@ 46,18 46,21 @@ from (import tukan.math) let expmix
 SAMPLE_CAMERA_OFFSET := false
 PROJECT_FINAL_VERTEX := false
 VISUALIZE_IDS := false
+VISUALIZE_LOD := false
 POST_TRANSFORM := false # true is worse
 OCCLUSION_CULLING := false
 FOG := false
-USE_FLAT_SHADING := true
+USE_FLAT_SHADING := false
 BALANCE_QUADS := true
-USE_COMPLEX_SURFACE := true
+USE_COMPLEX_SURFACE := false
 HIGH_QUALITY_FEATURES := true
 SOFT_WORLD_SAMPLING := true
 USE_CATMULL_CLARK := false
 BLOCKY_WORLD := false
 USE_VVF_PACKING := true
 AVERAGE_LOD_VERTICES := false
+USE_PERSPECTIVE_SUBDIVISION := false
+CULL_BACKFACES := true
 
 FETCH_UV_OFFSET := 0.5
 #FETCH_UV_OFFSET := 0.0

          
@@ 79,9 82,9 @@ let GROUP_SIZE = 4
 let MAX_SECTOR_LOD_I = 2
 let SECTOR_GROUP_SIZE = (1 << MAX_SECTOR_LOD_I)
 
-let SUBDIVIDE_RADIUS = 6
-#let SUBDIVIDE_RADIUS = 1
-let SUBDIVIDE_SCALE = 16
+#let SUBDIVIDE_RADIUS = 6
+let SUBDIVIDE_RADIUS = 4
+let SUBDIVIDE_SCALE = 12
 
 MAX_CASCADE_DEPTH := 6 # MAX_WORLD_LOD_I - MAX_SECTOR_LOD_I
 #MAX_CASCADE_DEPTH := 3 # MAX_WORLD_LOD_I - MAX_SECTOR_LOD_I

          
@@ 107,7 110,6 @@ let UNIFORM_SECTOR_OFFSET = 13
 let UNIFORM_SCREEN_SAMPLER = 4
 let UNIFORM_WORLD_SAMPLER = 7
 
-
 let LEVELS = 8
 
 let SEARCH_R = 5

          
@@ 435,7 437,6 @@ inline map-translation (tpos)
         tpos + (shglobals.view-inverse @ 3) . xyz
     else tpos
 
-
 fn calc-projection ()
     let aspect = (vec2 (/ (deref shglobals.aspect)) 1.0)
     'ifp-perspective ProjectionSetup aspect 0.1

          
@@ 1007,7 1008,7 @@ fn generate-world-lod ()
     inline fetch (pos)
         let __ cf = (unpack-vvf (imageLoad world-in (ibpos + pos * 2)))
         cf & 1
-    let w =
+    #let w =
         +
             2 * (fetch (ivec3 0))
             (fetch (ivec3 1 0 0))

          
@@ 1071,7 1072,7 @@ dump "shared memory requirements"
         (sizeof vec3) * SECTOR_SAMPLE_VOLUME
 
 shared cell-corner-flags : (array u32 SECTOR_SAMPLE_VOLUME)
-shared cell-vertex : (array vec3 SECTOR_SAMPLE_VOLUME)
+shared cell-vertex : (array vec4 SECTOR_SAMPLE_VOLUME)
 shared cell-normal : (array vec3 SECTOR_SAMPLE_VOLUME)
 
 #fn id2index (id)

          
@@ 1143,6 1144,27 @@ fn generate-quad (v00 v01 v10 v11)
         entries @ (ofs + 5) = v00
     ;
 
+let
+    BLEND+X = 1:u32
+    BLEND-X = 2:u32
+    BLEND+Y = 4:u32
+    BLEND-Y = 8:u32
+    BLEND+Z = 16:u32
+    BLEND-Z = 32:u32
+
+fn lod-skirt? (p sector-flags)
+    MIND := SECTOR_GROUP_SIZE // 2
+    MAXD := SECTOR_GROUP_SIZE
+    predicate-flags :=
+        |
+            ? (p.x >= MAXD) BLEND+X 0:u32
+            ? (p.x  < MIND) BLEND-X 0:u32
+            ? (p.y >= MAXD) BLEND+Y 0:u32
+            ? (p.y  < MIND) BLEND-Y 0:u32
+            ? (p.z >= MAXD) BLEND+Z 0:u32
+            ? (p.z  < MIND) BLEND-Z 0:u32
+    (sector-flags & predicate-flags) != 0:u32
+
 fn generate-cell-verts ()
     local_size NATIVE_LANE_WIDTH 1 1
     sector := (copy (sector-in.keys @ (gl_WorkGroupID.x + sector-offset)))

          
@@ 1184,51 1206,64 @@ fn generate-cell-verts ()
         #idx := (id2index lpos)
         gpos := lpos + sectorpos
 
-        inline fetch (pos)
-            unpack-vvf (texelFetch smp-world pos lod)
-
-        let vertex cf = (fetch gpos)
-        let vertex1 =
-            unpack-vvf (texelFetch smp-world (gpos >> 1) (lod + 1))
-        vertex1 := (vertex1 - (vec3 (gpos & 1))) * 2.0 + 1.0
-        local cflags = (cf & 1)
-        for i in (range 1 8)
+        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
-            wpos := gpos + (ivec3 x y z)
-            let vx cf = (fetch wpos)
+            delta := (ivec3 x y z)
+            wpos := gpos + delta
+            let wpos lod =
+                if
+                    & (lod-skirt? (lpos + delta) sector-flags)
+                        (wpos & (~ 1)) == wpos
+                    # use parent bit for major coordinates
+                    _ (wpos >> 1) (lod + 1)
+                else
+                    _ wpos lod
+            let vx cf =
+                unpack-vvf (texelFetch smp-world wpos lod)
             cflags |= ((cf & 1) << (i as u32))
             ;
         cflags := (deref cflags)
         cell-corner-flags @ idx = cflags
         if ((cflags != 0) & (cflags != 0xff))
-            cell-vertex @ idx =
-                do
-                    static-if BLOCKY_WORLD
-                        vec3 0
+            llod? := (lod-skirt? lpos sector-flags)
+            let vpos vlod vscale voffset =
+                if llod?
+                    _ (gpos >> 1) (lod + 1) 2.0 (1.0 - (vec3 (gpos & 1)) * 2.0)
+                else
+                    _ gpos lod 1.0 (vec3 0.0)
+            inline fetch (offset)
+                let vx =
+                    static-if BLOCKY_WORLD (vec3 0)
                     else
-                        if
-                            &
-                                (((shglobals.frame // 10) % 2) == 0)
-                                (cf & 2) == 0
-                            vec3 -10
-                        elseif (sector-flags == 0:u32) vertex
-                        else
-                            inline blend-factor (x f+1 f-2)
-                                ? ((sector-flags & (f+1 | f-2)) != 0)
-                                    ? ((sector-flags & f+1) != 0) x (1 - x)
-                                    0.0
-                            #w := (vec3 lpos) / (SECTOR_GROUP_SIZE - 1)
-                            w := (step (vec3 (SECTOR_GROUP_SIZE // 2)) (vec3 lpos))
-                            w :=
-                                vec3
-                                    blend-factor w.x BLEND+X BLEND-X
-                                    blend-factor w.y BLEND+Y BLEND-Y
-                                    blend-factor w.z BLEND+Z BLEND-Z
-                            mix vertex vertex1
-                                max w.x w.y w.z
-
-            #cell-normal @ idx = n
+                        _ (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
+            vertexlod := lod as f32 + (? llod? 0.5 0.0)
+            cell-vertex @ idx =
+                vec4 vc vertexlod
+            cell-normal @ idx = normal
             ;
         ;
     barrier;

          
@@ 1349,10 1384,10 @@ fn generate-cell-verts ()
     else
         inline getidxvertex (idx dpos)
             v := (copy (cell-vertex @ idx))
-            #n := (copy (cell-normal @ idx))
+            n := (copy (cell-normal @ idx))
             Vertex
-                vec4 (transform-vertex v dpos) 1
-                vec4 0 0 1 0
+                vec4 (transform-vertex v.xyz dpos) v.w
+                vec4 n 0
 
         inline getvertex (offset)
             dpos := lpos + offset

          
@@ 1436,7 1471,12 @@ fn rasterize-vert ()
             static-if VISUALIZE_IDS ((vec3hash (vertex-index as f32)) * 2.0 - 1.0)
             else n
     depthval.out = coord.z
-    albedo.out = (vec4 1) #material.albedo
+    albedo.out =
+        do
+            static-if VISUALIZE_LOD
+                vec4 (hue (lod / MAX_WORLD_LOD)) 1
+            else
+                vec4 1
     matdata.out =
         #vec4 material.roughness material.metallic 0 0
         vec4 1 0 0 0

          
@@ 1556,7 1596,10 @@ fn visualize-buffer (uv)
 
     let col =
         vec4
-            normal * 0.5 + 0.5
+            static-if VISUALIZE_LOD
+                mix (normal * 0.5 + 0.5) color.rgb 0.8
+            else
+                normal * 0.5 + 0.5
             #normhue depth
             #normhue (radius / 16.0)
             #color

          
@@ 1595,12 1638,30 @@ fn subdivide3d? (T t)
         t : ivec3 = camera position
     if (T.w <= 0) false
     else
-        static-if 0
-            R := (1 << T.w) as f32 * 0.5
+        static-if USE_PERSPECTIVE_SUBDIVISION
+            do
+                t := ((t >> T.w) - T.xyz)
+                if ((max (abs t.x) (abs t.y) (abs t.z)) == 0)
+                    return true
+            R := (1 << T.w) as f32
             p0 := (vec3 ((T.xyz as vec-type) << T.w))
-            pc := p0 + R
-            l := (length ((vec3 t) - pc))
-            ((R / l) * SUBDIVIDE_SCALE) > 1.0
+            p1 := p0 + R
+            t := (vec3 t)
+            let l =
+                min
+                    va-map
+                        inline (v)
+                            d := (v - t)
+                            dot d d
+                        vec3 p0.x p0.y p0.z
+                        vec3 p0.x p0.y p1.z
+                        vec3 p0.x p1.y p0.z
+                        vec3 p0.x p1.y p1.z
+                        vec3 p1.x p0.y p0.z
+                        vec3 p1.x p0.y p1.z
+                        vec3 p1.x p1.y p0.z
+                        vec3 p1.x p1.y p1.z
+            ((R / (sqrt l)) * SUBDIVIDE_SCALE) > 1.0
         elseif 1
             # subdivide if 3x3 tile contains camera
             t := ((t >> T.w) - T.xyz)

          
@@ 1861,8 1922,10 @@ inline main ()
             GL.DepthFunc GL.GREATER
             GL.ClearDepthf 0
             GL.DepthRangef -1 1
-            #GL.Enable GL.CULL_FACE
-            GL.Disable GL.CULL_FACE
+            static-if CULL_BACKFACES
+                GL.Enable GL.CULL_FACE
+            else
+                GL.Disable GL.CULL_FACE
             GL.CullFace GL.BACK
             GL.Enable GL.DEPTH_TEST
             GL.Clear