@@ 676,6 676,7 @@ typedef+ GLtexture
if lod
GL_NEAREST_MIPMAP_NEAREST
else GL_NEAREST
+ else min-filter
let defaultlevels =
if (lod | pyramid)
let s =
@@ 36,6 36,7 @@ using import tukan.sdl
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 @@ using import .testfragment
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 @@ let sqrt3 = (sqrt 3.0)
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 @@ fn one-box (p)
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 @@ fn normalmapf (p r)
- (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 @@ fn map_identity_radius (p) (_ p 1.0)
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 @@ inline transform-pos (p)
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 @@ fn rasterize-frag ()
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 @@ fn visualize-buffer (uv)
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 @@ inline main ()
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 @@ inline main ()
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 @@ inline main ()
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