Skip to content

Commit 554599b

Browse files
authored
Vulkan: render-target post-FX texels; Forward+ tile size from SSBO
Merge PR #126.
1 parent 83ade56 commit 554599b

7 files changed

Lines changed: 470650 additions & 468855 deletions

File tree

docs/GLTF.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ Larger assets are **silently clamped** during load.
7676
- **Skinned / morphed** primitives prefer the **GPU path** under Vulkan PBR when **`r_gltfGpu 1`** and constraints above are met; otherwise **`RB_GLTFSurface`** falls back to **CPU tess**.
7777
- **More than eight** non-zero morph weights per vertex: GPU path keeps only the **eight largest** weights per draw (same cap as IQM `IQM_MORPH_TOP_K`; tune `r_morphMaxActive` for IQM batching only).
7878

79+
### 8. Roadmap: full GPU qtangent / MikkTSpace (not shipped yet)
80+
81+
- **Today (Vulkan PBR GPU):** bind-pose tangents + **`r_gltfGpuTangentFix`** Gram–Schmidt **T** vs deformed **N** after skin+morph (`gen_vert.tmpl`). CPU tess still does **MikkTSpace-style qtangent** from deformed positions + **UV0** when PBR needs it.
82+
- **Next increment:** optional **compute** or **vertex-neighborhood** pass is required for true **MikkTSpace** on arbitrary meshes on the GPU (needs neighbor topology / shared-vertex groups, not just per-vertex attributes). Likely behind a **`r_gltfGpuQtangent`** (or similar) latched cvar with clear **startup** + **developer** logs when enabled or when falling back.
83+
- **Validation:** add Tier B scenes with known normal-map assets and compare against CPU tess / reference captures once a GPU path exists.
84+
7985
## Engine references
8086

8187
- Loader / registration: `src/renderers/vulkan/tr_model_gltf.c`, `tr_model_gltf.h`

scripts/renderer_regression_check.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,17 @@ else
218218
pass "forward_plus_shade_strength uses constant_id=$fp_cid (shader + pipeline agree)"
219219
fi
220220

221+
echo ""
222+
echo "Forward+ tile pixel size: VK_FP_TILE_DIM vs compute shader literals:"
223+
fp_dim="$(sed -n 's/^#define VK_FP_TILE_DIM[[:space:]]*\([0-9][0-9]*\)u*$/\1/p' "$FP_C" | head -1)"
224+
if [[ -z "$fp_dim" ]]; then
225+
fail "could not parse VK_FP_TILE_DIM from vk_forward_plus.c"
226+
elif ! grep -q "tileX \* ${fp_dim}u" "$FP_COMP" 2>/dev/null; then
227+
fail "forward_plus_tile_cull.comp sphere_tile_overlap must use VK_FP_TILE_DIM (${fp_dim}) in tile corner math"
228+
else
229+
pass "VK_FP_TILE_DIM=$fp_dim matches forward_plus_tile_cull.comp tile grid math"
230+
fi
231+
221232
echo ""
222233
echo "Vulkan temporal: reset bitmask vs reason_string / log table:"
223234
VK_TEMP_H="$PROJECT_ROOT/src/renderers/vulkan/vk_temporal.h"

