reze-engine 0.9.4 → 0.9.5
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 +20 -1
- package/dist/engine.d.ts +5 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +77 -13
- package/package.json +1 -1
- package/src/engine.ts +87 -25
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ npm install reze-engine
|
|
|
14
14
|
- VMD animation with IK solver and Bullet physics
|
|
15
15
|
- Orbit camera with bone-follow mode
|
|
16
16
|
- GPU picking (double-click/tap)
|
|
17
|
-
- Ground plane with PCF shadow mapping
|
|
17
|
+
- Ground plane with PCF shadow mapping, grid lines, and frosted texture
|
|
18
18
|
- Multi-model support
|
|
19
19
|
|
|
20
20
|
## Quick Start
|
|
@@ -108,6 +108,25 @@ engine.runRenderLoop()
|
|
|
108
108
|
|
|
109
109
|
`constraintSolverKeywords` — joints whose name contains any keyword use the Bullet 2.75 constraint solver; all others keep the stable Ammo 2.82+ default. See [babylon-mmd: Fix Constraint Behavior](https://noname0310.github.io/babylon-mmd/docs/reference/runtime/apply-physics-to-mmd-models/#fix-constraint-behavior) for details.
|
|
110
110
|
|
|
111
|
+
### Ground Options
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
engine.addGround({
|
|
115
|
+
width: 100, // ground plane width
|
|
116
|
+
height: 100, // ground plane depth
|
|
117
|
+
diffuseColor: Vec3, // base color (default: 0.8, 0.1, 1.0)
|
|
118
|
+
fadeStart: 5.0, // distance where edge fade begins
|
|
119
|
+
fadeEnd: 60.0, // distance where ground fully fades out
|
|
120
|
+
shadowMapSize: 4096, // shadow map resolution
|
|
121
|
+
shadowStrength: 1.0, // shadow darkness
|
|
122
|
+
gridSpacing: 5.0, // world-space distance between grid lines
|
|
123
|
+
gridLineWidth: 0.012, // thickness of grid lines
|
|
124
|
+
gridLineOpacity: 0.4, // grid line visibility (0–1)
|
|
125
|
+
gridLineColor: Vec3, // grid line color (default: 0.8, 0.8, 0.8)
|
|
126
|
+
noiseStrength: 0.08, // frosted/matte micro-texture intensity
|
|
127
|
+
})
|
|
128
|
+
```
|
|
129
|
+
|
|
111
130
|
## Projects Using This Engine
|
|
112
131
|
|
|
113
132
|
- **[MiKaPo](https://mikapo.vercel.app)** — Real-time motion capture for MMD
|
package/dist/engine.d.ts
CHANGED
|
@@ -142,6 +142,11 @@ export declare class Engine {
|
|
|
142
142
|
fadeEnd?: number;
|
|
143
143
|
shadowMapSize?: number;
|
|
144
144
|
shadowStrength?: number;
|
|
145
|
+
gridSpacing?: number;
|
|
146
|
+
gridLineWidth?: number;
|
|
147
|
+
gridLineOpacity?: number;
|
|
148
|
+
gridLineColor?: Vec3;
|
|
149
|
+
noiseStrength?: number;
|
|
145
150
|
}): void;
|
|
146
151
|
private updateLightBuffer;
|
|
147
152
|
getStats(): EngineStats;
|
package/dist/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/engine.js
CHANGED
|
@@ -446,7 +446,12 @@ export class Engine {
|
|
|
446
446
|
struct CameraUniforms { view: mat4x4f, projection: mat4x4f, viewPos: vec3f, _p: f32, };
|
|
447
447
|
struct Light { direction: vec4f, color: vec4f, };
|
|
448
448
|
struct LightUniforms { ambientColor: vec4f, lights: array<Light, 4>, };
|
|
449
|
-
struct GroundShadowMat {
|
|
449
|
+
struct GroundShadowMat {
|
|
450
|
+
diffuseColor: vec3f, fadeStart: f32,
|
|
451
|
+
fadeEnd: f32, shadowStrength: f32, pcfTexel: f32, gridSpacing: f32,
|
|
452
|
+
gridLineWidth: f32, gridLineOpacity: f32, noiseStrength: f32, _pad: f32,
|
|
453
|
+
gridLineColor: vec3f, _pad2: f32,
|
|
454
|
+
};
|
|
450
455
|
struct LightVP { viewProj: mat4x4f, };
|
|
451
456
|
@group(0) @binding(0) var<uniform> camera: CameraUniforms;
|
|
452
457
|
@group(0) @binding(1) var<uniform> light: LightUniforms;
|
|
@@ -454,6 +459,32 @@ export class Engine {
|
|
|
454
459
|
@group(0) @binding(3) var shadowSampler: sampler_comparison;
|
|
455
460
|
@group(0) @binding(4) var<uniform> material: GroundShadowMat;
|
|
456
461
|
@group(0) @binding(5) var<uniform> lightVP: LightVP;
|
|
462
|
+
|
|
463
|
+
// Hash-based noise for frosted/matte surface
|
|
464
|
+
fn hash2(p: vec2f) -> f32 {
|
|
465
|
+
var p3 = fract(vec3f(p.x, p.y, p.x) * 0.1031);
|
|
466
|
+
p3 += dot(p3, vec3f(p3.y + 33.33, p3.z + 33.33, p3.x + 33.33));
|
|
467
|
+
return fract((p3.x + p3.y) * p3.z);
|
|
468
|
+
}
|
|
469
|
+
fn valueNoise(p: vec2f) -> f32 {
|
|
470
|
+
let i = floor(p);
|
|
471
|
+
let f = fract(p);
|
|
472
|
+
let u = f * f * (3.0 - 2.0 * f);
|
|
473
|
+
return mix(mix(hash2(i), hash2(i + vec2f(1.0, 0.0)), u.x),
|
|
474
|
+
mix(hash2(i + vec2f(0.0, 1.0)), hash2(i + vec2f(1.0, 1.0)), u.x), u.y);
|
|
475
|
+
}
|
|
476
|
+
fn fbmNoise(p: vec2f) -> f32 {
|
|
477
|
+
var v = 0.0;
|
|
478
|
+
var a = 0.5;
|
|
479
|
+
var pp = p;
|
|
480
|
+
for (var i = 0; i < 4; i++) {
|
|
481
|
+
v += a * valueNoise(pp);
|
|
482
|
+
pp *= 2.0;
|
|
483
|
+
a *= 0.5;
|
|
484
|
+
}
|
|
485
|
+
return v;
|
|
486
|
+
}
|
|
487
|
+
|
|
457
488
|
struct VO { @builtin(position) position: vec4f, @location(0) worldPos: vec3f, @location(1) normal: vec3f, };
|
|
458
489
|
@vertex fn vs(@location(0) position: vec3f, @location(1) normal: vec3f, @location(2) uv: vec2f) -> VO {
|
|
459
490
|
var o: VO; o.worldPos = position; o.normal = normal;
|
|
@@ -463,6 +494,8 @@ export class Engine {
|
|
|
463
494
|
let n = normalize(i.normal);
|
|
464
495
|
let centerDist = length(i.worldPos.xz);
|
|
465
496
|
let edgeFade = 1.0 - smoothstep(0.0, 1.0, clamp((centerDist - material.fadeStart) / max(material.fadeEnd - material.fadeStart, 0.001), 0.0, 1.0));
|
|
497
|
+
|
|
498
|
+
// Shadow sampling
|
|
466
499
|
let lclip = lightVP.viewProj * vec4f(i.worldPos, 1.0);
|
|
467
500
|
let ndc = lclip.xyz / max(lclip.w, 1e-6);
|
|
468
501
|
let suv = vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);
|
|
@@ -476,10 +509,26 @@ export class Engine {
|
|
|
476
509
|
}
|
|
477
510
|
}
|
|
478
511
|
vis *= 0.04;
|
|
512
|
+
|
|
513
|
+
// Frosted/matte micro-texture (磨砂)
|
|
514
|
+
let noiseVal = fbmNoise(i.worldPos.xz * 3.0);
|
|
515
|
+
let noiseTint = 1.0 + (noiseVal - 0.5) * material.noiseStrength;
|
|
516
|
+
|
|
517
|
+
// Grid lines — anti-aliased via screen-space derivatives
|
|
518
|
+
let gp = i.worldPos.xz / material.gridSpacing;
|
|
519
|
+
let gridFrac = abs(fract(gp - 0.5) - 0.5);
|
|
520
|
+
let gridDeriv = fwidth(gp);
|
|
521
|
+
let halfLine = material.gridLineWidth * 0.5;
|
|
522
|
+
let gridLine = 1.0 - min(
|
|
523
|
+
smoothstep(halfLine - gridDeriv.x, halfLine + gridDeriv.x, gridFrac.x),
|
|
524
|
+
smoothstep(halfLine - gridDeriv.y, halfLine + gridDeriv.y, gridFrac.y)
|
|
525
|
+
);
|
|
479
526
|
let sun = light.ambientColor.xyz + light.lights[0].color.xyz * light.lights[0].color.w * max(dot(n, -light.lights[0].direction.xyz), 0.0);
|
|
480
527
|
let dark = (1.0 - vis) * material.shadowStrength;
|
|
481
|
-
|
|
482
|
-
|
|
528
|
+
var baseColor = material.diffuseColor * sun * (1.0 - dark * 0.65);
|
|
529
|
+
baseColor *= noiseTint;
|
|
530
|
+
let finalColor = mix(baseColor, material.gridLineColor, gridLine * material.gridLineOpacity * edgeFade);
|
|
531
|
+
return vec4f(finalColor * edgeFade, edgeFade);
|
|
483
532
|
}
|
|
484
533
|
`,
|
|
485
534
|
});
|
|
@@ -859,17 +908,22 @@ export class Engine {
|
|
|
859
908
|
}
|
|
860
909
|
addGround(options) {
|
|
861
910
|
const opts = {
|
|
862
|
-
width:
|
|
863
|
-
height:
|
|
864
|
-
diffuseColor: new Vec3(
|
|
865
|
-
fadeStart:
|
|
866
|
-
fadeEnd:
|
|
911
|
+
width: 160,
|
|
912
|
+
height: 160,
|
|
913
|
+
diffuseColor: new Vec3(0.8, 0.1, 1.0),
|
|
914
|
+
fadeStart: 10.0,
|
|
915
|
+
fadeEnd: 80.0,
|
|
867
916
|
shadowMapSize: 4096,
|
|
868
917
|
shadowStrength: 1.0,
|
|
918
|
+
gridSpacing: 4.2,
|
|
919
|
+
gridLineWidth: 0.012,
|
|
920
|
+
gridLineOpacity: 0.4,
|
|
921
|
+
gridLineColor: new Vec3(0.85, 0.85, 0.85),
|
|
922
|
+
noiseStrength: 0.05,
|
|
869
923
|
...options,
|
|
870
924
|
};
|
|
871
925
|
this.createGroundGeometry(opts.width, opts.height);
|
|
872
|
-
this.createShadowGroundResources(opts
|
|
926
|
+
this.createShadowGroundResources(opts);
|
|
873
927
|
this.hasGround = true;
|
|
874
928
|
this.groundDrawCall = {
|
|
875
929
|
type: "ground",
|
|
@@ -1171,7 +1225,8 @@ export class Engine {
|
|
|
1171
1225
|
});
|
|
1172
1226
|
this.device.queue.writeBuffer(this.groundIndexBuffer, 0, indices);
|
|
1173
1227
|
}
|
|
1174
|
-
createShadowGroundResources(
|
|
1228
|
+
createShadowGroundResources(opts) {
|
|
1229
|
+
const { shadowMapSize, diffuseColor, fadeStart, fadeEnd, shadowStrength, gridSpacing, gridLineWidth, gridLineOpacity, gridLineColor, noiseStrength } = opts;
|
|
1175
1230
|
this.shadowMapTexture = this.device.createTexture({
|
|
1176
1231
|
label: "shadow map",
|
|
1177
1232
|
size: [shadowMapSize, shadowMapSize],
|
|
@@ -1179,7 +1234,8 @@ export class Engine {
|
|
|
1179
1234
|
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1180
1235
|
});
|
|
1181
1236
|
this.shadowMapDepthView = this.shadowMapTexture.createView();
|
|
1182
|
-
|
|
1237
|
+
// Layout: diffuseColor(3f) fadeStart(1f) | fadeEnd(1f) shadowStrength(1f) pcfTexel(1f) gridSpacing(1f) | gridLineWidth(1f) gridOpacity(1f) noiseStrength(1f) _pad(1f) | gridColor(3f) _pad2(1f)
|
|
1238
|
+
const gb = new Float32Array(16);
|
|
1183
1239
|
gb[0] = diffuseColor.x;
|
|
1184
1240
|
gb[1] = diffuseColor.y;
|
|
1185
1241
|
gb[2] = diffuseColor.z;
|
|
@@ -1187,8 +1243,16 @@ export class Engine {
|
|
|
1187
1243
|
gb[4] = fadeEnd;
|
|
1188
1244
|
gb[5] = shadowStrength;
|
|
1189
1245
|
gb[6] = 1 / shadowMapSize;
|
|
1190
|
-
gb[7] =
|
|
1191
|
-
|
|
1246
|
+
gb[7] = gridSpacing;
|
|
1247
|
+
gb[8] = gridLineWidth;
|
|
1248
|
+
gb[9] = gridLineOpacity;
|
|
1249
|
+
gb[10] = noiseStrength;
|
|
1250
|
+
gb[11] = 0;
|
|
1251
|
+
gb[12] = gridLineColor.x;
|
|
1252
|
+
gb[13] = gridLineColor.y;
|
|
1253
|
+
gb[14] = gridLineColor.z;
|
|
1254
|
+
gb[15] = 0;
|
|
1255
|
+
this.groundShadowMaterialBuffer = this.device.createBuffer({ size: gb.byteLength, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
|
|
1192
1256
|
this.device.queue.writeBuffer(this.groundShadowMaterialBuffer, 0, gb);
|
|
1193
1257
|
this.groundShadowBindGroup = this.device.createBindGroup({
|
|
1194
1258
|
label: "ground shadow bind",
|
package/package.json
CHANGED
package/src/engine.ts
CHANGED
|
@@ -566,7 +566,12 @@ export class Engine {
|
|
|
566
566
|
struct CameraUniforms { view: mat4x4f, projection: mat4x4f, viewPos: vec3f, _p: f32, };
|
|
567
567
|
struct Light { direction: vec4f, color: vec4f, };
|
|
568
568
|
struct LightUniforms { ambientColor: vec4f, lights: array<Light, 4>, };
|
|
569
|
-
struct GroundShadowMat {
|
|
569
|
+
struct GroundShadowMat {
|
|
570
|
+
diffuseColor: vec3f, fadeStart: f32,
|
|
571
|
+
fadeEnd: f32, shadowStrength: f32, pcfTexel: f32, gridSpacing: f32,
|
|
572
|
+
gridLineWidth: f32, gridLineOpacity: f32, noiseStrength: f32, _pad: f32,
|
|
573
|
+
gridLineColor: vec3f, _pad2: f32,
|
|
574
|
+
};
|
|
570
575
|
struct LightVP { viewProj: mat4x4f, };
|
|
571
576
|
@group(0) @binding(0) var<uniform> camera: CameraUniforms;
|
|
572
577
|
@group(0) @binding(1) var<uniform> light: LightUniforms;
|
|
@@ -574,6 +579,32 @@ export class Engine {
|
|
|
574
579
|
@group(0) @binding(3) var shadowSampler: sampler_comparison;
|
|
575
580
|
@group(0) @binding(4) var<uniform> material: GroundShadowMat;
|
|
576
581
|
@group(0) @binding(5) var<uniform> lightVP: LightVP;
|
|
582
|
+
|
|
583
|
+
// Hash-based noise for frosted/matte surface
|
|
584
|
+
fn hash2(p: vec2f) -> f32 {
|
|
585
|
+
var p3 = fract(vec3f(p.x, p.y, p.x) * 0.1031);
|
|
586
|
+
p3 += dot(p3, vec3f(p3.y + 33.33, p3.z + 33.33, p3.x + 33.33));
|
|
587
|
+
return fract((p3.x + p3.y) * p3.z);
|
|
588
|
+
}
|
|
589
|
+
fn valueNoise(p: vec2f) -> f32 {
|
|
590
|
+
let i = floor(p);
|
|
591
|
+
let f = fract(p);
|
|
592
|
+
let u = f * f * (3.0 - 2.0 * f);
|
|
593
|
+
return mix(mix(hash2(i), hash2(i + vec2f(1.0, 0.0)), u.x),
|
|
594
|
+
mix(hash2(i + vec2f(0.0, 1.0)), hash2(i + vec2f(1.0, 1.0)), u.x), u.y);
|
|
595
|
+
}
|
|
596
|
+
fn fbmNoise(p: vec2f) -> f32 {
|
|
597
|
+
var v = 0.0;
|
|
598
|
+
var a = 0.5;
|
|
599
|
+
var pp = p;
|
|
600
|
+
for (var i = 0; i < 4; i++) {
|
|
601
|
+
v += a * valueNoise(pp);
|
|
602
|
+
pp *= 2.0;
|
|
603
|
+
a *= 0.5;
|
|
604
|
+
}
|
|
605
|
+
return v;
|
|
606
|
+
}
|
|
607
|
+
|
|
577
608
|
struct VO { @builtin(position) position: vec4f, @location(0) worldPos: vec3f, @location(1) normal: vec3f, };
|
|
578
609
|
@vertex fn vs(@location(0) position: vec3f, @location(1) normal: vec3f, @location(2) uv: vec2f) -> VO {
|
|
579
610
|
var o: VO; o.worldPos = position; o.normal = normal;
|
|
@@ -583,6 +614,8 @@ export class Engine {
|
|
|
583
614
|
let n = normalize(i.normal);
|
|
584
615
|
let centerDist = length(i.worldPos.xz);
|
|
585
616
|
let edgeFade = 1.0 - smoothstep(0.0, 1.0, clamp((centerDist - material.fadeStart) / max(material.fadeEnd - material.fadeStart, 0.001), 0.0, 1.0));
|
|
617
|
+
|
|
618
|
+
// Shadow sampling
|
|
586
619
|
let lclip = lightVP.viewProj * vec4f(i.worldPos, 1.0);
|
|
587
620
|
let ndc = lclip.xyz / max(lclip.w, 1e-6);
|
|
588
621
|
let suv = vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);
|
|
@@ -596,10 +629,26 @@ export class Engine {
|
|
|
596
629
|
}
|
|
597
630
|
}
|
|
598
631
|
vis *= 0.04;
|
|
632
|
+
|
|
633
|
+
// Frosted/matte micro-texture (磨砂)
|
|
634
|
+
let noiseVal = fbmNoise(i.worldPos.xz * 3.0);
|
|
635
|
+
let noiseTint = 1.0 + (noiseVal - 0.5) * material.noiseStrength;
|
|
636
|
+
|
|
637
|
+
// Grid lines — anti-aliased via screen-space derivatives
|
|
638
|
+
let gp = i.worldPos.xz / material.gridSpacing;
|
|
639
|
+
let gridFrac = abs(fract(gp - 0.5) - 0.5);
|
|
640
|
+
let gridDeriv = fwidth(gp);
|
|
641
|
+
let halfLine = material.gridLineWidth * 0.5;
|
|
642
|
+
let gridLine = 1.0 - min(
|
|
643
|
+
smoothstep(halfLine - gridDeriv.x, halfLine + gridDeriv.x, gridFrac.x),
|
|
644
|
+
smoothstep(halfLine - gridDeriv.y, halfLine + gridDeriv.y, gridFrac.y)
|
|
645
|
+
);
|
|
599
646
|
let sun = light.ambientColor.xyz + light.lights[0].color.xyz * light.lights[0].color.w * max(dot(n, -light.lights[0].direction.xyz), 0.0);
|
|
600
647
|
let dark = (1.0 - vis) * material.shadowStrength;
|
|
601
|
-
|
|
602
|
-
|
|
648
|
+
var baseColor = material.diffuseColor * sun * (1.0 - dark * 0.65);
|
|
649
|
+
baseColor *= noiseTint;
|
|
650
|
+
let finalColor = mix(baseColor, material.gridLineColor, gridLine * material.gridLineOpacity * edgeFade);
|
|
651
|
+
return vec4f(finalColor * edgeFade, edgeFade);
|
|
603
652
|
}
|
|
604
653
|
`,
|
|
605
654
|
})
|
|
@@ -1027,19 +1076,29 @@ export class Engine {
|
|
|
1027
1076
|
fadeEnd?: number
|
|
1028
1077
|
shadowMapSize?: number
|
|
1029
1078
|
shadowStrength?: number
|
|
1079
|
+
gridSpacing?: number
|
|
1080
|
+
gridLineWidth?: number
|
|
1081
|
+
gridLineOpacity?: number
|
|
1082
|
+
gridLineColor?: Vec3
|
|
1083
|
+
noiseStrength?: number
|
|
1030
1084
|
}): void {
|
|
1031
1085
|
const opts = {
|
|
1032
|
-
width:
|
|
1033
|
-
height:
|
|
1034
|
-
diffuseColor: new Vec3(
|
|
1035
|
-
fadeStart:
|
|
1036
|
-
fadeEnd:
|
|
1086
|
+
width: 160,
|
|
1087
|
+
height: 160,
|
|
1088
|
+
diffuseColor: new Vec3(0.8, 0.1, 1.0),
|
|
1089
|
+
fadeStart: 10.0,
|
|
1090
|
+
fadeEnd: 80.0,
|
|
1037
1091
|
shadowMapSize: 4096,
|
|
1038
1092
|
shadowStrength: 1.0,
|
|
1093
|
+
gridSpacing: 4.2,
|
|
1094
|
+
gridLineWidth: 0.012,
|
|
1095
|
+
gridLineOpacity: 0.4,
|
|
1096
|
+
gridLineColor: new Vec3(0.85, 0.85, 0.85),
|
|
1097
|
+
noiseStrength: 0.05,
|
|
1039
1098
|
...options,
|
|
1040
1099
|
}
|
|
1041
1100
|
this.createGroundGeometry(opts.width, opts.height)
|
|
1042
|
-
this.createShadowGroundResources(opts
|
|
1101
|
+
this.createShadowGroundResources(opts)
|
|
1043
1102
|
this.hasGround = true
|
|
1044
1103
|
this.groundDrawCall = {
|
|
1045
1104
|
type: "ground",
|
|
@@ -1391,13 +1450,19 @@ export class Engine {
|
|
|
1391
1450
|
this.device.queue.writeBuffer(this.groundIndexBuffer, 0, indices)
|
|
1392
1451
|
}
|
|
1393
1452
|
|
|
1394
|
-
private createShadowGroundResources(
|
|
1395
|
-
shadowMapSize: number
|
|
1396
|
-
diffuseColor: Vec3
|
|
1397
|
-
fadeStart: number
|
|
1398
|
-
fadeEnd: number
|
|
1453
|
+
private createShadowGroundResources(opts: {
|
|
1454
|
+
shadowMapSize: number
|
|
1455
|
+
diffuseColor: Vec3
|
|
1456
|
+
fadeStart: number
|
|
1457
|
+
fadeEnd: number
|
|
1399
1458
|
shadowStrength: number
|
|
1400
|
-
|
|
1459
|
+
gridSpacing: number
|
|
1460
|
+
gridLineWidth: number
|
|
1461
|
+
gridLineOpacity: number
|
|
1462
|
+
gridLineColor: Vec3
|
|
1463
|
+
noiseStrength: number
|
|
1464
|
+
}) {
|
|
1465
|
+
const { shadowMapSize, diffuseColor, fadeStart, fadeEnd, shadowStrength, gridSpacing, gridLineWidth, gridLineOpacity, gridLineColor, noiseStrength } = opts
|
|
1401
1466
|
this.shadowMapTexture = this.device.createTexture({
|
|
1402
1467
|
label: "shadow map",
|
|
1403
1468
|
size: [shadowMapSize, shadowMapSize],
|
|
@@ -1405,16 +1470,13 @@ export class Engine {
|
|
|
1405
1470
|
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1406
1471
|
})
|
|
1407
1472
|
this.shadowMapDepthView = this.shadowMapTexture.createView()
|
|
1408
|
-
|
|
1409
|
-
gb
|
|
1410
|
-
gb[1] = diffuseColor.y
|
|
1411
|
-
gb[
|
|
1412
|
-
gb[
|
|
1413
|
-
gb[
|
|
1414
|
-
|
|
1415
|
-
gb[6] = 1 / shadowMapSize
|
|
1416
|
-
gb[7] = 0
|
|
1417
|
-
this.groundShadowMaterialBuffer = this.device.createBuffer({ size: 64, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST })
|
|
1473
|
+
// Layout: diffuseColor(3f) fadeStart(1f) | fadeEnd(1f) shadowStrength(1f) pcfTexel(1f) gridSpacing(1f) | gridLineWidth(1f) gridOpacity(1f) noiseStrength(1f) _pad(1f) | gridColor(3f) _pad2(1f)
|
|
1474
|
+
const gb = new Float32Array(16)
|
|
1475
|
+
gb[0] = diffuseColor.x; gb[1] = diffuseColor.y; gb[2] = diffuseColor.z; gb[3] = fadeStart
|
|
1476
|
+
gb[4] = fadeEnd; gb[5] = shadowStrength; gb[6] = 1 / shadowMapSize; gb[7] = gridSpacing
|
|
1477
|
+
gb[8] = gridLineWidth; gb[9] = gridLineOpacity; gb[10] = noiseStrength; gb[11] = 0
|
|
1478
|
+
gb[12] = gridLineColor.x; gb[13] = gridLineColor.y; gb[14] = gridLineColor.z; gb[15] = 0
|
|
1479
|
+
this.groundShadowMaterialBuffer = this.device.createBuffer({ size: gb.byteLength, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST })
|
|
1418
1480
|
this.device.queue.writeBuffer(this.groundShadowMaterialBuffer, 0, gb)
|
|
1419
1481
|
this.groundShadowBindGroup = this.device.createBindGroup({
|
|
1420
1482
|
label: "ground shadow bind",
|