Skip to content

Commit 5140e1f

Browse files
committed
Enhance MeshBlendNode and example: Update rendering parameters and improve scene lighting
1 parent 9ca4c36 commit 5140e1f

File tree

2 files changed

+33
-37
lines changed

2 files changed

+33
-37
lines changed

examples/jsm/tsl/display/MeshBlendNode.js

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { TempNode, MeshBasicNodeMaterial, RenderTarget, RGBAFormat, NearestFilter, QuadMesh, Vector2 } from 'three/webgpu';
22
import { nodeObject, vec4, vec3, float, modelPosition, modelWorldMatrix, passTexture, hash, Fn, wgslFn, NodeUpdateType, texture, screenUV } from 'three/tsl';
33

4+
//Source: https://www.jacktollenaar.top/mesh-seam-smoothing-blending#h.50wag6hqg9gh
5+
46
const _size = /*@__PURE__*/ new Vector2();
57

68
class MeshBlendNode extends TempNode {
@@ -9,24 +11,18 @@ class MeshBlendNode extends TempNode {
911
this.sceneOutputNode = sceneOutputNode;
1012
this.sceneDepthNode = sceneDepthNode;
1113
this.updateBeforeType = NodeUpdateType.FRAME;
12-
this.renderTarget = new RenderTarget(
13-
window.innerWidth * window.devicePixelRatio,
14-
window.innerHeight * window.devicePixelRatio,
15-
{ format: RGBAFormat, count: 1, minFilter: NearestFilter, magFilter: NearestFilter }
16-
);
14+
this.renderTarget = new RenderTarget(1, 1);
1715
this.mainCamera = camera;
1816
this.mainScene = scene;
19-
this.factor = float(.1);
17+
this.blendFactor = float(1.2);
2018
this.kernelSize = float(5);
21-
this.kernelRadius = float(0.3);
22-
this.depthFalloff = float(0.00001);
23-
this.depthThreshold = float(0.5);
19+
this.kernelRadius = float(0.01 * this.blendFactor.value);
20+
this.depthFalloff = float(0.0001 * this.blendFactor.value);
2421
this.debugMaterial = new MeshBasicNodeMaterial();
2522
this._quadMesh = new QuadMesh(this.debugMaterial);
2623
}
2724

2825
setup(){
29-
console.log("setup mesh blend")
3026
const CustomHash = wgslFn(`
3127
fn Hash(p: vec3f) -> f32 {
3228
@@ -35,12 +31,8 @@ class MeshBlendNode extends TempNode {
3531
return fract(lp.x * lp.y * lp.z * (lp.x + lp.y + lp.z));
3632
}
3733
`)
38-
this.hashShader = Fn( ( { material, geometry, object } ) => {
39-
// const objectPosition = new THREE.Vector3();
40-
// object.getWorldPosition(objectPosition);
41-
// const pos = vec3().mul(modelPosition);
34+
this.hashShader = Fn( () => {
4235
let p = vec3(modelWorldMatrix.mul(vec3(modelPosition))).toVar();
43-
4436
return vec4(CustomHash(p), 0., 0., 1.);
4537
});
4638
this.hashMaterial = new MeshBasicNodeMaterial();
@@ -49,8 +41,7 @@ class MeshBlendNode extends TempNode {
4941
const uv = screenUV;
5042
const FinalOutputNode = Fn(()=>{
5143
const outputPassFunc1 = wgslFn(`
52-
fn OutputPassFunc1(sceneColor: vec4<f32>, sceneDepth: vec4<f32>, tex: texture_2d<f32>, sampler: sampler, uv: vec2f, kernelSize: f32, kernelRadius: f32, depthFalloff: f32, depthThreshold: f32) -> vec4<f32> {
53-
var result = sceneColor;
44+
fn OutputPassFunc1(sceneDepth: vec4<f32>, tex: texture_2d<f32>, sampler: sampler, uv: vec2f, kernelSize: f32, kernelRadius: f32, depthFalloff: f32) -> vec4<f32> {
5445
var seamLocation = vec2<f32>(0., 0.);
5546
var minDist = f32(9999999.);
5647
@@ -76,7 +67,7 @@ class MeshBlendNode extends TempNode {
7667
`)
7768

7869
const finalPass = wgslFn(`
79-
fn FinalPass(sceneColor: vec3f, mirroredColor: vec3f, seamLocation: vec2f, kernelRadius: f32, sceneDepth: vec4f, otherDepth: vec4f, depthFalloff: f32, minDist: f32, depthThreshold: f32) -> vec3f {
70+
fn FinalPass(sceneColor: vec4f, mirroredColor: vec4f, seamLocation: vec2f, kernelRadius: f32, sceneDepth: vec4f, otherDepth: vec4f, depthFalloff: f32, minDist: f32) -> vec4f {
8071
8172
let depthDiff = abs(otherDepth.r - sceneDepth.r);
8273
@@ -85,26 +76,22 @@ class MeshBlendNode extends TempNode {
8576
let depthWeight = saturate(1. -depthDiff / depthFalloff * kernelRadius);
8677
var finalWeight = weight * depthWeight;
8778
88-
if(sceneDepth.r > sceneDepth.r + depthThreshold){
89-
finalWeight = 0.;
90-
}
9179
return mix(sceneColor, mirroredColor, finalWeight);
9280
}
9381
`);
9482

9583
const pass1 = outputPassFunc1(
96-
texture(this.sceneOutputNode, uv),
9784
texture(this.sceneDepthNode, uv),
9885
texture(this.renderTarget.textures[0], uv),
9986
texture(this.sceneOutputNode, uv),
100-
uv, this.kernelSize, this.kernelRadius, this.depthFalloff, this.depthThreshold);
87+
uv, this.kernelSize, this.kernelRadius, this.depthFalloff);
10188

10289
const mirroredColor = texture(this.sceneOutputNode, uv.add(pass1.xy.mul(2.)));
10390
const otherDepth = texture(this.sceneDepthNode, uv.add(pass1.xy.mul(2.)));
10491

10592
const sceneColor = texture(this.sceneOutputNode, uv);
10693
const sceneDepth = texture(this.sceneDepthNode, uv);
107-
return finalPass(sceneColor, mirroredColor, pass1.xy, this.kernelRadius, sceneDepth, otherDepth, this.depthFalloff, pass1.z, this.depthThreshold);
94+
return finalPass(sceneColor, mirroredColor, pass1.xy, this.kernelRadius, sceneDepth, otherDepth, this.depthFalloff, pass1.z);
10895
})();
10996
return FinalOutputNode;
11097
}

examples/webgpu_postprocessing_meshblend.html

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<script type="module">
3333

3434
import * as THREE from 'three/webgpu';
35-
import { pass, mrt, output, normalView, diffuseColor, velocity, add, vec3, vec4, float, directionToColor, colorToDirection, sample } from 'three/tsl';
35+
import { pass, mrt, output, normalView, diffuseColor, velocity, add, vec3, vec4, directionToColor, colorToDirection, sample, depth } from 'three/tsl';
3636
import { meshblend } from 'three/addons/tsl/display/MeshBlendNode.js';
3737

3838
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
@@ -49,7 +49,7 @@
4949
camera.position.set( 0, 10, 30 );
5050

5151
scene = new THREE.Scene();
52-
scene.background = new THREE.Color( 0xaaaaaa );
52+
scene.background = new THREE.Color("#33334C");
5353

5454
renderer = new THREE.WebGPURenderer();
5555
//renderer.setPixelRatio( window.devicePixelRatio ); // probably too costly for most hardware
@@ -68,6 +68,9 @@
6868
controls.maxDistance = 100;
6969
controls.update();
7070

71+
var directionalLight = new THREE.DirectionalLight(0xffffff);
72+
directionalLight.position.set(1, 1, 1);
73+
scene.add(directionalLight);
7174
//
7275

7376
postProcessing = new THREE.PostProcessing( renderer );
@@ -106,36 +109,41 @@
106109
} );
107110

108111
// Ambient light
109-
const ambientLight = new THREE.AmbientLight( '#0c0c0c' );
112+
const ambientLight = new THREE.AmbientLight(0x404040, 2);
110113
scene.add( ambientLight );
111114

112115
textureLoader = new THREE.TextureLoader();
113116
const texture1 = textureLoader.load( 'textures/brick_diffuse.jpg' );
114-
const texture2 = textureLoader.load( 'textures/jade.jpg' );
117+
texture1.colorSpace = THREE.SRGBColorSpace;
118+
const texture2 = textureLoader.load( 'textures/floors/FloorsCheckerboard_S_Diffuse.jpg' );
119+
texture2.colorSpace = THREE.SRGBColorSpace;
115120

116-
sphere1 = new THREE.Mesh(new THREE.SphereGeometry(3), new THREE.MeshBasicMaterial({ map: texture1 }));
121+
sphere1 = new THREE.Mesh(new THREE.SphereGeometry(3), new THREE.MeshPhongMaterial({ map: texture1 }));
117122
sphere1.position.set(5, 5, 0);
118123
scene.add(sphere1);
119124

120-
sphere2 = new THREE.Mesh(new THREE.SphereGeometry(3), new THREE.MeshBasicMaterial({ map: texture2 }));
125+
sphere2 = new THREE.Mesh(new THREE.SphereGeometry(3), new THREE.MeshPhongMaterial({ color: "orange"}));
121126
sphere2.position.set(0, 5, 0);
122127
scene.add(sphere2);
123-
124-
floor = new THREE.Mesh(new THREE.BoxGeometry(50, 1, 50), new THREE.MeshStandardMaterial({ map: texture1 }));
128+
129+
floor = new THREE.Mesh(new THREE.BoxGeometry(50, 1, 50), new THREE.MeshPhongMaterial({ map: texture2 }));
125130
scene.add(floor);
126131
floor.position.set(0, 2.5, 0);
127132

128133
window.addEventListener( 'resize', onWindowResize );
129-
const blendRadius = float(0.1);
130134

131-
const meshBlend = meshblend( scenePassDiffuse, scenePassDepth, camera, scene );
135+
const meshBlend = meshblend( scenePassColor, scenePassDepth, camera, scene );
132136
postProcessing.outputNode = meshBlend;
133137

134138
const gui = renderer.inspector.createParameters( 'MeshBlend settings' );
135139
gui.add( meshBlend.kernelSize, 'value', 1, 20 ).step( 1 ).name( 'kernel size' ).onChange(() => postProcessing.needsUpdate = true);
136-
gui.add( meshBlend.kernelRadius, 'value', 0.01, 1 ).step( 0.01 ).name( 'kernel radius' ).onChange(() => postProcessing.needsUpdate = true);
137-
// gui.add( meshBlend.depthFalloff, 'value', 0.001, 1 ).step( 0.1 ).name( 'depth falloff' ).onChange(() => postProcessing.needsUpdate = true);
138-
gui.add( meshBlend.depthThreshold, 'value', 0, 1 ).step( 0.01 ).name( 'depth threshold' ).onChange(() => postProcessing.needsUpdate = true);
140+
gui.add( meshBlend.blendFactor, 'value', 0.1, 10 ).step( 0.01 ).name( 'blend factor' ).onChange(() => {
141+
meshBlend.kernelRadius.value = 0.01 * meshBlend.blendFactor.value;
142+
meshBlend.depthFalloff.value = 0.0001 * meshBlend.blendFactor.value;
143+
postProcessing.needsUpdate = true;
144+
});
145+
// gui.add( meshBlend.kernelRadius, 'value', 0.01, 1 ).step( 0.01 ).name( 'kernel radius' ).onChange(() => postProcessing.needsUpdate = true);
146+
// gui.add( meshBlend.depthFalloff, 'value', 0.001, 0.1 ).step( 0.01 ).name( 'depth falloff' ).onChange(() => postProcessing.needsUpdate = true);
139147

140148
postProcessing.needsUpdate = true;
141149
}
@@ -157,6 +165,7 @@
157165
controls.update();
158166

159167
sphere2.position.x = Math.sin( Date.now() * 0.001 ) * 3;
168+
sphere1.position.y = 5 + Math.sin( Date.now() * 0.001 ) * 3;
160169
postProcessing.render();
161170

162171
}

0 commit comments

Comments
 (0)