@@ 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