@@ 50,7 50,7 @@ VISUALIZE_LOD := false
POST_TRANSFORM := false # true is worse
OCCLUSION_CULLING := false
FOG := false
-USE_FLAT_SHADING := false
+USE_FLAT_SHADING := true
BALANCE_QUADS := true
USE_COMPLEX_SURFACE := false
HIGH_QUALITY_FEATURES := true
@@ 82,8 82,8 @@ 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 = 4
+let SUBDIVIDE_RADIUS = 6
+#let SUBDIVIDE_RADIUS = 4
let SUBDIVIDE_SCALE = 12
MAX_CASCADE_DEPTH := 6 # MAX_WORLD_LOD_I - MAX_SECTOR_LOD_I
@@ 136,6 136,15 @@ let
BLEND+Z = 16:u32
BLEND-Z = 32:u32
+# corner planes
+let
+ MASK_PLANE-X = 0x01010101
+ MASK_PLANE+X = 0x10101010
+ MASK_PLANE-Y = 0x00110011
+ MASK_PLANE+Y = 0x11001100
+ MASK_PLANE-Z = 0x00001111
+ MASK_PLANE+Z = 0x11110000
+
struct Sector plain
key : u32
flags : u32 # six face bits indicating where the next highest LOD level is
@@ 467,8 476,25 @@ fn gradient-root (v0 v1 dir)
q1 := (c + w) * 2.0 - 1.0
? ((abs q0) < (abs q1)) q0 q1
-fn triangle-area (A B C)
- (length (cross (B - A) (C - A))) / 2.0
+inline triangle-area-normal (v1 v2 v3)
+ if 1
+ cross
+ (v2 - v1) . xyz
+ (v3 - v1) . xyz
+ else
+ let a b =
+ (v2 - v1) . xyz
+ (v3 - v1) . xyz
+ *
+ cross (normalize a) (normalize b)
+ length (cross a b)
+
+inline triangle-normal (v1 v2 v3)
+ normalize (triangle-area-normal v1 v2 v3)
+
+# triangle area * 2
+inline triangle-areax2 (v1 v2 v3)
+ length (triangle-area-normal v1 v2 v3)
fn trimix (v p)
# corner weights of cube in [-1..1]³ domain
@@ 1099,13 1125,6 @@ fn svindex2id (idx)
NATIVE_LANE_WIDTH := 64
-fn normal (v1 v2 v3)
- cross
- normalize
- (v3 - v1) . xyz
- normalize
- (v2 - v1) . xyz
-
inline swapnormal (v n)
Vertex v.pos (vec4 n 0)
@@ 1125,8 1144,8 @@ fn generate-quad (v00 v01 v10 v11)
let ofs = (atomicAdd vertex-out.count 6)
entries := vertex-out.entries
static-if USE_FLAT_SHADING
- n0 := (normal v00.pos v10.pos v11.pos)
- n1 := (normal v11.pos v01.pos v00.pos)
+ n0 := (triangle-normal v00.pos v10.pos v11.pos)
+ n1 := (triangle-normal v11.pos v01.pos v00.pos)
#n1 := (normal v00.pos v11.pos v01.pos)
entries @ (ofs + 0) = (swapnormal v00 n0)
@@ 1153,8 1172,8 @@ let
BLEND-Z = 32:u32
fn lod-skirt? (p sector-flags)
- MIND := SECTOR_GROUP_SIZE // 2
- MAXD := SECTOR_GROUP_SIZE
+ MIND := 2
+ MAXD := SECTOR_GROUP_SIZE - 2
predicate-flags :=
|
? (p.x >= MAXD) BLEND+X 0:u32
@@ 1209,7 1228,6 @@ fn generate-cell-verts ()
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
delta := (ivec3 x y z)
wpos := gpos + delta
let wpos lod =
@@ 1233,37 1251,72 @@ fn generate-cell-verts ()
_ (gpos >> 1) (lod + 1) 2.0 (1.0 - (vec3 (gpos & 1)) * 2.0)
else
_ gpos lod 1.0 (vec3 0.0)
+
+ local cflags = 0:u32
+ for i in (range 0 8)
+ let x y z = (i & 1) ((i >> 1) & 1) ((i >> 2) & 1)
+ delta := (ivec3 x y z)
+ wpos := vpos + delta
+ let vx cf =
+ unpack-vvf (texelFetch smp-world wpos vlod)
+ cflags |= ((cf & 1) << (i as u32))
+ cflags := (deref cflags)
+
inline fetch (offset)
let vx =
static-if BLOCKY_WORLD (vec3 0)
else
_ (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
+ vx + (vec3 offset) * 2.0
+
+ let v000 = (fetch (ivec3 0 0 0))
+
+ ### compute vertex normal
+
+ inline edgebits (a b)
+ (cflags >> a as u32) & 1, (cflags >> b as u32) & 1
+
+ inline edge (a b)
+ let u v = (edgebits a b)
+ (u != v), (u == 0)
+
+ local normal_accum = (vec3 0)
+ inline collect-plane (Du fpermute u v)
+ Dv := (Du + 1) % 3
+ Dw := (Du + 2) % 3
+ i0 := (u << Du) | (v << Dv)
+ i1 := i0 ^ (1 << Dw)
+ let set? flip? = (edge i0 i1)
+ if set?
+ flip? := flip? ^ ((u ^ v) == 1)
+ v00 := v000
+ let du dv = (u * 2 - 1) (v * 2 - 1)
+ v01 := (fetch (fpermute du 0))
+ v10 := (fetch (fpermute 0 dv))
+ #v11 := (fetch (fpermute du dv))
+ n1 := (triangle-area-normal v00 v01 v10)
+ #n2 := (triangle-area-normal v11 v10 v00)
+
+ #normal_accum += (n1 + n2) * (? flip? -1.0 1.0)
+ normal_accum += n1 * (? flip? -1.0 1.0)
+ ;
+
+ for u v in (dim 2 2)
+ collect-plane 0 # XY
+ inline (du dv) (ivec3 du dv 0)
+ \ u v
+ collect-plane 1 # YZ
+ inline (du dv) (ivec3 0 du dv)
+ \ u v
+ collect-plane 2 # ZX
+ inline (du dv) (ivec3 dv 0 du)
+ \ u v
+
vertexlod := lod as f32 + (? llod? 0.5 0.0)
+ vertex := v000 * vscale + voffset
cell-vertex @ idx =
- vec4 vc vertexlod
- cell-normal @ idx = normal
+ vec4 vertex vertexlod
+ cell-normal @ idx = (normalize normal_accum)
;
;
barrier;
@@ 1283,22 1336,19 @@ fn generate-cell-verts ()
dpos := lpos + offset
idx := (id2svindex dpos)
v := (copy (cell-vertex @ idx))
- transform-vertex v dpos
+ _ (transform-vertex v.xyz dpos) (copy (cell-normal @ idx))
local verts : (array vec4 7)
+ local norms : (array vec4 7)
local n = 0
va-map
inline (i)
verts @ i = (vec4 0)
+ norms @ i = (vec4 0)
va-range 7
let C00- C00+ C0-0 C0+0 C-00 C+00 C000 = (va-range 7)
- let v000 = (getvertex (ivec3 0 0 0))
- #inline check-edge (IDX ofs mask)
- x := (cflags & mask)
- if ((x != mask) & ((x ^ mask) != mask))
- m := (v000 + (getvertex ofs))
- w @ C00- = (vec4 m 2)
+ let v000 n000 = (getvertex (ivec3 0 0 0))
inline edgebits (a b)
(cflags >> a as u32) & 1, (cflags >> b as u32) & 1
@@ 1316,18 1366,22 @@ fn generate-cell-verts ()
let set? flip? = (edge i0 i1)
if set?
v00 := v000
+ n00 := n000
let du dv = (u * 2 - 1) (v * 2 - 1)
- v01 := (getvertex (fpermute du 0))
- v10 := (getvertex (fpermute 0 dv))
- v11 := (getvertex (fpermute du dv))
- # face vertices
- fv := ((v00 + v01 + v10 + v11) / 4)
- # edge vertices
- ev01 := (v00 + v01) / 2
- ev10 := (v00 + v10) / 2
- verts @ C000 += (vec4 (fv + ev01 + ev10) 3)
- verts @ (Du * 2 + u) += (vec4 (fv + ev01) 2)
- verts @ (Dv * 2 + v) += (vec4 (fv + ev10) 2)
+ let v01 n01 = (getvertex (fpermute du 0))
+ let v10 n10 = (getvertex (fpermute 0 dv))
+ let v11 n11 = (getvertex (fpermute du dv))
+ inline compute-verts (verts v00 v01 v10 v11)
+ # face vertices
+ fv := ((v00 + v01 + v10 + v11) / 4)
+ # edge vertices
+ ev01 := (v00 + v01) / 2
+ ev10 := (v00 + v10) / 2
+ verts @ C000 += (vec4 (fv + ev01 + ev10) 3)
+ verts @ (Du * 2 + u) += (vec4 (fv + ev01) 2)
+ verts @ (Dv * 2 + v) += (vec4 (fv + ev10) 2)
+ compute-verts verts v00 v01 v10 v11
+ compute-verts norms n00 n01 n10 n11
n += 1
;
@@ 1351,28 1405,33 @@ fn generate-cell-verts ()
if set?
flip? := flip? ^ ((u ^ v) == 1)
v00 := v000
+ n00 := n000
let du dv = (u * 2 - 1) (v * 2 - 1)
- v01 := (getvertex (fpermute du 0))
- v10 := (getvertex (fpermute 0 dv))
- v11 := (getvertex (fpermute du dv))
- # face vertices
- fv := (v00 + v01 + v10 + v11) / 4
- # edge vertices
- ev01 := (copy (verts @ (Du * 2 + u)))
- ev01 := ev01.xyz / ev01.w
- ev10 := (copy (verts @ (Dv * 2 + v)))
- ev10 := ev10.xyz / ev10.w
- # center vertex
- cv := (copy (verts @ C000))
- cv := cv.xyz / cv.w
- let ev01 ev10 =
- if flip? (_ ev10 ev01)
- else (_ ev01 ev10)
+ let v01 n01 = (getvertex (fpermute du 0))
+ let v10 n10 = (getvertex (fpermute 0 dv))
+ let v11 n11 = (getvertex (fpermute du dv))
+ inline compute-quad (verts v00 v01 v10 v11)
+ # face vertices
+ fv := (v00 + v01 + v10 + v11) / 4
+ # edge vertices
+ ev01 := (copy (verts @ (Du * 2 + u)))
+ ev01 := ev01.xyz / ev01.w
+ ev10 := (copy (verts @ (Dv * 2 + v)))
+ ev10 := ev10.xyz / ev10.w
+ # center vertex
+ cv := (copy (verts @ C000))
+ cv := cv.xyz / cv.w
+ let ev01 ev10 =
+ if flip? (_ ev10 ev01)
+ else (_ ev01 ev10)
+ _ cv ev01 ev10 fv
+ let v0 v1 v2 v3 = (compute-quad verts v00 v01 v10 v11)
+ let n0 n1 n2 n3 = (compute-quad norms n00 n01 n10 n11)
generate-quad
- Vertex (vec4 cv 1) (vec4 0)
- Vertex (vec4 ev01 1) (vec4 0)
- Vertex (vec4 ev10 1) (vec4 0)
- Vertex (vec4 fv 1) (vec4 0)
+ Vertex (vec4 v0 1) (vec4 n0 0)
+ Vertex (vec4 v1 1) (vec4 n1 0)
+ Vertex (vec4 v2 1) (vec4 n2 0)
+ Vertex (vec4 v3 1) (vec4 n3 0)
build-plane 0 # XY
inline (du dv) (ivec3 du dv 0)