34ad1d667547 — Leonard Ritter 4 months ago
HZB rendering
1 files changed, 141 insertions(+), 6 deletions(-)

M testing/test_cascade_dmc_cc_vvf.sc
M testing/test_cascade_dmc_cc_vvf.sc +141 -6
@@ 62,6 62,7 @@ USE_VVF_PACKING := true
 AVERAGE_LOD_VERTICES := false
 USE_PERSPECTIVE_SUBDIVISION := false
 CULL_BACKFACES := true
+VISUALIZE_HZB := true
 
 FETCH_UV_OFFSET := 0.5
 #FETCH_UV_OFFSET := 0.0

          
@@ 96,6 97,10 @@ CASCADE_CENTER := (CASCADE_SIZE // 2)
 
 InstanceVertexCount := 4
 
+HZB_LEVELS := 10
+HZB_LOD_VIZ := 5
+HZB_SIZE := (1 << HZB_LEVELS)
+
 let BINDING_BUF_SECTOR_IN = 1
 let BINDING_BUF_SECTOR_INOUT = 2
 let BINDING_BUF_VERTEX_IN = 3

          
@@ 106,6 111,8 @@ let BINDING_IMG_ZBUFFER = 7
 let BINDING_IMG_WORLD_IN = 8
 let BINDING_IMG_WORLD_OUT = 9
 let BINDING_IMG_WORLD_INOUT = 10
+let BINDING_IMG_HZB_IN = 11
+let BINDING_IMG_HZB_OUT = 12
 
 let UNIFORM_LEVEL = 1
 let UNIFORM_PROGRAM = 2

          
@@ 113,6 120,7 @@ let UNIFORM_MOUSE_STATE = 12
 let UNIFORM_SECTOR_OFFSET = 13
 let UNIFORM_SCREEN_SAMPLER = 4
 let UNIFORM_WORLD_SAMPLER = 7
+let UNIFORM_HZB_SAMPLER = 8
 
 let LEVELS = 8
 

          
@@ 753,9 761,24 @@ uniform world-inout : WORLD_IMAGETYPE
     binding = BINDING_IMG_WORLD_INOUT
     \ coherent restrict
 
+embed
+    let HZB_PIXELFMT = GL.R32F
+    let HZB_IMAGETYPE = (image2D r32f)
+
+uniform hzb-in : HZB_IMAGETYPE
+    binding = BINDING_IMG_HZB_IN
+    \ coherent readonly restrict
+
+uniform hzb-out : HZB_IMAGETYPE
+    binding = BINDING_IMG_HZB_OUT
+    \ coherent writeonly restrict
+
 uniform smp-world : usampler3D
     location = UNIFORM_WORLD_SAMPLER
 
+uniform smp-hzb : sampler2D
+    location = UNIFORM_HZB_SAMPLER
+
 fn pack-vvf (vertex cflags)
     static-if USE_VVF_PACKING
         uvec4

          
@@ 1062,6 1085,22 @@ fn generate-world-lod ()
     imageStore world-out opos (pack-vvf vx cf)
     ;
 
+fn generate-hzb-lod ()
+    local_size 8 8 1
+    opos := (ivec2 gl_GlobalInvocationID.xy)
+    if (any? (opos >= (imageSize hzb-out)))
+        return;
+    isize := (imageSize hzb-in)
+    iz := (ivec2 0)
+    ibpos := opos << 1
+
+    local maxd = -inf
+    for x y in (dim 2 2)
+        ipos := ibpos + (ivec2 x y)
+        maxd = (max maxd (deref ((imageLoad hzb-in ipos) . r)))
+    imageStore hzb-out opos (vec4 maxd 0 0 0)
+    ;
+
 #inline mapf (p lod)
 #
     z := 0.5 * (exp2 (-lod * 1.0))

          
@@ 1583,6 1622,11 @@ fn rasterize-frag ()
             deref albedo.in
             deref matdata.in
 
+out out_Depth : f32
+    binding = 0
+fn rasterize-hzb-frag ()
+    out_Depth = depthval.in
+
 #uniform img-target-rgba32f : (image2D rgba32f)
     binding = IMAGE_TARGET_RGBA32F
     \ coherent writeonly restrict

          
@@ 1648,16 1692,18 @@ fn visualize-buffer (uv)
     #let t = (deref shglobals.time)
     let size =
         vec2 (deref shglobals.size)
+    let screen-uv = uv
     let uv2 =
         (uv * 2.0 - 1.0) * (vec2 shglobals.aspect 1)
-    let uv = (ivec2 ((deref gl_FragCoord) . xy + 0.5))
+    #let uv = (ivec2 ((deref gl_FragCoord) . xy + 0.5))
+    let uv = (ivec2 ((deref gl_FragCoord) . xy))
 
     let col =
         texelFetch smp-screen uv 0
     let normal depth color matdata = (unpack-surfel-data col)
     let fog-color = (vec4 0.6 0.8 1 1)
 
-    if (depth == 0.0)
+    #if (depth == 0.0)
         return fog-color
 
     let col =

          
@@ 1675,7 1721,30 @@ fn visualize-buffer (uv)
             mix col fog-color
                 1.0 - (exp2 (-depth * FOG_RATE))
         else col
-
+    let col =
+        static-if VISUALIZE_HZB
+            let z = (deref ((textureLod smp-hzb screen-uv HZB_LOD_VIZ) . r))
+            #let z = (deref ((texelFetch smp-hzb ((ivec2 gl_FragCoord.xy) >> HZB_LOD_VIZ) HZB_LOD_VIZ) . r))
+            let z-color =
+                ? (z == inf)
+                    vec4 0 0 1 1
+                    vec4 (vec3 (1.0 / z)) 1
+            let col =
+                mix col
+                    z-color
+                    0.5
+                #? (depth > z)
+                    vec4 1 0 0 1
+                    col
+        #elseif 0
+            let z = (deref ((imageLoad hzb-in ((ivec2 gl_FragCoord.xy) >> HZB_LOD_VIZ)) . r))
+            let col =
+                vec4
+                    ? (z == inf)
+                        vec3 0 0 1
+                        vec3 (1.0 / z)
+                    1
+        else col
     return col
 
 inout uv : vec2 (location = 0)

          
@@ 1981,7 2050,7 @@ inline main ()
                 GL.MapNamedBufferRange vertex_buffer 0 (sizeof u32)
                     GL.MAP_READ_BIT
             let ptr = (bitcast ptr (pointer Vertices))
-            print (ptr.count / 3) "triangles"
+            print (ptr.count // InstanceVertexCount) "primitives"
             GL.UnmapNamedBuffer vertex_buffer
 
         if ((frame % 60) == 0)

          
@@ 2002,6 2071,69 @@ inline main ()
             \ 0:i64 (i64 vertex_buffer_sz)
         setup-draw-arrays;
 
+        struct HZB
+            framebuffer : GL.Framebuffer
+            depth-buffer : GL.Renderbuffer
+            depth-texture = (GL.Texture GL.TEXTURE_2D)
+
+        let hzb =
+            static HZB
+                inline ()
+                    let hzb = (HZB)
+                    'setup hzb.depth-texture
+                        size = (ivec2 HZB_SIZE)
+                        format = HZB_PIXELFMT
+                        lod = true
+                    setup-renderbuffer hzb.depth-buffer HZB_SIZE HZB_SIZE
+                        format = GL.DEPTH_COMPONENT
+                    setup-framebuffer hzb.framebuffer
+                        color = hzb.depth-texture
+                        rb-depth = hzb.depth-buffer
+                    hzb
+
+        let pg-rasterize-hzb =
+            program
+                vertex = rasterize-vert
+                fragment = rasterize-hzb-frag
+
+        do
+            local zerodepth = inf
+            GL.ClearTexImage hzb.depth-texture 0 GL.RED GL.FLOAT &zerodepth
+            GL.BindFramebuffer GL.FRAMEBUFFER hzb.framebuffer
+            GL.Viewport 0 0 HZB_SIZE HZB_SIZE
+            GL.DepthFunc GL.GREATER
+            GL.ClearDepthf 0
+            GL.DepthRangef -1 1
+            static-if CULL_BACKFACES
+                GL.Enable GL.CULL_FACE
+                GL.CullFace GL.BACK
+            else
+                GL.Disable GL.CULL_FACE
+            GL.Enable GL.DEPTH_TEST
+            GL.Clear GL.DEPTH_BUFFER_BIT
+
+            GL.UseProgram pg-rasterize-hzb
+            GL.BindVertexArray vao-empty
+            exec-draw-arrays GL.TRIANGLE_FAN
+
+            GL.Disable GL.DEPTH_TEST
+            GL.Disable GL.CULL_FACE
+            GL.BindFramebuffer GL.FRAMEBUFFER 0
+
+            #GL.MemoryBarrier GL.FRAMEBUFFER_BARRIER_BIT
+
+            # generate mipmaps
+            let pg-genhzblod =
+                compute-program generate-hzb-lod
+            GL.UseProgram pg-genhzblod
+            for lod in (range 1 (HZB_LEVELS + 1))
+                let tex = (deref hzb.depth-texture)
+                GL.BindImageTexture BINDING_IMG_HZB_IN tex (lod - 1) GL.TRUE 0 GL.READ_ONLY HZB_PIXELFMT
+                GL.BindImageTexture BINDING_IMG_HZB_OUT tex lod GL.TRUE 0 GL.WRITE_ONLY HZB_PIXELFMT
+                size := ((HZB_SIZE >> (lod as u32)) + 8 - 1) // 8
+                GL.DispatchCompute size size 1
+                GL.MemoryBarrier (GL.TEXTURE_FETCH_BARRIER_BIT | GL.SHADER_IMAGE_ACCESS_BARRIER_BIT)
+
         do
             GL.BindFramebuffer GL.FRAMEBUFFER fb-scene
             GL.Viewport 0 0 (i32 size.x) (i32 size.y)

          
@@ 2011,9 2143,9 @@ inline main ()
             GL.DepthRangef -1 1
             static-if CULL_BACKFACES
                 GL.Enable GL.CULL_FACE
+                GL.CullFace GL.BACK
             else
                 GL.Disable GL.CULL_FACE
-            GL.CullFace GL.BACK
             GL.Enable GL.DEPTH_TEST
             GL.Clear
                 |

          
@@ 2025,7 2157,7 @@ inline main ()
             GL.BindVertexArray vao-empty
             #exec-draw-arrays GL.TRIANGLES
             exec-draw-arrays GL.TRIANGLE_FAN
-            #exec-draw-arrays GL.TRIANGLE_LINES
+            #exec-draw-arrays GL.LINE_LOOP
 
             GL.Disable GL.DEPTH_TEST
             GL.Disable GL.CULL_FACE

          
@@ 2039,6 2171,9 @@ inline main ()
         GL.UseProgram pg-presentfb
         GL.BindTextureUnit 0 fb-scene-color
         GL.Uniform smp-screen 0
+        #GL.BindImageTexture BINDING_IMG_HZB_IN hzb.depth-texture HZB_LOD_VIZ GL.TRUE 0 GL.READ_ONLY HZB_PIXELFMT
+        GL.BindTextureUnit 1 hzb.depth-texture
+        GL.Uniform smp-hzb 1
         'draw screen
 
     let per-frame-setup =