reze-engine 0.10.2 → 0.11.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/README.md +72 -13
- package/dist/engine.d.ts +170 -34
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +1080 -308
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/shaders/body.d.ts +2 -0
- package/dist/shaders/body.d.ts.map +1 -0
- package/dist/shaders/body.js +209 -0
- package/dist/shaders/classify.d.ts +4 -0
- package/dist/shaders/classify.d.ts.map +1 -0
- package/dist/shaders/classify.js +12 -0
- package/dist/shaders/cloth_rough.d.ts +2 -0
- package/dist/shaders/cloth_rough.d.ts.map +1 -0
- package/dist/shaders/cloth_rough.js +172 -0
- package/dist/shaders/cloth_smooth.d.ts +2 -0
- package/dist/shaders/cloth_smooth.d.ts.map +1 -0
- package/dist/shaders/cloth_smooth.js +171 -0
- package/dist/shaders/default.d.ts +2 -0
- package/dist/shaders/default.d.ts.map +1 -0
- package/dist/shaders/default.js +168 -0
- package/dist/shaders/dfg_lut.d.ts +4 -0
- package/dist/shaders/dfg_lut.d.ts.map +1 -0
- package/dist/shaders/dfg_lut.js +125 -0
- package/dist/shaders/eye.d.ts +2 -0
- package/dist/shaders/eye.d.ts.map +1 -0
- package/dist/shaders/eye.js +142 -0
- package/dist/shaders/face.d.ts +2 -0
- package/dist/shaders/face.d.ts.map +1 -0
- package/dist/shaders/face.js +211 -0
- package/dist/shaders/hair.d.ts +2 -0
- package/dist/shaders/hair.d.ts.map +1 -0
- package/dist/shaders/hair.js +186 -0
- package/dist/shaders/ltc_mag_lut.d.ts +3 -0
- package/dist/shaders/ltc_mag_lut.d.ts.map +1 -0
- package/dist/shaders/ltc_mag_lut.js +1033 -0
- package/dist/shaders/metal.d.ts +2 -0
- package/dist/shaders/metal.d.ts.map +1 -0
- package/dist/shaders/metal.js +171 -0
- package/dist/shaders/nodes.d.ts +2 -0
- package/dist/shaders/nodes.d.ts.map +1 -0
- package/dist/shaders/nodes.js +423 -0
- package/dist/shaders/stockings.d.ts +2 -0
- package/dist/shaders/stockings.d.ts.map +1 -0
- package/dist/shaders/stockings.js +229 -0
- package/package.json +1 -1
- package/src/engine.ts +1281 -376
- package/src/index.ts +12 -2
- package/src/shaders/body.ts +211 -0
- package/src/shaders/classify.ts +25 -0
- package/src/shaders/cloth_rough.ts +174 -0
- package/src/shaders/cloth_smooth.ts +173 -0
- package/src/shaders/default.ts +169 -0
- package/src/shaders/dfg_lut.ts +127 -0
- package/src/shaders/eye.ts +143 -0
- package/src/shaders/face.ts +213 -0
- package/src/shaders/hair.ts +188 -0
- package/src/shaders/ltc_mag_lut.ts +1035 -0
- package/src/shaders/metal.ts +173 -0
- package/src/shaders/nodes.ts +424 -0
- package/src/shaders/stockings.ts +231 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// M_Hair — WGSL trace of 仿深空之眼渲染预设v1.0_by_小绿毛猫_material_graph_dump.json "M_Hair" (socket ids + defaults).
|
|
2
|
+
// MixShader.001: Add→Shader (first), Principled→Shader_001 (second) → out = mix(first, second, Fac).
|
|
3
|
+
|
|
4
|
+
import { NODES_WGSL } from "./nodes"
|
|
5
|
+
|
|
6
|
+
export const HAIR_SHADER_WGSL = /* wgsl */ `
|
|
7
|
+
|
|
8
|
+
${NODES_WGSL}
|
|
9
|
+
|
|
10
|
+
struct CameraUniforms {
|
|
11
|
+
view: mat4x4f,
|
|
12
|
+
projection: mat4x4f,
|
|
13
|
+
viewPos: vec3f,
|
|
14
|
+
_padding: f32,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
struct Light {
|
|
18
|
+
direction: vec4f,
|
|
19
|
+
color: vec4f,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
struct LightUniforms {
|
|
23
|
+
ambientColor: vec4f,
|
|
24
|
+
lights: array<Light, 4>,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
struct MaterialUniforms {
|
|
28
|
+
diffuseColor: vec3f,
|
|
29
|
+
alpha: f32,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
struct VertexOutput {
|
|
33
|
+
@builtin(position) position: vec4f,
|
|
34
|
+
@location(0) normal: vec3f,
|
|
35
|
+
@location(1) uv: vec2f,
|
|
36
|
+
@location(2) worldPos: vec3f,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
struct LightVP { viewProj: mat4x4f, };
|
|
40
|
+
|
|
41
|
+
@group(0) @binding(0) var<uniform> camera: CameraUniforms;
|
|
42
|
+
@group(0) @binding(1) var<uniform> light: LightUniforms;
|
|
43
|
+
@group(0) @binding(2) var diffuseSampler: sampler;
|
|
44
|
+
@group(0) @binding(3) var shadowMap: texture_depth_2d;
|
|
45
|
+
@group(0) @binding(4) var shadowSampler: sampler_comparison;
|
|
46
|
+
@group(0) @binding(5) var<uniform> lightVP: LightVP;
|
|
47
|
+
@group(1) @binding(0) var<storage, read> skinMats: array<mat4x4f>;
|
|
48
|
+
@group(2) @binding(0) var diffuseTexture: texture_2d<f32>;
|
|
49
|
+
@group(2) @binding(1) var<uniform> material: MaterialUniforms;
|
|
50
|
+
|
|
51
|
+
fn sampleShadow(worldPos: vec3f, n: vec3f) -> f32 {
|
|
52
|
+
let biasedPos = worldPos + n * 0.08;
|
|
53
|
+
let lclip = lightVP.viewProj * vec4f(biasedPos, 1.0);
|
|
54
|
+
let ndc = lclip.xyz / max(lclip.w, 1e-6);
|
|
55
|
+
let suv = vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);
|
|
56
|
+
let cmpZ = ndc.z - 0.001;
|
|
57
|
+
let ts = 1.0 / 4096.0;
|
|
58
|
+
var vis = 0.0;
|
|
59
|
+
for (var y = -1; y <= 1; y++) {
|
|
60
|
+
for (var x = -1; x <= 1; x++) {
|
|
61
|
+
vis += textureSampleCompare(shadowMap, shadowSampler, suv + vec2f(f32(x), f32(y)) * ts, cmpZ);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return vis / 9.0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const PI_H: f32 = 3.141592653589793;
|
|
68
|
+
const HAIR_SPECULAR: f32 = 1.0;
|
|
69
|
+
const HAIR_ROUGHNESS: f32 = 0.3;
|
|
70
|
+
// Dump M_Hair: 运算.004 GREATER_THAN second operand Value_001; 运算.007 POWER exponent Value_001; 背景 Color
|
|
71
|
+
const HAIR_TEX_GATE_THRESH: f32 = 0.15000000596046448;
|
|
72
|
+
const HAIR_RIM2_POW: f32 = 0.6300000548362732;
|
|
73
|
+
const HAIR_MIX_BG: vec3f = vec3f(0.1673291176557541);
|
|
74
|
+
|
|
75
|
+
@vertex fn vs(
|
|
76
|
+
@location(0) position: vec3f,
|
|
77
|
+
@location(1) normal: vec3f,
|
|
78
|
+
@location(2) uv: vec2f,
|
|
79
|
+
@location(3) joints0: vec4<u32>,
|
|
80
|
+
@location(4) weights0: vec4<f32>
|
|
81
|
+
) -> VertexOutput {
|
|
82
|
+
var output: VertexOutput;
|
|
83
|
+
let pos4 = vec4f(position, 1.0);
|
|
84
|
+
let weightSum = weights0.x + weights0.y + weights0.z + weights0.w;
|
|
85
|
+
let invWeightSum = select(1.0, 1.0 / weightSum, weightSum > 0.0001);
|
|
86
|
+
let nw = select(vec4f(1.0, 0.0, 0.0, 0.0), weights0 * invWeightSum, weightSum > 0.0001);
|
|
87
|
+
var skinnedPos = vec4f(0.0);
|
|
88
|
+
var skinnedNrm = vec3f(0.0);
|
|
89
|
+
for (var i = 0u; i < 4u; i++) {
|
|
90
|
+
let m = skinMats[joints0[i]];
|
|
91
|
+
let w = nw[i];
|
|
92
|
+
skinnedPos += (m * pos4) * w;
|
|
93
|
+
skinnedNrm += (mat3x3f(m[0].xyz, m[1].xyz, m[2].xyz) * normal) * w;
|
|
94
|
+
}
|
|
95
|
+
output.position = camera.projection * camera.view * vec4f(skinnedPos.xyz, 1.0);
|
|
96
|
+
output.normal = normalize(skinnedNrm);
|
|
97
|
+
output.uv = uv;
|
|
98
|
+
output.worldPos = skinnedPos.xyz;
|
|
99
|
+
return output;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@fragment fn fs(input: VertexOutput) -> @location(0) vec4f {
|
|
103
|
+
let alpha = material.alpha;
|
|
104
|
+
if (alpha < 0.001) { discard; }
|
|
105
|
+
|
|
106
|
+
let n = normalize(input.normal);
|
|
107
|
+
let v = normalize(camera.viewPos - input.worldPos);
|
|
108
|
+
let l = -light.lights[0].direction.xyz;
|
|
109
|
+
let sun = light.lights[0].color.xyz * light.lights[0].color.w;
|
|
110
|
+
|
|
111
|
+
// 图像纹理 ← 纹理坐标.UV → 映射 (default 1,1,1 scale per JSON)
|
|
112
|
+
let tex_color = textureSample(diffuseTexture, diffuseSampler, input.uv).rgb;
|
|
113
|
+
let shadow = sampleShadow(input.worldPos, n);
|
|
114
|
+
|
|
115
|
+
// 色相/饱和度/明度 (Hue=0.5 Sat=1.2 Val=0.5 Fac=1) ← reroute from image
|
|
116
|
+
let hue_sat_shadow = hue_sat(0.5, 1.2, 0.5, 1.0, tex_color);
|
|
117
|
+
// 色相/饱和度/明度.002 (0.48, 1.2, 0.7, 1) ← previous
|
|
118
|
+
let hue_sat_002 = hue_sat(0.48, 1.2, 0.7, 1.0, hue_sat_shadow);
|
|
119
|
+
// 色相/饱和度/明度.001 (0.5, 1.5, 1.0, 1) ← image reroute (lit path)
|
|
120
|
+
let hue_sat_001 = hue_sat(0.5, 1.5, 1.0, 1.0, tex_color);
|
|
121
|
+
|
|
122
|
+
// 漫射 BSDF.002 → Shader --> RGB → 颜色渐变.008 CONSTANT [0→0, 0.2966→1]
|
|
123
|
+
let ndotl_raw = shader_to_rgb_diffuse(n, l, sun, light.ambientColor.xyz, shadow);
|
|
124
|
+
let ramp_008 = ramp_constant(ndotl_raw, 0.0, vec4f(0,0,0,1), 0.2966, vec4f(1,1,1,1)).r;
|
|
125
|
+
|
|
126
|
+
// 混合.004 MIX Fac=ramp_008, A=hue_sat_002, B=hue_sat_001
|
|
127
|
+
let mix_004 = mix_blend(ramp_008, hue_sat_002, hue_sat_001);
|
|
128
|
+
|
|
129
|
+
// 亮度/对比度 (Bright=0.1 Contrast=0.2) ← mix_004 only (links: not bevel path)
|
|
130
|
+
let bc = bright_contrast(mix_004, 0.1, 0.2);
|
|
131
|
+
|
|
132
|
+
// 倒角.001 → 分离 XYZ.001 → Z → 混合.003 Factor; A=bc, B=hue_sat_002
|
|
133
|
+
let bevel_z = clamp(n.y, 0.0, 1.0);
|
|
134
|
+
let mix_003 = mix_blend(bevel_z, bc, hue_sat_002);
|
|
135
|
+
|
|
136
|
+
// 环境光遮蔽 (AO).001 → 颜色渐变.001 CONSTANT [0→1, 0.3756→0] → 混合.001 → ao_factor
|
|
137
|
+
let ao = ao_fake(n, v);
|
|
138
|
+
let ramp_001 = ramp_constant(ao, 0.0, vec4f(1,1,1,1), 0.3756, vec4f(0,0,0,1)).r;
|
|
139
|
+
let ao_factor = mix(1.0, 0.0, ramp_001);
|
|
140
|
+
|
|
141
|
+
// 色相/饱和度/明度.004 (0.5, 0.8, 0.1, 1) ← mix_003
|
|
142
|
+
let hue_sat_004 = hue_sat(0.5, 0.8, 0.1, 1.0, mix_003);
|
|
143
|
+
|
|
144
|
+
// 混合.002 MIX Fac=ao_factor, A=hue_sat_004, B=mix_003
|
|
145
|
+
let mix_002 = mix_blend(ao_factor, hue_sat_004, mix_003);
|
|
146
|
+
|
|
147
|
+
// 自发光(发射).003 Strength=1.0 ← mix_002
|
|
148
|
+
let emission3 = mix_002 * 1.0;
|
|
149
|
+
|
|
150
|
+
// 菲涅尔.001 × 层权重.002 → 运算.003 MULTIPLY → 运算.007 POWER(exponent Value_001) → MixShader.002 Fac
|
|
151
|
+
let rim2_raw = fresnel(1.45, n, v) * layer_weight_fresnel(0.61, n, v);
|
|
152
|
+
let rim2_fac = math_power(rim2_raw, HAIR_RIM2_POW);
|
|
153
|
+
// MixShader.002: Shader=Emission.003, Shader_001=背景 — (1-Fac)*emission + Fac*bg
|
|
154
|
+
let mix_shader_002 = mix(emission3, HAIR_MIX_BG, rim2_fac);
|
|
155
|
+
|
|
156
|
+
// 运算.004 GREATER_THAN: 图像→Value, threshold Value_001 (R when Color plugs float socket)
|
|
157
|
+
let tex_gate = math_greater_than(tex_color.r, HAIR_TEX_GATE_THRESH);
|
|
158
|
+
let gate_emit = vec3f(tex_gate) * 0.1;
|
|
159
|
+
|
|
160
|
+
// 相加着色器: MixShader.002 + gate emission (color sum in linear space)
|
|
161
|
+
let add_shader = mix_shader_002 + gate_emit;
|
|
162
|
+
|
|
163
|
+
// 原理化BSDF (EEVEE port): metallic=0, specular=1.0, roughness=0.3, specular_tint=0.
|
|
164
|
+
// Graph's 噪波→法线贴图 Strength=0.1 is near-identity; plain n matches visually.
|
|
165
|
+
let NL = max(dot(n, l), 0.0);
|
|
166
|
+
let NV = max(dot(n, v), 1e-4);
|
|
167
|
+
|
|
168
|
+
let f0 = vec3f(0.08 * HAIR_SPECULAR);
|
|
169
|
+
let f90 = mix(f0, vec3f(1.0), sqrt(HAIR_SPECULAR));
|
|
170
|
+
let split_sum = brdf_lut_baked(NV, HAIR_ROUGHNESS);
|
|
171
|
+
let reflection_color = F_brdf_multi_scatter(f0, f90, split_sum);
|
|
172
|
+
|
|
173
|
+
let spec_direct = bsdf_ggx(n, l, v, HAIR_ROUGHNESS) * sun * shadow * ltc_brdf_scale(NV, HAIR_ROUGHNESS);
|
|
174
|
+
let spec_indirect = light.ambientColor.xyz;
|
|
175
|
+
let spec_radiance = (spec_direct + spec_indirect) * reflection_color;
|
|
176
|
+
|
|
177
|
+
// Indirect diffuse = base_color × L_w per Blender closure_eval_surface_lib.glsl line 302;
|
|
178
|
+
// probe_evaluate_world_diff returns radiance (SH-projected, not cosine-convolved).
|
|
179
|
+
let diffuse_radiance = bc * (sun * NL * shadow / PI_H + light.ambientColor.xyz);
|
|
180
|
+
let principled = diffuse_radiance + spec_radiance;
|
|
181
|
+
|
|
182
|
+
// 混合着色器.001 Fac=0.2: first socket=相加着色器, second=原理化BSDF
|
|
183
|
+
let final_color = mix(add_shader, principled, 0.2);
|
|
184
|
+
|
|
185
|
+
return vec4f(final_color, alpha);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
`
|