@tinypoly/gpu-renderer 0.0.4 → 0.1.0
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/ARCHITECTURE.md +81 -10
- package/README.md +53 -5
- package/dist/atmosphere.d.ts +21 -0
- package/dist/atmosphere.d.ts.map +1 -0
- package/dist/atmosphere.js +72 -0
- package/dist/atmosphere.js.map +1 -0
- package/dist/bvh.d.ts +11 -6
- package/dist/bvh.d.ts.map +1 -1
- package/dist/bvh.js +64 -11
- package/dist/bvh.js.map +1 -1
- package/dist/denoise.d.ts +17 -2
- package/dist/denoise.d.ts.map +1 -1
- package/dist/denoise.js +95 -27
- package/dist/denoise.js.map +1 -1
- package/dist/dispatchScheduler.d.ts +11 -4
- package/dist/dispatchScheduler.d.ts.map +1 -1
- package/dist/dispatchScheduler.js +14 -7
- package/dist/dispatchScheduler.js.map +1 -1
- package/dist/frameLayout.d.ts.map +1 -1
- package/dist/frameLayout.js +18 -0
- package/dist/frameLayout.js.map +1 -1
- package/dist/geometry.d.ts.map +1 -1
- package/dist/geometry.js +6 -3
- package/dist/geometry.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lensPass.d.ts +60 -0
- package/dist/lensPass.d.ts.map +1 -0
- package/dist/lensPass.js +235 -0
- package/dist/lensPass.js.map +1 -0
- package/dist/lightTree.d.ts +43 -0
- package/dist/lightTree.d.ts.map +1 -0
- package/dist/lightTree.js +107 -0
- package/dist/lightTree.js.map +1 -0
- package/dist/lights.d.ts +19 -1
- package/dist/lights.d.ts.map +1 -1
- package/dist/lights.js +63 -1
- package/dist/lights.js.map +1 -1
- package/dist/materialLayout.d.ts +24 -0
- package/dist/materialLayout.d.ts.map +1 -1
- package/dist/materialLayout.js +36 -1
- package/dist/materialLayout.js.map +1 -1
- package/dist/pathTracePass.d.ts +6 -3
- package/dist/pathTracePass.d.ts.map +1 -1
- package/dist/pathTracePass.js +16 -10
- package/dist/pathTracePass.js.map +1 -1
- package/dist/renderer.d.ts +19 -7
- package/dist/renderer.d.ts.map +1 -1
- package/dist/renderer.js +198 -36
- package/dist/renderer.js.map +1 -1
- package/dist/sceneUpload.d.ts +19 -1
- package/dist/sceneUpload.d.ts.map +1 -1
- package/dist/sceneUpload.js +25 -3
- package/dist/sceneUpload.js.map +1 -1
- package/dist/settings.d.ts +136 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +100 -0
- package/dist/settings.js.map +1 -0
- package/dist/subsurface.d.ts +76 -0
- package/dist/subsurface.d.ts.map +1 -0
- package/dist/subsurface.js +70 -0
- package/dist/subsurface.js.map +1 -0
- package/dist/texturePack.d.ts +16 -4
- package/dist/texturePack.d.ts.map +1 -1
- package/dist/texturePack.js +61 -8
- package/dist/texturePack.js.map +1 -1
- package/dist/volumeContainment.d.ts +17 -0
- package/dist/volumeContainment.d.ts.map +1 -0
- package/dist/volumeContainment.js +61 -0
- package/dist/volumeContainment.js.map +1 -0
- package/dist/wgsl/bsdf.wgsl.d.ts +1 -1
- package/dist/wgsl/bsdf.wgsl.d.ts.map +1 -1
- package/dist/wgsl/bsdf.wgsl.js +35 -3
- package/dist/wgsl/bsdf.wgsl.js.map +1 -1
- package/dist/wgsl/bvh.wgsl.d.ts +8 -2
- package/dist/wgsl/bvh.wgsl.d.ts.map +1 -1
- package/dist/wgsl/bvh.wgsl.js +167 -96
- package/dist/wgsl/bvh.wgsl.js.map +1 -1
- package/dist/wgsl/common.wgsl.d.ts.map +1 -1
- package/dist/wgsl/common.wgsl.js +24 -7
- package/dist/wgsl/common.wgsl.js.map +1 -1
- package/dist/wgsl/lens.wgsl.d.ts +17 -0
- package/dist/wgsl/lens.wgsl.d.ts.map +1 -0
- package/dist/wgsl/lens.wgsl.js +315 -0
- package/dist/wgsl/lens.wgsl.js.map +1 -0
- package/dist/wgsl/lights.wgsl.d.ts +1 -1
- package/dist/wgsl/lights.wgsl.d.ts.map +1 -1
- package/dist/wgsl/lights.wgsl.js +206 -33
- package/dist/wgsl/lights.wgsl.js.map +1 -1
- package/dist/wgsl/pathTrace.wgsl.d.ts +1 -1
- package/dist/wgsl/pathTrace.wgsl.d.ts.map +1 -1
- package/dist/wgsl/pathTrace.wgsl.js +410 -25
- package/dist/wgsl/pathTrace.wgsl.js.map +1 -1
- package/dist/wgsl/random.wgsl.d.ts +1 -1
- package/dist/wgsl/random.wgsl.d.ts.map +1 -1
- package/dist/wgsl/random.wgsl.js +9 -17
- package/dist/wgsl/random.wgsl.js.map +1 -1
- package/dist/wgsl/sampling.wgsl.d.ts +1 -1
- package/dist/wgsl/sampling.wgsl.d.ts.map +1 -1
- package/dist/wgsl/sampling.wgsl.js +25 -0
- package/dist/wgsl/sampling.wgsl.js.map +1 -1
- package/dist/wgsl/surface.wgsl.d.ts +1 -1
- package/dist/wgsl/surface.wgsl.d.ts.map +1 -1
- package/dist/wgsl/surface.wgsl.js +47 -4
- package/dist/wgsl/surface.wgsl.js.map +1 -1
- package/dist/wgsl/texture.wgsl.d.ts +1 -1
- package/dist/wgsl/texture.wgsl.d.ts.map +1 -1
- package/dist/wgsl/texture.wgsl.js +10 -11
- package/dist/wgsl/texture.wgsl.js.map +1 -1
- package/package.json +1 -1
- package/src/atmosphere.ts +95 -0
- package/src/bvh.ts +81 -12
- package/src/denoise.ts +110 -27
- package/src/dispatchScheduler.ts +16 -7
- package/src/frameLayout.ts +18 -0
- package/src/geometry.ts +6 -2
- package/src/index.ts +13 -0
- package/src/lensPass.ts +299 -0
- package/src/lightTree.ts +172 -0
- package/src/lights.ts +90 -2
- package/src/materialLayout.ts +52 -1
- package/src/pathTracePass.ts +19 -10
- package/src/renderer.ts +258 -43
- package/src/sceneUpload.ts +41 -4
- package/src/settings.ts +234 -0
- package/src/subsurface.ts +153 -0
- package/src/texturePack.ts +80 -13
- package/src/volumeContainment.ts +81 -0
- package/src/wgsl/bsdf.wgsl.ts +35 -3
- package/src/wgsl/bvh.wgsl.ts +167 -96
- package/src/wgsl/common.wgsl.ts +24 -7
- package/src/wgsl/lens.wgsl.ts +314 -0
- package/src/wgsl/lights.wgsl.ts +206 -33
- package/src/wgsl/pathTrace.wgsl.ts +410 -25
- package/src/wgsl/random.wgsl.ts +9 -17
- package/src/wgsl/sampling.wgsl.ts +25 -0
- package/src/wgsl/surface.wgsl.ts +47 -4
- package/src/wgsl/texture.wgsl.ts +10 -11
|
@@ -21,6 +21,31 @@ fn cosineDirection(normal: vec3<f32>, u: vec2<f32>) -> vec3<f32> {
|
|
|
21
21
|
return normalize(orthonormalBasis(normal) * local);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
/** A direction scattered from forward by the Henyey-Greenstein phase function, which its own sampling cancels. */
|
|
25
|
+
fn sampleHenyeyGreenstein(forward: vec3<f32>, g: f32, u: vec2<f32>) -> vec3<f32> {
|
|
26
|
+
var cosine = 1.0 - 2.0 * u.x;
|
|
27
|
+
|
|
28
|
+
if (abs(g) > 1e-3) {
|
|
29
|
+
let s = (1.0 - g * g) / (1.0 - g + 2.0 * g * u.x);
|
|
30
|
+
cosine = clamp((1.0 + g * g - s * s) / (2.0 * g), -1.0, 1.0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let sine = sqrt(max(0.0, 1.0 - cosine * cosine));
|
|
34
|
+
let angle = 2.0 * PI * u.y;
|
|
35
|
+
|
|
36
|
+
return normalize(orthonormalBasis(forward) * vec3<f32>(sine * cos(angle), sine * sin(angle), cosine));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The Henyey-Greenstein phase function, per steradian, for a turn whose cosine is given from the direction of travel:
|
|
41
|
+
* the density sampleHenyeyGreenstein draws with.
|
|
42
|
+
*/
|
|
43
|
+
fn henyeyGreenstein(cosine: f32, g: f32) -> f32 {
|
|
44
|
+
let denominator = 1.0 + g * g - 2.0 * g * cosine;
|
|
45
|
+
|
|
46
|
+
return (1.0 - g * g) / (4.0 * PI * denominator * sqrt(max(denominator, 1e-12)));
|
|
47
|
+
}
|
|
48
|
+
|
|
24
49
|
/** The unit normal of the triangle's plane; which side it faces does not matter, every emitter is two sided. */
|
|
25
50
|
fn triangleNormal(triangle: u32) -> vec3<f32> {
|
|
26
51
|
let a = triangleVertex(triangle, 0u);
|
package/src/wgsl/surface.wgsl.ts
CHANGED
|
@@ -62,6 +62,8 @@ struct Surface {
|
|
|
62
62
|
lightMap: vec3<f32>,
|
|
63
63
|
blending: u32,
|
|
64
64
|
material: u32,
|
|
65
|
+
// Share of the diffuse layer that scatters inside the material instead of at its surface.
|
|
66
|
+
subsurface: f32,
|
|
65
67
|
};
|
|
66
68
|
|
|
67
69
|
/** Barycentric weights of the two trailing vertices, for a point drawn uniformly over a triangle's area. */
|
|
@@ -114,6 +116,18 @@ fn isCulled(material: u32, triangle: u32, direction: vec3<f32>) -> bool {
|
|
|
114
116
|
/** What the triangle radiates at this point, its emissive map included so direct and indirect light agree on it. */
|
|
115
117
|
fn emissionAt(triangle: u32, bary: vec2<f32>) -> vec3<f32> {
|
|
116
118
|
let m = materialIndexOf(triangle);
|
|
119
|
+
|
|
120
|
+
// An unlit material emits its colour as the camera would see it, so a bounce ray finds what a light sample counted.
|
|
121
|
+
if ((materials[m].flags & MATERIAL_UNLIT_LIGHT) != 0u) {
|
|
122
|
+
var color = materials[m].color.rgb * sampleMap(materials[m].map, triangle, bary).rgb;
|
|
123
|
+
|
|
124
|
+
if ((materials[m].flags & MATERIAL_VERTEX_COLORS) != 0u) {
|
|
125
|
+
color = color * triangleColor(triangle, bary).rgb;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return color;
|
|
129
|
+
}
|
|
130
|
+
|
|
117
131
|
let map = sampleMap(materials[m].emissiveMap, triangle, bary);
|
|
118
132
|
|
|
119
133
|
return materials[m].emissive.rgb * materials[m].emissive.w * map.rgb;
|
|
@@ -173,8 +187,12 @@ fn onWireframe(triangle: u32, point: vec3<f32>) -> bool {
|
|
|
173
187
|
|
|
174
188
|
/** Three's diffuseColor.a: opacity, the colour map's alpha, the alpha map's green and the vertex alpha. */
|
|
175
189
|
fn materialAlpha(m: u32, triangle: u32, bary: vec2<f32>) -> f32 {
|
|
176
|
-
|
|
177
|
-
|
|
190
|
+
return materialAlphaFrom(m, triangle, bary, sampleMap(materials[m].map, triangle, bary));
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** The same, from the colour map's texel at this point. Multiplied in the order resolveSurface multiplies it. */
|
|
194
|
+
fn materialAlphaFrom(m: u32, triangle: u32, bary: vec2<f32>, base: vec4<f32>) -> f32 {
|
|
195
|
+
var alpha = materials[m].color.w * base.a * sampleMap(materials[m].alphaMap, triangle, bary).g;
|
|
178
196
|
|
|
179
197
|
if ((materials[m].flags & MATERIAL_VERTEX_COLORS) != 0u) {
|
|
180
198
|
alpha = alpha * triangleColor(triangle, bary).a;
|
|
@@ -554,12 +572,31 @@ fn toonRamp(gradientMap: u32, cosine: f32) -> f32 {
|
|
|
554
572
|
return sampleTextureRaw(gradientMap, vec2<f32>(coordinate, 0.0)).r;
|
|
555
573
|
}
|
|
556
574
|
|
|
575
|
+
/**
|
|
576
|
+
* Whether a material's coverage can be told from its maps alone, before the rest of the surface is read: no shader that
|
|
577
|
+
* might rewrite the alpha or discard, normal blending, and something that makes it partial at all.
|
|
578
|
+
*/
|
|
579
|
+
fn coverageFirst(m: u32) -> bool {
|
|
580
|
+
let flags = materials[m].flags;
|
|
581
|
+
let blending = materials[m].blending;
|
|
582
|
+
|
|
583
|
+
return materials[m].program == NO_PROGRAM
|
|
584
|
+
&& (blending == BLEND_NORMAL || blending == BLEND_NONE)
|
|
585
|
+
&& (materials[m].alphaTest > 0.0 || (flags & (MATERIAL_ALPHA_HASH | MATERIAL_TRANSPARENT)) != 0u);
|
|
586
|
+
}
|
|
587
|
+
|
|
557
588
|
/** Everything the lobes need about one point of one triangle. */
|
|
558
589
|
fn resolveSurface(triangle: u32, bary: vec2<f32>, direction: vec3<f32>) -> Surface {
|
|
559
590
|
let m = materialIndexOf(triangle);
|
|
591
|
+
|
|
592
|
+
return resolveSurfaceFrom(triangle, bary, direction, sampleMap(materials[m].map, triangle, bary));
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/** The same, from the colour map's texel at this point, for a caller that already read it. */
|
|
596
|
+
fn resolveSurfaceFrom(triangle: u32, bary: vec2<f32>, direction: vec3<f32>, base: vec4<f32>) -> Surface {
|
|
597
|
+
let m = materialIndexOf(triangle);
|
|
560
598
|
let flags = materials[m].flags;
|
|
561
599
|
let kind = materials[m].kind;
|
|
562
|
-
let base = sampleMap(materials[m].map, triangle, bary);
|
|
563
600
|
let facing = interpolatedNormal(m, triangle, bary, direction);
|
|
564
601
|
let view = -direction;
|
|
565
602
|
var surface: Surface;
|
|
@@ -588,7 +625,12 @@ fn resolveSurface(triangle: u32, bary: vec2<f32>, direction: vec3<f32>) -> Surfa
|
|
|
588
625
|
|
|
589
626
|
var roughness = materials[m].specular.w * sampleMap(materials[m].roughnessMap, triangle, bary).g;
|
|
590
627
|
var metalness = materials[m].metalness * sampleMap(materials[m].metalnessMap, triangle, bary).b;
|
|
591
|
-
var emissive =
|
|
628
|
+
var emissive = vec3<f32>(0.0);
|
|
629
|
+
|
|
630
|
+
// An unlit light's colour is added as what it shows, below; emissionAt gives the same colour to light samples.
|
|
631
|
+
if ((flags & MATERIAL_UNLIT_LIGHT) == 0u) {
|
|
632
|
+
emissive = emissionAt(triangle, bary);
|
|
633
|
+
}
|
|
592
634
|
|
|
593
635
|
surface.opacity = 1.0;
|
|
594
636
|
|
|
@@ -635,6 +677,7 @@ fn resolveSurface(triangle: u32, bary: vec2<f32>, direction: vec3<f32>) -> Surfa
|
|
|
635
677
|
surface.ior = max(materials[m].ior, 1.0);
|
|
636
678
|
surface.thickness = materials[m].thickness * sampleMap(materials[m].thicknessMap, triangle, bary).g;
|
|
637
679
|
surface.dispersion = materials[m].dispersion;
|
|
680
|
+
surface.subsurface = select(0.0, materials[m].subsurface.w, frame.subsurfaceEnabled != 0u);
|
|
638
681
|
surface.absorption = absorptionOf(m);
|
|
639
682
|
surface.shininess = materials[m].shininess;
|
|
640
683
|
surface.specularStrength = sampleMap(materials[m].specularMap, triangle, bary).r;
|
package/src/wgsl/texture.wgsl.ts
CHANGED
|
@@ -33,10 +33,6 @@ fn wrapIndex(index: i32, size: i32, mode: u32) -> i32 {
|
|
|
33
33
|
return clamp(index, 0, size - 1);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
fn srgbChannelToLinear(value: f32) -> f32 {
|
|
37
|
-
return select(pow((value + 0.055) / 1.055, 2.4), value / 12.92, value <= 0.04045);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
36
|
/** One texel, in linear light. Alpha is never encoded, as in Three. */
|
|
41
37
|
fn readTexel(info: TextureInfo, x: i32, y: i32) -> vec4<f32> {
|
|
42
38
|
let index = u32(y) * info.size.x + u32(x);
|
|
@@ -52,18 +48,21 @@ fn readTexel(info: TextureInfo, x: i32, y: i32) -> vec4<f32> {
|
|
|
52
48
|
}
|
|
53
49
|
|
|
54
50
|
let word = textures[info.offset + index];
|
|
55
|
-
let raw = vec4<f32>(
|
|
56
|
-
f32(word & 0xffu),
|
|
57
|
-
f32((word >> 8u) & 0xffu),
|
|
58
|
-
f32((word >> 16u) & 0xffu),
|
|
59
|
-
f32((word >> 24u) & 0xffu)) / 255.0;
|
|
60
51
|
|
|
52
|
+
// The decode is a table of the 256 codes rather than a power per channel and per texel: the same values, read.
|
|
61
53
|
if ((info.flags & TEXTURE_SRGB) != 0u) {
|
|
62
54
|
return vec4<f32>(
|
|
63
|
-
|
|
55
|
+
bitcast<f32>(textures[SRGB_TABLE + (word & 0xffu)]),
|
|
56
|
+
bitcast<f32>(textures[SRGB_TABLE + ((word >> 8u) & 0xffu)]),
|
|
57
|
+
bitcast<f32>(textures[SRGB_TABLE + ((word >> 16u) & 0xffu)]),
|
|
58
|
+
f32((word >> 24u) & 0xffu) / 255.0);
|
|
64
59
|
}
|
|
65
60
|
|
|
66
|
-
return
|
|
61
|
+
return vec4<f32>(
|
|
62
|
+
f32(word & 0xffu),
|
|
63
|
+
f32((word >> 8u) & 0xffu),
|
|
64
|
+
f32((word >> 16u) & 0xffu),
|
|
65
|
+
f32((word >> 24u) & 0xffu)) / 255.0;
|
|
67
66
|
}
|
|
68
67
|
|
|
69
68
|
/** One texture of the table, sampled with its own transform, wrap modes and filter. */
|