@plasius/gpu-lighting 0.2.5 → 0.2.7
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/CHANGELOG.md +35 -3
- package/README.md +98 -0
- package/dist/index.cjs +837 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +817 -0
- package/dist/index.js.map +1 -1
- package/dist/techniques/techniques/wavefront/accumulate-terminal-radiance.job.wgsl +61 -0
- package/dist/techniques/techniques/wavefront/prelude.wgsl +237 -0
- package/dist/techniques/techniques/wavefront/scatter-continuations.job.wgsl +136 -0
- package/package.json +2 -1
- package/src/index.js +889 -0
- package/src/techniques/wavefront/accumulate-terminal-radiance.job.wgsl +61 -0
- package/src/techniques/wavefront/prelude.wgsl +237 -0
- package/src/techniques/wavefront/scatter-continuations.job.wgsl +136 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
@group(0) @binding(0) var<uniform> wavefrontLightingParams: WavefrontLightingParams;
|
|
2
|
+
@group(0) @binding(1) var<storage, read> activeQueue: array<RayRecord>;
|
|
3
|
+
@group(0) @binding(2) var<storage, read> hitBuffer: array<HitRecord>;
|
|
4
|
+
@group(0) @binding(3) var<storage, read> surfaceBuffer: array<SurfaceRecord>;
|
|
5
|
+
@group(0) @binding(4) var<storage, read> materialRefBuffer: array<MaterialReferenceRecord>;
|
|
6
|
+
@group(0) @binding(5) var<storage, read> mediumRefBuffer: array<MediumReferenceRecord>;
|
|
7
|
+
@group(0) @binding(6) var<storage, read_write> accumulationBuffer: array<AccumulationRecord>;
|
|
8
|
+
|
|
9
|
+
fn resolve_emissive_radiance(
|
|
10
|
+
material: MaterialReferenceRecord,
|
|
11
|
+
surface: SurfaceRecord
|
|
12
|
+
) -> vec3<f32> {
|
|
13
|
+
let uv_weight = saturate_scalar(surface.uv.x + surface.uv.y);
|
|
14
|
+
let emissive_hint = select(0.0, 1.0, (material.flags & 0x1u) != 0u);
|
|
15
|
+
let base = material_base_albedo(material);
|
|
16
|
+
return base * (0.5 + uv_weight * 0.5 + emissive_hint * 2.0);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
fn accumulate_terminal_sample(
|
|
20
|
+
ray: RayRecord,
|
|
21
|
+
hit: HitRecord,
|
|
22
|
+
surface: SurfaceRecord,
|
|
23
|
+
material: MaterialReferenceRecord,
|
|
24
|
+
accumulation_index: u32
|
|
25
|
+
) {
|
|
26
|
+
let emissive_radiance = resolve_emissive_radiance(material, surface);
|
|
27
|
+
let terminal_radiance = terminal_radiance_for_hit(hit, ray, emissive_radiance);
|
|
28
|
+
if (luminance(terminal_radiance) <= LIGHTING_EPSILON) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
accumulationBuffer[accumulation_index].sourcePixelId = ray.sourcePixelId;
|
|
33
|
+
accumulationBuffer[accumulation_index].sampleCount =
|
|
34
|
+
accumulationBuffer[accumulation_index].sampleCount + 1u;
|
|
35
|
+
accumulationBuffer[accumulation_index].resetEpoch =
|
|
36
|
+
wavefrontLightingParams.accumulation_reset_epoch;
|
|
37
|
+
accumulationBuffer[accumulation_index].radiance =
|
|
38
|
+
accumulationBuffer[accumulation_index].radiance + terminal_radiance;
|
|
39
|
+
accumulationBuffer[accumulation_index].throughput = ray.throughput;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@compute @workgroup_size(64, 1, 1)
|
|
43
|
+
fn process_job(@builtin(global_invocation_id) global_id: vec3<u32>) {
|
|
44
|
+
let index = global_id.x;
|
|
45
|
+
if (index >= wavefrontLightingParams.active_count) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let ray = activeQueue[index];
|
|
50
|
+
let hit = hitBuffer[index];
|
|
51
|
+
if (!is_terminal_hit_type(hit.hitType)) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let surface = surfaceBuffer[index];
|
|
56
|
+
let material = materialRefBuffer[surface.materialRefId];
|
|
57
|
+
let _medium = mediumRefBuffer[surface.mediumRefId];
|
|
58
|
+
let accumulation_index = min(ray.sourcePixelId, wavefrontLightingParams.active_count - 1u);
|
|
59
|
+
|
|
60
|
+
accumulate_terminal_sample(ray, hit, surface, material, accumulation_index);
|
|
61
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
const LIGHTING_WAVEFRONT_SCHEMA_VERSION: u32 = 1u;
|
|
2
|
+
const LIGHTING_WAVEFRONT_QUEUE_PAIR_STRATEGY: u32 = 1u;
|
|
3
|
+
|
|
4
|
+
const HIT_TYPE_SURFACE: u32 = 0u;
|
|
5
|
+
const HIT_TYPE_EMISSIVE: u32 = 1u;
|
|
6
|
+
const HIT_TYPE_ENVIRONMENT: u32 = 2u;
|
|
7
|
+
const HIT_TYPE_TRANSPARENT: u32 = 3u;
|
|
8
|
+
const HIT_TYPE_MISS: u32 = 4u;
|
|
9
|
+
|
|
10
|
+
const EVENT_KIND_DIFFUSE: u32 = 0u;
|
|
11
|
+
const EVENT_KIND_REFLECTION: u32 = 1u;
|
|
12
|
+
const EVENT_KIND_REFRACTION: u32 = 2u;
|
|
13
|
+
const EVENT_KIND_TRANSPARENCY: u32 = 3u;
|
|
14
|
+
const EVENT_KIND_TERMINATE: u32 = 4u;
|
|
15
|
+
|
|
16
|
+
const RAY_KIND_PATH: u32 = 0u;
|
|
17
|
+
const RAY_KIND_VISIBILITY_PROBE: u32 = 1u;
|
|
18
|
+
const RAY_KIND_MASK: u32 = 0x3u;
|
|
19
|
+
|
|
20
|
+
const LIGHTING_EPSILON: f32 = 0.0001;
|
|
21
|
+
const LIGHTING_INV_PI: f32 = 0.3183098861837907;
|
|
22
|
+
|
|
23
|
+
struct WavefrontLightingParams {
|
|
24
|
+
active_count: u32,
|
|
25
|
+
next_queue_capacity: u32,
|
|
26
|
+
bounce_index: u32,
|
|
27
|
+
max_depth: u32,
|
|
28
|
+
enable_explicit_light_sampling: u32,
|
|
29
|
+
accumulation_reset_epoch: u32,
|
|
30
|
+
environment_mode: u32,
|
|
31
|
+
environment_intensity: f32,
|
|
32
|
+
sunlit_baseline: f32,
|
|
33
|
+
_padding0: vec3<f32>,
|
|
34
|
+
environment_color: vec4<f32>,
|
|
35
|
+
ambient_color: vec4<f32>,
|
|
36
|
+
environment_miss_radiance: vec4<f32>,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
struct RayRecord {
|
|
40
|
+
rayId: u32,
|
|
41
|
+
parentRayId: u32,
|
|
42
|
+
sourcePixelId: u32,
|
|
43
|
+
sampleId: u32,
|
|
44
|
+
bounce: u32,
|
|
45
|
+
origin: vec3<f32>,
|
|
46
|
+
_padding0: f32,
|
|
47
|
+
direction: vec3<f32>,
|
|
48
|
+
_padding1: f32,
|
|
49
|
+
throughput: vec3<f32>,
|
|
50
|
+
mediumRefId: u32,
|
|
51
|
+
flags: u32,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
struct HitRecord {
|
|
55
|
+
rayId: u32,
|
|
56
|
+
sourcePixelId: u32,
|
|
57
|
+
hitType: u32,
|
|
58
|
+
_padding0: u32,
|
|
59
|
+
distance: f32,
|
|
60
|
+
entityId: u32,
|
|
61
|
+
instanceId: u32,
|
|
62
|
+
primitiveId: u32,
|
|
63
|
+
materialId: u32,
|
|
64
|
+
_padding1: vec3<u32>,
|
|
65
|
+
barycentrics: vec3<f32>,
|
|
66
|
+
_padding2: f32,
|
|
67
|
+
uv: vec2<f32>,
|
|
68
|
+
_padding3: vec2<f32>,
|
|
69
|
+
geometricNormal: vec3<f32>,
|
|
70
|
+
_padding4: f32,
|
|
71
|
+
shadingNormal: vec3<f32>,
|
|
72
|
+
frontFace: u32,
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
struct SurfaceRecord {
|
|
76
|
+
rayId: u32,
|
|
77
|
+
entityId: u32,
|
|
78
|
+
materialRefId: u32,
|
|
79
|
+
mediumRefId: u32,
|
|
80
|
+
geometricNormal: vec3<f32>,
|
|
81
|
+
_padding0: f32,
|
|
82
|
+
shadingNormal: vec3<f32>,
|
|
83
|
+
_padding1: f32,
|
|
84
|
+
uv: vec2<f32>,
|
|
85
|
+
_padding2: vec2<f32>,
|
|
86
|
+
tangentFrame0: vec3<f32>,
|
|
87
|
+
_padding3: f32,
|
|
88
|
+
tangentFrame1: vec3<f32>,
|
|
89
|
+
_padding4: f32,
|
|
90
|
+
tangentFrame2: vec3<f32>,
|
|
91
|
+
_padding5: f32,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
struct MaterialReferenceRecord {
|
|
95
|
+
materialRefId: u32,
|
|
96
|
+
materialId: u32,
|
|
97
|
+
shadingModel: u32,
|
|
98
|
+
textureSetId: u32,
|
|
99
|
+
flags: u32,
|
|
100
|
+
_padding0: vec3<u32>,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
struct MediumReferenceRecord {
|
|
104
|
+
mediumRefId: u32,
|
|
105
|
+
mediumId: u32,
|
|
106
|
+
phaseModel: u32,
|
|
107
|
+
_padding0: u32,
|
|
108
|
+
absorption: vec3<f32>,
|
|
109
|
+
_padding1: f32,
|
|
110
|
+
scattering: vec3<f32>,
|
|
111
|
+
_padding2: f32,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
struct AccumulationRecord {
|
|
115
|
+
sourcePixelId: u32,
|
|
116
|
+
sampleCount: u32,
|
|
117
|
+
resetEpoch: u32,
|
|
118
|
+
_padding0: u32,
|
|
119
|
+
radiance: vec3<f32>,
|
|
120
|
+
_padding1: f32,
|
|
121
|
+
throughput: vec3<f32>,
|
|
122
|
+
_padding2: f32,
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
fn luminance(value: vec3<f32>) -> f32 {
|
|
126
|
+
return dot(value, vec3<f32>(0.2126, 0.7152, 0.0722));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
fn saturate_scalar(value: f32) -> f32 {
|
|
130
|
+
return clamp(value, 0.0, 1.0);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
fn saturate_vec3(value: vec3<f32>) -> vec3<f32> {
|
|
134
|
+
return max(value, vec3<f32>(0.0));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
fn safe_normalize(value: vec3<f32>) -> vec3<f32> {
|
|
138
|
+
if (dot(value, value) <= LIGHTING_EPSILON) {
|
|
139
|
+
return vec3<f32>(0.0, 1.0, 0.0);
|
|
140
|
+
}
|
|
141
|
+
return normalize(value);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
fn faceforward_normal(normal: vec3<f32>, direction: vec3<f32>) -> vec3<f32> {
|
|
145
|
+
return select(normal, -normal, dot(normal, direction) > 0.0);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
fn is_terminal_hit_type(hit_type: u32) -> bool {
|
|
149
|
+
return hit_type == HIT_TYPE_EMISSIVE ||
|
|
150
|
+
hit_type == HIT_TYPE_ENVIRONMENT ||
|
|
151
|
+
hit_type == HIT_TYPE_MISS;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
fn ray_kind(flags: u32) -> u32 {
|
|
155
|
+
return flags & RAY_KIND_MASK;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
fn environment_radiance(direction: vec3<f32>) -> vec3<f32> {
|
|
159
|
+
let upward = saturate_scalar(direction.y * 0.5 + 0.5);
|
|
160
|
+
let directional = mix(
|
|
161
|
+
wavefrontLightingParams.environment_color.xyz * 0.45,
|
|
162
|
+
wavefrontLightingParams.environment_color.xyz,
|
|
163
|
+
upward
|
|
164
|
+
);
|
|
165
|
+
let ambient = wavefrontLightingParams.ambient_color.xyz * 0.18;
|
|
166
|
+
let miss = wavefrontLightingParams.environment_miss_radiance.xyz;
|
|
167
|
+
return saturate_vec3(max(directional + ambient, miss));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
fn terminal_radiance_for_hit(
|
|
171
|
+
hit: HitRecord,
|
|
172
|
+
ray: RayRecord,
|
|
173
|
+
emissive_radiance: vec3<f32>
|
|
174
|
+
) -> vec3<f32> {
|
|
175
|
+
if (hit.hitType == HIT_TYPE_EMISSIVE) {
|
|
176
|
+
return ray.throughput * saturate_vec3(emissive_radiance);
|
|
177
|
+
}
|
|
178
|
+
if (hit.hitType == HIT_TYPE_ENVIRONMENT) {
|
|
179
|
+
return ray.throughput * environment_radiance(ray.direction);
|
|
180
|
+
}
|
|
181
|
+
if (hit.hitType == HIT_TYPE_MISS) {
|
|
182
|
+
let miss_radiance = max(
|
|
183
|
+
environment_radiance(ray.direction),
|
|
184
|
+
wavefrontLightingParams.environment_miss_radiance.xyz
|
|
185
|
+
);
|
|
186
|
+
return ray.throughput * saturate_vec3(miss_radiance);
|
|
187
|
+
}
|
|
188
|
+
return vec3<f32>(0.0);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
fn reflect_direction(direction: vec3<f32>, normal: vec3<f32>) -> vec3<f32> {
|
|
192
|
+
return safe_normalize(reflect(direction, normal));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
fn refract_direction(direction: vec3<f32>, normal: vec3<f32>, eta_ratio: f32) -> vec3<f32> {
|
|
196
|
+
let refracted = refract(direction, normal, eta_ratio);
|
|
197
|
+
if (dot(refracted, refracted) <= LIGHTING_EPSILON) {
|
|
198
|
+
return reflect_direction(direction, normal);
|
|
199
|
+
}
|
|
200
|
+
return safe_normalize(refracted);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
fn choose_continuation_event_kind(hit: HitRecord, material: MaterialReferenceRecord) -> u32 {
|
|
204
|
+
if (hit.hitType == HIT_TYPE_TRANSPARENT || (material.flags & 0x4u) != 0u) {
|
|
205
|
+
return EVENT_KIND_TRANSPARENCY;
|
|
206
|
+
}
|
|
207
|
+
if ((material.flags & 0x8u) != 0u) {
|
|
208
|
+
return EVENT_KIND_REFRACTION;
|
|
209
|
+
}
|
|
210
|
+
if ((material.flags & 0x2u) != 0u) {
|
|
211
|
+
return EVENT_KIND_REFLECTION;
|
|
212
|
+
}
|
|
213
|
+
return EVENT_KIND_DIFFUSE;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
fn material_base_albedo(material: MaterialReferenceRecord) -> vec3<f32> {
|
|
217
|
+
let tint = vec3<f32>(
|
|
218
|
+
f32((material.materialId & 0xffu)) / 255.0,
|
|
219
|
+
f32((material.textureSetId & 0xffu)) / 255.0,
|
|
220
|
+
f32(((material.materialId ^ material.textureSetId) & 0xffu)) / 255.0
|
|
221
|
+
);
|
|
222
|
+
return max(tint, vec3<f32>(0.12, 0.12, 0.12));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
fn continuation_attenuation(event_kind: u32, material: MaterialReferenceRecord) -> vec3<f32> {
|
|
226
|
+
let base_albedo = material_base_albedo(material);
|
|
227
|
+
if (event_kind == EVENT_KIND_REFLECTION) {
|
|
228
|
+
return mix(vec3<f32>(0.04), base_albedo, 0.7);
|
|
229
|
+
}
|
|
230
|
+
if (event_kind == EVENT_KIND_REFRACTION) {
|
|
231
|
+
return vec3<f32>(0.92, 0.94, 0.98);
|
|
232
|
+
}
|
|
233
|
+
if (event_kind == EVENT_KIND_TRANSPARENCY) {
|
|
234
|
+
return vec3<f32>(0.75, 0.82, 0.9);
|
|
235
|
+
}
|
|
236
|
+
return base_albedo * LIGHTING_INV_PI;
|
|
237
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
@group(0) @binding(0) var<uniform> wavefrontLightingParams: WavefrontLightingParams;
|
|
2
|
+
@group(0) @binding(1) var<storage, read> activeQueue: array<RayRecord>;
|
|
3
|
+
@group(0) @binding(2) var<storage, read> hitBuffer: array<HitRecord>;
|
|
4
|
+
@group(0) @binding(3) var<storage, read> surfaceBuffer: array<SurfaceRecord>;
|
|
5
|
+
@group(0) @binding(4) var<storage, read> materialRefBuffer: array<MaterialReferenceRecord>;
|
|
6
|
+
@group(0) @binding(5) var<storage, read> mediumRefBuffer: array<MediumReferenceRecord>;
|
|
7
|
+
@group(0) @binding(6) var<storage, read_write> nextQueue: array<RayRecord>;
|
|
8
|
+
@group(0) @binding(7) var<storage, read_write> nextQueueCounter: atomic<u32>;
|
|
9
|
+
|
|
10
|
+
fn queue_continuation_ray(
|
|
11
|
+
ray: RayRecord,
|
|
12
|
+
hit: HitRecord,
|
|
13
|
+
surface: SurfaceRecord,
|
|
14
|
+
direction: vec3<f32>,
|
|
15
|
+
attenuation: vec3<f32>
|
|
16
|
+
) {
|
|
17
|
+
let slot = atomicAdd(&nextQueueCounter, 1u);
|
|
18
|
+
if (slot >= wavefrontLightingParams.next_queue_capacity) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let offset_origin =
|
|
23
|
+
ray.origin +
|
|
24
|
+
ray.direction * hit.distance +
|
|
25
|
+
faceforward_normal(surface.geometricNormal, ray.direction) * 0.001;
|
|
26
|
+
nextQueue[slot] = RayRecord(
|
|
27
|
+
ray.rayId ^ ((wavefrontLightingParams.bounce_index + 1u) * 0x9e3779b9u),
|
|
28
|
+
ray.rayId,
|
|
29
|
+
ray.sourcePixelId,
|
|
30
|
+
ray.sampleId,
|
|
31
|
+
wavefrontLightingParams.bounce_index + 1u,
|
|
32
|
+
offset_origin,
|
|
33
|
+
0.0,
|
|
34
|
+
direction,
|
|
35
|
+
0.0,
|
|
36
|
+
ray.throughput * attenuation,
|
|
37
|
+
surface.mediumRefId,
|
|
38
|
+
ray.flags
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
fn queue_reflection_continuation(
|
|
43
|
+
ray: RayRecord,
|
|
44
|
+
hit: HitRecord,
|
|
45
|
+
surface: SurfaceRecord,
|
|
46
|
+
material: MaterialReferenceRecord
|
|
47
|
+
) {
|
|
48
|
+
let facing_normal = faceforward_normal(surface.shadingNormal, ray.direction);
|
|
49
|
+
let direction = reflect_direction(ray.direction, facing_normal);
|
|
50
|
+
let attenuation = continuation_attenuation(EVENT_KIND_REFLECTION, material);
|
|
51
|
+
queue_continuation_ray(ray, hit, surface, direction, attenuation);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
fn queue_refraction_continuation(
|
|
55
|
+
ray: RayRecord,
|
|
56
|
+
hit: HitRecord,
|
|
57
|
+
surface: SurfaceRecord,
|
|
58
|
+
material: MaterialReferenceRecord
|
|
59
|
+
) {
|
|
60
|
+
let front_face = hit.frontFace != 0u;
|
|
61
|
+
let facing_normal = faceforward_normal(surface.shadingNormal, ray.direction);
|
|
62
|
+
let eta_ratio = select(1.45, 1.0 / 1.45, front_face);
|
|
63
|
+
let direction = refract_direction(ray.direction, facing_normal, eta_ratio);
|
|
64
|
+
let attenuation = continuation_attenuation(EVENT_KIND_REFRACTION, material);
|
|
65
|
+
queue_continuation_ray(ray, hit, surface, direction, attenuation);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
fn queue_transparency_continuation(
|
|
69
|
+
ray: RayRecord,
|
|
70
|
+
hit: HitRecord,
|
|
71
|
+
surface: SurfaceRecord,
|
|
72
|
+
material: MaterialReferenceRecord
|
|
73
|
+
) {
|
|
74
|
+
let attenuation = continuation_attenuation(EVENT_KIND_TRANSPARENCY, material);
|
|
75
|
+
queue_continuation_ray(ray, hit, surface, ray.direction, attenuation);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
fn queue_diffuse_continuation(
|
|
79
|
+
ray: RayRecord,
|
|
80
|
+
hit: HitRecord,
|
|
81
|
+
surface: SurfaceRecord,
|
|
82
|
+
material: MaterialReferenceRecord
|
|
83
|
+
) {
|
|
84
|
+
let facing_normal = faceforward_normal(surface.shadingNormal, ray.direction);
|
|
85
|
+
let attenuation = continuation_attenuation(EVENT_KIND_DIFFUSE, material);
|
|
86
|
+
let bias =
|
|
87
|
+
surface.tangentFrame0 * (surface.uv.x - 0.5) +
|
|
88
|
+
surface.tangentFrame1 * (surface.uv.y - 0.5) +
|
|
89
|
+
facing_normal;
|
|
90
|
+
let direction = safe_normalize(bias);
|
|
91
|
+
queue_continuation_ray(ray, hit, surface, direction, attenuation);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@compute @workgroup_size(64, 1, 1)
|
|
95
|
+
fn process_job(@builtin(global_invocation_id) global_id: vec3<u32>) {
|
|
96
|
+
let index = global_id.x;
|
|
97
|
+
if (index >= wavefrontLightingParams.active_count) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (wavefrontLightingParams.bounce_index + 1u >= wavefrontLightingParams.max_depth) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
let ray = activeQueue[index];
|
|
105
|
+
let hit = hitBuffer[index];
|
|
106
|
+
if (is_terminal_hit_type(hit.hitType) || hit.hitType == HIT_TYPE_MISS) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
let surface = surfaceBuffer[index];
|
|
111
|
+
let material = materialRefBuffer[surface.materialRefId];
|
|
112
|
+
let _medium = mediumRefBuffer[surface.mediumRefId];
|
|
113
|
+
let event_kind = choose_continuation_event_kind(hit, material);
|
|
114
|
+
let explicit_light_sampling_enabled = wavefrontLightingParams.enable_explicit_light_sampling != 0u;
|
|
115
|
+
|
|
116
|
+
if (event_kind == EVENT_KIND_REFLECTION) {
|
|
117
|
+
queue_reflection_continuation(ray, hit, surface, material);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (event_kind == EVENT_KIND_REFRACTION) {
|
|
121
|
+
queue_refraction_continuation(ray, hit, surface, material);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (event_kind == EVENT_KIND_TRANSPARENCY) {
|
|
125
|
+
queue_transparency_continuation(ray, hit, surface, material);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (explicit_light_sampling_enabled) {
|
|
130
|
+
// Explicit light sampling remains optional for correctness in this first slice.
|
|
131
|
+
queue_diffuse_continuation(ray, hit, surface, material);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
queue_diffuse_continuation(ray, hit, surface, material);
|
|
136
|
+
}
|