reze-engine 0.41.0 → 0.41.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/dist/engine.d.ts +31 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +141 -15
- package/dist/graph/presets/body.js +2 -2
- package/dist/graph/presets/cloth_rough.js +2 -2
- package/dist/graph/presets/cloth_smooth.js +2 -2
- package/dist/graph/presets/default.js +2 -2
- package/dist/graph/presets/eye.js +2 -2
- package/dist/graph/presets/face.js +2 -2
- package/dist/graph/presets/hair.js +2 -2
- package/dist/graph/presets/metal.js +2 -2
- package/dist/graph/presets/stockings.js +3 -3
- package/dist/graph/registry.d.ts.map +1 -1
- package/dist/graph/registry.js +426 -10
- package/dist/graph/style-group.d.ts +46 -0
- package/dist/graph/style-group.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/shaders/agx-lut.d.ts +11 -0
- package/dist/shaders/agx-lut.d.ts.map +1 -0
- package/dist/shaders/agx-lut.js +29 -0
- package/dist/shaders/materials/common.d.ts +1 -1
- package/dist/shaders/materials/common.d.ts.map +1 -1
- package/dist/shaders/materials/common.js +10 -0
- package/dist/shaders/materials/nodes.d.ts +1 -1
- package/dist/shaders/materials/nodes.d.ts.map +1 -1
- package/dist/shaders/materials/nodes.js +957 -576
- package/dist/shaders/passes/composite.d.ts.map +1 -1
- package/dist/shaders/passes/composite.js +57 -3
- package/package.json +1 -1
- package/src/engine.ts +165 -14
- package/src/graph/presets/body.ts +2 -2
- package/src/graph/presets/cloth_rough.ts +2 -2
- package/src/graph/presets/cloth_smooth.ts +2 -2
- package/src/graph/presets/default.ts +2 -2
- package/src/graph/presets/eye.ts +2 -2
- package/src/graph/presets/face.ts +2 -2
- package/src/graph/presets/hair.ts +2 -2
- package/src/graph/presets/metal.ts +2 -2
- package/src/graph/presets/stockings.ts +3 -3
- package/src/graph/registry.ts +439 -10
- package/src/graph/style-group.ts +44 -0
- package/src/index.ts +2 -0
- package/src/shaders/agx-lut.ts +30 -0
- package/src/shaders/materials/common.ts +10 -0
- package/src/shaders/materials/nodes.ts +962 -581
- package/src/shaders/passes/composite.ts +57 -3
|
@@ -84,7 +84,7 @@ override APPLY_GAMMA: bool = true;
|
|
|
84
84
|
// the compiled variant IS the flag.
|
|
85
85
|
// viewU[3] = (camera right, tanHalfFov·aspect); viewU[4] = (camera up, tanHalfFov);
|
|
86
86
|
// viewU[5] = (camera forward, _) — refreshed per frame while skybox/effect active.
|
|
87
|
-
// viewU[6] = (time seconds,
|
|
87
|
+
// viewU[6] = (time seconds, view transform id, canvas width, canvas height).
|
|
88
88
|
// viewU[7] = (grade offset.rgb, contrast); viewU[8] = (grade power.rgb, saturation);
|
|
89
89
|
// viewU[9] = (grade slope.rgb, grade on/off) — see grade() below.
|
|
90
90
|
// viewU[10] = (camera world position, _) — refreshed with the basis above.
|
|
@@ -104,6 +104,9 @@ override APPLY_GAMMA: bool = true;
|
|
|
104
104
|
// track the camera radius. Cleared depth (1.0) inverts to the far
|
|
105
105
|
// plane, so empty sky reads as maximally defocused background.
|
|
106
106
|
@group(0) @binding(9) var<uniform> dofU: array<vec4<f32>, 3>;
|
|
107
|
+
// Blender's AgX, as the 57³ lookup it ships as rather than a reconstruction of
|
|
108
|
+
// it. Sampled in the log-encoded E-Gamut space the cube expects — see agxTransform.
|
|
109
|
+
@group(0) @binding(10) var agxLut: texture_3d<f32>;
|
|
107
110
|
|
|
108
111
|
// Must match FILMIC_LUT_WIDTH in engine.ts (bakeFilmicLut).
|
|
109
112
|
const FILMIC_LUT_W: f32 = 256.0;
|
|
@@ -147,6 +150,58 @@ fn filmic(x: f32) -> f32 {
|
|
|
147
150
|
return textureSampleLevel(filmicLut, bloomSamp, vec2f(u, 0.5), 0.0).r;
|
|
148
151
|
}
|
|
149
152
|
|
|
153
|
+
/** The sRGB display encoding — Blender's "Standard" view transform, which is what
|
|
154
|
+
* NPR work uses: no film curve at all, so the colours a graph computes are the
|
|
155
|
+
* colours that land. Not a 2.2 power law; sRGB has a linear toe. */
|
|
156
|
+
fn srgb_encode(x: f32) -> f32 {
|
|
157
|
+
let c = max(x, 0.0);
|
|
158
|
+
return select(1.055 * pow(c, 1.0 / 2.4) - 0.055, c * 12.92, c <= 0.0031308);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* AgX, the chain config.ocio states for "AgX Base Rec.1886" on an sRGB display:
|
|
163
|
+
*
|
|
164
|
+
* scene-linear Rec.709 → 3x3 into FilmLight E-Gamut
|
|
165
|
+
* → log2 across 25 stops, [-12.47393, +12.5261] → 0..1
|
|
166
|
+
* → the 57³ cube
|
|
167
|
+
* → Rec.1886 (pure γ2.4) decoded, then re-encoded as sRGB for the swapchain
|
|
168
|
+
*
|
|
169
|
+
* The last step is not pedantry: Rec.1886 is a pure power law and sRGB has a
|
|
170
|
+
* linear toe, so skipping it lifts the darkest few code values.
|
|
171
|
+
*
|
|
172
|
+
* Blender interpolates the cube tetrahedrally and a GPU sampler is trilinear.
|
|
173
|
+
* The difference is small and confined to saturated gradients; if it ever shows,
|
|
174
|
+
* tetrahedral is a dozen lines here.
|
|
175
|
+
*/
|
|
176
|
+
fn agxTransform(c: vec3f) -> vec3f {
|
|
177
|
+
let m = mat3x3<f32>(
|
|
178
|
+
vec3f(0.55937113, 0.07622071, 0.06552670),
|
|
179
|
+
vec3f(0.30478326, 0.78797183, 0.16454675),
|
|
180
|
+
vec3f(0.13584556, 0.13580748, 0.76992653),
|
|
181
|
+
);
|
|
182
|
+
let e = m * max(c, vec3f(0.0));
|
|
183
|
+
// The cube's domain: an unlit pixel would take log2 to -inf, so floor it at
|
|
184
|
+
// the bottom stop rather than sampling outside the LUT.
|
|
185
|
+
let t = clamp((log2(max(e, vec3f(1e-10))) + vec3f(12.47393)) / 25.0, vec3f(0.0), vec3f(1.0));
|
|
186
|
+
// Half-texel inset, so the end stops are the cube's own values and not a blend
|
|
187
|
+
// with the clamp-to-edge border.
|
|
188
|
+
let n = 57.0;
|
|
189
|
+
let uvw = t * ((n - 1.0) / n) + (0.5 / n);
|
|
190
|
+
let formed = textureSampleLevel(agxLut, bloomSamp, uvw, 0.0).rgb;
|
|
191
|
+
let linear = pow(max(formed, vec3f(0.0)), vec3f(2.4));
|
|
192
|
+
return vec3f(srgb_encode(linear.r), srgb_encode(linear.g), srgb_encode(linear.b));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Which display transform, chosen per frame at viewU[6].y (0 filmic, 1 standard, 2 agx).
|
|
196
|
+
* A uniform branch rather than a pipeline variant: switching is rare, and both
|
|
197
|
+
* arms are cheap enough that specialising the pipeline would buy nothing. */
|
|
198
|
+
fn viewTransform(c: vec3f) -> vec3f {
|
|
199
|
+
let mode = viewU[6].y;
|
|
200
|
+
if (mode > 1.5) { return agxTransform(c); }
|
|
201
|
+
if (mode > 0.5) { return vec3f(srgb_encode(c.r), srgb_encode(c.g), srgb_encode(c.b)); }
|
|
202
|
+
return vec3f(filmic(c.r), filmic(c.g), filmic(c.b));
|
|
203
|
+
}
|
|
204
|
+
|
|
150
205
|
/** Canvas size in pixels — for user effects (aspect correction). */
|
|
151
206
|
fn bgResolution() -> vec2f { return viewU[6].zw; }
|
|
152
207
|
|
|
@@ -260,8 +315,7 @@ const COMPOSITE_BODY = /* wgsl */ `
|
|
|
260
315
|
let sceneStraight = scenePm.rgb / max(sceneAlpha, 1e-6);
|
|
261
316
|
|
|
262
317
|
let exposed = sceneStraight * exp2(viewU[0].x);
|
|
263
|
-
|
|
264
|
-
var disp = max(tm, vec3f(0.0));
|
|
318
|
+
var disp = max(viewTransform(exposed), vec3f(0.0));
|
|
265
319
|
// Grade the SCENE only, before the display gamma. Deliberately not applied to
|
|
266
320
|
// the background: it keeps a picked background color exactly as picked, and —
|
|
267
321
|
// load-bearing — leaves green-screen mode's key color unshifted so chroma
|