reze-engine 0.11.2 → 0.11.3
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 +4 -2
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +58 -426
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/shaders/body.d.ts +1 -1
- package/dist/shaders/body.d.ts.map +1 -1
- package/dist/shaders/body.js +7 -28
- package/dist/shaders/cloth_rough.d.ts +1 -1
- package/dist/shaders/cloth_rough.d.ts.map +1 -1
- package/dist/shaders/cloth_rough.js +4 -16
- package/dist/shaders/cloth_smooth.d.ts +1 -1
- package/dist/shaders/cloth_smooth.d.ts.map +1 -1
- package/dist/shaders/cloth_smooth.js +5 -17
- package/dist/shaders/default.d.ts +1 -1
- package/dist/shaders/default.d.ts.map +1 -1
- package/dist/shaders/eye.d.ts +1 -1
- package/dist/shaders/eye.d.ts.map +1 -1
- package/dist/shaders/face.d.ts +1 -1
- package/dist/shaders/face.d.ts.map +1 -1
- package/dist/shaders/face.js +21 -57
- package/dist/shaders/hair.d.ts +1 -1
- package/dist/shaders/hair.d.ts.map +1 -1
- package/dist/shaders/hair.js +7 -27
- package/dist/shaders/materials/body.d.ts +2 -0
- package/dist/shaders/materials/body.d.ts.map +1 -0
- package/dist/shaders/materials/body.js +199 -0
- package/dist/shaders/materials/cloth_rough.d.ts +2 -0
- package/dist/shaders/materials/cloth_rough.d.ts.map +1 -0
- package/dist/shaders/materials/cloth_rough.js +178 -0
- package/dist/shaders/materials/cloth_smooth.d.ts +2 -0
- package/dist/shaders/materials/cloth_smooth.d.ts.map +1 -0
- package/dist/shaders/materials/cloth_smooth.js +174 -0
- package/dist/shaders/materials/default.d.ts +2 -0
- package/dist/shaders/materials/default.d.ts.map +1 -0
- package/dist/shaders/materials/default.js +171 -0
- package/dist/shaders/materials/eye.d.ts +2 -0
- package/dist/shaders/materials/eye.d.ts.map +1 -0
- package/dist/shaders/materials/eye.js +146 -0
- package/dist/shaders/materials/face.d.ts +2 -0
- package/dist/shaders/materials/face.d.ts.map +1 -0
- package/dist/shaders/materials/face.js +199 -0
- package/dist/shaders/materials/hair.d.ts +2 -0
- package/dist/shaders/materials/hair.d.ts.map +1 -0
- package/dist/shaders/materials/hair.js +176 -0
- package/dist/shaders/materials/metal.d.ts +2 -0
- package/dist/shaders/materials/metal.d.ts.map +1 -0
- package/dist/shaders/materials/metal.js +183 -0
- package/dist/shaders/materials/nodes.d.ts +2 -0
- package/dist/shaders/materials/nodes.d.ts.map +1 -0
- package/{src/shaders/nodes.ts → dist/shaders/materials/nodes.js} +32 -16
- package/dist/shaders/materials/stockings.d.ts +2 -0
- package/dist/shaders/materials/stockings.d.ts.map +1 -0
- package/dist/shaders/materials/stockings.js +244 -0
- package/dist/shaders/metal.d.ts +1 -1
- package/dist/shaders/metal.d.ts.map +1 -1
- package/dist/shaders/metal.js +4 -17
- package/dist/shaders/nodes.d.ts +1 -1
- package/dist/shaders/nodes.d.ts.map +1 -1
- package/dist/shaders/nodes.js +0 -9
- package/dist/shaders/passes/bloom.d.ts +4 -0
- package/dist/shaders/passes/bloom.d.ts.map +1 -0
- package/dist/shaders/passes/bloom.js +117 -0
- package/dist/shaders/passes/composite.d.ts +2 -0
- package/dist/shaders/passes/composite.d.ts.map +1 -0
- package/dist/shaders/passes/composite.js +61 -0
- package/dist/shaders/passes/ground.d.ts +2 -0
- package/dist/shaders/passes/ground.d.ts.map +1 -0
- package/dist/shaders/passes/ground.js +93 -0
- package/dist/shaders/passes/mipmap.d.ts +2 -0
- package/dist/shaders/passes/mipmap.d.ts.map +1 -0
- package/dist/shaders/passes/mipmap.js +16 -0
- package/dist/shaders/passes/outline.d.ts +2 -0
- package/dist/shaders/passes/outline.d.ts.map +1 -0
- package/dist/shaders/passes/outline.js +83 -0
- package/dist/shaders/passes/pick.d.ts +2 -0
- package/dist/shaders/passes/pick.d.ts.map +1 -0
- package/dist/shaders/passes/pick.js +39 -0
- package/dist/shaders/passes/shadow.d.ts +2 -0
- package/dist/shaders/passes/shadow.d.ts.map +1 -0
- package/dist/shaders/passes/shadow.js +16 -0
- package/dist/shaders/stockings.d.ts +1 -1
- package/dist/shaders/stockings.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/engine.ts +93 -438
- package/src/index.ts +3 -2
- package/src/shaders/{body.ts → materials/body.ts} +7 -28
- package/src/shaders/{cloth_rough.ts → materials/cloth_rough.ts} +4 -16
- package/src/shaders/{cloth_smooth.ts → materials/cloth_smooth.ts} +5 -17
- package/src/shaders/{face.ts → materials/face.ts} +21 -57
- package/src/shaders/{hair.ts → materials/hair.ts} +7 -27
- package/src/shaders/{metal.ts → materials/metal.ts} +15 -19
- package/src/shaders/materials/nodes.ts +483 -0
- package/src/shaders/passes/bloom.ts +121 -0
- package/src/shaders/passes/composite.ts +62 -0
- package/src/shaders/passes/ground.ts +94 -0
- package/src/shaders/passes/mipmap.ts +17 -0
- package/src/shaders/passes/outline.ts +84 -0
- package/src/shaders/passes/pick.ts +40 -0
- package/src/shaders/passes/shadow.ts +17 -0
- package/src/shaders/classify.ts +0 -25
- /package/src/shaders/{default.ts → materials/default.ts} +0 -0
- /package/src/shaders/{eye.ts → materials/eye.ts} +0 -0
- /package/src/shaders/{stockings.ts → materials/stockings.ts} +0 -0
|
@@ -71,11 +71,10 @@ fn sampleShadow(worldPos: vec3f, n: vec3f) -> f32 {
|
|
|
71
71
|
|
|
72
72
|
const PI_B: f32 = 3.141592653589793;
|
|
73
73
|
const BODY_ROUGHNESS: f32 = 0.3;
|
|
74
|
-
// Dump: 层权重.002 Blend; 运算.007 POWER exponent Value_001; 背景 Color; 运算.004 after invert
|
|
75
74
|
const BODY_RIM2_LAYER_BLEND: f32 = 0.20000000298023224;
|
|
76
75
|
const BODY_RIM2_POW: f32 = 1.4300000667572021;
|
|
77
76
|
const BODY_RIM2_BG: vec3f = vec3f(1.0, 0.4303792119026184, 0.3315804898738861);
|
|
78
|
-
const
|
|
77
|
+
const BODY_WARM_STR: f32 = 0.30000001192092896;
|
|
79
78
|
const BODY_SPECULAR: f32 = 0.5;
|
|
80
79
|
const BODY_MIX_NPR: f32 = 0.5;
|
|
81
80
|
// EEVEE Light Clamp equivalent — caps firefly specular from noise-bumped NDF aliasing.
|
|
@@ -133,49 +132,33 @@ struct FSOut {
|
|
|
133
132
|
let tex_color = textureSample(diffuseTexture, diffuseSampler, input.uv).rgb;
|
|
134
133
|
let shadow = sampleShadow(input.worldPos, n);
|
|
135
134
|
|
|
136
|
-
// ═══ TOON MASK: ShaderToRGB → ramp.008 CONSTANT [0→black, 0.2966→white] ═══
|
|
137
135
|
let ndotl_raw = shader_to_rgb_diffuse(n, l, sun, light.ambientColor.xyz, shadow);
|
|
138
136
|
let toon = ramp_constant(ndotl_raw, 0.0, vec4f(0,0,0,1), 0.2966, vec4f(1,1,1,1)).r;
|
|
139
137
|
|
|
140
|
-
// ═══ TOON COLOR: Mix.004 A=HueSat, B=HueSat.001, Fac=ramp.008 (R) ═══
|
|
141
138
|
let shadow_tint = hue_sat_id(2.0, 0.3499999940395355, 1.0, tex_color);
|
|
142
139
|
let lit_tint = hue_sat_id(1.5, 1.0, 1.0, tex_color);
|
|
143
140
|
let toon_color = mix_blend(toon, shadow_tint, lit_tint);
|
|
144
141
|
let bc = bright_contrast(toon_color, 0.1, 0.2);
|
|
145
142
|
|
|
146
|
-
|
|
147
|
-
let ao = 1.0; // ao_fake(n, v) — no SSAO yet; inline 1.0 so the ramp/mix chain folds at compile time.
|
|
148
|
-
let ao_ramp = ramp_constant(ao, 0.0, vec4f(1,1,1,1), 0.5995, vec4f(0,0,0,1)).r;
|
|
149
|
-
let ao_mixed = mix_blend(ao_ramp, bc, vec3f(0.8301780223846436, 0.3345769941806793, 0.27946099638938904));
|
|
143
|
+
let emission3 = bc * 4.0;
|
|
150
144
|
|
|
151
|
-
// ═══ EMISSION.003 (strength=4.0) ═══
|
|
152
|
-
let emission3 = ao_mixed * 4.0;
|
|
153
|
-
|
|
154
|
-
// ═══ WARM: 颜色渐变.008 → 运算.006 ADD +0.5 (m_graphs) → clamp → 颜色渐变.003 ═══
|
|
155
|
-
let ao_inv = invert_f(1.0, ao_ramp);
|
|
156
|
-
let warm_str = ao_inv * BODY_WARM_AO_MUL;
|
|
157
145
|
let warm_input = clamp(toon + 0.5, 0.0, 1.0);
|
|
158
146
|
let warm_color = ramp_cardinal(warm_input, 0.2409,
|
|
159
147
|
vec4f(0.2426, 0.068, 0.0588, 1.0), 0.4663,
|
|
160
148
|
vec4f(0.6677, 0.5024, 0.5126, 1.0)).rgb;
|
|
161
|
-
let warm_emission = warm_color *
|
|
149
|
+
let warm_emission = warm_color * BODY_WARM_STR;
|
|
162
150
|
|
|
163
|
-
// ═══ RIM 1: 菲涅尔 × 层权重.001 Facing Blend=0.24 → 自发光 Strength ═══
|
|
164
151
|
let rim1_str = fresnel(2.0, n, v) * layer_weight_facing(0.24000005424022675, n, v);
|
|
165
152
|
let rim1 = vec3f(0.984157919883728, 0.6110184788703918, 0.5736401677131653) * rim1_str;
|
|
166
153
|
|
|
167
|
-
// ═══ RIM 2: 层权重.002 Facing → 运算.007 POWER → 颜色渐变.010 EASE → MixShader.002 Fac ═══
|
|
168
154
|
let facing_raw = layer_weight_facing(BODY_RIM2_LAYER_BLEND, n, v);
|
|
169
155
|
let facing_pow = math_power(facing_raw, BODY_RIM2_POW);
|
|
170
156
|
let rim2_fac = ramp_ease(facing_pow, 0.0, vec4f(0,0,0,1), 0.5052, vec4f(1,1,1,1)).r;
|
|
171
157
|
let rim2_mixed = mix(emission3, BODY_RIM2_BG, rim2_fac);
|
|
172
158
|
|
|
173
|
-
|
|
174
|
-
let add0 = rim1 + rim2_mixed;
|
|
175
|
-
let npr_stack = add0 + warm_emission;
|
|
159
|
+
let npr_stack = rim1 + rim2_mixed + warm_emission;
|
|
176
160
|
|
|
177
|
-
//
|
|
178
|
-
// Mapping loc=rot=0 → plain scale multiply, inline.
|
|
161
|
+
// Noise bump — Mapping loc=rot=0 folds to a plain scale multiply.
|
|
179
162
|
let noise_val = tex_noise_d2(input.worldPos * vec3f(1.0, 1.0, 1.5), 1.0);
|
|
180
163
|
let noise_ramp = ramp_linear(noise_val, 0.0, vec4f(0,0,0,1), 1.0, vec4f(1,1,1,1)).r;
|
|
181
164
|
let bumped_n = bump_lh(0.324644535779953, noise_ramp, n, input.worldPos);
|
|
@@ -183,10 +166,7 @@ struct FSOut {
|
|
|
183
166
|
let principled_base = mix_blend(noise_ramp, bc, vec3f(0.6831911206245422, 0.19474034011363983, 0.13732507824897766));
|
|
184
167
|
let p_emission = bc * 0.2;
|
|
185
168
|
|
|
186
|
-
//
|
|
187
|
-
let sss = ramp_linear(ao, 0.003, vec4f(0,0,0,1), 1.0, vec4f(0.0786, 0.0786, 0.0786, 1.0)).r;
|
|
188
|
-
|
|
189
|
-
// 原理化BSDF (EEVEE port): metallic=0, specular=0.5, roughness=0.3, specular_tint=0.
|
|
169
|
+
// Principled BSDF (EEVEE port): metallic=0, specular=0.5, roughness=0.3, specular_tint=0.
|
|
190
170
|
let NL = max(dot(bumped_n, l), 0.0);
|
|
191
171
|
let NV = max(dot(bumped_n, v), 1e-4);
|
|
192
172
|
|
|
@@ -208,9 +188,8 @@ struct FSOut {
|
|
|
208
188
|
// probe_evaluate_world_diff returns radiance (SH-projected, not cosine-convolved).
|
|
209
189
|
// No (1-F) factor per EEVEE — it doesn't energy-conserve spec<->diffuse.
|
|
210
190
|
let diffuse_radiance = principled_base * (sun * NL * shadow / PI_B + light.ambientColor.xyz);
|
|
211
|
-
let principled = diffuse_radiance + spec_radiance + p_emission
|
|
191
|
+
let principled = diffuse_radiance + spec_radiance + p_emission;
|
|
212
192
|
|
|
213
|
-
// 混合着色器.001: Shader=相加着色器.001, Shader_001=原理化BSDF
|
|
214
193
|
let final_color = mix(npr_stack, principled, BODY_MIX_NPR);
|
|
215
194
|
|
|
216
195
|
var out: FSOut;
|
|
@@ -128,34 +128,22 @@ struct FSOut {
|
|
|
128
128
|
let out_alpha = material.alpha * tex_s.a;
|
|
129
129
|
if (out_alpha < 0.001) { discard; }
|
|
130
130
|
|
|
131
|
-
// Shader→RGB → 颜色渐变.008 CONSTANT (edge AA terminator)
|
|
132
131
|
let lum_shade = shader_to_rgb_diffuse(n, l, sun, amb, shadow);
|
|
132
|
+
// ramp_constant_edge_aa: avoids binary fac shimmer on terminator (fwidth + smoothstep).
|
|
133
133
|
let ramp008 = ramp_constant_edge_aa(lum_shade, CLOTH_R_TOON_EDGE, vec4f(0,0,0,1), vec4f(1,1,1,1));
|
|
134
|
-
let
|
|
135
|
-
let mix04_fac = math_multiply(toon_r, CLOTH_R_MIX04_MUL);
|
|
134
|
+
let mix04_fac = math_multiply(ramp008.r, CLOTH_R_MIX04_MUL);
|
|
136
135
|
|
|
137
|
-
// 混合.004: A=色相/饱和度/明度.002(Hue=0.5 Sat=1.0 Val=0.2), B=纹理
|
|
138
136
|
let dark_tex = hue_sat_id(1.0, 0.19999998807907104, 1.0, tex_rgb);
|
|
139
137
|
let mix04 = mix_blend(mix04_fac, dark_tex, tex_rgb);
|
|
140
138
|
|
|
141
|
-
// 倒角.001.Z → 混合.003: A=混合.004, B=色相/饱和度/明度.002
|
|
142
139
|
let bevel_z = clamp(n.y, 0.0, 1.0);
|
|
143
140
|
let mix03 = mix_blend(bevel_z, mix04, dark_tex);
|
|
144
141
|
|
|
145
|
-
// 环境光遮蔽 → 颜色渐变.001 LINEAR → 混合.001 (white/black) → 混合.002 OVERLAY Fac
|
|
146
|
-
let ao = 1.0; // ao_fake(n, v) — no SSAO yet; inline 1.0 so the ramp/mix chain folds at compile time.
|
|
147
|
-
let ao_ramp_c = ramp_linear(ao, 0.0, vec4f(1,1,1,1), 0.8808, vec4f(0,0,0,1));
|
|
148
|
-
let mix01_fac = ao_ramp_c.r;
|
|
149
|
-
let mix01_rgb = mix(vec3f(1.0), vec3f(0.0), mix01_fac);
|
|
150
|
-
|
|
151
|
-
// 混合.002 OVERLAY: Fac=混合.001, A=混合.003, B=色相/饱和度/明度.004
|
|
152
142
|
let hue004 = hue_sat_id(0.800000011920929, 2.0, 1.0, mix03);
|
|
153
|
-
let
|
|
154
|
-
let npr_rgb = mix_overlay(overlay_fac, mix03, hue004);
|
|
143
|
+
let npr_rgb = mix_overlay(1.0, mix03, hue004);
|
|
155
144
|
let npr_emission = npr_rgb * CLOTH_R_EMIT_STR;
|
|
156
145
|
|
|
157
|
-
//
|
|
158
|
-
// mapping scale=(1,1,1), loc=rot=0 → identity; use worldPos directly.
|
|
146
|
+
// Noise bump is LIVE in M_Rough_Cloth — unlike Smooth Cloth where the subtree is dead.
|
|
159
147
|
let noise_val = tex_noise_d2(input.worldPos, CLOTH_R_NOISE_SCALE);
|
|
160
148
|
let noise_ramp = ramp_linear(noise_val, 0.0, vec4f(0,0,0,1), 1.0, vec4f(1,1,1,1)).r;
|
|
161
149
|
let bumped_n = bump_lh(CLOTH_R_BUMP_STR, noise_ramp, n, input.worldPos);
|
|
@@ -123,35 +123,23 @@ struct FSOut {
|
|
|
123
123
|
let out_alpha = material.alpha * tex_s.a;
|
|
124
124
|
if (out_alpha < 0.001) { discard; }
|
|
125
125
|
|
|
126
|
-
// Shader→RGB → 颜色渐变.008 CONSTANT — AA like face (same terminator artifact class)
|
|
127
126
|
let lum_shade = shader_to_rgb_diffuse(n, l, sun, amb, shadow);
|
|
127
|
+
// ramp_constant_edge_aa: avoids binary fac shimmer on terminator (fwidth + smoothstep).
|
|
128
128
|
let ramp008 = ramp_constant_edge_aa(lum_shade, CLOTH_TOON_EDGE, vec4f(0,0,0,1), vec4f(1,1,1,1));
|
|
129
|
-
let
|
|
130
|
-
// 颜色渐变.008 → 运算.004 MULTIPLY 0.5 → 混合.004 Factor
|
|
131
|
-
let mix04_fac = math_multiply(toon_r, CLOTH_MIX04_MUL);
|
|
129
|
+
let mix04_fac = math_multiply(ramp008.r, CLOTH_MIX04_MUL);
|
|
132
130
|
|
|
133
|
-
// 混合.004: A=色相/饱和度/明度.002, B=纹理
|
|
134
131
|
let dark_tex = hue_sat_id(1.0, 0.19999998807907104, 1.0, tex_rgb);
|
|
135
132
|
let mix04 = mix_blend(mix04_fac, dark_tex, tex_rgb);
|
|
136
133
|
|
|
137
|
-
// 倒角.001→Z → 混合.003 Factor; A=混合.004, B=色相/饱和度/明度.002
|
|
138
134
|
let bevel_z = clamp(n.y, 0.0, 1.0);
|
|
139
135
|
let mix03 = mix_blend(bevel_z, mix04, dark_tex);
|
|
140
136
|
|
|
141
|
-
// 环境光遮蔽 → 颜色渐变.001 LINEAR → 混合.001 (白/黑) → 混合.002 OVERLAY Fac
|
|
142
|
-
let ao = 1.0; // ao_fake(n, v) — no SSAO yet; inline 1.0 so the ramp/mix chain folds at compile time.
|
|
143
|
-
let ao_ramp_c = ramp_linear(ao, 0.0, vec4f(1,1,1,1), 0.8808, vec4f(0,0,0,1));
|
|
144
|
-
let mix01_fac = ao_ramp_c.r;
|
|
145
|
-
let mix01_rgb = mix(vec3f(1.0), vec3f(0.0), mix01_fac);
|
|
146
|
-
|
|
147
|
-
// 混合.002 OVERLAY: Fac=混合.001, A=混合.003, B=色相/饱和度/明度.004
|
|
148
137
|
let hue004 = hue_sat_id(0.800000011920929, 2.0, 1.0, mix03);
|
|
149
|
-
let
|
|
150
|
-
let npr_rgb = mix_overlay(overlay_fac, mix03, hue004);
|
|
138
|
+
let npr_rgb = mix_overlay(1.0, mix03, hue004);
|
|
151
139
|
let npr_emission = npr_rgb * NPR_EMIT_STR;
|
|
152
140
|
|
|
153
|
-
//
|
|
154
|
-
// Bump subtree is dead in the Blender graph (
|
|
141
|
+
// Principled BSDF (EEVEE port): metallic=0, specular=0.8, roughness=0.5, specular_tint=0.
|
|
142
|
+
// Bump subtree is dead in the Blender graph (noise→bump not linked to Principled.Normal).
|
|
155
143
|
let principled_base = hue_sat_id(1.0, 0.800000011920929, 1.0, tex_rgb);
|
|
156
144
|
let NL = max(dot(n, l), 0.0);
|
|
157
145
|
let NV = max(dot(n, v), 1e-4);
|
|
@@ -73,12 +73,11 @@ fn sampleShadow(worldPos: vec3f, n: vec3f) -> f32 {
|
|
|
73
73
|
const PI_F: f32 = 3.141592653589793;
|
|
74
74
|
const FACE_SPECULAR: f32 = 0.5;
|
|
75
75
|
const FACE_ROUGHNESS: f32 = 0.3;
|
|
76
|
-
// Dump M_Face unlinked defaults (math op enum not serialized — warm clamp chain still from m_graphs)
|
|
77
76
|
const FACE_RIM2_POW: f32 = 0.6300000548362732;
|
|
78
77
|
const FACE_RIM2_BG: vec3f = vec3f(1.0, 0.4684903025627136, 0.3698573112487793);
|
|
79
|
-
const
|
|
80
|
-
const FACE_BRIGHT_TEX_THRESH: f32 = 0.9300000071525574;
|
|
81
|
-
const FACE_MIX_NPR: f32 = 0.5;
|
|
78
|
+
const FACE_WARM_STR: f32 = 0.30000001192092896;
|
|
79
|
+
const FACE_BRIGHT_TEX_THRESH: f32 = 0.9300000071525574;
|
|
80
|
+
const FACE_MIX_NPR: f32 = 0.5;
|
|
82
81
|
// EEVEE Light Clamp equivalent (Render Props → Sampling → Clamping). Caps direct
|
|
83
82
|
// specular firefly from the noise-bumped normal's NDF aliasing — Blender hides this
|
|
84
83
|
// via TAA, which we don't have. Value mirrors EEVEE's default Clamp Indirect=10.0.
|
|
@@ -112,10 +111,6 @@ const FACE_SPEC_CLAMP: f32 = 10.0;
|
|
|
112
111
|
return output;
|
|
113
112
|
}
|
|
114
113
|
|
|
115
|
-
// Fragment: M_Face NPR + Principled hybrid
|
|
116
|
-
// TEX → HueSat shadow/lit → toon gate → BrightContrast → AO chain → emission stack
|
|
117
|
-
// Fresnel rims, warm AO emission, bright-texture gate, noise-bumped Principled
|
|
118
|
-
// Final = mix(Principled, NPR, 0.5)
|
|
119
114
|
struct FSOut {
|
|
120
115
|
@location(0) color: vec4f,
|
|
121
116
|
@location(1) mask: f32,
|
|
@@ -134,79 +129,49 @@ struct FSOut {
|
|
|
134
129
|
let tex_color = textureSample(diffuseTexture, diffuseSampler, input.uv).rgb;
|
|
135
130
|
let shadow = sampleShadow(input.worldPos, n);
|
|
136
131
|
|
|
137
|
-
// ═══ SOURCES ═══
|
|
138
|
-
// DiffuseBSDF(white) → ShaderToRGB (energy-matched); shadow on direct only
|
|
139
132
|
let ndotl_raw = shader_to_rgb_diffuse(n, l, sun, light.ambientColor.xyz, shadow);
|
|
140
|
-
//
|
|
133
|
+
// ramp_constant_edge_aa: avoids binary fac shimmer on terminator (fwidth + smoothstep).
|
|
141
134
|
let toon = ramp_constant_edge_aa(ndotl_raw, 0.2966, vec4f(0,0,0,1), vec4f(1,1,1,1)).r;
|
|
142
|
-
let ao = 1.0; // ao_fake(n, v) — no SSAO yet; inline 1.0 so the ramp/mix chain folds at compile time.
|
|
143
135
|
|
|
144
|
-
|
|
145
|
-
let
|
|
146
|
-
let
|
|
147
|
-
let toon_color = mix_blend(toon, shadow_tint, lit_tint); // Mix.004
|
|
136
|
+
let shadow_tint = hue_sat(0.46000000834465027, 2.0, 0.3499999940395355, 1.0, tex_color);
|
|
137
|
+
let lit_tint = hue_sat(0.46000000834465027, 1.600000023841858, 1.5, 1.0, tex_color);
|
|
138
|
+
let toon_color = mix_blend(toon, shadow_tint, lit_tint);
|
|
148
139
|
let bc = bright_contrast(toon_color, 0.1, 0.2);
|
|
149
140
|
|
|
150
|
-
|
|
151
|
-
// ramp CONSTANT [0→white, 0.5995→black]
|
|
152
|
-
let ao_ramp = ramp_constant(ao, 0.0, vec4f(1,1,1,1), 0.5995, vec4f(0,0,0,1)).r;
|
|
153
|
-
// Mix.003(Factor=ao_ramp, A=bc, B=reddish tint)
|
|
154
|
-
let ao_mixed = mix_blend(ao_ramp, bc, vec3f(0.8302, 0.3346, 0.2795));
|
|
141
|
+
let emission3 = bc * 2.5;
|
|
155
142
|
|
|
156
|
-
|
|
157
|
-
let emission3 = ao_mixed * 2.5; // Emission.003(Strength=2.5)
|
|
158
|
-
|
|
159
|
-
// ═══ WARM EMISSION ═══
|
|
160
|
-
let ao_inv = invert_f(1.0, ao_ramp);
|
|
161
|
-
let warm_str = ao_inv * FACE_WARM_AO_MUL; // 反转 → 运算.004 MULTIPLY Value_001
|
|
162
|
-
let warm_input = clamp(toon * 0.5 + 0.5, 0.0, 1.0); // 运算.001→运算.006→Clamp
|
|
163
|
-
// ramp.003 CARDINAL [0.2409→warm dark, 0.4663→warm light]
|
|
143
|
+
let warm_input = clamp(toon * 0.5 + 0.5, 0.0, 1.0);
|
|
164
144
|
let warm_color = ramp_cardinal(warm_input, 0.2409,
|
|
165
145
|
vec4f(0.2426, 0.068, 0.0588, 1.0), 0.4663,
|
|
166
146
|
vec4f(0.6677, 0.5024, 0.5126, 1.0)).rgb;
|
|
167
|
-
let warm_emission = warm_color *
|
|
147
|
+
let warm_emission = warm_color * FACE_WARM_STR;
|
|
168
148
|
|
|
169
|
-
// ═══ RIM 1 ═══
|
|
170
|
-
// Fresnel(IOR=2.0) × LayerWeight.001(Facing, Blend=0.24)
|
|
171
149
|
let rim1_str = fresnel(2.0, n, v) * layer_weight_facing(0.24, n, v);
|
|
172
150
|
let rim1 = vec3f(0.984157919883728, 0.6110184788703918, 0.5736401677131653) * rim1_str;
|
|
173
151
|
|
|
174
|
-
// ═══ RIM 2 ═══
|
|
175
|
-
// Fresnel.001(IOR=1.45) × LayerWeight.002(Fresnel output, Blend=0.61)
|
|
176
152
|
let rim2_raw = fresnel(1.45, n, v) * layer_weight_fresnel(0.61, n, v);
|
|
177
153
|
let rim2_fac = math_power(rim2_raw, FACE_RIM2_POW);
|
|
178
|
-
// MixShader.002: Shader=Emission.003, Shader_001=背景
|
|
179
154
|
let rim2_mixed = mix(emission3, FACE_RIM2_BG, rim2_fac);
|
|
180
155
|
|
|
181
|
-
//
|
|
182
|
-
//
|
|
183
|
-
//
|
|
184
|
-
//
|
|
185
|
-
//
|
|
186
|
-
// only fires on genuinely near-white painted features (the author's intent).
|
|
156
|
+
// Blender implicitly converts Color → Float via BT.601 grayscale when plugging a color
|
|
157
|
+
// output into a Math node's Value input. An earlier trace used tex_color.r, which fires
|
|
158
|
+
// aggressively on R-dominant skin — single near-white R pixels produced firefly speckles.
|
|
159
|
+
// color_to_value matches the Blender socket semantic and only fires on genuinely near-
|
|
160
|
+
// white painted features (the author's intent).
|
|
187
161
|
let tex_gate = math_greater_than(color_to_value(tex_color), FACE_BRIGHT_TEX_THRESH);
|
|
188
|
-
let bright_emit = vec3f(tex_gate) * 3.0;
|
|
162
|
+
let bright_emit = vec3f(tex_gate) * 3.0;
|
|
189
163
|
|
|
190
|
-
|
|
191
|
-
let add2 = rim2_mixed + bright_emit; // AddShader.002
|
|
192
|
-
let add0 = rim1 + add2; // AddShader
|
|
193
|
-
let npr_stack = add0 + warm_emission; // AddShader.001
|
|
164
|
+
let npr_stack = rim1 + rim2_mixed + bright_emit + warm_emission;
|
|
194
165
|
|
|
195
|
-
//
|
|
196
|
-
// Noise-based bump normal. Mapping loc=rot=0 → plain scale multiply, inline.
|
|
166
|
+
// Noise bump — Mapping loc=rot=0 folds to a plain scale multiply.
|
|
197
167
|
let noise_val = tex_noise_d2(input.worldPos * vec3f(1.0, 1.0, 1.5), 1.0);
|
|
198
168
|
let noise_ramp = ramp_linear(noise_val, 0.0, vec4f(0,0,0,1), 1.0, vec4f(1,1,1,1)).r;
|
|
199
|
-
let bumped_n = bump_lh(0.324644535779953, noise_ramp, n, input.worldPos);
|
|
169
|
+
let bumped_n = bump_lh(0.324644535779953, noise_ramp, n, input.worldPos);
|
|
200
170
|
|
|
201
|
-
// Mix.001(Factor=noise_ramp, A=bc, B=dark red)
|
|
202
171
|
let principled_base = mix_blend(noise_ramp, bc, vec3f(0.6832, 0.1947, 0.1373));
|
|
203
|
-
// Emission input from reroute.011 (bc), Strength=0.2
|
|
204
172
|
let p_emission = bc * 0.2;
|
|
205
|
-
// AO.002 → ramp.005 LINEAR [0.003→black, 1.0→gray] for subsurface approx.
|
|
206
|
-
// Reuse 'ao' (ao_fake(n, v) above) — identical inputs, avoid a second procedural AO pass.
|
|
207
|
-
let sss = ramp_linear(ao, 0.003, vec4f(0,0,0,1), 1.0, vec4f(0.0786, 0.0786, 0.0786, 1.0)).r;
|
|
208
173
|
|
|
209
|
-
//
|
|
174
|
+
// Principled BSDF (EEVEE port): metallic=0, specular=0.5, roughness=0.3, specular_tint=0.
|
|
210
175
|
let NL = max(dot(bumped_n, l), 0.0);
|
|
211
176
|
let NV = max(dot(bumped_n, v), 1e-4);
|
|
212
177
|
|
|
@@ -223,9 +188,8 @@ struct FSOut {
|
|
|
223
188
|
// Indirect diffuse = base_color × L_w per Blender closure_eval_surface_lib.glsl line 302;
|
|
224
189
|
// probe_evaluate_world_diff returns radiance (SH-projected, not cosine-convolved).
|
|
225
190
|
let diffuse_radiance = principled_base * (sun * NL * shadow / PI_F + light.ambientColor.xyz);
|
|
226
|
-
let principled = diffuse_radiance + spec_radiance + p_emission
|
|
191
|
+
let principled = diffuse_radiance + spec_radiance + p_emission;
|
|
227
192
|
|
|
228
|
-
// 混合着色器.001: Shader=相加着色器.001, Shader_001=原理化BSDF — Fac blends toward second
|
|
229
193
|
let final_color = mix(npr_stack, principled, FACE_MIX_NPR);
|
|
230
194
|
|
|
231
195
|
var out: FSOut;
|
|
@@ -73,7 +73,6 @@ fn sampleShadow(worldPos: vec3f, n: vec3f) -> f32 {
|
|
|
73
73
|
const PI_H: f32 = 3.141592653589793;
|
|
74
74
|
const HAIR_SPECULAR: f32 = 1.0;
|
|
75
75
|
const HAIR_ROUGHNESS: f32 = 0.3;
|
|
76
|
-
// Dump M_Hair: 运算.004 GREATER_THAN second operand Value_001; 运算.007 POWER exponent Value_001; 背景 Color
|
|
77
76
|
const HAIR_TEX_GATE_THRESH: f32 = 0.15000000596046448;
|
|
78
77
|
const HAIR_RIM2_POW: f32 = 0.6300000548362732;
|
|
79
78
|
const HAIR_MIX_BG: vec3f = vec3f(0.1673291176557541);
|
|
@@ -120,55 +119,37 @@ struct FSOut {
|
|
|
120
119
|
let l = -light.lights[0].direction.xyz;
|
|
121
120
|
let sun = light.lights[0].color.xyz * light.lights[0].color.w;
|
|
122
121
|
|
|
123
|
-
// 图像纹理 ← 纹理坐标.UV → 映射 (default 1,1,1 scale per JSON)
|
|
124
122
|
let tex_color = textureSample(diffuseTexture, diffuseSampler, input.uv).rgb;
|
|
125
123
|
let shadow = sampleShadow(input.worldPos, n);
|
|
126
124
|
|
|
127
|
-
// 色相/饱和度/明度 (Hue=0.5 Sat=1.2 Val=0.5 Fac=1) ← reroute from image
|
|
128
125
|
let hue_sat_shadow = hue_sat_id(1.2, 0.5, 1.0, tex_color);
|
|
129
|
-
// 色相/饱和度/明度.002 (0.48, 1.2, 0.7, 1) ← previous
|
|
130
126
|
let hue_sat_002 = hue_sat(0.48, 1.2, 0.7, 1.0, hue_sat_shadow);
|
|
131
|
-
// 色相/饱和度/明度.001 (0.5, 1.5, 1.0, 1) ← image reroute (lit path)
|
|
132
127
|
let hue_sat_001 = hue_sat_id(1.5, 1.0, 1.0, tex_color);
|
|
133
128
|
|
|
134
|
-
// 漫射 BSDF.002 → Shader --> RGB → 颜色渐变.008 CONSTANT [0→0, 0.2966→1]
|
|
135
129
|
let ndotl_raw = shader_to_rgb_diffuse(n, l, sun, light.ambientColor.xyz, shadow);
|
|
136
130
|
let ramp_008 = ramp_constant(ndotl_raw, 0.0, vec4f(0,0,0,1), 0.2966, vec4f(1,1,1,1)).r;
|
|
137
131
|
|
|
138
|
-
// 混合.004 MIX Fac=ramp_008, A=hue_sat_002, B=hue_sat_001
|
|
139
132
|
let mix_004 = mix_blend(ramp_008, hue_sat_002, hue_sat_001);
|
|
140
|
-
|
|
141
|
-
// 亮度/对比度 (Bright=0.1 Contrast=0.2) ← mix_004 only (links: not bevel path)
|
|
142
133
|
let bc = bright_contrast(mix_004, 0.1, 0.2);
|
|
143
134
|
|
|
144
|
-
// 倒角.001 → 分离 XYZ.001 → Z → 混合.003 Factor; A=bc, B=hue_sat_002
|
|
145
135
|
let bevel_z = clamp(n.y, 0.0, 1.0);
|
|
146
136
|
let mix_003 = mix_blend(bevel_z, bc, hue_sat_002);
|
|
147
137
|
|
|
148
|
-
// 环境光遮蔽 (AO).001 → 颜色渐变.001 → 混合.001 → 混合.002 chain collapses with fake AO=1:
|
|
149
|
-
// ramp_constant(1, 0→white, 0.3756→black).r = 0 → ao_factor = mix(1,0,0) = 1 → mix_002 = mix_003.
|
|
150
|
-
// hue_sat_004 becomes unreachable. When real SSAO lands, restore the original 5-line port.
|
|
151
|
-
let emission3 = mix_003; // Emission.003 Strength=1.0 (×1 omitted)
|
|
152
|
-
|
|
153
|
-
// 菲涅尔.001 × 层权重.002 → 运算.003 MULTIPLY → 运算.007 POWER(exponent Value_001) → MixShader.002 Fac
|
|
154
138
|
let rim2_raw = fresnel(1.45, n, v) * layer_weight_fresnel(0.61, n, v);
|
|
155
139
|
let rim2_fac = math_power(rim2_raw, HAIR_RIM2_POW);
|
|
156
|
-
|
|
157
|
-
let mix_shader_002 = mix(emission3, HAIR_MIX_BG, rim2_fac);
|
|
140
|
+
let mix_shader_002 = mix(mix_003, HAIR_MIX_BG, rim2_fac);
|
|
158
141
|
|
|
159
|
-
//
|
|
160
|
-
//
|
|
142
|
+
// Blender's GREATER_THAN converts Color→Float via BT.601 luminance, not raw R — same
|
|
143
|
+
// socket-semantic fix as M_Face.
|
|
161
144
|
let tex_gate = math_greater_than(color_to_value(tex_color), HAIR_TEX_GATE_THRESH);
|
|
162
145
|
let gate_emit = vec3f(tex_gate) * 0.1;
|
|
163
146
|
|
|
164
|
-
// 相加着色器: MixShader.002 + gate emission (color sum in linear space)
|
|
165
147
|
let add_shader = mix_shader_002 + gate_emit;
|
|
166
148
|
|
|
167
|
-
//
|
|
168
|
-
//
|
|
169
|
-
// weights Principled at only 0.2
|
|
170
|
-
//
|
|
171
|
-
// tex_noise + bump_lh per hair fragment.
|
|
149
|
+
// Principled BSDF (EEVEE port): metallic=0, specular=1.0, roughness=0.3, specular_tint=0.
|
|
150
|
+
// Graph has a noise→normal_map bump (Strength=0.1) on Principled.Normal, but MixShader.001
|
|
151
|
+
// weights Principled at only 0.2 — the bumped spec × that weight is imperceptible, so we
|
|
152
|
+
// drop the subtree and keep plain n (saves a tex_noise + bump_lh per hair fragment).
|
|
172
153
|
let NL = max(dot(n, l), 0.0);
|
|
173
154
|
let NV = max(dot(n, v), 1e-4);
|
|
174
155
|
|
|
@@ -186,7 +167,6 @@ struct FSOut {
|
|
|
186
167
|
let diffuse_radiance = bc * (sun * NL * shadow / PI_H + light.ambientColor.xyz);
|
|
187
168
|
let principled = diffuse_radiance + spec_radiance;
|
|
188
169
|
|
|
189
|
-
// 混合着色器.001 Fac=0.2: first socket=相加着色器, second=原理化BSDF
|
|
190
170
|
let final_color = mix(add_shader, principled, 0.2);
|
|
191
171
|
|
|
192
172
|
var out: FSOut;
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
// + NPR toon/AO emission stack (Strength=8.1), MixShader Fac=0.6967.
|
|
3
3
|
// Base color uses a Voronoi pattern sampled in reflection-coord space (Blender 纹理坐标.Reflection)
|
|
4
4
|
// to add subtle metallic sparkle variation. No Normal link in the graph.
|
|
5
|
+
//
|
|
6
|
+
// Graph's base color chain is: 纹理坐标.Reflection → 矢量运算.007(CROSS, Vec2=(0,1,0)) →
|
|
7
|
+
// 沃罗诺伊纹理(F1, Color out) → 颜色渐变(linear) → 混合.005. The dumper did not capture the
|
|
8
|
+
// VectorMath operation — CROSS is the assumed op based on the hardcoded (0,1,0) Vector_001
|
|
9
|
+
// constant (MULTIPLY would zero X/Z producing 1D bands; CROSS produces horizontal ring
|
|
10
|
+
// patterns consistent with metallic anisotropy).
|
|
5
11
|
|
|
6
12
|
import { NODES_WGSL } from "./nodes"
|
|
7
13
|
|
|
@@ -129,40 +135,30 @@ struct FSOut {
|
|
|
129
135
|
let out_alpha = material.alpha * tex_s.a;
|
|
130
136
|
if (out_alpha < 0.001) { discard; }
|
|
131
137
|
|
|
132
|
-
// ═══ NPR toon stack (图像 → HSV.007 Val=0.8 → 转接点.001) ═══
|
|
133
138
|
let tex_tint = hue_sat_id(1.0, 0.800000011920929, 1.0, tex_rgb);
|
|
134
139
|
let lum_shade = shader_to_rgb_diffuse(n, l, sun, amb, shadow);
|
|
135
140
|
let ramp008 = ramp_constant_edge_aa(lum_shade, METAL_TOON_EDGE, vec4f(0,0,0,1), vec4f(1,1,1,1));
|
|
136
141
|
let mix04_fac = math_multiply(ramp008.r, METAL_MIX04_MUL);
|
|
137
142
|
|
|
138
|
-
// 混合.004: A=HSV.002(Val=0.2 dark), B=tex_tint
|
|
139
143
|
let dark_tex = hue_sat_id(1.0, 0.19999998807907104, 1.0, tex_tint);
|
|
140
144
|
let mix04 = mix_blend(mix04_fac, dark_tex, tex_tint);
|
|
141
145
|
|
|
142
|
-
// AO white/black ramp → 混合.002 factor
|
|
143
|
-
let ao = 1.0; // ao_fake(n, v) — no SSAO yet; inline 1.0 so the ramp/mix chain folds at compile time.
|
|
144
|
-
let ao_ramp_c = ramp_linear(ao, 0.0, vec4f(1,1,1,1), 0.8808, vec4f(0,0,0,1));
|
|
145
|
-
let overlay_fac = mix(1.0, 0.0, ao_ramp_c.r);
|
|
146
|
-
|
|
147
|
-
// 混合.002 OVERLAY: A=HSV.008(Val=1.0 identity) ← mix04, B=HSV.004(Val=2.0 bright) ← mix04
|
|
148
|
-
let hue008 = mix04; // identity HSV
|
|
149
146
|
let hue004 = hue_sat_id(1.0, 2.0, 1.0, mix04);
|
|
150
|
-
let npr_rgb = mix_overlay(
|
|
147
|
+
let npr_rgb = mix_overlay(1.0, mix04, hue004);
|
|
151
148
|
let npr_emission = npr_rgb * METAL_EMIT_STR;
|
|
152
149
|
|
|
153
|
-
//
|
|
154
|
-
//
|
|
155
|
-
// 纹理坐标.Reflection → 矢量运算 → 沃罗诺伊(Scale=4.3) → 颜色渐变 → 混合.005
|
|
150
|
+
// Reflection-coord Voronoi produces the metallic sparkle variation.
|
|
151
|
+
// VALTORGB takes Color → Fac via Blender's BT.601 implicit color_to_value.
|
|
156
152
|
let refl_dir = reflect(-v, n);
|
|
157
|
-
let
|
|
158
|
-
let
|
|
159
|
-
|
|
153
|
+
let voro_input = cross(refl_dir, vec3f(0.0, 1.0, 0.0));
|
|
154
|
+
let voro_rgb = tex_voronoi_color(voro_input, METAL_VORONOI_SCALE);
|
|
155
|
+
let voro_scalar = color_to_value(voro_rgb);
|
|
156
|
+
let voro_ramp = ramp_linear(voro_scalar, 0.0, vec4f(0,0,0,1), 1.0, vec4f(1,1,1,1)).r;
|
|
160
157
|
let hue006 = hue_sat_id(1.5, 1.2999999523162842, 1.0, tex_tint);
|
|
161
158
|
let albedo = mix_blend(voro_ramp, vec3f(voro_ramp), hue006);
|
|
162
159
|
|
|
163
|
-
//
|
|
164
|
-
//
|
|
165
|
-
// metallic=1 this is just albedo (specular_tint is dielectric-only and ignored here).
|
|
160
|
+
// Principled BSDF (EEVEE port): metallic=1 collapses f0 = mix(dielectric, albedo, 1) = albedo;
|
|
161
|
+
// specular_tint is dielectric-only and ignored here.
|
|
166
162
|
let f0 = albedo;
|
|
167
163
|
let f90 = mix(f0, vec3f(1.0), sqrt(METAL_SPECULAR));
|
|
168
164
|
let NL = max(dot(n, l), 0.0);
|