Skip to content

Commit

Permalink
Nodes: Add VelocityNode and MotionBlurNode. (#1181)
Browse files Browse the repository at this point in the history
* Nodes: Add VelocityNode and MotionBlurNode.

* Update three.js

* Add examples

* Update patch and delete examples

* Update three.js

* Add src

* Update patch and delete src
  • Loading branch information
Methuselah96 authored Aug 25, 2024
1 parent c16b1df commit f728b6a
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 34 deletions.
42 changes: 39 additions & 3 deletions examples-testing/changes.patch
Original file line number Diff line number Diff line change
Expand Up @@ -14841,7 +14841,7 @@ index 97186836..583a9eb3 100644
init();

diff --git a/examples-testing/examples/webgpu_postprocessing_bloom_selective.ts b/examples-testing/examples/webgpu_postprocessing_bloom_selective.ts
index 7140a8ad..a2dae285 100644
index 066a4766..6ce4437c 100644
--- a/examples-testing/examples/webgpu_postprocessing_bloom_selective.ts
+++ b/examples-testing/examples/webgpu_postprocessing_bloom_selective.ts
@@ -1,5 +1,5 @@
Expand All @@ -14860,8 +14860,8 @@ index 7140a8ad..a2dae285 100644
+ const material = (intersects[0].object as THREE.Mesh<THREE.IcosahedronGeometry, THREE.MeshBasicNodeMaterial>)
+ .material;

- const bloomIntensity = material.mrtNode.getNode('bloomIntensity');
+ const bloomIntensity = material.mrtNode!.getNode('bloomIntensity') as UniformNode<number>;
- const bloomIntensity = material.mrtNode.get('bloomIntensity');
+ const bloomIntensity = material.mrtNode!.get('bloomIntensity') as UniformNode<number>;
bloomIntensity.value = bloomIntensity.value === 0 ? 1 : 0;
}
});
Expand Down Expand Up @@ -14978,6 +14978,42 @@ index a4f56b17..ce7e7ad3 100644
compose = sceneMask1.mix(compose, texture(texture1));
compose = sceneMask2.mix(compose, texture(texture2));

diff --git a/examples-testing/examples/webgpu_postprocessing_motion_blur.ts b/examples-testing/examples/webgpu_postprocessing_motion_blur.ts
index aa76acb9..77f5f8b1 100644
--- a/examples-testing/examples/webgpu_postprocessing_motion_blur.ts
+++ b/examples-testing/examples/webgpu_postprocessing_motion_blur.ts
@@ -1,4 +1,4 @@
-import * as THREE from 'three';
+import * as THREE from 'three/webgpu';
import { pass, texture, motionBlur, uniform, output, mrt, mix, velocity, uv, viewportTopLeft } from 'three/tsl';

import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
@@ -9,11 +9,11 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js';

import Stats from 'three/addons/libs/stats.module.js';

-let camera, scene, renderer;
-let boxLeft, boxRight, model, mixer, clock;
-let postProcessing;
-let controls;
-let stats;
+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer;
+let boxLeft: THREE.Mesh, boxRight: THREE.Mesh, model: THREE.Group, mixer: THREE.AnimationMixer, clock: THREE.Clock;
+let postProcessing: THREE.PostProcessing;
+let controls: OrbitControls;
+let stats: Stats;

