shader_type spatial;
// ── Sparse Virtual Texture atlas and page table ─────────────────────────────
uniform sampler2D ssvt_atlas : source_color, filter_linear, repeat_disable;
uniform sampler2D ssvt_page_table : filter_nearest, repeat_disable;
// Cache geometry: 1.0 / cache_grid_size (e.g. 1/32 = 0.03125)
uniform float tile_size_uv;
// Virtual tiles per edge at mip 0 (e.g. 128)
uniform float page_table_size;
// ── Material fallbacks (used when tile not yet resident) ────────────────────
uniform vec4 albedo_color : source_color = vec4(0.8, 0.8, 0.8, 1.0);
uniform float roughness : hint_range(0,1) = 0.5;
uniform float metallic : hint_range(0,1) = 0.0;
void fragment() {
// Virtual tile address from UV
vec2 svt_coord = UV * page_table_size;
ivec2 tile_id = ivec2(floor(svt_coord));
vec2 in_tile_frac = fract(svt_coord);
// Page table texel: R=atlas_x, G=atlas_y, B=valid, A=0
vec4 page = texelFetch(svt_page_table, tile_id, 0);
if (page.b > 0.5) {
// Tile is resident — sample from atlas
vec2 atlas_uv = (vec2(page.r, page.g) * 255.0 + in_tile_frac) * tile_size_uv;
ALBEDO = texture(svt_atlas, atlas_uv).rgb;
} else {
// Tile not loaded — use fallback color
ALBEDO = albedo_color.rgb;
}
ROUGHNESS = roughness;
METALLIC = metallic;
}