Needle Engine

Changes between version 3.45.1-beta.3 and 3.45.1-beta.4
Files changed (2) hide show
  1. src/engine/engine_three_utils.ts +14 -1
  2. src/engine-components/GroundProjection.ts +38 -32
src/engine/engine_three_utils.ts CHANGED
@@ -390,15 +390,24 @@
390
390
  */
391
391
  static copyTexture(texture: Texture, blitMaterial?: ShaderMaterial): Texture {
392
392
  const material = blitMaterial ?? this.blipMaterial!;
393
+
393
394
  material.uniforms.map.value = texture;
394
395
  material.needsUpdate = true;
395
396
  material.uniformsNeedUpdate = true;
396
- if (!this.blipMaterial)
397
+
398
+ // ensure that a blit material exists
399
+ if (!this.blipMaterial) {
397
400
  this.blipMaterial = new ShaderMaterial({
398
401
  uniforms: { map: new Uniform(null) },
399
402
  vertexShader: this.vertex,
400
403
  fragmentShader: this.fragment
401
404
  });
405
+ }
406
+
407
+ // ensure that the blit material has the correct vertex shader
408
+ const origVertexShader = material.vertexShader;
409
+ material.vertexShader = this.vertex;
410
+
402
411
  if (!this.mesh)
403
412
  this.mesh = new Mesh(this.planeGeometry, this.blipMaterial);
404
413
  const mesh = this.mesh;
@@ -414,6 +423,10 @@
414
423
  const tex = new Texture(this.renderer.domElement);
415
424
  tex.name = "Copy";
416
425
  tex.needsUpdate = true; // < important!
426
+
427
+ // reset vertex shader
428
+ material.vertexShader = origVertexShader;
429
+
417
430
  return tex;
418
431
  }
419
432
 
src/engine-components/GroundProjection.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { Material, MeshBasicMaterial, ShaderMaterial, Texture, Vector3 } from "three";
1
+ import { ShaderMaterial, Texture } from "three";
2
2
  import { GroundedSkybox as GroundProjection } from 'three/examples/jsm/objects/GroundedSkybox.js';
3
3
 
4
4
  import { serializable } from "../engine/engine_serialization_decorator.js";
5
5
  import { getParam, Watch as Watch } from "../engine/engine_utils.js";
6
6
  import { Behaviour } from "./Component.js";
7
- import { getBoundingBox, getWorldPosition, setWorldPosition } from "../engine/engine_three_utils.js";
7
+ import { getBoundingBox, getWorldPosition, Graphics, setWorldPosition } from "../engine/engine_three_utils.js";
8
8
 
9
9
  const debug = getParam("debuggroundprojection");
10
10
 
@@ -88,9 +88,9 @@
88
88
  if (this._projection && this.scene.backgroundRotation) {
89
89
  this._projection.rotation.copy(this.scene.backgroundRotation);
90
90
  }
91
- const mat = this._projection?.material as unknown as ShaderMaterial;
92
- if (mat?.uniforms?.blurriness && this.context.scene.backgroundBlurriness !== undefined && mat.uniforms.blurriness.value != this.context.scene.backgroundBlurriness) {
93
- mat.uniforms.blurriness.value = this.context.scene.backgroundBlurriness;
91
+
92
+ if (this.context.scene.backgroundBlurriness !== undefined && this._lastBlurriness != this.context.scene.backgroundBlurriness && this.context.scene.backgroundBlurriness > 0.001) {
93
+ this.updateBlurriness();
94
94
  }
95
95
  }
96
96
 
@@ -114,29 +114,9 @@
114
114
  this._projection?.removeFromParent();
115
115
  this._projection = new GroundProjection(this.context.scene.environment, this._height, this.radius);
116
116
  this._projection.position.y = this._height - offset;
