reze-engine 0.5.0 → 0.6.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 +0 -1
- package/dist/engine.d.ts +0 -24
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +9 -394
- package/package.json +1 -1
- package/src/engine.ts +9 -450
- package/dist/bezier-interpolate.d.ts +0 -15
- package/dist/bezier-interpolate.d.ts.map +0 -1
- package/dist/bezier-interpolate.js +0 -40
- package/dist/e.d.ts +0 -1
- package/dist/e.d.ts.map +0 -1
- package/dist/e.js +0 -638
- package/dist/engine_r.d.ts +0 -132
- package/dist/engine_r.d.ts.map +0 -1
- package/dist/engine_r.js +0 -1489
- package/dist/engine_ts.d.ts +0 -143
- package/dist/engine_ts.d.ts.map +0 -1
- package/dist/engine_ts.js +0 -1575
- package/dist/player.d.ts +0 -64
- package/dist/player.d.ts.map +0 -1
- package/dist/player.js +0 -220
package/README.md
CHANGED
package/dist/engine.d.ts
CHANGED
|
@@ -4,8 +4,6 @@ export type EngineOptions = {
|
|
|
4
4
|
ambientColor?: Vec3;
|
|
5
5
|
directionalLightIntensity?: number;
|
|
6
6
|
minSpecularIntensity?: number;
|
|
7
|
-
bloomIntensity?: number;
|
|
8
|
-
bloomThreshold?: number;
|
|
9
7
|
rimLightIntensity?: number;
|
|
10
8
|
cameraDistance?: number;
|
|
11
9
|
cameraTarget?: Vec3;
|
|
@@ -56,28 +54,9 @@ export declare class Engine {
|
|
|
56
54
|
private readonly sampleCount;
|
|
57
55
|
private renderPassDescriptor;
|
|
58
56
|
private readonly STENCIL_EYE_VALUE;
|
|
59
|
-
private readonly BLOOM_DOWNSCALE_FACTOR;
|
|
60
57
|
private ambientColor;
|
|
61
58
|
private directionalLightIntensity;
|
|
62
59
|
private minSpecularIntensity;
|
|
63
|
-
private sceneRenderTexture;
|
|
64
|
-
private sceneRenderTextureView;
|
|
65
|
-
private bloomExtractTexture;
|
|
66
|
-
private bloomBlurTexture1;
|
|
67
|
-
private bloomBlurTexture2;
|
|
68
|
-
private bloomExtractPipeline;
|
|
69
|
-
private bloomBlurPipeline;
|
|
70
|
-
private bloomComposePipeline;
|
|
71
|
-
private blurDirectionBuffer;
|
|
72
|
-
private bloomIntensityBuffer;
|
|
73
|
-
private bloomThresholdBuffer;
|
|
74
|
-
private linearSampler;
|
|
75
|
-
private bloomExtractBindGroup?;
|
|
76
|
-
private bloomBlurHBindGroup?;
|
|
77
|
-
private bloomBlurVBindGroup?;
|
|
78
|
-
private bloomComposeBindGroup?;
|
|
79
|
-
private bloomThreshold;
|
|
80
|
-
private bloomIntensity;
|
|
81
60
|
private rimLightIntensity;
|
|
82
61
|
private groundVertexBuffer?;
|
|
83
62
|
private groundIndexBuffer?;
|
|
@@ -112,8 +91,6 @@ export declare class Engine {
|
|
|
112
91
|
init(): Promise<void>;
|
|
113
92
|
private createRenderPipeline;
|
|
114
93
|
private createPipelines;
|
|
115
|
-
private createBloomPipelines;
|
|
116
|
-
private setupBloom;
|
|
117
94
|
private setupResize;
|
|
118
95
|
private handleResize;
|
|
119
96
|
private setupCamera;
|
|
@@ -174,7 +151,6 @@ export declare class Engine {
|
|
|
174
151
|
private handleCanvasTouch;
|
|
175
152
|
private performRaycast;
|
|
176
153
|
render(): void;
|
|
177
|
-
private applyBloom;
|
|
178
154
|
private updateCameraUniforms;
|
|
179
155
|
private updateRenderTarget;
|
|
180
156
|
private updateSkinMatrices;
|
package/dist/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAIzC,MAAM,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;AAEjG,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,CAAC,EAAE,IAAI,CAAA;IACnB,yBAAyB,CAAC,EAAE,MAAM,CAAA;IAClC,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/engine.js
CHANGED
|
@@ -2,11 +2,9 @@ import { Camera } from "./camera";
|
|
|
2
2
|
import { Mat4, Vec3 } from "./math";
|
|
3
3
|
import { PmxLoader } from "./pmx-loader";
|
|
4
4
|
export const DEFAULT_ENGINE_OPTIONS = {
|
|
5
|
-
ambientColor: new Vec3(0.
|
|
6
|
-
directionalLightIntensity: 0.
|
|
5
|
+
ambientColor: new Vec3(0.88, 0.88, 0.88),
|
|
6
|
+
directionalLightIntensity: 0.24,
|
|
7
7
|
minSpecularIntensity: 0.3,
|
|
8
|
-
bloomIntensity: 0.1,
|
|
9
|
-
bloomThreshold: 0.5,
|
|
10
8
|
rimLightIntensity: 0.4,
|
|
11
9
|
cameraDistance: 26.6,
|
|
12
10
|
cameraTarget: new Vec3(0, 12.5, 0),
|
|
@@ -22,7 +20,6 @@ export class Engine {
|
|
|
22
20
|
this.sampleCount = 4;
|
|
23
21
|
// Constants
|
|
24
22
|
this.STENCIL_EYE_VALUE = 1;
|
|
25
|
-
this.BLOOM_DOWNSCALE_FACTOR = 2;
|
|
26
23
|
this.groundHasReflections = false;
|
|
27
24
|
this.cachedSkinMatricesVersion = -1;
|
|
28
25
|
this.skinMatricesVersion = 0;
|
|
@@ -87,8 +84,6 @@ export class Engine {
|
|
|
87
84
|
this.directionalLightIntensity =
|
|
88
85
|
options.directionalLightIntensity ?? DEFAULT_ENGINE_OPTIONS.directionalLightIntensity;
|
|
89
86
|
this.minSpecularIntensity = options.minSpecularIntensity ?? DEFAULT_ENGINE_OPTIONS.minSpecularIntensity;
|
|
90
|
-
this.bloomIntensity = options.bloomIntensity ?? DEFAULT_ENGINE_OPTIONS.bloomIntensity;
|
|
91
|
-
this.bloomThreshold = options.bloomThreshold ?? DEFAULT_ENGINE_OPTIONS.bloomThreshold;
|
|
92
87
|
this.rimLightIntensity = options.rimLightIntensity ?? DEFAULT_ENGINE_OPTIONS.rimLightIntensity;
|
|
93
88
|
this.cameraDistance = options.cameraDistance ?? DEFAULT_ENGINE_OPTIONS.cameraDistance;
|
|
94
89
|
this.cameraTarget = options.cameraTarget ?? DEFAULT_ENGINE_OPTIONS.cameraTarget;
|
|
@@ -118,7 +113,6 @@ export class Engine {
|
|
|
118
113
|
this.setupCamera();
|
|
119
114
|
this.setupLighting();
|
|
120
115
|
this.createPipelines();
|
|
121
|
-
this.createBloomPipelines();
|
|
122
116
|
this.setupResize();
|
|
123
117
|
}
|
|
124
118
|
createRenderPipeline(config) {
|
|
@@ -760,287 +754,6 @@ export class Engine {
|
|
|
760
754
|
this.hairPipelineOverEyes = createHairPipeline(true);
|
|
761
755
|
this.hairPipelineOverNonEyes = createHairPipeline(false);
|
|
762
756
|
}
|
|
763
|
-
// Create bloom post-processing pipelines
|
|
764
|
-
createBloomPipelines() {
|
|
765
|
-
// Bloom extraction shader (extracts bright areas)
|
|
766
|
-
const bloomExtractShader = this.device.createShaderModule({
|
|
767
|
-
label: "bloom extract",
|
|
768
|
-
code: /* wgsl */ `
|
|
769
|
-
struct VertexOutput {
|
|
770
|
-
@builtin(position) position: vec4f,
|
|
771
|
-
@location(0) uv: vec2f,
|
|
772
|
-
};
|
|
773
|
-
|
|
774
|
-
@vertex fn vs(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
|
|
775
|
-
var output: VertexOutput;
|
|
776
|
-
// Generate fullscreen quad from vertex index
|
|
777
|
-
let x = f32((vertexIndex << 1u) & 2u) * 2.0 - 1.0;
|
|
778
|
-
let y = f32(vertexIndex & 2u) * 2.0 - 1.0;
|
|
779
|
-
output.position = vec4f(x, y, 0.0, 1.0);
|
|
780
|
-
output.uv = vec2f(x * 0.5 + 0.5, 1.0 - (y * 0.5 + 0.5));
|
|
781
|
-
return output;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
struct BloomExtractUniforms {
|
|
785
|
-
threshold: f32,
|
|
786
|
-
_padding1: f32,
|
|
787
|
-
_padding2: f32,
|
|
788
|
-
_padding3: f32,
|
|
789
|
-
_padding4: f32,
|
|
790
|
-
_padding5: f32,
|
|
791
|
-
_padding6: f32,
|
|
792
|
-
_padding7: f32,
|
|
793
|
-
};
|
|
794
|
-
|
|
795
|
-
@group(0) @binding(0) var inputTexture: texture_2d<f32>;
|
|
796
|
-
@group(0) @binding(1) var inputSampler: sampler;
|
|
797
|
-
@group(0) @binding(2) var<uniform> extractUniforms: BloomExtractUniforms;
|
|
798
|
-
|
|
799
|
-
@fragment fn fs(input: VertexOutput) -> @location(0) vec4f {
|
|
800
|
-
let color = textureSample(inputTexture, inputSampler, input.uv);
|
|
801
|
-
// Extract bright areas above threshold
|
|
802
|
-
let threshold = extractUniforms.threshold;
|
|
803
|
-
let bloom = max(vec3f(0.0), color.rgb - vec3f(threshold)) / max(0.001, 1.0 - threshold);
|
|
804
|
-
return vec4f(bloom, color.a);
|
|
805
|
-
}
|
|
806
|
-
`,
|
|
807
|
-
});
|
|
808
|
-
// Bloom blur shader (gaussian blur - can be used for both horizontal and vertical)
|
|
809
|
-
const bloomBlurShader = this.device.createShaderModule({
|
|
810
|
-
label: "bloom blur",
|
|
811
|
-
code: /* wgsl */ `
|
|
812
|
-
struct VertexOutput {
|
|
813
|
-
@builtin(position) position: vec4f,
|
|
814
|
-
@location(0) uv: vec2f,
|
|
815
|
-
};
|
|
816
|
-
|
|
817
|
-
@vertex fn vs(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
|
|
818
|
-
var output: VertexOutput;
|
|
819
|
-
let x = f32((vertexIndex << 1u) & 2u) * 2.0 - 1.0;
|
|
820
|
-
let y = f32(vertexIndex & 2u) * 2.0 - 1.0;
|
|
821
|
-
output.position = vec4f(x, y, 0.0, 1.0);
|
|
822
|
-
output.uv = vec2f(x * 0.5 + 0.5, 1.0 - (y * 0.5 + 0.5));
|
|
823
|
-
return output;
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
struct BlurUniforms {
|
|
827
|
-
direction: vec2f,
|
|
828
|
-
_padding1: f32,
|
|
829
|
-
_padding2: f32,
|
|
830
|
-
_padding3: f32,
|
|
831
|
-
_padding4: f32,
|
|
832
|
-
_padding5: f32,
|
|
833
|
-
_padding6: f32,
|
|
834
|
-
};
|
|
835
|
-
|
|
836
|
-
@group(0) @binding(0) var inputTexture: texture_2d<f32>;
|
|
837
|
-
@group(0) @binding(1) var inputSampler: sampler;
|
|
838
|
-
@group(0) @binding(2) var<uniform> blurUniforms: BlurUniforms;
|
|
839
|
-
|
|
840
|
-
// 3-tap gaussian blur using bilinear filtering trick (40% fewer texture fetches!)
|
|
841
|
-
@fragment fn fs(input: VertexOutput) -> @location(0) vec4f {
|
|
842
|
-
let texelSize = 1.0 / vec2f(textureDimensions(inputTexture));
|
|
843
|
-
|
|
844
|
-
// Bilinear optimization: leverage hardware filtering to sample between pixels
|
|
845
|
-
// Original 5-tap: weights [0.06136, 0.24477, 0.38774, 0.24477, 0.06136] at offsets [-2, -1, 0, 1, 2]
|
|
846
|
-
// Optimized 3-tap: combine adjacent samples using weighted offsets
|
|
847
|
-
let weight0 = 0.38774; // Center sample
|
|
848
|
-
let weight1 = 0.24477 + 0.06136; // Combined outer samples = 0.30613
|
|
849
|
-
let offset1 = (0.24477 * 1.0 + 0.06136 * 2.0) / weight1; // Weighted position = 1.2
|
|
850
|
-
|
|
851
|
-
var result = textureSample(inputTexture, inputSampler, input.uv) * weight0;
|
|
852
|
-
let offsetVec = offset1 * texelSize * blurUniforms.direction;
|
|
853
|
-
result += textureSample(inputTexture, inputSampler, input.uv + offsetVec) * weight1;
|
|
854
|
-
result += textureSample(inputTexture, inputSampler, input.uv - offsetVec) * weight1;
|
|
855
|
-
|
|
856
|
-
return result;
|
|
857
|
-
}
|
|
858
|
-
`,
|
|
859
|
-
});
|
|
860
|
-
// Bloom composition shader (combines original scene with bloom)
|
|
861
|
-
const bloomComposeShader = this.device.createShaderModule({
|
|
862
|
-
label: "bloom compose",
|
|
863
|
-
code: /* wgsl */ `
|
|
864
|
-
struct VertexOutput {
|
|
865
|
-
@builtin(position) position: vec4f,
|
|
866
|
-
@location(0) uv: vec2f,
|
|
867
|
-
};
|
|
868
|
-
|
|
869
|
-
@vertex fn vs(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
|
|
870
|
-
var output: VertexOutput;
|
|
871
|
-
let x = f32((vertexIndex << 1u) & 2u) * 2.0 - 1.0;
|
|
872
|
-
let y = f32(vertexIndex & 2u) * 2.0 - 1.0;
|
|
873
|
-
output.position = vec4f(x, y, 0.0, 1.0);
|
|
874
|
-
output.uv = vec2f(x * 0.5 + 0.5, 1.0 - (y * 0.5 + 0.5));
|
|
875
|
-
return output;
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
struct BloomComposeUniforms {
|
|
879
|
-
intensity: f32,
|
|
880
|
-
_padding1: f32,
|
|
881
|
-
_padding2: f32,
|
|
882
|
-
_padding3: f32,
|
|
883
|
-
_padding4: f32,
|
|
884
|
-
_padding5: f32,
|
|
885
|
-
_padding6: f32,
|
|
886
|
-
_padding7: f32,
|
|
887
|
-
};
|
|
888
|
-
|
|
889
|
-
@group(0) @binding(0) var sceneTexture: texture_2d<f32>;
|
|
890
|
-
@group(0) @binding(1) var sceneSampler: sampler;
|
|
891
|
-
@group(0) @binding(2) var bloomTexture: texture_2d<f32>;
|
|
892
|
-
@group(0) @binding(3) var bloomSampler: sampler;
|
|
893
|
-
@group(0) @binding(4) var<uniform> composeUniforms: BloomComposeUniforms;
|
|
894
|
-
|
|
895
|
-
@fragment fn fs(input: VertexOutput) -> @location(0) vec4f {
|
|
896
|
-
let scene = textureSample(sceneTexture, sceneSampler, input.uv);
|
|
897
|
-
let bloom = textureSample(bloomTexture, bloomSampler, input.uv);
|
|
898
|
-
// Additive blending with intensity control
|
|
899
|
-
let result = scene.rgb + bloom.rgb * composeUniforms.intensity;
|
|
900
|
-
return vec4f(result, scene.a);
|
|
901
|
-
}
|
|
902
|
-
`,
|
|
903
|
-
});
|
|
904
|
-
// Create uniform buffer for blur direction (minimum 32 bytes for WebGPU)
|
|
905
|
-
const blurDirectionBuffer = this.device.createBuffer({
|
|
906
|
-
label: "blur direction",
|
|
907
|
-
size: 32, // Minimum 32 bytes required for uniform buffers in WebGPU
|
|
908
|
-
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
909
|
-
});
|
|
910
|
-
// Create uniform buffer for bloom intensity (minimum 32 bytes for WebGPU)
|
|
911
|
-
const bloomIntensityBuffer = this.device.createBuffer({
|
|
912
|
-
label: "bloom intensity",
|
|
913
|
-
size: 32, // Minimum 32 bytes required for uniform buffers in WebGPU
|
|
914
|
-
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
915
|
-
});
|
|
916
|
-
// Create uniform buffer for bloom threshold (minimum 32 bytes for WebGPU)
|
|
917
|
-
const bloomThresholdBuffer = this.device.createBuffer({
|
|
918
|
-
label: "bloom threshold",
|
|
919
|
-
size: 32, // Minimum 32 bytes required for uniform buffers in WebGPU
|
|
920
|
-
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
921
|
-
});
|
|
922
|
-
// Set default bloom values
|
|
923
|
-
const intensityData = new Float32Array(8); // f32 + 7 padding floats = 8 floats = 32 bytes
|
|
924
|
-
intensityData[0] = this.bloomIntensity;
|
|
925
|
-
this.device.queue.writeBuffer(bloomIntensityBuffer, 0, intensityData);
|
|
926
|
-
const thresholdData = new Float32Array(8); // f32 + 7 padding floats = 8 floats = 32 bytes
|
|
927
|
-
thresholdData[0] = this.bloomThreshold;
|
|
928
|
-
this.device.queue.writeBuffer(bloomThresholdBuffer, 0, thresholdData);
|
|
929
|
-
// Create linear sampler for post-processing
|
|
930
|
-
const linearSampler = this.device.createSampler({
|
|
931
|
-
magFilter: "linear",
|
|
932
|
-
minFilter: "linear",
|
|
933
|
-
addressModeU: "clamp-to-edge",
|
|
934
|
-
addressModeV: "clamp-to-edge",
|
|
935
|
-
});
|
|
936
|
-
// Bloom extraction pipeline
|
|
937
|
-
this.bloomExtractPipeline = this.device.createRenderPipeline({
|
|
938
|
-
label: "bloom extract",
|
|
939
|
-
layout: "auto",
|
|
940
|
-
vertex: {
|
|
941
|
-
module: bloomExtractShader,
|
|
942
|
-
entryPoint: "vs",
|
|
943
|
-
},
|
|
944
|
-
fragment: {
|
|
945
|
-
module: bloomExtractShader,
|
|
946
|
-
entryPoint: "fs",
|
|
947
|
-
targets: [{ format: this.presentationFormat }],
|
|
948
|
-
},
|
|
949
|
-
primitive: { topology: "triangle-list" },
|
|
950
|
-
});
|
|
951
|
-
// Bloom blur pipeline
|
|
952
|
-
this.bloomBlurPipeline = this.device.createRenderPipeline({
|
|
953
|
-
label: "bloom blur",
|
|
954
|
-
layout: "auto",
|
|
955
|
-
vertex: {
|
|
956
|
-
module: bloomBlurShader,
|
|
957
|
-
entryPoint: "vs",
|
|
958
|
-
},
|
|
959
|
-
fragment: {
|
|
960
|
-
module: bloomBlurShader,
|
|
961
|
-
entryPoint: "fs",
|
|
962
|
-
targets: [{ format: this.presentationFormat }],
|
|
963
|
-
},
|
|
964
|
-
primitive: { topology: "triangle-list" },
|
|
965
|
-
});
|
|
966
|
-
// Bloom composition pipeline
|
|
967
|
-
this.bloomComposePipeline = this.device.createRenderPipeline({
|
|
968
|
-
label: "bloom compose",
|
|
969
|
-
layout: "auto",
|
|
970
|
-
vertex: {
|
|
971
|
-
module: bloomComposeShader,
|
|
972
|
-
entryPoint: "vs",
|
|
973
|
-
},
|
|
974
|
-
fragment: {
|
|
975
|
-
module: bloomComposeShader,
|
|
976
|
-
entryPoint: "fs",
|
|
977
|
-
targets: [{ format: this.presentationFormat }],
|
|
978
|
-
},
|
|
979
|
-
primitive: { topology: "triangle-list" },
|
|
980
|
-
});
|
|
981
|
-
// Store buffers and sampler for later use
|
|
982
|
-
this.blurDirectionBuffer = blurDirectionBuffer;
|
|
983
|
-
this.bloomIntensityBuffer = bloomIntensityBuffer;
|
|
984
|
-
this.bloomThresholdBuffer = bloomThresholdBuffer;
|
|
985
|
-
this.linearSampler = linearSampler;
|
|
986
|
-
}
|
|
987
|
-
setupBloom(width, height) {
|
|
988
|
-
const bloomWidth = Math.floor(width / this.BLOOM_DOWNSCALE_FACTOR);
|
|
989
|
-
const bloomHeight = Math.floor(height / this.BLOOM_DOWNSCALE_FACTOR);
|
|
990
|
-
this.bloomExtractTexture = this.device.createTexture({
|
|
991
|
-
label: "bloom extract",
|
|
992
|
-
size: [bloomWidth, bloomHeight],
|
|
993
|
-
format: this.presentationFormat,
|
|
994
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
995
|
-
});
|
|
996
|
-
this.bloomBlurTexture1 = this.device.createTexture({
|
|
997
|
-
label: "bloom blur 1",
|
|
998
|
-
size: [bloomWidth, bloomHeight],
|
|
999
|
-
format: this.presentationFormat,
|
|
1000
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1001
|
-
});
|
|
1002
|
-
this.bloomBlurTexture2 = this.device.createTexture({
|
|
1003
|
-
label: "bloom blur 2",
|
|
1004
|
-
size: [bloomWidth, bloomHeight],
|
|
1005
|
-
format: this.presentationFormat,
|
|
1006
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1007
|
-
});
|
|
1008
|
-
// Create bloom bind groups
|
|
1009
|
-
this.bloomExtractBindGroup = this.device.createBindGroup({
|
|
1010
|
-
layout: this.bloomExtractPipeline.getBindGroupLayout(0),
|
|
1011
|
-
entries: [
|
|
1012
|
-
{ binding: 0, resource: this.sceneRenderTexture.createView() },
|
|
1013
|
-
{ binding: 1, resource: this.linearSampler },
|
|
1014
|
-
{ binding: 2, resource: { buffer: this.bloomThresholdBuffer } },
|
|
1015
|
-
],
|
|
1016
|
-
});
|
|
1017
|
-
this.bloomBlurHBindGroup = this.device.createBindGroup({
|
|
1018
|
-
layout: this.bloomBlurPipeline.getBindGroupLayout(0),
|
|
1019
|
-
entries: [
|
|
1020
|
-
{ binding: 0, resource: this.bloomExtractTexture.createView() },
|
|
1021
|
-
{ binding: 1, resource: this.linearSampler },
|
|
1022
|
-
{ binding: 2, resource: { buffer: this.blurDirectionBuffer } },
|
|
1023
|
-
],
|
|
1024
|
-
});
|
|
1025
|
-
this.bloomBlurVBindGroup = this.device.createBindGroup({
|
|
1026
|
-
layout: this.bloomBlurPipeline.getBindGroupLayout(0),
|
|
1027
|
-
entries: [
|
|
1028
|
-
{ binding: 0, resource: this.bloomBlurTexture1.createView() },
|
|
1029
|
-
{ binding: 1, resource: this.linearSampler },
|
|
1030
|
-
{ binding: 2, resource: { buffer: this.blurDirectionBuffer } },
|
|
1031
|
-
],
|
|
1032
|
-
});
|
|
1033
|
-
this.bloomComposeBindGroup = this.device.createBindGroup({
|
|
1034
|
-
layout: this.bloomComposePipeline.getBindGroupLayout(0),
|
|
1035
|
-
entries: [
|
|
1036
|
-
{ binding: 0, resource: this.sceneRenderTexture.createView() },
|
|
1037
|
-
{ binding: 1, resource: this.linearSampler },
|
|
1038
|
-
{ binding: 2, resource: this.bloomBlurTexture2.createView() },
|
|
1039
|
-
{ binding: 3, resource: this.linearSampler },
|
|
1040
|
-
{ binding: 4, resource: { buffer: this.bloomIntensityBuffer } },
|
|
1041
|
-
],
|
|
1042
|
-
});
|
|
1043
|
-
}
|
|
1044
757
|
// Step 3: Setup canvas resize handling
|
|
1045
758
|
setupResize() {
|
|
1046
759
|
this.resizeObserver = new ResizeObserver(() => this.handleResize());
|
|
@@ -1075,29 +788,18 @@ export class Engine {
|
|
|
1075
788
|
format: "depth24plus-stencil8",
|
|
1076
789
|
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
1077
790
|
});
|
|
1078
|
-
// Create scene render texture (non-multisampled for post-processing)
|
|
1079
|
-
this.sceneRenderTexture = this.device.createTexture({
|
|
1080
|
-
label: "scene render texture",
|
|
1081
|
-
size: [width, height],
|
|
1082
|
-
format: this.presentationFormat,
|
|
1083
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1084
|
-
});
|
|
1085
|
-
// Setup bloom textures and bind groups
|
|
1086
|
-
this.setupBloom(width, height);
|
|
1087
791
|
const depthTextureView = this.depthTexture.createView();
|
|
1088
|
-
//
|
|
1089
|
-
this.sceneRenderTextureView = this.sceneRenderTexture.createView();
|
|
1090
|
-
// Render scene to texture instead of directly to canvas
|
|
792
|
+
// Render directly to canvas
|
|
1091
793
|
const colorAttachment = this.sampleCount > 1
|
|
1092
794
|
? {
|
|
1093
795
|
view: this.multisampleTexture.createView(),
|
|
1094
|
-
resolveTarget: this.
|
|
796
|
+
resolveTarget: this.context.getCurrentTexture().createView(),
|
|
1095
797
|
clearValue: { r: 0, g: 0, b: 0, a: 0 },
|
|
1096
798
|
loadOp: "clear",
|
|
1097
799
|
storeOp: "store",
|
|
1098
800
|
}
|
|
1099
801
|
: {
|
|
1100
|
-
view: this.
|
|
802
|
+
view: this.context.getCurrentTexture().createView(),
|
|
1101
803
|
clearValue: { r: 0, g: 0, b: 0, a: 0 },
|
|
1102
804
|
loadOp: "clear",
|
|
1103
805
|
storeOp: "store",
|
|
@@ -2035,7 +1737,7 @@ export class Engine {
|
|
|
2035
1737
|
this.onRaycast(closestHit?.materialName || null, screenX, screenY);
|
|
2036
1738
|
}
|
|
2037
1739
|
}
|
|
2038
|
-
// Render strategy: 1) Opaque non-eye/hair 2) Eyes (stencil=1) 3) Hair (depth pre-pass + split by stencil) 4) Transparent
|
|
1740
|
+
// Render strategy: 1) Opaque non-eye/hair 2) Eyes (stencil=1) 3) Hair (depth pre-pass + split by stencil) 4) Transparent
|
|
2039
1741
|
render() {
|
|
2040
1742
|
if (this.multisampleTexture && this.camera && this.device) {
|
|
2041
1743
|
const currentTime = performance.now();
|
|
@@ -2094,96 +1796,9 @@ export class Engine {
|
|
|
2094
1796
|
}
|
|
2095
1797
|
pass.end();
|
|
2096
1798
|
this.device.queue.submit([encoder.finish()]);
|
|
2097
|
-
this.applyBloom();
|
|
2098
1799
|
this.updateStats(performance.now() - currentTime);
|
|
2099
1800
|
}
|
|
2100
1801
|
}
|
|
2101
|
-
applyBloom() {
|
|
2102
|
-
if (!this.sceneRenderTexture || !this.bloomExtractTexture) {
|
|
2103
|
-
return;
|
|
2104
|
-
}
|
|
2105
|
-
// Update bloom parameters
|
|
2106
|
-
const thresholdData = new Float32Array(8);
|
|
2107
|
-
thresholdData[0] = this.bloomThreshold;
|
|
2108
|
-
this.device.queue.writeBuffer(this.bloomThresholdBuffer, 0, thresholdData);
|
|
2109
|
-
const intensityData = new Float32Array(8);
|
|
2110
|
-
intensityData[0] = this.bloomIntensity;
|
|
2111
|
-
this.device.queue.writeBuffer(this.bloomIntensityBuffer, 0, intensityData);
|
|
2112
|
-
const encoder = this.device.createCommandEncoder();
|
|
2113
|
-
// Extract bright areas
|
|
2114
|
-
const extractPass = encoder.beginRenderPass({
|
|
2115
|
-
label: "bloom extract",
|
|
2116
|
-
colorAttachments: [
|
|
2117
|
-
{
|
|
2118
|
-
view: this.bloomExtractTexture.createView(),
|
|
2119
|
-
clearValue: { r: 0, g: 0, b: 0, a: 0 },
|
|
2120
|
-
loadOp: "clear",
|
|
2121
|
-
storeOp: "store",
|
|
2122
|
-
},
|
|
2123
|
-
],
|
|
2124
|
-
});
|
|
2125
|
-
extractPass.setPipeline(this.bloomExtractPipeline);
|
|
2126
|
-
extractPass.setBindGroup(0, this.bloomExtractBindGroup);
|
|
2127
|
-
extractPass.draw(6, 1, 0, 0);
|
|
2128
|
-
extractPass.end();
|
|
2129
|
-
// Horizontal blur
|
|
2130
|
-
const hBlurData = new Float32Array(4);
|
|
2131
|
-
hBlurData[0] = 1.0;
|
|
2132
|
-
hBlurData[1] = 0.0;
|
|
2133
|
-
this.device.queue.writeBuffer(this.blurDirectionBuffer, 0, hBlurData);
|
|
2134
|
-
const blurHPass = encoder.beginRenderPass({
|
|
2135
|
-
label: "bloom blur horizontal",
|
|
2136
|
-
colorAttachments: [
|
|
2137
|
-
{
|
|
2138
|
-
view: this.bloomBlurTexture1.createView(),
|
|
2139
|
-
clearValue: { r: 0, g: 0, b: 0, a: 0 },
|
|
2140
|
-
loadOp: "clear",
|
|
2141
|
-
storeOp: "store",
|
|
2142
|
-
},
|
|
2143
|
-
],
|
|
2144
|
-
});
|
|
2145
|
-
blurHPass.setPipeline(this.bloomBlurPipeline);
|
|
2146
|
-
blurHPass.setBindGroup(0, this.bloomBlurHBindGroup);
|
|
2147
|
-
blurHPass.draw(6, 1, 0, 0);
|
|
2148
|
-
blurHPass.end();
|
|
2149
|
-
// Vertical blur
|
|
2150
|
-
const vBlurData = new Float32Array(4);
|
|
2151
|
-
vBlurData[0] = 0.0;
|
|
2152
|
-
vBlurData[1] = 1.0;
|
|
2153
|
-
this.device.queue.writeBuffer(this.blurDirectionBuffer, 0, vBlurData);
|
|
2154
|
-
const blurVPass = encoder.beginRenderPass({
|
|
2155
|
-
label: "bloom blur vertical",
|
|
2156
|
-
colorAttachments: [
|
|
2157
|
-
{
|
|
2158
|
-
view: this.bloomBlurTexture2.createView(),
|
|
2159
|
-
clearValue: { r: 0, g: 0, b: 0, a: 0 },
|
|
2160
|
-
loadOp: "clear",
|
|
2161
|
-
storeOp: "store",
|
|
2162
|
-
},
|
|
2163
|
-
],
|
|
2164
|
-
});
|
|
2165
|
-
blurVPass.setPipeline(this.bloomBlurPipeline);
|
|
2166
|
-
blurVPass.setBindGroup(0, this.bloomBlurVBindGroup);
|
|
2167
|
-
blurVPass.draw(6, 1, 0, 0);
|
|
2168
|
-
blurVPass.end();
|
|
2169
|
-
// Compose to canvas
|
|
2170
|
-
const composePass = encoder.beginRenderPass({
|
|
2171
|
-
label: "bloom compose",
|
|
2172
|
-
colorAttachments: [
|
|
2173
|
-
{
|
|
2174
|
-
view: this.context.getCurrentTexture().createView(),
|
|
2175
|
-
clearValue: { r: 0, g: 0, b: 0, a: 0 },
|
|
2176
|
-
loadOp: "clear",
|
|
2177
|
-
storeOp: "store",
|
|
2178
|
-
},
|
|
2179
|
-
],
|
|
2180
|
-
});
|
|
2181
|
-
composePass.setPipeline(this.bloomComposePipeline);
|
|
2182
|
-
composePass.setBindGroup(0, this.bloomComposeBindGroup);
|
|
2183
|
-
composePass.draw(6, 1, 0, 0);
|
|
2184
|
-
composePass.end();
|
|
2185
|
-
this.device.queue.submit([encoder.finish()]);
|
|
2186
|
-
}
|
|
2187
1802
|
updateCameraUniforms() {
|
|
2188
1803
|
const viewMatrix = this.camera.getViewMatrix();
|
|
2189
1804
|
const projectionMatrix = this.camera.getProjectionMatrix();
|
|
@@ -2196,13 +1811,13 @@ export class Engine {
|
|
|
2196
1811
|
this.device.queue.writeBuffer(this.cameraUniformBuffer, 0, this.cameraMatrixData);
|
|
2197
1812
|
}
|
|
2198
1813
|
updateRenderTarget() {
|
|
2199
|
-
//
|
|
1814
|
+
// Update render target to use current canvas texture
|
|
2200
1815
|
const colorAttachment = this.renderPassDescriptor.colorAttachments[0];
|
|
2201
1816
|
if (this.sampleCount > 1) {
|
|
2202
|
-
colorAttachment.resolveTarget = this.
|
|
1817
|
+
colorAttachment.resolveTarget = this.context.getCurrentTexture().createView();
|
|
2203
1818
|
}
|
|
2204
1819
|
else {
|
|
2205
|
-
colorAttachment.view = this.
|
|
1820
|
+
colorAttachment.view = this.context.getCurrentTexture().createView();
|
|
2206
1821
|
}
|
|
2207
1822
|
}
|
|
2208
1823
|
updateSkinMatrices() {
|