const params = {
speed: 1.0,
@@ -59,7 +59,7 @@ function init() {
model.rotation.y = Math.PI / 2;

model.traverse(function (child) {
- if (child.isMesh) {
+ if ((child as THREE.Mesh).isMesh) {
child.castShadow = true;
child.receiveShadow = true;
}
diff --git a/examples-testing/examples/webgpu_postprocessing_pixel.ts b/examples-testing/examples/webgpu_postprocessing_pixel.ts
index d7e51008..a9decd46 100644
--- a/examples-testing/examples/webgpu_postprocessing_pixel.ts
Expand Down
63 changes: 34 additions & 29 deletions src-testing/changes.patch
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ index e4a040de..c52771e6 100644
addNodeElement('toAttribute', bufferNode => bufferAttribute(bufferNode.value));

diff --git a/src-testing/src/nodes/accessors/TextureNode.ts b/src-testing/src/nodes/accessors/TextureNode.ts
index 163e3ccc..e5516cc2 100644
index 644c08f4..2141c761 100644
--- a/src-testing/src/nodes/accessors/TextureNode.ts
+++ b/src-testing/src/nodes/accessors/TextureNode.ts
@@ -3,15 +3,41 @@ import { uv } from './UVNode.js';
Expand Down Expand Up @@ -206,7 +206,7 @@ index 163e3ccc..e5516cc2 100644
+ referenceNode: this | null;
+
+ _value: Texture;
+ _matrixUniform: ShaderNodeObject<UniformNode<Matrix3>>;
+ _matrixUniform: ShaderNodeObject<UniformNode<Matrix3>> | null;
+
+ constructor(
+ value: Texture,
Expand Down Expand Up @@ -316,7 +316,7 @@ index 163e3ccc..e5516cc2 100644
+ uv(uvNode: ShaderNodeObject<Node> | null) {
const textureNode = this.clone();
textureNode.uvNode = nodeObject(uvNode);
textureNode.referenceNode = this;
textureNode.referenceNode = this.getSelf();
@@ -262,7 +288,7 @@ class TextureNode extends UniformNode {
return nodeObject(textureNode);
}
Expand All @@ -325,7 +325,7 @@ index 163e3ccc..e5516cc2 100644
+ blur(amountNode: ShaderNodeObject<Node>) {
const textureNode = this.clone();
textureNode.biasNode = nodeObject(amountNode).mul(maxMipLevel(textureNode));
textureNode.referenceNode = this;
textureNode.referenceNode = this.getSelf();
@@ -270,7 +296,7 @@ class TextureNode extends UniformNode {
return nodeObject(textureNode);
}
Expand All @@ -334,7 +334,7 @@ index 163e3ccc..e5516cc2 100644
+ level(levelNode: ShaderNodeObject<Node> | null) {
const textureNode = this.clone();
textureNode.levelNode = nodeObject(levelNode);
textureNode.referenceNode = this;
textureNode.referenceNode = this.getSelf();
diff --git a/src-testing/src/nodes/code/CodeNode.ts b/src-testing/src/nodes/code/CodeNode.ts
index 06347564..1f81819b 100644
--- a/src-testing/src/nodes/code/CodeNode.ts
Expand Down Expand Up @@ -3719,7 +3719,7 @@ index 0d0c35a2..f5a186e1 100644
// size of a chunk in bytes (STD140 layout)

diff --git a/src-testing/src/renderers/common/CubeRenderTarget.ts b/src-testing/src/renderers/common/CubeRenderTarget.ts
index 44f4f3c2..3c970fc0 100644
index f964768c..75ffd8ca 100644
--- a/src-testing/src/renderers/common/CubeRenderTarget.ts
+++ b/src-testing/src/renderers/common/CubeRenderTarget.ts
@@ -9,17 +9,22 @@ import { CubeCamera } from '../../cameras/CubeCamera.js';
Expand Down Expand Up @@ -6734,10 +6734,10 @@ index d2d92cb2..c022f814 100644
for (const uniform of this.uniforms) {
const node = uniform.nodeUniform.node;
diff --git a/src-testing/src/renderers/common/nodes/Nodes.ts b/src-testing/src/renderers/common/nodes/Nodes.ts
index a162ac89..d43ca101 100644
index 6cac5017..1d75e72b 100644
--- a/src-testing/src/renderers/common/nodes/Nodes.ts
+++ b/src-testing/src/renderers/common/nodes/Nodes.ts
@@ -15,25 +15,78 @@ import {
@@ -16,25 +16,78 @@ import {
normalWorld,
pmremTexture,
viewportTopLeft,
Expand Down Expand Up @@ -6820,7 +6820,7 @@ index a162ac89..d43ca101 100644
const groupNode = nodeUniformsGroup.groupNode;
const name = groupNode.name;

@@ -73,7 +126,7 @@ class Nodes extends DataMap {
@@ -74,7 +127,7 @@ class Nodes extends DataMap {

// other groups are updated just when groupNode.needsUpdate is true

Expand All @@ -6829,7 +6829,7 @@ index a162ac89..d43ca101 100644

let groupData = this.groupsData.get(groupChain);
if (groupData === undefined) this.groupsData.set(groupChain, (groupData = {}));
@@ -87,11 +140,11 @@ class Nodes extends DataMap {
@@ -88,11 +141,11 @@ class Nodes extends DataMap {
return false;
}

Expand All @@ -6843,7 +6843,7 @@ index a162ac89..d43ca101 100644
const renderObjectData = this.get(renderObject);

let nodeBuilderState = renderObjectData.nodeBuilderState;
@@ -128,20 +181,20 @@ class Nodes extends DataMap {
@@ -129,20 +182,20 @@ class Nodes extends DataMap {
return nodeBuilderState;
}

Expand All @@ -6869,7 +6869,7 @@ index a162ac89..d43ca101 100644
const computeData = this.get(computeNode);

let nodeBuilderState = computeData.nodeBuilderState;
@@ -158,7 +211,7 @@ class Nodes extends DataMap {
@@ -159,7 +212,7 @@ class Nodes extends DataMap {
return nodeBuilderState;
}

Expand All @@ -6878,7 +6878,7 @@ index a162ac89..d43ca101 100644
return new NodeBuilderState(
nodeBuilder.vertexShader,
nodeBuilder.fragmentShader,
@@ -173,20 +226,28 @@ class Nodes extends DataMap {
@@ -174,20 +227,28 @@ class Nodes extends DataMap {
);
}

Expand Down Expand Up @@ -6915,7 +6915,7 @@ index a162ac89..d43ca101 100644
const callId = this.renderer.info.calls;

let cacheKeyData = this.callHashCache.get(chain);
@@ -212,7 +273,7 @@ class Nodes extends DataMap {
@@ -213,7 +274,7 @@ class Nodes extends DataMap {
return cacheKeyData.cacheKey;
}

Expand All @@ -6924,7 +6924,7 @@ index a162ac89..d43ca101 100644
this.updateEnvironment(scene);
this.updateFog(scene);
this.updateBackground(scene);
@@ -222,7 +283,7 @@ class Nodes extends DataMap {
@@ -223,7 +284,7 @@ class Nodes extends DataMap {
return this.renderer.getRenderTarget() ? false : true;
}

Expand All @@ -6933,7 +6933,7 @@ index a162ac89..d43ca101 100644
const sceneData = this.get(scene);
const background = scene.background;

@@ -231,15 +292,15 @@ class Nodes extends DataMap {
@@ -236,9 +297,9 @@ class Nodes extends DataMap {
let backgroundNode = null;

if (
Expand All @@ -6944,7 +6944,12 @@ index a162ac89..d43ca101 100644
+ (background as CubeTexture).mapping === EquirectangularReflectionMapping ||
+ (background as CubeTexture).mapping === EquirectangularRefractionMapping
) {
backgroundNode = pmremTexture(background, normalWorld);
if (scene.backgroundBlurriness > 0) {
backgroundNode = pmremTexture(background, normalWorld);
@@ -253,10 +314,10 @@ class Nodes extends DataMap {

backgroundNode = cubeMapNode(envMap);
}
- } else if (background.isTexture === true) {
- backgroundNode = texture(background, viewportBottomLeft).setUpdateMatrix(true);
- } else if (background.isColor !== true) {
Expand All @@ -6956,7 +6961,7 @@ index a162ac89..d43ca101 100644
}

sceneData.backgroundNode = backgroundNode;
@@ -251,7 +312,7 @@ class Nodes extends DataMap {
@@ -269,7 +330,7 @@ class Nodes extends DataMap {
}
}

Expand All @@ -6965,7 +6970,7 @@ index a162ac89..d43ca101 100644
const sceneData = this.get(scene);
const fog = scene.fog;

@@ -259,9 +320,9 @@ class Nodes extends DataMap {
@@ -277,9 +338,9 @@ class Nodes extends DataMap {
if (sceneData.fog !== fog) {
let fogNode = null;

Expand All @@ -6977,7 +6982,7 @@ index a162ac89..d43ca101 100644
fogNode = rangeFog(
reference('color', 'color', fog),
reference('near', 'float', fog),
@@ -280,7 +341,7 @@ class Nodes extends DataMap {
@@ -298,7 +359,7 @@ class Nodes extends DataMap {
}
}

Expand All @@ -6986,7 +6991,7 @@ index a162ac89..d43ca101 100644
const sceneData = this.get(scene);
const environment = scene.environment;

@@ -288,7 +349,7 @@ class Nodes extends DataMap {
@@ -306,7 +367,7 @@ class Nodes extends DataMap {
if (sceneData.environment !== environment) {
let environmentNode = null;

Expand All @@ -6995,7 +7000,7 @@ index a162ac89..d43ca101 100644
environmentNode = cubeTexture(environment);
} else if (environment.isTexture === true) {
environmentNode = texture(environment);
@@ -305,7 +366,13 @@ class Nodes extends DataMap {
@@ -323,7 +384,13 @@ class Nodes extends DataMap {
}
}

Expand All @@ -7010,7 +7015,7 @@ index a162ac89..d43ca101 100644
const nodeFrame = this.nodeFrame;
nodeFrame.renderer = renderer;
nodeFrame.scene = scene;
@@ -316,7 +383,7 @@ class Nodes extends DataMap {
@@ -334,7 +401,7 @@ class Nodes extends DataMap {
return nodeFrame;
}

Expand All @@ -7019,7 +7024,7 @@ index a162ac89..d43ca101 100644
return this.getNodeFrame(
renderObject.renderer,
renderObject.scene,
@@ -332,17 +399,17 @@ class Nodes extends DataMap {
@@ -350,17 +417,17 @@ class Nodes extends DataMap {
return renderer.toneMapping + ',' + renderer.currentColorSpace;
}

Expand All @@ -7040,7 +7045,7 @@ index a162ac89..d43ca101 100644
renderer.toneMapping,
renderer.currentColorSpace,
);
@@ -352,7 +419,7 @@ class Nodes extends DataMap {
@@ -370,7 +437,7 @@ class Nodes extends DataMap {
return output;
}

Expand All @@ -7049,7 +7054,7 @@ index a162ac89..d43ca101 100644
const nodeFrame = this.getNodeFrameForRender(renderObject);
const nodeBuilder = renderObject.getNodeBuilderState();

@@ -361,7 +428,7 @@ class Nodes extends DataMap {
@@ -379,7 +446,7 @@ class Nodes extends DataMap {
}
}

Expand All @@ -7058,7 +7063,7 @@ index a162ac89..d43ca101 100644
const nodeFrame = this.getNodeFrameForRender(renderObject);
const nodeBuilder = renderObject.getNodeBuilderState();

@@ -370,7 +437,7 @@ class Nodes extends DataMap {
@@ -388,7 +455,7 @@ class Nodes extends DataMap {
}
}

Expand All @@ -7067,7 +7072,7 @@ index a162ac89..d43ca101 100644
const nodeFrame = this.getNodeFrame();
const nodeBuilder = this.getForCompute(computeNode);

@@ -379,7 +446,7 @@ class Nodes extends DataMap {
@@ -397,7 +464,7 @@ class Nodes extends DataMap {
}
}

Expand Down Expand Up @@ -7502,7 +7507,7 @@ index ec5211b5..4fe4f075 100644
const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache);

diff --git a/src-testing/src/renderers/webgpu/WebGPUBackend.ts b/src-testing/src/renderers/webgpu/WebGPUBackend.ts
index 2b2aeefc..82d67043 100644
index dd4e9ca8..b2b10545 100644
--- a/src-testing/src/renderers/webgpu/WebGPUBackend.ts
+++ b/src-testing/src/renderers/webgpu/WebGPUBackend.ts
@@ -957,7 +957,7 @@ class WebGPUBackend extends Backend {
Expand Down
2 changes: 1 addition & 1 deletion three.js
Submodule three.js updated 41 files
+3 −3 build/three.cjs
+3 −3 build/three.module.js
+458 −49 build/three.webgpu.js
+1 −1 build/three.webgpu.min.js
+1 −0 examples/files.json
+3 −3 examples/jsm/objects/SkyMesh.js
+2 −2 examples/jsm/objects/Water2Mesh.js
+3 −3 examples/jsm/objects/WaterMesh.js
+ examples/screenshots/webgpu_clearcoat.jpg
+ examples/screenshots/webgpu_cubemap_adjustments.jpg
+ examples/screenshots/webgpu_cubemap_dynamic.jpg
+ examples/screenshots/webgpu_lightprobe.jpg
+ examples/screenshots/webgpu_loader_gltf.jpg
+ examples/screenshots/webgpu_loader_gltf_iridescence.jpg
+ examples/screenshots/webgpu_loader_gltf_sheen.jpg
+ examples/screenshots/webgpu_loader_materialx.jpg
+ examples/screenshots/webgpu_materials_basic.jpg
+ examples/screenshots/webgpu_materials_envmaps.jpg
+ examples/screenshots/webgpu_materials_transmission.jpg
+ examples/screenshots/webgpu_mrt.jpg
+ examples/screenshots/webgpu_parallax_uv.jpg
+ examples/screenshots/webgpu_postprocessing_3dlut.jpg
+ examples/screenshots/webgpu_postprocessing_motion_blur.jpg
+1 −1 examples/webgpu_postprocessing_bloom_selective.html
+244 −0 examples/webgpu_postprocessing_motion_blur.html
+2 −0 src/nodes/Nodes.js
+2 −1 src/nodes/accessors/PositionNode.js
+1 −1 src/nodes/accessors/ReferenceNode.js
+68 −12 src/nodes/accessors/SkinningNode.js
+7 −8 src/nodes/accessors/TextureNode.js
+83 −0 src/nodes/accessors/VelocityNode.js
+7 −1 src/nodes/core/MRTNode.js
+25 −0 src/nodes/display/MotionBlurNode.js
+5 −1 src/nodes/display/PassNode.js
+2 −2 src/nodes/display/ToneMappingNode.js
+1 −1 src/nodes/utils/CubeMapNode.js
+3 −0 src/nodes/utils/ReflectorNode.js
+6 −0 src/renderers/common/CubeRenderTarget.js
+2 −0 src/renderers/common/QuadMesh.js
+26 −2 src/renderers/common/nodes/Nodes.js
+1 −1 src/renderers/webgpu/WebGPUBackend.js
2 changes: 2 additions & 0 deletions types/three/src/nodes/Nodes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ export { default as TextureNode, sampler, texture } from "./accessors/TextureNod
export { default as UniformArrayNode, uniformArray } from "./accessors/UniformArrayNode.js";
export { default as UserDataNode, userData } from "./accessors/UserDataNode.js";
export * from "./accessors/UVNode.js";
export * from "./accessors/VelocityNode.js";
export { default as VertexColorNode, vertexColor } from "./accessors/VertexColorNode.js";

// display
Expand Down Expand Up @@ -327,6 +328,7 @@ export { default as FXAANode, fxaa } from "./display/FXAANode.js";
export { default as GaussianBlurNode, gaussianBlur } from "./display/GaussianBlurNode.js";
export { ao, default as GTAONode } from "./display/GTAONode.js";
export { default as Lut3DNode, lut3D } from "./display/Lut3DNode.js";
export * from "./display/MotionBlurNode.js";
export { default as NormalMapNode, normalMap } from "./display/NormalMapNode.js";
export { default as PixelationPassNode, pixelationPass } from "./display/PixelationPassNode.js";
export { default as PosterizeNode, posterize } from "./display/PosterizeNode.js";
Expand Down
1 change: 1 addition & 0 deletions types/three/src/nodes/accessors/PositionNode.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ShaderNodeObject } from "../shadernode/ShaderNode.js";

export const positionGeometry: ShaderNodeObject<Node>;
export const positionLocal: ShaderNodeObject<Node>;
export const positionPrevious: ShaderNodeObject<Node>;
export const positionWorld: ShaderNodeObject<Node>;
export const positionWorldDirection: ShaderNodeObject<Node>;
export const positionView: ShaderNodeObject<Node>;
Expand Down
10 changes: 10 additions & 0 deletions types/three/src/nodes/accessors/SkinningNode.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SkinnedMesh } from "../../objects/SkinnedMesh.js";
import Node from "../core/Node.js";
import NodeBuilder from "../core/NodeBuilder.js";
import { ShaderNodeObject } from "../shadernode/ShaderNode.js";

export default class SkinningNode extends Node {
Expand All @@ -12,8 +13,17 @@ export default class SkinningNode extends Node {
bindMatrixNode: Node;
bindMatrixInverseNode: Node;
boneMatricesNode: Node;
previousBoneMatricesNode: Node | null;

constructor(skinnedMesh: SkinnedMesh, useReference?: boolean);

getSkinnedPosition(boneMatrices?: Node, position?: Node): ShaderNodeObject<Node>;

getSkinnedNormal(boneMatrices?: Node, normal?: Node): ShaderNodeObject<Node>;

getPreviousSkinnedPosition(builder: NodeBuilder): ShaderNodeObject<Node>;

needsPreviousBoneMatrices(builder: NodeBuilder): boolean;
}

export const skinning: (skinnedMesh: SkinnedMesh) => ShaderNodeObject<SkinningNode>;
Expand Down
15 changes: 15 additions & 0 deletions types/three/src/nodes/accessors/VelocityNode.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Matrix4 } from "../../math/Matrix4.js";
import TempNode from "../core/TempNode.js";
import UniformNode from "../core/UniformNode.js";
import { ShaderNodeObject } from "../shadernode/ShaderNode.js";

declare class VelocityNode extends TempNode {
previousProjectionMatrix: UniformNode<Matrix4>;
previousModelViewMatrix: UniformNode<Matrix4>;

constructor();
}

export default VelocityNode;

export const velocity: ShaderNodeObject<VelocityNode>;
Loading

0 comments on commit f728b6a

Please sign in to comment.