@woosh/meep-engine 3.61.0 → 3.61.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +4 -0
- package/src/engine/graphics/ecs/decal/v2/Decal.d.ts +46 -2
- package/src/engine/graphics/ecs/decal/v2/Decal.d.ts.map +1 -1
- package/src/engine/graphics/ecs/decal/v2/Decal.js +74 -5
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.d.ts.map +1 -1
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.js +13 -1
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.d.ts +9 -0
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.d.ts.map +1 -0
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.js +37 -0
- package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
- package/src/engine/graphics3/DecalSystem.js +462 -447
- package/src/engine/graphics3/decal/DECAL_GPU_RECORD.d.ts +14 -0
- package/src/engine/graphics3/decal/DECAL_GPU_RECORD.d.ts.map +1 -1
- package/src/engine/graphics3/decal/DECAL_GPU_RECORD.js +53 -13
- package/src/engine/graphics3/decal/chunk_decal_record.d.ts +6 -1
- package/src/engine/graphics3/decal/chunk_decal_record.d.ts.map +1 -1
- package/src/engine/graphics3/decal/chunk_decal_record.js +28 -9
- package/src/engine/graphics3/decal/decal_gpu_records.d.ts +2 -1
- package/src/engine/graphics3/decal/decal_gpu_records.d.ts.map +1 -1
- package/src/engine/graphics3/decal/decal_gpu_records.js +26 -5
- package/src/engine/graphics3/decal/decal_material_samplers.d.ts +6 -0
- package/src/engine/graphics3/decal/decal_material_samplers.d.ts.map +1 -1
- package/src/engine/graphics3/decal/decal_material_samplers.js +13 -0
- package/src/engine/graphics3/decal/shader_cluster_assign_decals.js +1 -1
- package/src/engine/graphics3/decal/shader_cull_decals_frustum.js +1 -1
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts +5 -0
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_decal_composite.js +69 -28
- package/src/generation/foliage/skeleton/ShootWoodHash.d.ts +3 -2
- package/src/generation/foliage/skeleton/ShootWoodHash.d.ts.map +1 -1
- package/src/generation/foliage/skeleton/ShootWoodHash.js +25 -2
- package/src/shade/renderer/buffer/graph_read_buffer.d.ts +3 -1
- package/src/shade/renderer/buffer/graph_read_buffer.d.ts.map +1 -1
- package/src/shade/renderer/buffer/graph_read_buffer.js +9 -6
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +1 -7
- package/src/shade/renderer/restir/di/chunk_restir_resolve.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/chunk_restir_resolve.js +91 -94
- package/src/shade/renderer/restir/reservoir/chunk_rtxdi_stream_sample.js +1 -1
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.d.ts +14 -0
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.js +36 -21
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.d.ts +22 -0
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.js +64 -0
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_vertex_normal.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_vertex_normal.js +13 -18
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_encode_vertex_normal.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_encode_vertex_normal.js +28 -30
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_u32_to_vec2.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_u32_to_vec2.js +15 -16
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.d.ts +0 -1
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.js +15 -18
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +8 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +3 -3
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.d.ts +0 -2
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.js +0 -6
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { aabb3_intersects_segment3 } from "../../../core/geom/3d/aabb/aabb3_intersects_segment3.js";
|
|
1
2
|
import { line3_compute_segment_segment_closest_points } from "../../../core/geom/3d/line/line3_compute_segment_segment_closest_points.js";
|
|
2
3
|
import { shoot_radius } from "./shoot_geometry.js";
|
|
3
4
|
|
|
@@ -20,6 +21,14 @@ const CLEARANCE = 0.001;
|
|
|
20
21
|
*/
|
|
21
22
|
const KEY_SPAN = 2048;
|
|
22
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Margin (m) a cell is widened by when asking whether an axis line crosses it: far above the rounding of a point at
|
|
26
|
+
* the key's 205 m span, far below any wood, so a line along a cell's face or through its edge is under the cells either
|
|
27
|
+
* side of it.
|
|
28
|
+
* @type {number}
|
|
29
|
+
*/
|
|
30
|
+
const CROSSING_TOLERANCE = WOOD_CELL * 2 ** -20;
|
|
31
|
+
|
|
23
32
|
const SCRATCH_ST = new Float64Array(2);
|
|
24
33
|
|
|
25
34
|
/**
|
|
@@ -27,7 +36,7 @@ const SCRATCH_ST = new Float64Array(2);
|
|
|
27
36
|
* wood, and thinner wood that thicker wood has grown into can be found. A unit is added once, when it has grown, under
|
|
28
37
|
* the cells its axis line crosses; a query reads every unit's place and radius from its axis as they are then, and
|
|
29
38
|
* reaches as far round as the thickest wood ({@link max_radius}), so wood that thickens needs no re-adding. The units
|
|
30
|
-
* of an axis that has died are passed over.
|
|
39
|
+
* of an axis that has died are passed over, and leave the hash at the next {@link refresh}.
|
|
31
40
|
*/
|
|
32
41
|
export class ShootWoodHash {
|
|
33
42
|
/** @type {Map<number, number[]>} */
|
|
@@ -89,6 +98,11 @@ export class ShootWoodHash {
|
|
|
89
98
|
const y0 = Math.floor(Math.min(p[a + 1], p[b + 1]) / WOOD_CELL), y1 = Math.floor(Math.max(p[a + 1], p[b + 1]) / WOOD_CELL);
|
|
90
99
|
const z0 = Math.floor(Math.min(p[a + 2], p[b + 2]) / WOOD_CELL), z1 = Math.floor(Math.max(p[a + 2], p[b + 2]) / WOOD_CELL);
|
|
91
100
|
for (let x = x0; x <= x1; x++) for (let y = y0; y <= y1; y++) for (let z = z0; z <= z1; z++) {
|
|
101
|
+
if (!aabb3_intersects_segment3(
|
|
102
|
+
x * WOOD_CELL - CROSSING_TOLERANCE, y * WOOD_CELL - CROSSING_TOLERANCE, z * WOOD_CELL - CROSSING_TOLERANCE,
|
|
103
|
+
(x + 1) * WOOD_CELL + CROSSING_TOLERANCE, (y + 1) * WOOD_CELL + CROSSING_TOLERANCE, (z + 1) * WOOD_CELL + CROSSING_TOLERANCE,
|
|
104
|
+
p[a], p[a + 1], p[a + 2], p[b], p[b + 1], p[b + 2]
|
|
105
|
+
)) continue;
|
|
92
106
|
const key = ((x + KEY_SPAN / 2) * KEY_SPAN + (y + KEY_SPAN / 2)) * KEY_SPAN + (z + KEY_SPAN / 2);
|
|
93
107
|
let list = this.cells.get(key);
|
|
94
108
|
if (list === undefined) {
|
|
@@ -102,21 +116,30 @@ export class ShootWoodHash {
|
|
|
102
116
|
|
|
103
117
|
/**
|
|
104
118
|
* Records each cell's thickest living unit, after the wood has thickened, and the thickest of all
|
|
105
|
-
* ({@link max_radius}).
|
|
119
|
+
* ({@link max_radius}). A dead axis does not live again, so its units leave their cells, in the order the rest
|
|
120
|
+
* were added, and a cell left empty leaves the hash.
|
|
106
121
|
*/
|
|
107
122
|
refresh() {
|
|
108
123
|
const axes = this.axes;
|
|
109
124
|
let most = 0;
|
|
110
125
|
for (const [key, list] of this.cells) {
|
|
111
126
|
let max = 0;
|
|
127
|
+
let kept = 0;
|
|
112
128
|
for (let i = 0; i < list.length; i++) {
|
|
113
129
|
const id = list[i];
|
|
114
130
|
const axis = axes[this.unit_axis[id]];
|
|
115
131
|
if (!axis.alive) continue;
|
|
132
|
+
list[kept++] = id;
|
|
116
133
|
const k = this.unit_index[id];
|
|
117
134
|
const thickest = axis.radii.length > k + 1 ? Math.max(axis.radii[k], axis.radii[k + 1]) : shoot_radius(axis.units[k], 0);
|
|
118
135
|
if (thickest > max) max = thickest;
|
|
119
136
|
}
|
|
137
|
+
if (kept === 0) {
|
|
138
|
+
this.cells.delete(key);
|
|
139
|
+
this.cell_max.delete(key);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
list.length = kept;
|
|
120
143
|
this.cell_max.set(key, max);
|
|
121
144
|
if (max > most) most = max;
|
|
122
145
|
}
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* @param {number} buffer
|
|
6
6
|
* @param {number} [offset=0]
|
|
7
7
|
* @param {number} [size] defaults to buffer.size - offset
|
|
8
|
-
* @param {number} [timeout] in milliseconds, 0 for no timeout
|
|
8
|
+
* @param {number} [timeout] in milliseconds, 0 for no timeout: how long the read waits for its pass to run, starting
|
|
9
|
+
* now. A graph that is never run, or stops at a throwing pass before this one, rejects the read here. Once the pass has
|
|
10
|
+
* run, the read waits for the device however far behind it is, and settles when the mapping does.
|
|
9
11
|
* @returns {Promise<Reference<ArrayBuffer>>} don't forget to release the reference
|
|
10
12
|
*/
|
|
11
13
|
export function graph_read_buffer({ graph, buffer, offset, size, timeout }: FrameGraph): Promise<Reference<ArrayBuffer>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph_read_buffer.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/buffer/graph_read_buffer.js"],"names":[],"mappings":"AAOA
|
|
1
|
+
{"version":3,"file":"graph_read_buffer.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/buffer/graph_read_buffer.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;GAWG;AACH,yFAFa,QAAQ,UAAU,WAAW,CAAC,CAAC,CAwH3C;0BAvIyB,2CAA2C"}
|
|
@@ -12,7 +12,9 @@ const scratch_buffer_descriptor = new BufferResourceDescriptor();
|
|
|
12
12
|
* @param {number} buffer
|
|
13
13
|
* @param {number} [offset=0]
|
|
14
14
|
* @param {number} [size] defaults to buffer.size - offset
|
|
15
|
-
* @param {number} [timeout] in milliseconds, 0 for no timeout
|
|
15
|
+
* @param {number} [timeout] in milliseconds, 0 for no timeout: how long the read waits for its pass to run, starting
|
|
16
|
+
* now. A graph that is never run, or stops at a throwing pass before this one, rejects the read here. Once the pass has
|
|
17
|
+
* run, the read waits for the device however far behind it is, and settles when the mapping does.
|
|
16
18
|
* @returns {Promise<Reference<ArrayBuffer>>} don't forget to release the reference
|
|
17
19
|
*/
|
|
18
20
|
export function graph_read_buffer({
|
|
@@ -47,6 +49,12 @@ export function graph_read_buffer({
|
|
|
47
49
|
* @param {GraphicsExecutionContext} context
|
|
48
50
|
*/
|
|
49
51
|
function execute(data, resources, context) {
|
|
52
|
+
// the copy is recorded: the mapping lands, or is refused, however long the device takes
|
|
53
|
+
if (timeout_handle !== -1) {
|
|
54
|
+
clearTimeout(timeout_handle);
|
|
55
|
+
timeout_handle = -1;
|
|
56
|
+
}
|
|
57
|
+
|
|
50
58
|
/**
|
|
51
59
|
* @type {GPUBuffer}
|
|
52
60
|
*/
|
|
@@ -94,11 +102,6 @@ export function graph_read_buffer({
|
|
|
94
102
|
return;
|
|
95
103
|
}
|
|
96
104
|
|
|
97
|
-
if (timeout_handle !== -1) {
|
|
98
|
-
clearTimeout(timeout_handle);
|
|
99
|
-
timeout_handle = -1;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
105
|
const data = destination.getMappedRange(0, _size);
|
|
103
106
|
|
|
104
107
|
ref = new Reference();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUParticleSystem.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/particles/GPUParticleSystem.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GPUParticleSystem.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/particles/GPUParticleSystem.js"],"names":[],"mappings":"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"}
|
|
@@ -68,13 +68,7 @@ const STORAGE_GROWABLE = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUB
|
|
|
68
68
|
*/
|
|
69
69
|
const INDIRECT = GPUBufferUsage.STORAGE | GPUBufferUsage.INDIRECT | GPUBufferUsage.COPY_SRC;
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
* Particles a scene holds at once unless the constructor is told otherwise — and the renderer never
|
|
73
|
-
* tells it ({@link ../Renderer.js Renderer#particles}), so this is every scene's pool. 2^17: about
|
|
74
|
-
* 18 MB of pool, free list, alive list and coherence scratch at a 128-byte record, which a game with
|
|
75
|
-
* dense bursts (a body dissolving into thousands of motes) fills before 65,536 does.
|
|
76
|
-
*/
|
|
77
|
-
const DEFAULT_CAPACITY = 131072;
|
|
71
|
+
const DEFAULT_CAPACITY = 65536;
|
|
78
72
|
|
|
79
73
|
/**
|
|
80
74
|
* What {@link GPUParticleSystem#read_stats} decodes: the counts the GPU keeps between frames, named.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_restir_resolve.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/restir/di/chunk_restir_resolve.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,mCAFU,SAAS,
|
|
1
|
+
{"version":3,"file":"chunk_restir_resolve.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/restir/di/chunk_restir_resolve.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,mCAFU,SAAS,CA4DjB;0BApFwB,oCAAoC"}
|
|
@@ -1,94 +1,91 @@
|
|
|
1
|
-
import { REFLECTED_LIGHT_STRUCT } from "../../shader/chunk/light/REFLECTED_LIGHT_STRUCT.js";
|
|
2
|
-
import { chunk_re_direct_multiscatter } from "../../shader/chunk/material/chunk_re_direct_multiscatter.js";
|
|
3
|
-
import { chunk_re_direct_physical } from "../../shader/chunk/material/chunk_re_direct_physical.js";
|
|
4
|
-
import { GEOMETRIC_SHADING_INFO_STRUCT } from "../../shader/chunk/material/GEOMETRIC_SHADING_INFO_STRUCT.js";
|
|
5
|
-
import { MATERIAL_SHADING_INFO_STRUCT } from "../../shader/chunk/material/MATERIAL_SHADING_INFO_STRUCT.js";
|
|
6
|
-
import { RTXDI_Reservoir } from "../reservoir/RTXDI_Reservoir.js";
|
|
7
|
-
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
8
|
-
import { chunk_restir_get_light_info } from "./chunk_restir_get_light_info.js";
|
|
9
|
-
import { chunk_restir_light_ref } from "./chunk_restir_light_ref.js";
|
|
10
|
-
import { chunk_restir_sample_light_record } from "./chunk_restir_sample_light_record.js";
|
|
11
|
-
import { chunk_restir_trace_visibility } from "./chunk_restir_trace_visibility.js";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Resolve a finalized reservoir to outgoing radiance for the selected light:
|
|
15
|
-
*
|
|
16
|
-
* radiance = BRDF·Le·G (full RGB, unshadowed) · W · V
|
|
17
|
-
*
|
|
18
|
-
* where W == reservoir.weightSum after FinalizeResampling (it already folds in
|
|
19
|
-
* 1/p_hat and 1/M) and V is the traced visibility (the RTXDI `f_rgb · weightSum`
|
|
20
|
-
* identity). p_hat is the luminance of the single-scattering BRDF·Le·G; this
|
|
21
|
-
* BRDF also carries `re_direct_multiscatter`'s per-pixel scale of the specular,
|
|
22
|
-
* so f / p_hat is no longer 1 but stays within [1, that scale]. The estimate is
|
|
23
|
-
* unbiased either way: f and p_hat are positive on the same lights.
|
|
24
|
-
*
|
|
25
|
-
* Visibility is a single opaque shadow ray toward the survivor's sampled emitter
|
|
26
|
-
* point — matching the brute-force NEE reference (`ray_sample_light`), which also
|
|
27
|
-
* uses `ray_query_occluded`. Requires the RTX resource group to be bound.
|
|
28
|
-
*
|
|
29
|
-
* Emissive is intentionally excluded; the deferred pass adds it once.
|
|
30
|
-
*
|
|
31
|
-
* @type {CodeChunk}
|
|
32
|
-
*/
|
|
33
|
-
export const chunk_restir_resolve = CodeChunk.from(
|
|
34
|
-
//language=WGSL
|
|
35
|
-
`
|
|
36
|
-
fn restir_resolve(
|
|
37
|
-
i_coord: vec2<u32>,
|
|
38
|
-
reservoir: ${RTXDI_Reservoir.wgsl_ref},
|
|
39
|
-
geometry: ${GEOMETRIC_SHADING_INFO_STRUCT.wgsl_ref},
|
|
40
|
-
material: ${MATERIAL_SHADING_INFO_STRUCT.wgsl_ref},
|
|
41
|
-
use_screen_space_shadow: u32
|
|
42
|
-
) -> vec3<f32> {
|
|
43
|
-
if (!restir_light_ref_is_valid(reservoir.lightData) || reservoir.weightSum <= 0.0) {
|
|
44
|
-
return vec3<f32>(0.0);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
let light_type = restir_light_ref_type(reservoir.lightData);
|
|
48
|
-
let light_index = restir_light_ref_index(reservoir.lightData);
|
|
49
|
-
|
|
50
|
-
// Full RGB unshadowed contribution via the representative-point incident light.
|
|
51
|
-
let incident = restir_get_light_info(light_type, light_index, geometry.position);
|
|
52
|
-
var reflected: ${REFLECTED_LIGHT_STRUCT.wgsl_ref};
|
|
53
|
-
re_direct_physical(incident, geometry, material, &reflected);
|
|
54
|
-
re_direct_multiscatter(geometry, material, &reflected);
|
|
55
|
-
let radiance = reflected.diffuse + reflected.specular;
|
|
56
|
-
|
|
57
|
-
if (all(radiance <= vec3<f32>(0.0))) {
|
|
58
|
-
return vec3<f32>(0.0);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Decode the stored 16-bit-fixed-point area-light sample point.
|
|
62
|
-
let uv =
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
chunk_restir_trace_visibility,
|
|
93
|
-
]
|
|
94
|
-
);
|
|
1
|
+
import { REFLECTED_LIGHT_STRUCT } from "../../shader/chunk/light/REFLECTED_LIGHT_STRUCT.js";
|
|
2
|
+
import { chunk_re_direct_multiscatter } from "../../shader/chunk/material/chunk_re_direct_multiscatter.js";
|
|
3
|
+
import { chunk_re_direct_physical } from "../../shader/chunk/material/chunk_re_direct_physical.js";
|
|
4
|
+
import { GEOMETRIC_SHADING_INFO_STRUCT } from "../../shader/chunk/material/GEOMETRIC_SHADING_INFO_STRUCT.js";
|
|
5
|
+
import { MATERIAL_SHADING_INFO_STRUCT } from "../../shader/chunk/material/MATERIAL_SHADING_INFO_STRUCT.js";
|
|
6
|
+
import { RTXDI_Reservoir } from "../reservoir/RTXDI_Reservoir.js";
|
|
7
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
8
|
+
import { chunk_restir_get_light_info } from "./chunk_restir_get_light_info.js";
|
|
9
|
+
import { chunk_restir_light_ref } from "./chunk_restir_light_ref.js";
|
|
10
|
+
import { chunk_restir_sample_light_record } from "./chunk_restir_sample_light_record.js";
|
|
11
|
+
import { chunk_restir_trace_visibility } from "./chunk_restir_trace_visibility.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a finalized reservoir to outgoing radiance for the selected light:
|
|
15
|
+
*
|
|
16
|
+
* radiance = BRDF·Le·G (full RGB, unshadowed) · W · V
|
|
17
|
+
*
|
|
18
|
+
* where W == reservoir.weightSum after FinalizeResampling (it already folds in
|
|
19
|
+
* 1/p_hat and 1/M) and V is the traced visibility (the RTXDI `f_rgb · weightSum`
|
|
20
|
+
* identity). p_hat is the luminance of the single-scattering BRDF·Le·G; this
|
|
21
|
+
* BRDF also carries `re_direct_multiscatter`'s per-pixel scale of the specular,
|
|
22
|
+
* so f / p_hat is no longer 1 but stays within [1, that scale]. The estimate is
|
|
23
|
+
* unbiased either way: f and p_hat are positive on the same lights.
|
|
24
|
+
*
|
|
25
|
+
* Visibility is a single opaque shadow ray toward the survivor's sampled emitter
|
|
26
|
+
* point — matching the brute-force NEE reference (`ray_sample_light`), which also
|
|
27
|
+
* uses `ray_query_occluded`. Requires the RTX resource group to be bound.
|
|
28
|
+
*
|
|
29
|
+
* Emissive is intentionally excluded; the deferred pass adds it once.
|
|
30
|
+
*
|
|
31
|
+
* @type {CodeChunk}
|
|
32
|
+
*/
|
|
33
|
+
export const chunk_restir_resolve = CodeChunk.from(
|
|
34
|
+
//language=WGSL
|
|
35
|
+
`
|
|
36
|
+
fn restir_resolve(
|
|
37
|
+
i_coord: vec2<u32>,
|
|
38
|
+
reservoir: ${RTXDI_Reservoir.wgsl_ref},
|
|
39
|
+
geometry: ${GEOMETRIC_SHADING_INFO_STRUCT.wgsl_ref},
|
|
40
|
+
material: ${MATERIAL_SHADING_INFO_STRUCT.wgsl_ref},
|
|
41
|
+
use_screen_space_shadow: u32
|
|
42
|
+
) -> vec3<f32> {
|
|
43
|
+
if (!restir_light_ref_is_valid(reservoir.lightData) || reservoir.weightSum <= 0.0) {
|
|
44
|
+
return vec3<f32>(0.0);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let light_type = restir_light_ref_type(reservoir.lightData);
|
|
48
|
+
let light_index = restir_light_ref_index(reservoir.lightData);
|
|
49
|
+
|
|
50
|
+
// Full RGB unshadowed contribution via the representative-point incident light.
|
|
51
|
+
let incident = restir_get_light_info(light_type, light_index, geometry.position);
|
|
52
|
+
var reflected: ${REFLECTED_LIGHT_STRUCT.wgsl_ref};
|
|
53
|
+
re_direct_physical(incident, geometry, material, &reflected);
|
|
54
|
+
re_direct_multiscatter(geometry, material, &reflected);
|
|
55
|
+
let radiance = reflected.diffuse + reflected.specular;
|
|
56
|
+
|
|
57
|
+
if (all(radiance <= vec3<f32>(0.0))) {
|
|
58
|
+
return vec3<f32>(0.0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Decode the stored 16-bit-fixed-point area-light sample point.
|
|
62
|
+
let uv = unpack2x16unorm(reservoir.uvData);
|
|
63
|
+
let record = restir_sample_light_record(light_type, light_index, geometry.position, uv);
|
|
64
|
+
|
|
65
|
+
var visibility = 1.0;
|
|
66
|
+
if (record.distance > 0.0) {
|
|
67
|
+
visibility = restir_trace_visibility(
|
|
68
|
+
i_coord,
|
|
69
|
+
geometry.position,
|
|
70
|
+
geometry.geometric_normal,
|
|
71
|
+
record.direction,
|
|
72
|
+
record.distance,
|
|
73
|
+
use_screen_space_shadow != 0u,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return radiance * reservoir.weightSum * visibility;
|
|
78
|
+
}
|
|
79
|
+
`, [
|
|
80
|
+
RTXDI_Reservoir.declaration_chunk,
|
|
81
|
+
REFLECTED_LIGHT_STRUCT.declaration_chunk,
|
|
82
|
+
GEOMETRIC_SHADING_INFO_STRUCT.declaration_chunk,
|
|
83
|
+
MATERIAL_SHADING_INFO_STRUCT.declaration_chunk,
|
|
84
|
+
chunk_re_direct_physical,
|
|
85
|
+
chunk_re_direct_multiscatter,
|
|
86
|
+
chunk_restir_get_light_info,
|
|
87
|
+
chunk_restir_light_ref,
|
|
88
|
+
chunk_restir_sample_light_record,
|
|
89
|
+
chunk_restir_trace_visibility,
|
|
90
|
+
]
|
|
91
|
+
);
|
|
@@ -36,7 +36,7 @@ fn rtxdi_stream_sample(
|
|
|
36
36
|
if (selectSample)
|
|
37
37
|
{
|
|
38
38
|
reservoir.lightData = lightIndex | RTXDI_Reservoir_LightValidBit;
|
|
39
|
-
reservoir.uvData =
|
|
39
|
+
reservoir.uvData = pack2x16unorm(uv);
|
|
40
40
|
reservoir.targetPdf = targetPdf;
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Decodes a packed RGBE 9-9-9-5 (`u32`) word into linear RGB (`vec3<f32>`).
|
|
3
|
+
*
|
|
4
|
+
* Bit layout:
|
|
5
|
+
* - `[0..8]`: 9-bit R mantissa
|
|
6
|
+
* - `[9..17]`: 9-bit G mantissa
|
|
7
|
+
* - `[18..26]`: 9-bit B mantissa
|
|
8
|
+
* - `[27..31]`: 5-bit biased exponent E (bias = 15, mantissa bits = 9)
|
|
9
|
+
*
|
|
10
|
+
* Rather than evaluating a transcendental `exp2(E - 24.0)` on the SFU, `2^(E - 24)` is
|
|
11
|
+
* constructed directly in IEEE-754 binary32 bits: shifting E from `[27..31]` down to the
|
|
12
|
+
* float exponent field `[23..27]` and adding the combined exponent bias `(127 - 24) << 23 = 0x33800000u`.
|
|
13
|
+
* Because `E` is in `[0, 31]`, the biased IEEE-754 exponent `E + 103` is in `[103, 134]`,
|
|
14
|
+
* which is always a normal positive float.
|
|
15
|
+
*
|
|
2
16
|
* @see https://en.wikipedia.org/wiki/RGBE_image_format
|
|
3
17
|
* @see https://github.com/zhangjiangen11/godot/blob/b64ac6341347906dacdda712dc78b574334ff4af/servers/rendering/renderer_rd/shaders/environment/hddagi_direct_light.glsl#L331
|
|
4
18
|
* @type {CodeChunk}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_rgbe9995_decode.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.js"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"chunk_rgbe9995_decode.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,oCAFU,SAAS,CAgBjB;0BAnCwB,gCAAgC"}
|
|
@@ -1,21 +1,36 @@
|
|
|
1
|
-
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Decodes a packed RGBE 9-9-9-5 (`u32`) word into linear RGB (`vec3<f32>`).
|
|
5
|
+
*
|
|
6
|
+
* Bit layout:
|
|
7
|
+
* - `[0..8]`: 9-bit R mantissa
|
|
8
|
+
* - `[9..17]`: 9-bit G mantissa
|
|
9
|
+
* - `[18..26]`: 9-bit B mantissa
|
|
10
|
+
* - `[27..31]`: 5-bit biased exponent E (bias = 15, mantissa bits = 9)
|
|
11
|
+
*
|
|
12
|
+
* Rather than evaluating a transcendental `exp2(E - 24.0)` on the SFU, `2^(E - 24)` is
|
|
13
|
+
* constructed directly in IEEE-754 binary32 bits: shifting E from `[27..31]` down to the
|
|
14
|
+
* float exponent field `[23..27]` and adding the combined exponent bias `(127 - 24) << 23 = 0x33800000u`.
|
|
15
|
+
* Because `E` is in `[0, 31]`, the biased IEEE-754 exponent `E + 103` is in `[103, 134]`,
|
|
16
|
+
* which is always a normal positive float.
|
|
17
|
+
*
|
|
18
|
+
* @see https://en.wikipedia.org/wiki/RGBE_image_format
|
|
19
|
+
* @see https://github.com/zhangjiangen11/godot/blob/b64ac6341347906dacdda712dc78b574334ff4af/servers/rendering/renderer_rd/shaders/environment/hddagi_direct_light.glsl#L331
|
|
20
|
+
* @type {CodeChunk}
|
|
21
|
+
*/
|
|
22
|
+
export const chunk_rgbe9995_decode = CodeChunk.from(
|
|
23
|
+
//language=WGSL
|
|
24
|
+
`
|
|
25
|
+
fn rgbe9995_decode(p_rgbe: u32) -> vec3<f32> {
|
|
26
|
+
let rgb = vec3<f32>(
|
|
27
|
+
(vec3<u32>(p_rgbe) >> vec3<u32>(0u, 9u, 18u))
|
|
28
|
+
& vec3<u32>(0x1FFu)
|
|
29
|
+
);
|
|
30
|
+
let exp_bits = ((p_rgbe >> 4u) & 0x0F800000u) + 0x33800000u;
|
|
31
|
+
let scale = bitcast<f32>(exp_bits);
|
|
32
|
+
|
|
33
|
+
return rgb * scale;
|
|
34
|
+
}
|
|
35
|
+
`
|
|
36
|
+
);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Software-bilinear sample of an RGBE 9-9-9-5 (`r32uint`) 2D texture using a single `textureGather`.
|
|
3
|
+
*
|
|
4
|
+
* WebGPU's `rgb9e5ufloat` format is hardware-filterable, but cannot be written as a storage texture
|
|
5
|
+
* (`STORAGE_BINDING`) or render attachment, nor view-aliased with `r32uint`. When an HDR texture is
|
|
6
|
+
* produced on the GPU via `textureStore` into `r32uint`, this function performs a 4-texel bilinear
|
|
7
|
+
* tap using one `textureGather`:
|
|
8
|
+
*
|
|
9
|
+
* 1. Snaps the gather UV to `(floor(uv * tex_size - 0.5) + 1.0) * inv_tex_size` (dead-center
|
|
10
|
+
* between the 4 texels) so the TMU's 16.8 fixed-point floor never disagrees with the ALU's
|
|
11
|
+
* `f32` fractional weights near half-texel boundaries.
|
|
12
|
+
* 2. Constructs the four `2^(E - 24)` scale factors directly in IEEE-754 float bits via shift,
|
|
13
|
+
* mask, bias addition (`103 << 23 = 0x33800000u`), and `bitcast<vec4<f32>>`, avoiding 4 SFU
|
|
14
|
+
* `exp2` instructions.
|
|
15
|
+
* 3. Folds the 4 shared-exponent scales into the 4 bilinear weights (`w = bilinear * scale`) and
|
|
16
|
+
* evaluates each RGB channel as a single `dot(mantissa, w)`.
|
|
17
|
+
*
|
|
18
|
+
* @type {CodeChunk}
|
|
19
|
+
*/
|
|
20
|
+
export const chunk_rgbe9995_sample_gather: CodeChunk;
|
|
21
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
22
|
+
//# sourceMappingURL=chunk_rgbe9995_sample_gather.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_rgbe9995_sample_gather.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,2CAFU,SAAS,CA4CjB;0BA/DwB,gCAAgC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Software-bilinear sample of an RGBE 9-9-9-5 (`r32uint`) 2D texture using a single `textureGather`.
|
|
5
|
+
*
|
|
6
|
+
* WebGPU's `rgb9e5ufloat` format is hardware-filterable, but cannot be written as a storage texture
|
|
7
|
+
* (`STORAGE_BINDING`) or render attachment, nor view-aliased with `r32uint`. When an HDR texture is
|
|
8
|
+
* produced on the GPU via `textureStore` into `r32uint`, this function performs a 4-texel bilinear
|
|
9
|
+
* tap using one `textureGather`:
|
|
10
|
+
*
|
|
11
|
+
* 1. Snaps the gather UV to `(floor(uv * tex_size - 0.5) + 1.0) * inv_tex_size` (dead-center
|
|
12
|
+
* between the 4 texels) so the TMU's 16.8 fixed-point floor never disagrees with the ALU's
|
|
13
|
+
* `f32` fractional weights near half-texel boundaries.
|
|
14
|
+
* 2. Constructs the four `2^(E - 24)` scale factors directly in IEEE-754 float bits via shift,
|
|
15
|
+
* mask, bias addition (`103 << 23 = 0x33800000u`), and `bitcast<vec4<f32>>`, avoiding 4 SFU
|
|
16
|
+
* `exp2` instructions.
|
|
17
|
+
* 3. Folds the 4 shared-exponent scales into the 4 bilinear weights (`w = bilinear * scale`) and
|
|
18
|
+
* evaluates each RGB channel as a single `dot(mantissa, w)`.
|
|
19
|
+
*
|
|
20
|
+
* @type {CodeChunk}
|
|
21
|
+
*/
|
|
22
|
+
export const chunk_rgbe9995_sample_gather = CodeChunk.from(
|
|
23
|
+
//language=WGSL
|
|
24
|
+
`
|
|
25
|
+
fn rgbe9995_sample_gather(
|
|
26
|
+
tex: texture_2d<u32>,
|
|
27
|
+
samp: sampler,
|
|
28
|
+
uv: vec2<f32>,
|
|
29
|
+
tex_size: vec2<f32>,
|
|
30
|
+
inv_tex_size: vec2<f32>
|
|
31
|
+
) -> vec3<f32> {
|
|
32
|
+
// 1. Align UV to prevent 16.8 fixed-point TMU vs f32 ALU boundary mismatch
|
|
33
|
+
let coord = uv * tex_size - 0.5;
|
|
34
|
+
let base = floor(coord);
|
|
35
|
+
let f = coord - base;
|
|
36
|
+
let gather_uv = (base + 1.0) * inv_tex_size;
|
|
37
|
+
|
|
38
|
+
// WebGPU textureGather component order:
|
|
39
|
+
// .x = (u0, v1) [bottom-left], .y = (u1, v1) [bottom-right]
|
|
40
|
+
// .z = (u1, v0) [top-right], .w = (u0, v0) [top-left]
|
|
41
|
+
let raw: vec4<u32> = textureGather(0, tex, samp, gather_uv);
|
|
42
|
+
|
|
43
|
+
// 2. Construct 2^(E - 24) directly in IEEE-754 float bits:
|
|
44
|
+
// Shift E from [27..31] to [23..27] and add bias (103 << 23 = 0x33800000u)
|
|
45
|
+
let exp_bits = ((raw >> vec4<u32>(4u)) & vec4<u32>(0x0F800000u)) + vec4<u32>(0x33800000u);
|
|
46
|
+
let scale = bitcast<vec4<f32>>(exp_bits);
|
|
47
|
+
|
|
48
|
+
// 3. Fold bilinear weights and shared-exponent scales into a single vec4 weight
|
|
49
|
+
let w = vec4<f32>(
|
|
50
|
+
(1.0 - f.x) * f.y, // .x: (u0, v1)
|
|
51
|
+
f.x * f.y, // .y: (u1, v1)
|
|
52
|
+
f.x * (1.0 - f.y), // .z: (u1, v0)
|
|
53
|
+
(1.0 - f.x) * (1.0 - f.y)// .w: (u0, v0)
|
|
54
|
+
) * scale;
|
|
55
|
+
|
|
56
|
+
// 4. Extract 9-bit mantissas and dot with combined weights
|
|
57
|
+
let r = vec4<f32>(raw & vec4<u32>(0x1FFu));
|
|
58
|
+
let g = vec4<f32>((raw >> vec4<u32>(9u)) & vec4<u32>(0x1FFu));
|
|
59
|
+
let b = vec4<f32>((raw >> vec4<u32>(18u)) & vec4<u32>(0x1FFu));
|
|
60
|
+
|
|
61
|
+
return vec3<f32>(dot(r, w), dot(g, w), dot(b, w));
|
|
62
|
+
}
|
|
63
|
+
`
|
|
64
|
+
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_decode_vertex_normal.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_vertex_normal.js"],"names":[],"mappings":"AAGA,
|
|
1
|
+
{"version":3,"file":"chunk_decode_vertex_normal.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_vertex_normal.js"],"names":[],"mappings":"AAGA,mDASE;0BAZwB,gCAAgC"}
|
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
2
|
-
import { chunk_uv_octahedral_unit_decode } from "../octahedron/chunk_uv_octahedral_unit_decode.js";
|
|
3
|
-
|
|
4
|
-
export const chunk_decode_vertex_normal = CodeChunk.from(
|
|
5
|
-
//language=WGSL
|
|
6
|
-
`
|
|
7
|
-
fn decode_vertex_normal(base: u32) -> vec3<f32>{
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
`, [
|
|
16
|
-
chunk_uv_octahedral_unit_decode,
|
|
17
|
-
]
|
|
18
|
-
);
|
|
1
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
2
|
+
import { chunk_uv_octahedral_unit_decode } from "../octahedron/chunk_uv_octahedral_unit_decode.js";
|
|
3
|
+
|
|
4
|
+
export const chunk_decode_vertex_normal = CodeChunk.from(
|
|
5
|
+
//language=WGSL
|
|
6
|
+
`
|
|
7
|
+
fn decode_vertex_normal(base: u32) -> vec3<f32>{
|
|
8
|
+
return uv_octahedral_unit_decode(unpack2x16unorm(base));
|
|
9
|
+
}
|
|
10
|
+
`, [
|
|
11
|
+
chunk_uv_octahedral_unit_decode,
|
|
12
|
+
]
|
|
13
|
+
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_encode_vertex_normal.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/normal/chunk_encode_vertex_normal.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,yCAFU,SAAS,
|
|
1
|
+
{"version":3,"file":"chunk_encode_vertex_normal.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/normal/chunk_encode_vertex_normal.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,yCAFU,SAAS,CAWjB;0BA3BwB,gCAAgC"}
|
|
@@ -1,30 +1,28 @@
|
|
|
1
|
-
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
2
|
-
import { chunk_uv_octahedral_unit_encode } from "../octahedron/chunk_uv_octahedral_unit_encode.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Inverse of `decode_vertex_normal` — packs a unit normal into a single
|
|
6
|
-
* `u32` via octahedral-unit encoding into two 16-bit u-norms (one per
|
|
7
|
-
* u32 half).
|
|
8
|
-
*
|
|
9
|
-
* Layout matches the decoder:
|
|
10
|
-
* - bits [0, 15]: oct.x (16-bit u-norm of `uv_octahedral_unit_encode(n).x`)
|
|
11
|
-
* - bits [16, 31]: oct.y
|
|
12
|
-
*
|
|
13
|
-
* Round-trips lossily — the 16-bit quantization gives ~1.5° worst-case
|
|
14
|
-
* angular error, which is what the format buys us in exchange for the
|
|
15
|
-
* 4-byte stride.
|
|
16
|
-
*
|
|
17
|
-
* @type {CodeChunk}
|
|
18
|
-
*/
|
|
19
|
-
export const chunk_encode_vertex_normal = CodeChunk.from(
|
|
20
|
-
//language=WGSL
|
|
21
|
-
`
|
|
22
|
-
fn encode_vertex_normal(n: vec3<f32>) -> u32 {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
]
|
|
30
|
-
);
|
|
1
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
2
|
+
import { chunk_uv_octahedral_unit_encode } from "../octahedron/chunk_uv_octahedral_unit_encode.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Inverse of `decode_vertex_normal` — packs a unit normal into a single
|
|
6
|
+
* `u32` via octahedral-unit encoding into two 16-bit u-norms (one per
|
|
7
|
+
* u32 half).
|
|
8
|
+
*
|
|
9
|
+
* Layout matches the decoder:
|
|
10
|
+
* - bits [0, 15]: oct.x (16-bit u-norm of `uv_octahedral_unit_encode(n).x`)
|
|
11
|
+
* - bits [16, 31]: oct.y
|
|
12
|
+
*
|
|
13
|
+
* Round-trips lossily — the 16-bit quantization gives ~1.5° worst-case
|
|
14
|
+
* angular error, which is what the format buys us in exchange for the
|
|
15
|
+
* 4-byte stride.
|
|
16
|
+
*
|
|
17
|
+
* @type {CodeChunk}
|
|
18
|
+
*/
|
|
19
|
+
export const chunk_encode_vertex_normal = CodeChunk.from(
|
|
20
|
+
//language=WGSL
|
|
21
|
+
`
|
|
22
|
+
fn encode_vertex_normal(n: vec3<f32>) -> u32 {
|
|
23
|
+
return pack2x16unorm(uv_octahedral_unit_encode(n));
|
|
24
|
+
}
|
|
25
|
+
`, [
|
|
26
|
+
chunk_uv_octahedral_unit_encode,
|
|
27
|
+
]
|
|
28
|
+
);
|