src/renderers/vulkan/shaders/glsl/gen_frag.tmpl

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,17 +1232,18 @@ void main() {
12321232
uint tilesY = uint( fp_lights.fp_light_data[1].y + 0.5 );
12331233
float vw = fp_lights.fp_light_data[1].z;
12341234
float vh = fp_lights.fp_light_data[1].w;
1235-
if ( tilesX > 0u && tilesY > 0u && vw > 1.0 && vh > 1.0 ) {
1236-
vec4 wc = fp_params.fp_clip_from_world * vec4( var_WorldPos, 1.0 );
1237-
if ( abs( wc.w ) > 1e-5 ) {
1238-
vec3 ndc = wc.xyz / wc.w;
1239-
if ( ndc.z >= -1.0 && ndc.z <= 1.0 && ndc.x >= -1.05 && ndc.x <= 1.05 && ndc.y >= -1.05 && ndc.y <= 1.05 ) {
1240-
vec2 px;
1241-
px.x = 0.5 * ( 1.0 + ndc.x ) * vw;
1242-
px.y = 0.5 * ( 1.0 + ndc.y ) * vh;
1243-
const float tilePx = 16.0;
1244-
uint tx = min( uint( px.x / tilePx ), tilesX - 1u );
1245-
uint ty = min( uint( px.y / tilePx ), tilesY - 1u );
1235+
if ( tilesX > 0u && tilesY > 0u && vw > 1.0 && vh > 1.0 ) {
1236+
float tilePxX = vw / max( float( tilesX ), 1.0 );
1237+
float tilePxY = vh / max( float( tilesY ), 1.0 );
1238+
vec4 wc = fp_params.fp_clip_from_world * vec4( var_WorldPos, 1.0 );
1239+
if ( abs( wc.w ) > 1e-5 ) {
1240+
vec3 ndc = wc.xyz / wc.w;
1241+
if ( ndc.z >= -1.0 && ndc.z <= 1.0 && ndc.x >= -1.05 && ndc.x <= 1.05 && ndc.y >= -1.05 && ndc.y <= 1.05 ) {
1242+
vec2 px;
1243+
px.x = 0.5 * ( 1.0 + ndc.x ) * vw;
1244+
px.y = 0.5 * ( 1.0 + ndc.y ) * vh;
1245+
uint tx = min( uint( px.x / tilePxX ), tilesX - 1u );
1246+
uint ty = min( uint( px.y / tilePxY ), tilesY - 1u );
12461247
uint tileId = ty * tilesX + tx;
12471248
uint tbase = tileId * 8u;
12481249
float nLights = fp_lights.fp_light_data[0].x;
@@ -1430,11 +1431,14 @@ void main() {
14301431
if ( fp_dbg > 1e-6 ) {
14311432
uint tilesX = uint( fp_lights.fp_light_data[1].x + 0.5 );
14321433
uint tilesY = uint( fp_lights.fp_light_data[1].y + 0.5 );
1433-
if ( tilesX > 0u && tilesY > 0u ) {
1434-
const float tilePx = 16.0;
1434+
float vwDbg = fp_lights.fp_light_data[1].z;
1435+
float vhDbg = fp_lights.fp_light_data[1].w;
1436+
if ( tilesX > 0u && tilesY > 0u && vwDbg > 1.0 && vhDbg > 1.0 ) {
1437+
float tilePxX = vwDbg / max( float( tilesX ), 1.0 );
1438+
float tilePxY = vhDbg / max( float( tilesY ), 1.0 );
14351439
vec2 px = gl_FragCoord.xy;
1436-
uint tx = min( uint( px.x / tilePx ), tilesX - 1u );
1437-
uint ty = min( uint( px.y / tilePx ), tilesY - 1u );
1440+
uint tx = min( uint( px.x / tilePxX ), tilesX - 1u );
1441+
uint ty = min( uint( px.y / tilePxY ), tilesY - 1u );
14381442
uint tileId = ty * tilesX + tx;
14391443
uint base = tileId * 8u;
14401444
uint maxPerTile = uint( max( fp_lights.fp_light_data[0].z + 0.5, 1.0 ) );
@@ -1456,7 +1460,7 @@ void main() {
14561460
} else {
14571461
col = mix( vec3( 1.0, 0.88, 0.05 ), vec3( 0.92, 0.08, 0.02 ), ( occ - 0.75 ) * 4.0 );
14581462
}
1459-
vec2 f = fract( px / tilePx );
1463+
vec2 f = fract( vec2( px.x / tilePxX, px.y / tilePxY ) );
14601464
float edge = min( min( f.x, 1.0 - f.x ), min( f.y, 1.0 - f.y ) );
14611465
float border = smoothstep( 0.0, 0.35, edge );
14621466
col = mix( vec3( 0.08 ), col, border );
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
glslang_validator_path=/usr/bin/glslangValidator
22
glslang_validator_version=Glslang Version: 11:15.1.0
3-
generated_at=2026-04-19T12:38:57Z
4-
shader_data_sha256=49a4145ab67781b295fff758553e7f345ebcaa15277a33baa7216e1ddf8fee9f
3+
generated_at=2026-04-20T19:11:32Z
4+
shader_data_sha256=d85565a5bab935619eea87c0372b8ad703ad0e7a8ba7ca3f8710f8c8e9d366e3
55
shader_binding_sha256=960921d52493ab4fcf2f8b60edb34fa0b64a852c47b5ad2ae3abdf06c35ebe4a

0 commit comments

Comments
 (0)