# HG changeset patch # User Leonard Ritter # Date 1639486058 -3600 # Tue Dec 14 13:47:38 2021 +0100 # Node ID 2e1fa33b431b25fcaabfecb597790ca2b601b518 # Parent 291368236a9d917f8dd7983f39fe6f48889ec76e * world volume diff --git a/lib/tukan/gl.sc b/lib/tukan/gl.sc --- a/lib/tukan/gl.sc +++ b/lib/tukan/gl.sc @@ -676,6 +676,7 @@ if lod GL_NEAREST_MIPMAP_NEAREST else GL_NEAREST + else min-filter let defaultlevels = if (lod | pyramid) let s = diff --git a/testing/test_subjective_mt.sc b/testing/test_subjective_mt.sc --- a/testing/test_subjective_mt.sc +++ b/testing/test_subjective_mt.sc @@ -36,6 +36,7 @@ using import tukan.rotation using import tukan.brdf using import tukan.normal +using import tukan.noise using import tukan.projection using import tukan.derivative using import tukan.isosurface @@ -46,25 +47,36 @@ let RG = (ResourceGroup "RG") from (import tukan.math) let expmix -# reserve 10MB for each voxel buffer - at 4 bytes per voxel -let MAX_VOXELS = ((10 * (1 << 20)) // 4) -let POINTLIMIT = (1600000 * 6) +SAMPLE_CAMERA_OFFSET := true +PROJECT_FINAL_VERTEX := true +VISUALIZE_IDS := false +POST_TRANSFORM := false # true is worse +OCCLUSION_CULLING := true +FOG := true + +# to reach fog density D at depth Z, FOG_RATE = -log2(1 - D)/Z +FOG_RATE := 0.01 # 50% at 100 units -let BINDING_BUF_CELLS_IN = 1 -let BINDING_BUF_CELLS_OUT = 2 +let MAX_VERTICES = (20 * (1 << 20)) + +let WORLD_SIZE = (uvec3 256) +let WORLD_SCALE = (vec3 310.0) + +let CUBE_SIZE = (uvec3 128) +let GROUP_SIZE = 4 + +let BINDING_BUF_VERTEX_IN = 1 +let BINDING_BUF_VERTEX_OUT = 2 let BINDING_BUF_DRAW_VOXELS_CMD = 3 let BINDING_BUF_DISPATCH_CMD = 4 - -let IMAGE_TARGET_RGBA32F = 1 +let BINDING_IMG_ZBUFFER = 5 +let BINDING_IMG_WORLD_IN = 6 +let BINDING_IMG_WORLD_OUT = 7 let UNIFORM_LEVEL = 1 let UNIFORM_PROGRAM = 2 let UNIFORM_SCREEN_SAMPLER = 3 - -let ProgramVoxelizeInit = 0 -let ProgramVoxelize = 1 -let ProgramSimplify = 2 +let UNIFORM_WORLD_SAMPLER = 7 let LEVELS = 8 @@ -75,38 +87,22 @@ run-stage; -struct CellVals plain +struct Vertices plain count : u32 - # each entry holds a key - entries : (array u32) + # each entry holds a vertex + entries : (array vec4) -buffer buf-cells-in : CellVals - binding = BINDING_BUF_CELLS_IN +buffer vertex-in : Vertices + binding = BINDING_BUF_VERTEX_IN \ readonly coherent -buffer buf-cells-out : CellVals - binding = BINDING_BUF_CELLS_OUT +buffer vertex-out : Vertices + binding = BINDING_BUF_VERTEX_OUT \ coherent -uniform u-program : i32 - location = UNIFORM_PROGRAM - -uniform u-level : i32 - location = UNIFORM_LEVEL - uniform smp-screen : sampler2D location = UNIFORM_SCREEN_SAMPLER -struct DrawElementsIndirectCommand plain - count : u32 = 0 - instanceCount : u32 = 0 - firstIndex : u32 = 0 - baseVertex : u32 = 0 - baseInstance : u32 = 0 - -buffer buf-draw-voxels-cmd : DrawElementsIndirectCommand - binding = BINDING_BUF_DRAW_VOXELS_CMD - fn simple-sphere (p) (length p) - 0.5 @@ -233,15 +229,27 @@ sdBox p (vec3 0.33) fn matmapf (p) - p := p + 1.0 - p := p + (vec3 1 0 0) * shglobals.time - p := (sdDomainRep p 2.0) + #p := p + 1.0 + #p := p + (vec3 1 0 0) * shglobals.time + #p := (sdDomainRep p 2.0) #do p := p.yzx * 2.0 (two-boxes-merge p) * 0.5 #doubletori p + #sdmDist + simple-sphere p + sdMaterial + vec4 0.5 0.3 1.0 1.0 sdmDist - simple-sphere p + do + S := ((length p) - 300.0) + p := p * 0.01 + local d = 0.0 + for i in (range 8) + s := (exp2 (i as f32)) + d += ((triquad-noise3 (p * s)) * 2.0 - 1.0) / s + max S + deref d sdMaterial vec4 0.5 0.3 1.0 1.0 @@ -272,19 +280,28 @@ - (sdNormalFast mapf p r) let ONION_NEAR = 0.6 -let ONION_FAR = 20.0 +let ONION_FAR = 100.0 let ONION_LAYERS = 32.0 fn map_onion_radius (p) #r := (clamp ((p.z * 0.5 + 0.5) * 0.5 + 0.5) 0.0 1.0) r := (clamp (p.z * 0.5 + 0.5) 0.0 1.0) #r := (p.z * 0.5 + 0.5) * ONION_LAYERS - #r := (1 + 2 * (sqrt pi) / (ONION_LAYERS * 0.5)) ** r - #r := (exp2 (mix (log2 ONION_NEAR) (log2 ONION_FAR) r)) - r := (expmix ONION_NEAR ONION_FAR r 1.0) + + # roughly square layers + embed + Z := CUBE_SIZE.z as f32 + r := ONION_NEAR * ((1 + 2 * (sqrt pi) / (Z * 0.5)) ** (r * Z)) - #r := r * 0.9999 - #r := r / (1.0 * (1.0 - r)) + # exponential interpolation + #embed + r := (expmix ONION_NEAR ONION_FAR r 0.5) + + # infinite perspective projection + #embed + r := r * 0.9999 + k := 0.01 + r := r / (k * (1.0 - r)) _ ((unpack_normal_snorm p.xy) * r) (r * 2.5) @@ -297,177 +314,12 @@ let map_vertex map_vertex_rlimit = map_onion map_onion_radius #let map_vertex map_vertex_rlimit = map_identity map_identity_radius -PROJECT_FINAL_VERTEX := false -VISUALIZE_IDS := false - -fn subdivide-cell (key) - let level = ((deref u-level) as u32) - let r = (/ (f32 (1:u32 << level))) - let d = (2.0 * r) - #let rlimit = - if (level == 8:u32) r - else (sqrt3 * r) - - key := (key << 3:u32) - - ucoord := (unpack-morton3x10 key) - coord := (vec3 ucoord) * d - 1.0 + r - - global cells : (array u32 8) - global written = 0:u32 - - fn test-cell (i ofs key coord r) - let rlimit = (sqrt3 * r) - key := key | i - pos := coord + ofs - let vx vr = (map_onion_radius pos) - let dist = (mapf vx) - let hit = ((abs dist) < (rlimit * vr)) - if hit - cells @ (deref written) = key - written += 1:u32 - - inline test-cell (i ofs) - test-cell i ofs key coord r - - test-cell 0:u32 (vec3 0 0 0) - test-cell 1:u32 (vec3 d 0 0) - test-cell 2:u32 (vec3 0 d 0) - test-cell 3:u32 (vec3 d d 0) - test-cell 4:u32 (vec3 0 0 d) - test-cell 5:u32 (vec3 d 0 d) - test-cell 6:u32 (vec3 0 d d) - test-cell 7:u32 (vec3 d d d) - - # commit - if (written != 0:u32) - let id = (atomicAdd buf-cells-out.count (deref written)) - for i in (range (deref written)) - buf-cells-out.entries @ (id + i) = (cells @ i) - -fn simplify-cell (key) - let level = (((deref u-level) as u32) - 1) - let r = (/ (f32 (1:u32 << level))) - let d = (2.0 * r) - - ucoord := (unpack-morton3x10 key) - coord := (vec3 ucoord) * d - 1.0 - key := (key << 3:u32) - - global mask = 0:u32 - - fn check-cell (i ofs coord) - let dist = (mapf (map_vertex (coord + ofs))) - let bit = (? (dist < 0.0) 1:u32 0:u32) - mask |= (bit << i) - - inline check-cell (i ofs) - check-cell i ofs coord - - #do - let coord = (coord + r) - let n = - normalmapf coord r - embed - let a = ((deref shglobals.time) * 0.2) - let c s = (cos a) (sin a) - - n := - vec3 - c * n.x - s * n.z - n.y - s * n.x + c * n.z - coord := - vec3 - c * coord.x - s * coord.z - coord.y - s * coord.x + c * coord.z - - coord := - coord + (vec3 0 0 1) - - if ((dot n (normalize coord)) < -0.3) - return; - - check-cell 0:u32 (vec3 0 0 0) - check-cell 1:u32 (vec3 d 0 0) - check-cell 2:u32 (vec3 0 d 0) - check-cell 3:u32 (vec3 d d 0) - check-cell 4:u32 (vec3 0 0 d) - check-cell 5:u32 (vec3 d 0 d) - check-cell 6:u32 (vec3 0 d d) - check-cell 7:u32 (vec3 d d d) - let mask = (deref mask) - - if ((mask != 0:u32) & (mask != 255:u32)) - global cells : (array u32 8) - global written = 0:u32 - - fn test-cell (i k1 k3 checkmask mask key packedmask) - let hit = ((checkmask != 0:u32) & (checkmask != mask)) - if hit - cells @ (deref written) = key | i | (packedmask << 28:u32) - written += 1:u32 +inline map-translation (tpos) + static-if SAMPLE_CAMERA_OFFSET + tpos + (shglobals.view-inverse @ 3) . xyz + else tpos - inline test-cell (i) - let tetverts = 0x6cc99:u32 - k := i * 3:u32 - k1 := (tetverts >> k) & 7:u32 - k3 := (tetverts >> (k + 3:u32)) & 7:u32 - packedmask := - | - mask & 1:u32 - ((mask >> k1) & 1:u32) << 1:u32 - ((mask >> 7:u32) & 1:u32) << 2:u32 - ((mask >> k3) & 1:u32) << 3:u32 - checkmask := - | - (1:u32 << 0:u32) | (1:u32 << 7:u32) - 1:u32 << k1 - 1:u32 << k3 - static-assert (constant? checkmask) - test-cell i k1 k3 checkmask mask key packedmask - - test-cell 0:u32 - test-cell 1:u32 - test-cell 2:u32 - test-cell 3:u32 - test-cell 4:u32 - test-cell 5:u32 - - # commit - if (written != 0:u32) - let id = (atomicAdd buf-cells-out.count (deref written)) - for i in (range (deref written)) - buf-cells-out.entries @ (id + i) = (cells @ i) - -fn voxelize-init () - let index = (deref gl_GlobalInvocationID.x) - subdivide-cell index - -fn voxelize () - let index = (deref gl_GlobalInvocationID.x) - if (index < buf-cells-in.count) - subdivide-cell (deref (buf-cells-in.entries @ index)) - -fn simplify () - let index = (deref gl_GlobalInvocationID.x) - if (index < buf-cells-in.count) - simplify-cell (deref (buf-cells-in.entries @ index)) - -fn supershader () - local_size 64 1 1 - let mode = (deref u-program) - switch mode - case ProgramVoxelizeInit - voxelize-init; - case ProgramVoxelize - voxelize; - case ProgramSimplify - simplify; - default - ;; fn calc-projection () let aspect = (vec2 (/ (deref shglobals.aspect)) 1.0) @@ -487,117 +339,212 @@ v := (deref shglobals.view) * (vec4 p 1) v.xyz -inout normal : vec3 -inout depthval : f32 -inout albedo : vec4 -inout matdata : vec4 -fn rasterize-vert () - let index = ((deref gl_InstanceID) as u32) - if (index < buf-cells-in.count) - let vertex-index = ((deref gl_VertexID) as u32) - let key = (deref (buf-cells-in.entries @ index)) - tetidx := (key & 7:u32) - signs := (key >> 28:u32) - key := (key >> 3:u32) & 0x1ffffff +uniform world-out : (image3D r32f) + binding = BINDING_IMG_WORLD_OUT + \ coherent readonly restrict + +uniform smp-world : sampler3D + location = UNIFORM_WORLD_SAMPLER + +uniform zbuffer-inout : (image2D r32f) + binding = BINDING_IMG_ZBUFFER + \ coherent restrict + +fn generate-world () + local_size GROUP_SIZE GROUP_SIZE GROUP_SIZE + ipos := (uvec3 gl_GlobalInvocationID.xyz) + #if (any? (ipos >= WORLD_SIZE)) + return; + rd := (2.0 / (vec3 WORLD_SIZE)) + fpos := (vec3 ipos) * rd - 1.0 + let density = + static-if false + pos := fpos * WORLD_SCALE + mapf pos + else + local bits = 0 + for z in (range 4:u32) + for y in (range 4:u32) + for x in (range 4:u32) + pos := (fpos + ((vec3 x y z) / 4) * rd) * WORLD_SCALE + if ((mapf pos) <= 0.0) + bits += 1 + bits as f32 / 64.0 + imageStore world-out ipos (vec4 density 0 0 0) + ; + +inline mapf (p) + d := (textureLod smp-world ((p / WORLD_SCALE) * 0.5 + 0.5) 0) . r + 1.0 - d * 2.0 + #d +inline matmapf (p) + sdmDist (mapf p) + sdMaterial + vec4 0.5 0.3 1.0 1.0 +fn normalmapf (p r) + r := (0.25 / WORLD_SIZE.x) * WORLD_SCALE + - (sdNormalFast mapf p r) - let level = (((deref u-level) as u32) - 1) - let r = (/ (f32 (1:u32 << level))) - let d = (2.0 * r) - ucoord := (unpack-morton3x10 key) - coord := (vec3 ucoord) * d - 1.0 +fn generate-verts () + local_size GROUP_SIZE GROUP_SIZE GROUP_SIZE + ipos := (uvec3 gl_GlobalInvocationID.xyz) + if (any? (ipos >= CUBE_SIZE)) + return; + + z := ipos.z / CUBE_SIZE.z + zbpos := (ivec2 ipos.xy) + static-if OCCLUSION_CULLING + let imgz = (deref ((imageLoad zbuffer-inout zbpos) . r)) + if (z > imgz) + return; + + d := (2 / (vec3 CUBE_SIZE)) + coord := (vec3 ipos) * d - 1 + + center := (coord.xy + d.xy / 2) + flipped? := ((center.x * center.y) >= 0.0) + #if (not flipped?) + return; + flipmask := (? flipped? 1 0) + flipsign := (? flipped? -1.0 1.0) + local cp : (array vec3 8) + local cd : (array f32 8) + local mind = inf + local maxd = -inf + for i in (range 8) + k := i ^ flipmask + pos := (coord + ((vec3 ((uvec3 k (k >> 1:u32) (k >> 2:u32)) & 1:u32)) * d)) + tpos := (map_vertex pos) + d := (mapf (map-translation tpos)) + cp @ i = + do + static-if PROJECT_FINAL_VERTEX + static-if POST_TRANSFORM pos + else tpos + else pos + cd @ i = d * flipsign + mind = (min mind d) + maxd = (max maxd d) + ; + if ((mind * maxd) >= 0.0) # all values have same sign, no isosurface inbetween + static-if OCCLUSION_CULLING + if (maxd < 0.0) # full occlusion + imageStore zbuffer-inout (ivec2 zbpos) (vec4 z 0 0 0) + return; + for tetidx in (range 6:u32) let tetverts = 0x6cc99:u32 k := tetidx * 3:u32 k1 := (tetverts >> k) & 7:u32 k3 := (tetverts >> (k + 3:u32)) & 7:u32 - xycenter := (coord.xy + (vec2 (d * 0.5))) + let idxs = (ivec4 0 k1 7 k3) local p : (array vec3 4) - p @ 0 = coord - p @ 1 = coord + ((vec3 ((uvec3 k1 (k1 >> 1:u32) (k1 >> 2:u32)) & 1:u32)) * d) - p @ 2 = coord + (vec3 d d d) - p @ 3 = coord + ((vec3 ((uvec3 k3 (k3 >> 1:u32) (k3 >> 2:u32)) & 1:u32)) * d) - - let d = - vec4 - ? ((signs & 1:u32) == 1:u32) -1.0 1.0 - ? ((signs & 2:u32) == 2:u32) -1.0 1.0 - ? ((signs & 4:u32) == 4:u32) -1.0 1.0 - ? ((signs & 8:u32) == 8:u32) -1.0 1.0 - - if ((xycenter.x * xycenter.y) >= 0.0) - # flip - return; + p @ 0 = cp @ 0 + p @ 1 = cp @ k1 + p @ 2 = cp @ 7 + p @ 3 = cp @ k3 + let d = (vec4 (cd @ 0) (cd @ k1) (cd @ 7) (cd @ k3)) let c i = (tetfaces d) - let shift = ((((c - 1) << 2) | vertex-index) * 2) - let i0 i1 = - (0x5000 >> shift) & 3 - (0xeef9 >> shift) & 3 - let i0 i1 = (deref (i @ i0)) (deref (i @ i1)) - let dist0 dist1 = - mapf (map_vertex (deref (p @ i0))) - mapf (map_vertex (deref (p @ i1))) - let d0 d1 = (dist0 as f32) (dist1 as f32) - let l = (tetlerp d0 d1) - let coord = (mix (deref (p @ i0)) (deref (p @ i1)) l) - #let coord = (deref (p @ vertex-index)) - let dist = (matmapf (map_vertex coord)) - let material = - dist.material - #let dist = dist0 - #let material = - 'mix dist0.material dist1.material l - let n = - normalmapf (map_vertex coord) (r * 0.5) + if (c == 0:u32) + continue; + let vc = (c * 3) + let ofs = (atomicAdd vertex-out.count vc) + if ((ofs + vc) > MAX_VERTICES) + return; + entries := vertex-out.entries + + inline tf (i0 i1) + let p = + mix (p @ i0) (p @ i1) (tetlerp (d @ i0) (d @ i1)) + static-if (PROJECT_FINAL_VERTEX & POST_TRANSFORM) (map_vertex p) + else p + - # rotate it a little - #embed - let a = ((deref shglobals.time) * 0.2) - let c s = (cos a) (sin a) + if (c == 1:u32) + # generate triangle + entries @ (ofs + 0) . xyz = (tf i.x i.y) + entries @ (ofs + 1) . xyz = (tf i.x i.z) + entries @ (ofs + 2) . xyz = (tf i.x i.w) + elseif (c == 2:u32) + p0 := (tf i.x i.z) + p2 := (tf i.y i.w) + # generate quad + entries @ (ofs + 0) . xyz = p0 + entries @ (ofs + 1) . xyz = (tf i.x i.w) + entries @ (ofs + 2) . xyz = p2 + entries @ (ofs + 3) . xyz = p2 + entries @ (ofs + 4) . xyz = (tf i.y i.z) + entries @ (ofs + 5) . xyz = p0 - n := - vec3 - c * n.x - s * n.z - n.y - s * n.x + c * n.z + ; + +inout normal : vec3 +inout depthval : f32 +inout albedo : vec4 +inout matdata : vec4 +fn rasterize-vert () + let vertex-index = ((deref gl_VertexID) as u32) + let coord = (vec3 (vertex-in.entries @ vertex-index . xyz)) + + let tcoord = + static-if PROJECT_FINAL_VERTEX (map-translation coord) + else (map_vertex coord) - coord := - vec3 - c * coord.x - s * coord.z - coord.y - s * coord.x + c * coord.z + let dist = (matmapf tcoord) + let material = + dist.material + #let dist = dist0 + #let material = + 'mix dist0.material dist1.material l + let n = + normalmapf tcoord 0.001 # (r * 0.5) - #coord := - coord + (vec3 0 0 1) - #n := (transform-dist n) + # rotate it a little + #embed + let a = ((deref shglobals.time) * 0.2) + let c s = (cos a) (sin a) - let coord = - if PROJECT_FINAL_VERTEX - map_vertex coord - else coord - coord := (transform-pos coord) + n := + vec3 + c * n.x - s * n.z + n.y + s * n.x + c * n.z + + coord := + vec3 + c * coord.x - s * coord.z + coord.y + s * coord.x + c * coord.z - let proj = - calc-projection; + #coord := + coord + (vec3 0 0 1) + #n := (transform-dist n) + + #if PROJECT_FINAL_VERTEX - let pcoord = - 'project proj - vec4 coord 1.0 + let coord = + static-if SAMPLE_CAMERA_OFFSET (transform-dist coord) + else (transform-pos coord) + + let proj = + calc-projection; - normal.out = - do - static-if VISUALIZE_IDS (vec3hash (key as f32)) - else n - depthval.out = coord.z - albedo.out = material.albedo - matdata.out = - vec4 material.roughness material.metallic 0 0 - gl_Position = pcoord - return; + let pcoord = + 'project proj + vec4 coord 1.0 - gl_Position = (vec4 0 0 0 inf) + normal.out = + do + static-if VISUALIZE_IDS ((vec3hash (vertex-index as f32)) * 2.0 - 1.0) + else n + depthval.out = coord.z + albedo.out = material.albedo + matdata.out = + vec4 material.roughness material.metallic 0 0 + gl_Position = pcoord ; fn pack-surfel-data (normal depth color matdata) @@ -636,9 +583,6 @@ binding = IMAGE_TARGET_RGBA32F \ coherent writeonly restrict -uniform u-level : i32 - location = UNIFORM_LEVEL - fn mixdown (uv) #let t = (deref shglobals.time) let size = @@ -707,17 +651,23 @@ let col = texelFetch smp-screen uv 0 let normal depth color matdata = (unpack-surfel-data col) + let fog-color = (vec4 0.3 0.5 1 1) + if (depth == 0.0) - return - vec4 0 0 0 1 + return fog-color - return + let col = vec4 normal * 0.5 + 0.5 #normhue depth #normhue (radius / 16.0) #color - 1.0 + 0.0 + return + static-if FOG + mix col fog-color + 1.0 - (exp2 (-depth * FOG_RATE)) + else col fn shader (uv) #mixdown uv @@ -748,22 +698,6 @@ in: indirect draw call argument out: rasterized voxel cubes - let NUM_BUFFERS = 5 - - global cell_buffers = - arrayof GL.uint - GL.Buffer; - GL.Buffer; - GL.Buffer; - GL.Buffer; - GL.Buffer; - let cell_buffer_sz = ((sizeof u32) * (1 + MAX_VOXELS)) - for i in (range (NUM_BUFFERS as u32)) - let buf = (cell_buffers @ i) - GL.NamedBufferData buf (i32 cell_buffer_sz) null GL.STREAM_COPY - GL.BindBufferRange GL.SHADER_STORAGE_BUFFER (BINDING_BUF_CELLS_IN + i) - \ buf 0:i64 (i64 cell_buffer_sz) - #global draw_voxels_cmd = (GL.CreateBuffer) #setup-ssbo draw_voxels_cmd buf-draw-voxels-cmd #let draw_voxels_cmd_sz = (sizeof DrawElementsIndirectCommand) @@ -798,102 +732,112 @@ fragment = rasterize-frag #debug = true - global pg-supershader = (GL.Program) - call - attach-shaders (deref pg-supershader) - compute = supershader - #debug = true - global rg : (Option RG) fn per-frame-setup (size pg-test frame) let rg = 'force-unwrap rg - from (methodsof rg) let static program compute-program + from (methodsof rg) let static program compute-program indirect-draw-arrays-setup GL.BindTextureUnit 0 fb-scene-color GL.Uniform smp-screen 0 - for i in (range NUM_BUFFERS) - let buf = (cell_buffers @ i) - let ptr = - GL.MapNamedBufferRange buf 0 (sizeof u32) - | GL.MAP_WRITE_BIT - GL.MAP_INVALIDATE_BUFFER_BIT - #GL.MAP_UNSYNCHRONIZED_BIT - let ptr = (bitcast ptr (mutable pointer CellVals)) - ptr.count = 0:u32 - GL.UnmapNamedBuffer buf - - #local cmd = (DrawElementsIndirectCommand) - #bind-ssbo draw_voxels_cmd buf-draw-voxels-cmd &cmd - #GL.NamedBufferSubData draw_voxels_cmd 0 draw_voxels_cmd_sz &cmd + let world = + static GL.Texture + inline () + let tex = (GL.Texture GL.TEXTURE_3D) + 'setup tex + size = (ivec3 WORLD_SIZE) + format = GL.R32F + lod = true + min-filter = GL.LINEAR_MIPMAP_LINEAR + mag-filter = GL.LINEAR + tex - inline bind-buffers (i0 i1) - GL.BindBufferRange GL.SHADER_STORAGE_BUFFER - BINDING_BUF_CELLS_IN - cell_buffers @ i0 - \ 0:i64 (i64 cell_buffer_sz) - GL.BindBufferRange GL.SHADER_STORAGE_BUFFER - BINDING_BUF_CELLS_OUT - cell_buffers @ i1 - \ 0:i64 (i64 cell_buffer_sz) + if (frame == 0) + # generate world + let pg-genworld = (compute-program generate-world) + GL.UseProgram pg-genworld + GL.BindImageTexture BINDING_IMG_WORLD_OUT world 0 GL.TRUE 0 + GL.READ_ONLY + GL.R32F + GL.DispatchCompute (unpack ((WORLD_SIZE + GROUP_SIZE - 1) // GROUP_SIZE)) + GL.MemoryBarrier GL.TEXTURE_FETCH_BARRIER_BIT + GL.GenerateTextureMipmap world - GL.UseProgram pg-supershader + let vertex_buffer_sz = ((sizeof Vertices) + (sizeof vec3) * MAX_VERTICES) + let vertex_buffer = + static GL.Buffer + inline () + let buf = (GL.Buffer) + GL.NamedBufferData buf (i32 vertex_buffer_sz) null GL.STREAM_COPY + buf - do - GL.Uniform u-program ProgramVoxelizeInit - GL.Uniform u-level 6 - bind-buffers 0 1 - GL.DispatchCompute ((8 ** 3) as u32) 1 1 - GL.MemoryBarrier GL.SHADER_STORAGE_BARRIER_BIT - #GL.MemoryBarrier (GL.ALL_BARRIER_BITS as u32) + if true #(frame == 0) + do + # clear vertex buffer count + let ptr = + GL.MapNamedBufferRange vertex_buffer 0 (sizeof u32) + | GL.MAP_WRITE_BIT + GL.MAP_INVALIDATE_BUFFER_BIT + #GL.MAP_UNSYNCHRONIZED_BIT + let ptr = (bitcast ptr (mutable pointer Vertices)) + ptr.count = 0:u32 + GL.UnmapNamedBuffer vertex_buffer - #do - GL.UseProgram pg-voxelize - GL.Uniform u-level 7 - bind-buffers 1 2 - GL.DispatchCompute 84 1 1 - GL.MemoryBarrier GL.SHADER_STORAGE_BARRIER_BIT - #GL.MemoryBarrier (GL.ALL_BARRIER_BITS as u32) + static-if OCCLUSION_CULLING + let zbuffer = + static GL.Texture + inline () + let tex = (GL.Texture GL.TEXTURE_2D) + 'setup tex + size = (ivec2 CUBE_SIZE.xy) + format = GL.R32F + tex + do + local clearval = 1.0 + GL.ClearTexImage zbuffer 0 GL.RED GL.FLOAT &clearval - GL.Uniform u-program ProgramVoxelize - - #do - GL.Uniform u-level 6 - bind-buffers 1 2 - #GL.DispatchCompute 21 1 1 - #GL.DispatchCompute 346 1 1 - GL.DispatchCompute 594 1 1 - GL.MemoryBarrier GL.SHADER_STORAGE_BARRIER_BIT - #GL.MemoryBarrier (GL.ALL_BARRIER_BITS as u32) + GL.BindImageTexture BINDING_IMG_ZBUFFER zbuffer 0 GL.FALSE 0 + GL.READ_WRITE + GL.R32F + GL.BindBufferRange GL.SHADER_STORAGE_BUFFER + BINDING_BUF_VERTEX_OUT + vertex_buffer + \ 0:i64 (i64 vertex_buffer_sz) - do - GL.Uniform u-level 7 - bind-buffers 1 2 - #GL.DispatchCompute 84 1 1 - #GL.DispatchCompute 1395 1 1 - GL.DispatchCompute ((POINTLIMIT // 15) // 64) 1 1 + let pg-gen = (compute-program generate-verts) + GL.UseProgram pg-gen + GL.BindTextureUnit 1 world + GL.Uniform smp-world 1 + GL.DispatchCompute (unpack ((CUBE_SIZE + GROUP_SIZE - 1) // GROUP_SIZE)) GL.MemoryBarrier GL.SHADER_STORAGE_BARRIER_BIT - #GL.MemoryBarrier (GL.ALL_BARRIER_BITS as u32) + + inline print-in-count () + let ptr = + GL.MapNamedBufferRange vertex_buffer 0 (sizeof u32) + GL.MAP_READ_BIT + let ptr = (bitcast ptr (pointer Vertices)) + print (ptr.count / 3) "triangles" + GL.UnmapNamedBuffer vertex_buffer - do - GL.Uniform u-program ProgramSimplify - GL.Uniform u-level 8 - bind-buffers 2 3 - GL.DispatchCompute ((POINTLIMIT // 3) // 64) 1 1 - GL.MemoryBarrier GL.SHADER_STORAGE_BARRIER_BIT - #GL.MemoryBarrier (GL.ALL_BARRIER_BITS as u32) + if ((frame % 60) == 0) + print-in-count; - #do - for i in (range NUM_BUFFERS) - let buf = (cell_buffers @ i) - let ptr = - GL.MapNamedBufferRange buf 0 (sizeof u32) - GL.MAP_READ_BIT - let ptr = (bitcast ptr (pointer CellVals)) - print i "=" ptr.count "/" ((ptr.count + 63:u32) // 64:u32) - GL.UnmapNamedBuffer buf + vvv bind setup-draw-arrays exec-draw-arrays + indirect-draw-arrays-setup + inline () + _ + deref vertex-in.count + 1 + 0 + 0 + + GL.BindBufferRange GL.SHADER_STORAGE_BUFFER + BINDING_BUF_VERTEX_IN + vertex_buffer + \ 0:i64 (i64 vertex_buffer_sz) + setup-draw-arrays; do GL.BindFramebuffer GL.FRAMEBUFFER fb-scene @@ -912,12 +856,10 @@ GL.STENCIL_BUFFER_BIT GL.UseProgram pg-rasterize - bind-buffers 3 0 - GL.Uniform u-level 8 + GL.BindTextureUnit 1 world + GL.Uniform smp-world 1 GL.BindVertexArray vao-empty - #GL.DrawArrays GL.POINTS 0 POINTLIMIT - #GL.DrawArraysInstanced GL.POINTS 0 1 POINTLIMIT - GL.DrawArraysInstanced GL.TRIANGLE_STRIP 0 4 POINTLIMIT + exec-draw-arrays GL.TRIANGLES GL.Disable GL.DEPTH_TEST GL.Disable GL.CULL_FACE