117
- const originalMaterial = this._projection.material as MeshBasicMaterial;
118
-
119
- // const mat = this._projection.material;
120
- const customShader = new ShaderMaterial({
121
- uniforms: {
122
- map: { value: this.context.scene.environment },
123
- blurriness: { value: this.context.scene.backgroundBlurriness }
124
- },
125
- vertexShader: vertexShader,
126
- fragmentShader: fragmentShader
127
- });
128
- customShader.depthWrite = false;
129
- this._projection.material = customShader as unknown as MeshBasicMaterial;
130
- // TODO: Blit the result of this shader once to a texture and use that texture for the projection
131
-
132
- // setInterval(() => {
133
- // if (this._projection?.material === originalMaterial) {
134
- // this._projection.material = customShader as unknown as MeshBasicMaterial;
135
- // }
136
- // else {
137
- // this._projection.material = originalMaterial;
138
- // }
139
- // }, 1000)
117
+ if (this.context.scene.backgroundBlurriness > 0.001) {
118
+ this.updateBlurriness();
119
+ }
140
120
  }
141
121
 
142
122
  this._lastEnvironment = this.context.scene.environment;
@@ -171,6 +151,32 @@
171
151
  }
172
152
  }
173
153
 
154
+ private _blurrynessShader: ShaderMaterial | null = null;
155
+ private _lastBlurriness: number = -1;
156
+
157
+ private updateBlurriness() {
158
+ if (!this._projection) {
159
+ return;
160
+ }
161
+ else if (!this.context.scene.environment) {
162
+ return;
163
+ }
164
+
165
+ if (debug) console.log("Update Blurriness", this.context.scene.backgroundBlurriness);
166
+ this._blurrynessShader ??= new ShaderMaterial({
167
+ uniforms: {
168
+ map: { value: this.context.scene.environment },
169
+ blurriness: { value: this.context.scene.backgroundBlurriness }
170
+ },
171
+ vertexShader: vertexShader,
172
+ fragmentShader: fragmentShader
173
+ });
174
+ this._blurrynessShader.depthWrite = false;
175
+ this._blurrynessShader.uniforms.blurriness.value = this.context.scene.backgroundBlurriness;
176
+ this._lastBlurriness = this.context.scene.backgroundBlurriness;
177
+ this._projection.material.map = Graphics.copyTexture(this.context.scene.environment, this._blurrynessShader);
178
+ }
179
+
174
180
  }
175
181
 
176
182
 
@@ -209,14 +215,14 @@
209
215
  float distance = length(pos - center) * 2.0;
210
216
 
211
217
  // Calculate blur amount based on custom falloff
212
- float blurAmount = customSmoothstep(0.4, 1.0, distance);
218
+ float blurAmount = customSmoothstep(0.5, 1.0, distance);
213
219
  blurAmount = clamp(blurAmount, 0.0, 1.0); // Ensure blur amount is within valid range
214
220
 
215
221
  // Gaussian blur
216
222
  vec2 pixelSize = 1.0 / vec2(textureSize(map, 0));
217
223
  vec4 color = vec4(0.0);
218
224
  float totalWeight = 0.0;
219
- int blurSize = int(20.0 * min(1.0, blurriness) * blurAmount); // Adjust blur size based on distance and blurriness
225
+ int blurSize = int(60.0 * min(1.0, blurriness) * blurAmount); // Adjust blur size based on distance and blurriness
220
226
  float lodLevel = log2(float(blurSize)) * 0.5; // Compute LOD level
221
227
 
222
228
  for (int x = -blurSize; x <= blurSize; x++) {
@@ -232,8 +238,8 @@
232
238
 
233
239
  gl_FragColor = color;
234
240
 
235
- #include <tonemapping_fragment>
236
- #include <colorspace_fragment>
241
+ // #include <tonemapping_fragment>
242
+ // #include <colorspace_fragment>
237
243
 
238
244
  // Uncomment to visualize blur amount
239
245
  // gl_FragColor = vec4(blurAmount, 0.0, 0.0, 1.0);