From 24e0b3272a857c185056fc2c30bde933f8e9b746 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Tue, 22 Mar 2022 17:20:28 -0400 Subject: [PATCH 01/15] beginning work on TRAA pass. --- examples/jsm/postprocessing/TRAAPass.js | 272 ++++++++++++++++++ examples/jsm/shaders/TRAASuperSampleShader.js | 232 +++++++++++++++ src/materials/MeshVelocityMaterial.js | 86 ++++++ src/renderers/WebGLRenderer.js | 12 + .../shaders/ShaderChunk/packing.glsl.js | 22 ++ src/renderers/shaders/ShaderLib.js | 16 ++ .../shaders/ShaderLib/meshvelocity.glsl.js | 90 ++++++ 7 files changed, 730 insertions(+) create mode 100644 examples/jsm/postprocessing/TRAAPass.js create mode 100644 examples/jsm/shaders/TRAASuperSampleShader.js create mode 100644 src/materials/MeshVelocityMaterial.js create mode 100644 src/renderers/shaders/ShaderLib/meshvelocity.glsl.js diff --git a/examples/jsm/postprocessing/TRAAPass.js b/examples/jsm/postprocessing/TRAAPass.js new file mode 100644 index 00000000000000..6107687ff0586f --- /dev/null +++ b/examples/jsm/postprocessing/TRAAPass.js @@ -0,0 +1,272 @@ +import { + Color, + LinearFilter, + Object3D, + Matrix4, + Mesh, + PlaneGeometry, + RGBAFormat, + ShaderMaterial, + UniformsUtils, + WebGLRenderTarget, + Vector2, + Vector3, +} from 'three'; +import { Pass, FullScreenQuad } from './Pass.js'; +import { CopyShader } from '../shaders/CopyShader.js'; +import { TRAASuperSampleShader } from '../shaders/TRAASuperSampleShader.js'; + +class TexturePass extends Pass { + constructor(scene, camera, resolution) { + THREE.Pass.call(this); + + this.scene = scene; + this.camera = camera; + + + this.orthoScene = new THREE.Scene(); + this.orthoCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, -0.01, 1000); + + this.superSampleTRAAMaterial = new TRAASuperSampleShader(); + this.velocityMaterial = new MeshVelocityMaterial(); + + this.currentMaterial = this.superSampleTRAAMaterial; + + var quad = new PlaneGeometry(2, 2); + var quadMesh = new Mesh(quad, this.currentMaterial); + this.orthoScene.add(quadMesh); + this.oldClearColor = new THREE.Color(); + this.oldClearAlpha = 1; + this.needsSwap = false; + + var copyShader = CopyShader; + this.copyUniforms = UniformsUtils.clone(copyShader.uniforms); + + this.copyMaterial = new ShaderMaterial({ + uniforms: this.copyUniforms, + vertexShader: copyShader.vertexShader, + fragmentShader: copyShader.fragmentShader, + transparent: true, + depthWrite: false, + }); + + var params = { + minFilter: LinearFilter, + magFilter: LinearFilter, + format: RGBAFormat, + stencilBuffer: true, + }; + this.accumulatedBeautyRenderTarget = new WebGLRenderTarget( + 256, + 256, + params + ); + + this.previousProjectionViewMatrix = new Matrix4(); + this.currentProjectionViewMatrix = new Matrix4(); + + this.projectionMatrix = new Matrix4(); + this.projectionMatrix.copy(this.camera.projectionMatrix); + + this.numSamplesPerAccumulation = 16; + this.staticMode = false; + + this.depthTexture = null; + } + + dispose() { + if (this.accumulatedBeautyRenderTarget) + this.accumulatedBeautyRenderTarget.dispose(); + } + + setSize(width, height) { + if (this.accumulatedBeautyRenderTarget) + this.accumulatedBeautyRenderTarget.setSize(width, height); + if (this.velocityRenderTarget) + this.velocityRenderTarget.setSize(width, height); + this.projectionMatrix.copy(this.camera.projectionMatrix); + + this.resetPending = true; + }, + + renderOverride( + renderer, + overrideMaterial, + renderTarget, + clearColor, + clearAlpha + ) { + var originalClearColor = renderer.getClearColor().getHex(); + var originalClearAlpha = renderer.getClearAlpha(); + var originalAutoClear = renderer.autoClear; + + renderer.autoClear = false; + + clearColor = overrideMaterial.clearColor || clearColor; + clearAlpha = overrideMaterial.clearAlpha || clearAlpha; + var clearNeeded = clearColor !== undefined && clearColor !== null; + if (clearNeeded) { + renderer.setClearColor(clearColor); + renderer.setClearAlpha(clearAlpha || 0.0); + } + + this.scene.overrideMaterial = overrideMaterial; + // if ( this.camera.clearViewOffset ) this.camera.clearViewOffset(); + + renderer.render( + this.scene, + this.camera, + renderTarget, + clearNeeded, + this.visibilityFunc + ); + this.scene.overrideMaterial = null; + + // restore original state + renderer.autoClear = originalAutoClear; + renderer.setClearColor(originalClearColor); + renderer.setClearAlpha(originalClearAlpha); + }, + + render( + renderer, + writeBuffer, + readBuffer, + delta, + maskActive, + overrideCamera + ) { + var camera = overrideCamera || this.camera; + + this.oldClearColor = renderer.getClearColor().getHex(); + this.oldClearAlpha = renderer.getClearAlpha(); + var oldAutoClear = renderer.autoClear; + var oldAutoClearDepth = renderer.autoClearDepth; + + var width = writeBuffer.width, + height = writeBuffer.height; + + if (!this.velocityRenderTarget) { + var params = { + minFilter: LinearFilter, + magFilter: LinearFilter, + format: RGBAFormat, + }; + this.velocityRenderTarget = new WebGLRenderTarget( + width, + height, + params + ); + } + + this.currentMaterial = this.superSampleTRAAMaterial; + this.currentProjectionViewMatrix.multiplyMatrices( + this.projectionMatrix, + camera.matrixWorldInverse + ); + + this.oldClearColor = renderer.getClearColor().getHex(); + this.oldClearAlpha = renderer.getClearAlpha(); + var oldAutoClear = renderer.autoClear; + var oldAutoClearDepth = renderer.autoClearDepth; + var oldAutoClearColor = renderer.autoClearColor; + + renderer.autoClear = false; + + renderer.setClearColor(new Color(0, 0, 0), 0); + + this.velocityMaterial.currentProjectionViewMatrix.copy( + this.currentProjectionViewMatrix + ); + this.velocityMaterial.previousProjectionViewMatrix.copy( + this.previousProjectionViewMatrix + ); + + //renderer.autoClearColor = true; + this.scene.overrideMaterial = this.velocityMaterial; + renderer.render( + this.scene, + camera, + this.velocityRenderTarget, + true, + this.visibilityFunc + ); + this.scene.overrideMaterial = null; + this.scene.traverse(function (obj) { + if (obj instanceof Object3D) { + obj.matrixWorldPrevious.copy(obj.matrixWorld); + } + }); + + if (camera.view) { + this.currentMaterial.uniforms["jitterOffset"].value.set( + camera.view.offsetX, + camera.view.offsetY + ); + } + + this.currentMaterial.uniforms["currentBeauty"].value = readBuffer.texture; + this.currentMaterial.uniforms["previousBeauty"].value = + this.accumulatedBeautyRenderTarget.texture; + + this.currentMaterial.defines["DEPTH_PACKING"] = + this.depthTexture.depthPacking; + this.currentMaterial.uniforms["tDepth"].value = this.depthTexture; + this.currentMaterial.uniforms["tVelocity"].value = + this.velocityRenderTarget.texture; + if (this.resetPending) { + this.currentMaterial.uniforms["mode"].value = 2; + this.resetPending = false; + } else if (this.staticMode) { + this.currentMaterial.uniforms["mode"].value = 1; + } else { + this.currentMaterial.uniforms["mode"].value = 0; + } + this.currentMaterial.uniforms[ + "cameraInverseProjectionMatrix" + ].value.getInverse(this.projectionMatrix); + this.currentMaterial.uniforms["cameraProjectionMatrix"].value.copy( + this.projectionMatrix + ); + this.currentMaterial.uniforms["cameraInverseViewMatrix"].value.copy( + camera.matrixWorld + ); + this.currentMaterial.uniforms["cameraNearFar"].value.copy( + new Vector2(camera.near, camera.far) + ); + this.currentMaterial.uniforms["textureSize"].value.copy( + new Vector2(width, height) + ); + this.currentMaterial.uniforms["minSampleWeight"].value = + 1.0 / this.numSamplesPerAccumulation; + + //renderer.autoClearColor = true; + //renderer.autoClearDepth = false; + this.orthoScene.overrideMaterial = this.currentMaterial; + renderer.autoClearDepth = false; + renderer.render(this.orthoScene, this.orthoCamera, writeBuffer, true); + this.orthoScene.overrideMaterial = null; + + this.copyUniforms["tDiffuse"].value = writeBuffer.texture; + this.copyUniforms["opacity"].value = 1; + this.orthoScene.overrideMaterial = this.copyMaterial; + renderer.render( + this.orthoScene, + this.orthoCamera, + this.accumulatedBeautyRenderTarget, + true + ); + renderer.render(this.orthoScene, this.orthoCamera, readBuffer, true); + this.orthoScene.overrideMaterial = null; + + renderer.setClearColor(this.oldClearColor, this.oldClearAlpha); + renderer.autoClear = oldAutoClear; + renderer.autoClearColor = oldAutoClearColor; + renderer.autoClearDepth = oldAutoClearDepth; + this.previousProjectionViewMatrix.copy(this.currentProjectionViewMatrix); + } + +} + + +export { TexturePass }; diff --git a/examples/jsm/shaders/TRAASuperSampleShader.js b/examples/jsm/shaders/TRAASuperSampleShader.js new file mode 100644 index 00000000000000..2b6813b7e7d03e --- /dev/null +++ b/examples/jsm/shaders/TRAASuperSampleShader.js @@ -0,0 +1,232 @@ +import { + Color, + Vector3 +} from 'three'; + +/** + * Currently contains: + * + * toon1 + * toon2 + * hatching + * dotted + */ + +const TRAASuperSampleShader = { + + defines: { + DEPTH_PACKING: 1, + PERSPECTIVE_CAMERA: 1, + }, + + uniforms: { + jitterOffset: { value: new THREE.Vector2(0, 0) }, + currentBeauty: { value: null }, + previousBeauty: { value: null }, + tDepth: { value: null }, + tVelocity: { value: null }, + minSampleWeight: { value: 1.0 / 16.0 }, + mode: { value: 0 }, + cameraNearFar: { value: new THREE.Vector2() }, + textureSize: { value: new THREE.Vector2() }, + cameraProjectionMatrix: { value: new THREE.Matrix4() }, + cameraInverseProjectionMatrix: { value: new THREE.Matrix4() }, + cameraInverseViewMatrix: { value: new THREE.Matrix4() }, + }, + + depthWrite: false, + + vertexShader: + "varying vec2 vUv;\ +void main() {\ + vUv = uv;\ + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\ +}", + + fragmentShader: [ + "#include ", + "varying vec2 vUv;", + "uniform sampler2D currentBeauty;", + "uniform sampler2D previousBeauty;", + "uniform sampler2D tDepth;", + "uniform sampler2D tVelocity;", + "uniform vec2 textureSize;", + "uniform mat4 prevProjectionViewMatrix;", + "uniform mat4 currentProjectionViewMatrix;", + "uniform mat4 cameraProjectionMatrix;", + "uniform mat4 cameraInverseProjectionMatrix;", + "uniform mat4 cameraInverseViewMatrix;", + "uniform vec2 cameraNearFar;", + "uniform float minSampleWeight;", + "uniform int mode;", + + "#define MODE_MOVING 0", + "#define MODE_STATIC 1", + + "#include ", + + "float getDepth( const in vec2 screenPosition ) {", + " #if DEPTH_PACKING == 1", + " return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );", + " #else", + " return texture2D( tDepth, screenPosition ).x;", + " #endif", + "}", + + "vec3 find_closest_fragment_9tap(const in vec2 uv) { ", + "const vec3 offset = vec3(1.0, -1.0, 0.0);", + "vec2 texelSize = 1.0/textureSize; ", + + "vec3 dtl = vec3(-1, 1, getDepth( uv + offset.yx * texelSize) ); ", + "vec3 dtc = vec3( 0, 1, getDepth( uv + offset.zx * texelSize) );", + "vec3 dtr = vec3( 1, 1, getDepth( uv + offset.xx * texelSize) );", + + "vec3 dml = vec3(-1, 0, getDepth( uv + offset.yz * texelSize) );", + "vec3 dmc = vec3( 0, 0, getDepth( uv ) );", + "vec3 dmr = vec3( 1, 0, getDepth( uv + offset.xz * texelSize) );", + + "vec3 dbl = vec3(-1, -1, getDepth( uv + offset.yy * texelSize) );", + "vec3 dbc = vec3( 0, -1, getDepth( uv + offset.zy * texelSize) );", + "vec3 dbr = vec3( 1, -1, getDepth( uv + offset.xy * texelSize) );", + + "vec3 dmin = dtl;", + "if ( dmin.z > dtc.z ) dmin = dtc;", + "if ( dmin.z > dtr.z ) dmin = dtr;", + + "if ( dmin.z > dml.z ) dmin = dml;", + "if ( dmin.z > dmc.z ) dmin = dmc;", + "if ( dmin.z > dmr.z ) dmin = dmr;", + + "if ( dmin.z > dbl.z ) dmin = dbl;", + "if ( dmin.z > dbc.z ) dmin = dbc;", + "if ( dmin.z > dbr.z ) dmin = dbr;", + + "return vec3(uv + texelSize.xy * dmin.xy, dmin.z);", + "}", + + "vec3 find_closest_fragment_5tap(const in vec2 uv) ", + "{ ", + "vec2 offset = vec2(1.0, -1.0);", + "vec2 texelSize = 1.0/textureSize; ", + + "vec3 dtl = vec3(-1, 1, getDepth( uv + offset.yx * texelSize ) ); ", + "vec3 dtr = vec3( 1, 1, getDepth( uv + offset.xx * texelSize ) );", + + "vec3 dmc = vec3( 0, 0, getDepth( uv) );", + + "vec3 dbl = vec3(-1, -1, getDepth( uv + offset.yy * texelSize ) );", + "vec3 dbr = vec3( 1, -1, getDepth( uv + offset.xy * texelSize ) );", + + "vec3 dmin = dtl;", + "if ( dmin.z > dtr.z ) dmin = dtr;", + "if ( dmin.z > dmc.z ) dmin = dmc;", + + "if ( dmin.z > dbl.z ) dmin = dbl;", + "if ( dmin.z > dbr.z ) dmin = dbr;", + + "return vec3(uv + texelSize * dmin.xy, dmin.z);", + "}", + + "vec4 clip_aabb(const in vec4 aabb_min, const in vec4 aabb_max, vec4 p )", + "{ ", + "const float FLT_EPS = 1e-8;", + "vec4 p_clip = 0.5 * (aabb_max + aabb_min); ", + "vec4 e_clip = 0.5 * (aabb_max - aabb_min) + FLT_EPS; ", + + "vec4 v_clip = p - p_clip;", + "vec4 v_unit = abs(v_clip / e_clip);", + "float mv_unit = max(v_unit.x, max(v_unit.y, v_unit.z));", + + "if (mv_unit > 1.0) ", + "return p_clip + v_clip / mv_unit;", + "else ", + "return p;", + "}", + + "vec2 getScreenSpaceVelocity( vec2 uv ) {", + "vec4 value = texture2D(tVelocity, uv);", + "if( value.x == 0.0 && value.y == 0.0 && value.z == 0.0 && value.w == 0.0 ) {", + "return vec2( 0.0, 0.0 );", + "}", + "float vx = unpackRGToDepth(value.xy);", + "float vy = unpackRGToDepth(value.zw);", + "return vec2(2.*vx - 1., 2.*vy - 1.);", + "}", + + "vec4 calculateTAA(const in vec2 uv, const in vec2 screenSpaceVelocity) {", + "float _FeedbackMin = 1.0 - 2.0 * minSampleWeight;", + "float _FeedbackMax = 1.0 - minSampleWeight;", + "vec4 currentColor = texture2D(currentBeauty, uv);", + "vec2 lookBackUV = uv - screenSpaceVelocity;", + "vec4 previousColor = texture2D(previousBeauty, lookBackUV);", + "const vec3 offset = vec3(1., -1., 0.);", + "vec2 texelSize = 1./textureSize;", + + "vec4 ctl = texture2D(currentBeauty, uv + offset.yx * texelSize);", + "vec4 ctc = texture2D(currentBeauty, uv + offset.zx * texelSize);", + "vec4 ctr = texture2D(currentBeauty, uv + offset.xx * texelSize);", + "vec4 cml = texture2D(currentBeauty, uv + offset.yz * texelSize);", + "vec4 cmc = currentColor;//texture2D(currentBeauty, uv);", + "vec4 cmr = texture2D(currentBeauty, uv + offset.xz * texelSize);", + "vec4 cbl = texture2D(currentBeauty, uv + offset.yy * texelSize);", + "vec4 cbc = texture2D(currentBeauty, uv + offset.zy * texelSize);", + "vec4 cbr = texture2D(currentBeauty, uv + offset.xy * texelSize);", + + "vec4 cmin = min(ctl, min(ctc, min(ctr, min(cml, min(cmc, min(cmr, min(cbl, min(cbc, cbr))))))));", + "vec4 cmax = max(ctl, max(ctc, max(ctr, max(cml, max(cmc, max(cmr, max(cbl, max(cbc, cbr))))))));", + + "vec4 cavg = (ctl + ctc + ctr + cml + cmc + cmr + cbl + cbc + cbr) / 9.0;", + + "vec4 cmin5 = min(ctc, min(cml, min(cmc, min(cmr, cbc))));", + "vec4 cmax5 = max(ctc, max(cml, max(cmc, max(cmr, cbc))));", + "vec4 cavg5 = (ctc + cml + cmc + cmr + cbc) / 5.0;", + "cmin = 0.5 * (cmin + cmin5);", + "cmax = 0.5 * (cmax + cmax5);", + "cavg = 0.5 * (cavg + cavg5);", + "vec4 clampedPreviousColor =clip_aabb(cmin, cmax, previousColor);", + + "float lum0 = linearToRelativeLuminance(currentColor.rgb);", + "float lum1 = linearToRelativeLuminance(clampedPreviousColor.rgb);", + "float unbiased_diff = abs(lum0 - lum1) / max(lum0, max(lum1, 0.2));", + "float unbiased_weight = 1.0 - unbiased_diff;", + "float unbiased_weight_sqr = unbiased_weight * unbiased_weight;", + "float k_feedback = mix(_FeedbackMin, _FeedbackMax, unbiased_weight_sqr);", + + "vec2 previousVelocity = getScreenSpaceVelocity(lookBackUV);", + + // velocity field over 10 pixels. + "k_feedback *= 1.0 - saturate( length( ( screenSpaceVelocity - previousVelocity ) / texelSize ) / 10.0 );", + + // deals with mirror and other transparent surfaces + "k_feedback *= min( currentColor.a, clampedPreviousColor.a );", + + "if( mode == MODE_MOVING ) {", + "return mix(currentColor, clampedPreviousColor, k_feedback);", + "}", + "else if( mode == MODE_STATIC ) {", + "return mix(currentColor, mix( clampedPreviousColor, previousColor, pow2( previousColor.a ) ), 1.0 - pow( minSampleWeight, 0.75 ) );", + "}", + "else { // mode == MODE_RESET", + "return currentColor;", + "}", + + "}", + + "void main() {", + + "vec3 c_frag = find_closest_fragment_9tap(vUv);", + + "if( c_frag.z >= 1. ) {", + + "gl_FragColor = texture2D(currentBeauty, vUv);", + + "}", + "else {", + + "vec2 screenSpaceVelocity = getScreenSpaceVelocity( vUv );", + "gl_FragColor = calculateTAA(vUv, screenSpaceVelocity);", + + "}", + "}", + ].join("\n"), +} diff --git a/src/materials/MeshVelocityMaterial.js b/src/materials/MeshVelocityMaterial.js new file mode 100644 index 00000000000000..b2ebfb27b401fa --- /dev/null +++ b/src/materials/MeshVelocityMaterial.js @@ -0,0 +1,86 @@ +import { Material } from './Material.js'; +import { Vector2 } from '../math/Vector2.js'; +import { Matrix4 } from '../math/Matrix4.js'; +import { Color } from '../math/Color.js'; + +class MeshVelocityMaterial extends Material { + + constructor( parameters ) { + + Material.call( this ); + + this.type = 'MeshVelocityMaterial'; + + this.depthPacking = BasicDepthPacking; + + this.currentProjectionViewMatrix = new Matrix4(); + this.previousProjectionViewMatrix = new Matrix4(); + + this.color = new Color( 0xffffff ); // diffuse + this.map = null; + + this.displacementMap = null; + + this.alphaMap = null; + + this.skinning = false; + this.morphTargets = false; + + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + + this.fog = false; + this.lights = false; + + // far clipping plane in both RGBA and Basic encoding + this.clearColor = new Color( 1.0, 1.0, 1.0 ); + this.clearAlpha = 1.0; + + this.blending = NoBlending; + this.flatShading = false; + + this.setValues( parameters ); + + } + + + copy( source ) { + + super.copy( source ); + + this.currentProjectionViewMatrix.copy( this.currentProjectionViewMatrix ); + this.previousProjectionViewMatrix.copy( this.previousProjectionViewMatrix ); + + this.opacity = source.opacity; + this.mapSlot.copy( source.mapSlot ); + + this.displacementMapSlot.copy( source.displacementMapSlot ); + + this.alphaMapSlot.copy( source.alphaMapSlot ); + + this.depthPacking = source.depthPacking; + + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + + this.flatShading = source.flatShading; + + this.clearColor = source.clearColor; + this.clearAlpha = source.clearAlpha; + + return this; + + } + +} + +MeshVelocityMaterial.prototype.isMeshVelocityMaterial = true; + +export { MeshVelocityMaterial }; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index e90d9568fcefb2..35d616b649cbf2 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1614,6 +1614,7 @@ function WebGLRenderer( parameters = {} ) { material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshStandardMaterial || + material.isMeshVelocityMaterial || material.envMap ) { const uCamPos = p_uniforms.map.cameraPosition; @@ -1632,6 +1633,7 @@ function WebGLRenderer( parameters = {} ) { material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || + material.isMeshVelocityMaterial || material.isShaderMaterial ) { p_uniforms.setValue( _gl, 'isOrthographic', camera.isOrthographicCamera === true ); @@ -1643,6 +1645,7 @@ function WebGLRenderer( parameters = {} ) { material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || + material.isMeshVelocityMaterial || material.isShaderMaterial || material.isShadowMaterial || object.isSkinnedMesh ) { @@ -1745,6 +1748,15 @@ function WebGLRenderer( parameters = {} ) { } + if ( material.isMeshVelocityMaterial ) { + + // nothing yet + + m_uniforms.currentProjectionViewMatrix.value = material.currentProjectionViewMatrix; + m_uniforms.previousProjectionViewMatrix.value = material.previousProjectionViewMatrix; + + } + // common matrices p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix ); diff --git a/src/renderers/shaders/ShaderChunk/packing.glsl.js b/src/renderers/shaders/ShaderChunk/packing.glsl.js index aaa73db069a91a..620d2564b6ab73 100644 --- a/src/renderers/shaders/ShaderChunk/packing.glsl.js +++ b/src/renderers/shaders/ShaderChunk/packing.glsl.js @@ -25,6 +25,28 @@ float unpackRGBAToDepth( const in vec4 v ) { return dot( v, UnpackFactors ); } +vec2 packDepthToRG( in highp float v ) { + v = v * (1. - EDGE_DISTANCE * 2.) + EDGE_DISTANCE; + v += 0.5 / ( 255.0 ); + + const highp vec4 packFactor = vec4( 1.0, 255.0, 65025.0, 16581375.0 ); + highp vec4 res = fract( v * packFactor ); + res.xy -= res.yz * (1.0/255.0); + + res.zw = vec2( 0.0 ); + + return res.yx; +} + + +float unpackRGToDepth( const in highp vec2 v ) { + const highp vec2 unpackFactor = 1.0 / vec2( 1.0, 255.0 ); + highp float depth = dot( v.yx, unpackFactor ); + depth -= 0.5 / ( 255.0 ); + depth = (depth - EDGE_DISTANCE) * (1. / (1. - EDGE_DISTANCE * 2.)); + return depth; +} + vec4 pack2HalfToRGBA( vec2 v ) { vec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) ); return vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w ); diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 0eb045a995d6ec..2cea805dd49645 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -198,6 +198,22 @@ const ShaderLib = { }, + velocity: { + + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.displacementmap, + { + currentProjectionViewMatrix: { value: null }, + previousProjectionViewMatrix: { value: null } + } + ] ), + + vertexShader: ShaderChunk.meshvelocity_vert, + fragmentShader: ShaderChunk.meshvelocity_frag + + }, + sprite: { uniforms: mergeUniforms( [ diff --git a/src/renderers/shaders/ShaderLib/meshvelocity.glsl.js b/src/renderers/shaders/ShaderLib/meshvelocity.glsl.js new file mode 100644 index 00000000000000..8bc50b74d1663e --- /dev/null +++ b/src/renderers/shaders/ShaderLib/meshvelocity.glsl.js @@ -0,0 +1,90 @@ +export const vertex = /* glsl */` +#include +#include +#include +#include +#include +#include +#include +#include + +uniform mat4 previousProjectionViewMatrix; +uniform mat4 currentProjectionViewMatrix; + +varying vec4 clipPositionCurrent; +varying vec4 clipPositionPrevious; + +void main() { + + + #include + + #include + + #include + #include + #include + #include + +#ifdef USE_SKINNING + + vec4 mvPosition = modelViewMatrix * skinned; + clipPositionCurrent = currentProjectionViewMatrix * modelMatrix * skinned; + clipPositionPrevious = previousProjectionViewMatrix * modelMatrixPrev * skinned; + +#else + + vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 ); + clipPositionCurrent = currentProjectionViewMatrix * modelMatrix * vec4( transformed, 1.0 ); + clipPositionPrevious = previousProjectionViewMatrix * modelMatrixPrev * vec4( transformed, 1.0 ); + +#endif + + gl_Position = projectionMatrix * mvPosition; + + #include + #include +} + +`; + +export const fragment = /* glsl */` +#define NORMAL + +uniform float opacity; + +#include +#include +#include +#include +#include +#include +#include + +varying vec4 clipPositionCurrent; +varying vec4 clipPositionPrevious; + +void main() { + + vec4 diffuseColor = vec4( 1.0 ); + diffuseColor.a = opacity; + + #include + #include + #include + + vec2 ndcPositionCurrent = clipPositionCurrent.xy/clipPositionCurrent.w; + vec2 ndcPositionPrevious = clipPositionPrevious.xy/clipPositionPrevious.w; + vec2 vel = ( ndcPositionCurrent - ndcPositionPrevious ) * 0.5; + vel = vel * 0.5 + 0.5; + vec2 v1 = packDepthToRG(vel.x); + vec2 v2 = packDepthToRG(vel.y); + gl_FragColor = vec4(v1.x, v1.y, v2.x, v2.y); + + #include + +} + +`; + + From 0657f95eba23aa7def4d12e2205e4cb5de7787b8 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Thu, 24 Mar 2022 17:38:06 -0400 Subject: [PATCH 02/15] more work on TRAA. --- examples/jsm/postprocessing/TRAAPass.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/examples/jsm/postprocessing/TRAAPass.js b/examples/jsm/postprocessing/TRAAPass.js index 6107687ff0586f..c96fa39d5d9476 100644 --- a/examples/jsm/postprocessing/TRAAPass.js +++ b/examples/jsm/postprocessing/TRAAPass.js @@ -4,8 +4,11 @@ import { Object3D, Matrix4, Mesh, + MeshVelocityMaterial, + OrthographicCamera, PlaneGeometry, RGBAFormat, + Scene, ShaderMaterial, UniformsUtils, WebGLRenderTarget, @@ -18,14 +21,13 @@ import { TRAASuperSampleShader } from '../shaders/TRAASuperSampleShader.js'; class TexturePass extends Pass { constructor(scene, camera, resolution) { - THREE.Pass.call(this); this.scene = scene; this.camera = camera; - this.orthoScene = new THREE.Scene(); - this.orthoCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, -0.01, 1000); + this.orthoScene = new Scene(); + this.orthoCamera = new OrthographicCamera(-1, 1, 1, -1, -0.01, 1000); this.superSampleTRAAMaterial = new TRAASuperSampleShader(); this.velocityMaterial = new MeshVelocityMaterial(); @@ -35,17 +37,16 @@ class TexturePass extends Pass { var quad = new PlaneGeometry(2, 2); var quadMesh = new Mesh(quad, this.currentMaterial); this.orthoScene.add(quadMesh); - this.oldClearColor = new THREE.Color(); + this.oldClearColor = new Color(); this.oldClearAlpha = 1; this.needsSwap = false; - var copyShader = CopyShader; - this.copyUniforms = UniformsUtils.clone(copyShader.uniforms); + this.copyUniforms = UniformsUtils.clone(CopyShader.uniforms); this.copyMaterial = new ShaderMaterial({ uniforms: this.copyUniforms, - vertexShader: copyShader.vertexShader, - fragmentShader: copyShader.fragmentShader, + vertexShader: CopyShader.vertexShader, + fragmentShader: CopyShader.fragmentShader, transparent: true, depthWrite: false, }); From 476e309e8ba2d352349de491fde79c740cffe4fb Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Thu, 24 Mar 2022 17:39:13 -0400 Subject: [PATCH 03/15] remove TRAA for now. --- examples/jsm/postprocessing/TRAAPass.js | 273 ------------------ examples/jsm/shaders/TRAASuperSampleShader.js | 232 --------------- 2 files changed, 505 deletions(-) delete mode 100644 examples/jsm/postprocessing/TRAAPass.js delete mode 100644 examples/jsm/shaders/TRAASuperSampleShader.js diff --git a/examples/jsm/postprocessing/TRAAPass.js b/examples/jsm/postprocessing/TRAAPass.js deleted file mode 100644 index c96fa39d5d9476..00000000000000 --- a/examples/jsm/postprocessing/TRAAPass.js +++ /dev/null @@ -1,273 +0,0 @@ -import { - Color, - LinearFilter, - Object3D, - Matrix4, - Mesh, - MeshVelocityMaterial, - OrthographicCamera, - PlaneGeometry, - RGBAFormat, - Scene, - ShaderMaterial, - UniformsUtils, - WebGLRenderTarget, - Vector2, - Vector3, -} from 'three'; -import { Pass, FullScreenQuad } from './Pass.js'; -import { CopyShader } from '../shaders/CopyShader.js'; -import { TRAASuperSampleShader } from '../shaders/TRAASuperSampleShader.js'; - -class TexturePass extends Pass { - constructor(scene, camera, resolution) { - - this.scene = scene; - this.camera = camera; - - - this.orthoScene = new Scene(); - this.orthoCamera = new OrthographicCamera(-1, 1, 1, -1, -0.01, 1000); - - this.superSampleTRAAMaterial = new TRAASuperSampleShader(); - this.velocityMaterial = new MeshVelocityMaterial(); - - this.currentMaterial = this.superSampleTRAAMaterial; - - var quad = new PlaneGeometry(2, 2); - var quadMesh = new Mesh(quad, this.currentMaterial); - this.orthoScene.add(quadMesh); - this.oldClearColor = new Color(); - this.oldClearAlpha = 1; - this.needsSwap = false; - - this.copyUniforms = UniformsUtils.clone(CopyShader.uniforms); - - this.copyMaterial = new ShaderMaterial({ - uniforms: this.copyUniforms, - vertexShader: CopyShader.vertexShader, - fragmentShader: CopyShader.fragmentShader, - transparent: true, - depthWrite: false, - }); - - var params = { - minFilter: LinearFilter, - magFilter: LinearFilter, - format: RGBAFormat, - stencilBuffer: true, - }; - this.accumulatedBeautyRenderTarget = new WebGLRenderTarget( - 256, - 256, - params - ); - - this.previousProjectionViewMatrix = new Matrix4(); - this.currentProjectionViewMatrix = new Matrix4(); - - this.projectionMatrix = new Matrix4(); - this.projectionMatrix.copy(this.camera.projectionMatrix); - - this.numSamplesPerAccumulation = 16; - this.staticMode = false; - - this.depthTexture = null; - } - - dispose() { - if (this.accumulatedBeautyRenderTarget) - this.accumulatedBeautyRenderTarget.dispose(); - } - - setSize(width, height) { - if (this.accumulatedBeautyRenderTarget) - this.accumulatedBeautyRenderTarget.setSize(width, height); - if (this.velocityRenderTarget) - this.velocityRenderTarget.setSize(width, height); - this.projectionMatrix.copy(this.camera.projectionMatrix); - - this.resetPending = true; - }, - - renderOverride( - renderer, - overrideMaterial, - renderTarget, - clearColor, - clearAlpha - ) { - var originalClearColor = renderer.getClearColor().getHex(); - var originalClearAlpha = renderer.getClearAlpha(); - var originalAutoClear = renderer.autoClear; - - renderer.autoClear = false; - - clearColor = overrideMaterial.clearColor || clearColor; - clearAlpha = overrideMaterial.clearAlpha || clearAlpha; - var clearNeeded = clearColor !== undefined && clearColor !== null; - if (clearNeeded) { - renderer.setClearColor(clearColor); - renderer.setClearAlpha(clearAlpha || 0.0); - } - - this.scene.overrideMaterial = overrideMaterial; - // if ( this.camera.clearViewOffset ) this.camera.clearViewOffset(); - - renderer.render( - this.scene, - this.camera, - renderTarget, - clearNeeded, - this.visibilityFunc - ); - this.scene.overrideMaterial = null; - - // restore original state - renderer.autoClear = originalAutoClear; - renderer.setClearColor(originalClearColor); - renderer.setClearAlpha(originalClearAlpha); - }, - - render( - renderer, - writeBuffer, - readBuffer, - delta, - maskActive, - overrideCamera - ) { - var camera = overrideCamera || this.camera; - - this.oldClearColor = renderer.getClearColor().getHex(); - this.oldClearAlpha = renderer.getClearAlpha(); - var oldAutoClear = renderer.autoClear; - var oldAutoClearDepth = renderer.autoClearDepth; - - var width = writeBuffer.width, - height = writeBuffer.height; - - if (!this.velocityRenderTarget) { - var params = { - minFilter: LinearFilter, - magFilter: LinearFilter, - format: RGBAFormat, - }; - this.velocityRenderTarget = new WebGLRenderTarget( - width, - height, - params - ); - } - - this.currentMaterial = this.superSampleTRAAMaterial; - this.currentProjectionViewMatrix.multiplyMatrices( - this.projectionMatrix, - camera.matrixWorldInverse - ); - - this.oldClearColor = renderer.getClearColor().getHex(); - this.oldClearAlpha = renderer.getClearAlpha(); - var oldAutoClear = renderer.autoClear; - var oldAutoClearDepth = renderer.autoClearDepth; - var oldAutoClearColor = renderer.autoClearColor; - - renderer.autoClear = false; - - renderer.setClearColor(new Color(0, 0, 0), 0); - - this.velocityMaterial.currentProjectionViewMatrix.copy( - this.currentProjectionViewMatrix - ); - this.velocityMaterial.previousProjectionViewMatrix.copy( - this.previousProjectionViewMatrix - ); - - //renderer.autoClearColor = true; - this.scene.overrideMaterial = this.velocityMaterial; - renderer.render( - this.scene, - camera, - this.velocityRenderTarget, - true, - this.visibilityFunc - ); - this.scene.overrideMaterial = null; - this.scene.traverse(function (obj) { - if (obj instanceof Object3D) { - obj.matrixWorldPrevious.copy(obj.matrixWorld); - } - }); - - if (camera.view) { - this.currentMaterial.uniforms["jitterOffset"].value.set( - camera.view.offsetX, - camera.view.offsetY - ); - } - - this.currentMaterial.uniforms["currentBeauty"].value = readBuffer.texture; - this.currentMaterial.uniforms["previousBeauty"].value = - this.accumulatedBeautyRenderTarget.texture; - - this.currentMaterial.defines["DEPTH_PACKING"] = - this.depthTexture.depthPacking; - this.currentMaterial.uniforms["tDepth"].value = this.depthTexture; - this.currentMaterial.uniforms["tVelocity"].value = - this.velocityRenderTarget.texture; - if (this.resetPending) { - this.currentMaterial.uniforms["mode"].value = 2; - this.resetPending = false; - } else if (this.staticMode) { - this.currentMaterial.uniforms["mode"].value = 1; - } else { - this.currentMaterial.uniforms["mode"].value = 0; - } - this.currentMaterial.uniforms[ - "cameraInverseProjectionMatrix" - ].value.getInverse(this.projectionMatrix); - this.currentMaterial.uniforms["cameraProjectionMatrix"].value.copy( - this.projectionMatrix - ); - this.currentMaterial.uniforms["cameraInverseViewMatrix"].value.copy( - camera.matrixWorld - ); - this.currentMaterial.uniforms["cameraNearFar"].value.copy( - new Vector2(camera.near, camera.far) - ); - this.currentMaterial.uniforms["textureSize"].value.copy( - new Vector2(width, height) - ); - this.currentMaterial.uniforms["minSampleWeight"].value = - 1.0 / this.numSamplesPerAccumulation; - - //renderer.autoClearColor = true; - //renderer.autoClearDepth = false; - this.orthoScene.overrideMaterial = this.currentMaterial; - renderer.autoClearDepth = false; - renderer.render(this.orthoScene, this.orthoCamera, writeBuffer, true); - this.orthoScene.overrideMaterial = null; - - this.copyUniforms["tDiffuse"].value = writeBuffer.texture; - this.copyUniforms["opacity"].value = 1; - this.orthoScene.overrideMaterial = this.copyMaterial; - renderer.render( - this.orthoScene, - this.orthoCamera, - this.accumulatedBeautyRenderTarget, - true - ); - renderer.render(this.orthoScene, this.orthoCamera, readBuffer, true); - this.orthoScene.overrideMaterial = null; - - renderer.setClearColor(this.oldClearColor, this.oldClearAlpha); - renderer.autoClear = oldAutoClear; - renderer.autoClearColor = oldAutoClearColor; - renderer.autoClearDepth = oldAutoClearDepth; - this.previousProjectionViewMatrix.copy(this.currentProjectionViewMatrix); - } - -} - - -export { TexturePass }; diff --git a/examples/jsm/shaders/TRAASuperSampleShader.js b/examples/jsm/shaders/TRAASuperSampleShader.js deleted file mode 100644 index 2b6813b7e7d03e..00000000000000 --- a/examples/jsm/shaders/TRAASuperSampleShader.js +++ /dev/null @@ -1,232 +0,0 @@ -import { - Color, - Vector3 -} from 'three'; - -/** - * Currently contains: - * - * toon1 - * toon2 - * hatching - * dotted - */ - -const TRAASuperSampleShader = { - - defines: { - DEPTH_PACKING: 1, - PERSPECTIVE_CAMERA: 1, - }, - - uniforms: { - jitterOffset: { value: new THREE.Vector2(0, 0) }, - currentBeauty: { value: null }, - previousBeauty: { value: null }, - tDepth: { value: null }, - tVelocity: { value: null }, - minSampleWeight: { value: 1.0 / 16.0 }, - mode: { value: 0 }, - cameraNearFar: { value: new THREE.Vector2() }, - textureSize: { value: new THREE.Vector2() }, - cameraProjectionMatrix: { value: new THREE.Matrix4() }, - cameraInverseProjectionMatrix: { value: new THREE.Matrix4() }, - cameraInverseViewMatrix: { value: new THREE.Matrix4() }, - }, - - depthWrite: false, - - vertexShader: - "varying vec2 vUv;\ -void main() {\ - vUv = uv;\ - gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\ -}", - - fragmentShader: [ - "#include ", - "varying vec2 vUv;", - "uniform sampler2D currentBeauty;", - "uniform sampler2D previousBeauty;", - "uniform sampler2D tDepth;", - "uniform sampler2D tVelocity;", - "uniform vec2 textureSize;", - "uniform mat4 prevProjectionViewMatrix;", - "uniform mat4 currentProjectionViewMatrix;", - "uniform mat4 cameraProjectionMatrix;", - "uniform mat4 cameraInverseProjectionMatrix;", - "uniform mat4 cameraInverseViewMatrix;", - "uniform vec2 cameraNearFar;", - "uniform float minSampleWeight;", - "uniform int mode;", - - "#define MODE_MOVING 0", - "#define MODE_STATIC 1", - - "#include ", - - "float getDepth( const in vec2 screenPosition ) {", - " #if DEPTH_PACKING == 1", - " return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );", - " #else", - " return texture2D( tDepth, screenPosition ).x;", - " #endif", - "}", - - "vec3 find_closest_fragment_9tap(const in vec2 uv) { ", - "const vec3 offset = vec3(1.0, -1.0, 0.0);", - "vec2 texelSize = 1.0/textureSize; ", - - "vec3 dtl = vec3(-1, 1, getDepth( uv + offset.yx * texelSize) ); ", - "vec3 dtc = vec3( 0, 1, getDepth( uv + offset.zx * texelSize) );", - "vec3 dtr = vec3( 1, 1, getDepth( uv + offset.xx * texelSize) );", - - "vec3 dml = vec3(-1, 0, getDepth( uv + offset.yz * texelSize) );", - "vec3 dmc = vec3( 0, 0, getDepth( uv ) );", - "vec3 dmr = vec3( 1, 0, getDepth( uv + offset.xz * texelSize) );", - - "vec3 dbl = vec3(-1, -1, getDepth( uv + offset.yy * texelSize) );", - "vec3 dbc = vec3( 0, -1, getDepth( uv + offset.zy * texelSize) );", - "vec3 dbr = vec3( 1, -1, getDepth( uv + offset.xy * texelSize) );", - - "vec3 dmin = dtl;", - "if ( dmin.z > dtc.z ) dmin = dtc;", - "if ( dmin.z > dtr.z ) dmin = dtr;", - - "if ( dmin.z > dml.z ) dmin = dml;", - "if ( dmin.z > dmc.z ) dmin = dmc;", - "if ( dmin.z > dmr.z ) dmin = dmr;", - - "if ( dmin.z > dbl.z ) dmin = dbl;", - "if ( dmin.z > dbc.z ) dmin = dbc;", - "if ( dmin.z > dbr.z ) dmin = dbr;", - - "return vec3(uv + texelSize.xy * dmin.xy, dmin.z);", - "}", - - "vec3 find_closest_fragment_5tap(const in vec2 uv) ", - "{ ", - "vec2 offset = vec2(1.0, -1.0);", - "vec2 texelSize = 1.0/textureSize; ", - - "vec3 dtl = vec3(-1, 1, getDepth( uv + offset.yx * texelSize ) ); ", - "vec3 dtr = vec3( 1, 1, getDepth( uv + offset.xx * texelSize ) );", - - "vec3 dmc = vec3( 0, 0, getDepth( uv) );", - - "vec3 dbl = vec3(-1, -1, getDepth( uv + offset.yy * texelSize ) );", - "vec3 dbr = vec3( 1, -1, getDepth( uv + offset.xy * texelSize ) );", - - "vec3 dmin = dtl;", - "if ( dmin.z > dtr.z ) dmin = dtr;", - "if ( dmin.z > dmc.z ) dmin = dmc;", - - "if ( dmin.z > dbl.z ) dmin = dbl;", - "if ( dmin.z > dbr.z ) dmin = dbr;", - - "return vec3(uv + texelSize * dmin.xy, dmin.z);", - "}", - - "vec4 clip_aabb(const in vec4 aabb_min, const in vec4 aabb_max, vec4 p )", - "{ ", - "const float FLT_EPS = 1e-8;", - "vec4 p_clip = 0.5 * (aabb_max + aabb_min); ", - "vec4 e_clip = 0.5 * (aabb_max - aabb_min) + FLT_EPS; ", - - "vec4 v_clip = p - p_clip;", - "vec4 v_unit = abs(v_clip / e_clip);", - "float mv_unit = max(v_unit.x, max(v_unit.y, v_unit.z));", - - "if (mv_unit > 1.0) ", - "return p_clip + v_clip / mv_unit;", - "else ", - "return p;", - "}", - - "vec2 getScreenSpaceVelocity( vec2 uv ) {", - "vec4 value = texture2D(tVelocity, uv);", - "if( value.x == 0.0 && value.y == 0.0 && value.z == 0.0 && value.w == 0.0 ) {", - "return vec2( 0.0, 0.0 );", - "}", - "float vx = unpackRGToDepth(value.xy);", - "float vy = unpackRGToDepth(value.zw);", - "return vec2(2.*vx - 1., 2.*vy - 1.);", - "}", - - "vec4 calculateTAA(const in vec2 uv, const in vec2 screenSpaceVelocity) {", - "float _FeedbackMin = 1.0 - 2.0 * minSampleWeight;", - "float _FeedbackMax = 1.0 - minSampleWeight;", - "vec4 currentColor = texture2D(currentBeauty, uv);", - "vec2 lookBackUV = uv - screenSpaceVelocity;", - "vec4 previousColor = texture2D(previousBeauty, lookBackUV);", - "const vec3 offset = vec3(1., -1., 0.);", - "vec2 texelSize = 1./textureSize;", - - "vec4 ctl = texture2D(currentBeauty, uv + offset.yx * texelSize);", - "vec4 ctc = texture2D(currentBeauty, uv + offset.zx * texelSize);", - "vec4 ctr = texture2D(currentBeauty, uv + offset.xx * texelSize);", - "vec4 cml = texture2D(currentBeauty, uv + offset.yz * texelSize);", - "vec4 cmc = currentColor;//texture2D(currentBeauty, uv);", - "vec4 cmr = texture2D(currentBeauty, uv + offset.xz * texelSize);", - "vec4 cbl = texture2D(currentBeauty, uv + offset.yy * texelSize);", - "vec4 cbc = texture2D(currentBeauty, uv + offset.zy * texelSize);", - "vec4 cbr = texture2D(currentBeauty, uv + offset.xy * texelSize);", - - "vec4 cmin = min(ctl, min(ctc, min(ctr, min(cml, min(cmc, min(cmr, min(cbl, min(cbc, cbr))))))));", - "vec4 cmax = max(ctl, max(ctc, max(ctr, max(cml, max(cmc, max(cmr, max(cbl, max(cbc, cbr))))))));", - - "vec4 cavg = (ctl + ctc + ctr + cml + cmc + cmr + cbl + cbc + cbr) / 9.0;", - - "vec4 cmin5 = min(ctc, min(cml, min(cmc, min(cmr, cbc))));", - "vec4 cmax5 = max(ctc, max(cml, max(cmc, max(cmr, cbc))));", - "vec4 cavg5 = (ctc + cml + cmc + cmr + cbc) / 5.0;", - "cmin = 0.5 * (cmin + cmin5);", - "cmax = 0.5 * (cmax + cmax5);", - "cavg = 0.5 * (cavg + cavg5);", - "vec4 clampedPreviousColor =clip_aabb(cmin, cmax, previousColor);", - - "float lum0 = linearToRelativeLuminance(currentColor.rgb);", - "float lum1 = linearToRelativeLuminance(clampedPreviousColor.rgb);", - "float unbiased_diff = abs(lum0 - lum1) / max(lum0, max(lum1, 0.2));", - "float unbiased_weight = 1.0 - unbiased_diff;", - "float unbiased_weight_sqr = unbiased_weight * unbiased_weight;", - "float k_feedback = mix(_FeedbackMin, _FeedbackMax, unbiased_weight_sqr);", - - "vec2 previousVelocity = getScreenSpaceVelocity(lookBackUV);", - - // velocity field over 10 pixels. - "k_feedback *= 1.0 - saturate( length( ( screenSpaceVelocity - previousVelocity ) / texelSize ) / 10.0 );", - - // deals with mirror and other transparent surfaces - "k_feedback *= min( currentColor.a, clampedPreviousColor.a );", - - "if( mode == MODE_MOVING ) {", - "return mix(currentColor, clampedPreviousColor, k_feedback);", - "}", - "else if( mode == MODE_STATIC ) {", - "return mix(currentColor, mix( clampedPreviousColor, previousColor, pow2( previousColor.a ) ), 1.0 - pow( minSampleWeight, 0.75 ) );", - "}", - "else { // mode == MODE_RESET", - "return currentColor;", - "}", - - "}", - - "void main() {", - - "vec3 c_frag = find_closest_fragment_9tap(vUv);", - - "if( c_frag.z >= 1. ) {", - - "gl_FragColor = texture2D(currentBeauty, vUv);", - - "}", - "else {", - - "vec2 screenSpaceVelocity = getScreenSpaceVelocity( vUv );", - "gl_FragColor = calculateTAA(vUv, screenSpaceVelocity);", - - "}", - "}", - ].join("\n"), -} From 6d8db2eef4fe41276fdbf971830ca0c8a6ff5ec6 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Thu, 24 Mar 2022 17:43:18 -0400 Subject: [PATCH 04/15] velocity material is working. --- examples/webgl_materials_channels.html | 25 ++++++++++++++++--- src/core/Object3D.js | 1 + src/materials/Materials.js | 3 +++ src/materials/MeshVelocityMaterial.js | 18 +++++++------ src/renderers/WebGLRenderer.js | 6 +++-- src/renderers/shaders/ShaderChunk.js | 3 +++ .../shaders/ShaderChunk/packing.glsl.js | 18 ++----------- src/renderers/shaders/ShaderLib.js | 5 ++-- .../shaders/ShaderLib/meshvelocity.glsl.js | 16 ++++++++++++ src/renderers/webgl/WebGLProgram.js | 1 + src/renderers/webgl/WebGLPrograms.js | 1 + 11 files changed, 67 insertions(+), 30 deletions(-) diff --git a/examples/webgl_materials_channels.html b/examples/webgl_materials_channels.html index 4cc3d9607d7d6e..1c15027291fd2b 100644 --- a/examples/webgl_materials_channels.html +++ b/examples/webgl_materials_channels.html @@ -40,7 +40,7 @@ let camera, scene, renderer; const params = { - material: 'normal', + material: 'velocity', camera: 'perspective', side: 'double' }; @@ -54,7 +54,7 @@ let cameraOrtho, cameraPerspective; let controlsOrtho, controlsPerspective; - let mesh, materialStandard, materialDepthBasic, materialDepthRGBA, materialNormal; + let mesh, materialStandard, materialDepthBasic, materialDepthRGBA, materialNormal, materialVelocity; const SCALE = 2.436143; // from original model const BIAS = - 0.428408; // from original model @@ -67,7 +67,7 @@ function initGui() { const gui = new GUI(); - gui.add( params, 'material', [ 'standard', 'normal', 'depthBasic', 'depthRGBA' ] ); + gui.add( params, 'material', [ 'standard', 'normal', 'velocity', 'depthBasic', 'depthRGBA' ] ); gui.add( params, 'camera', [ 'perspective', 'ortho' ] ); gui.add( params, 'side', [ 'front', 'back', 'double' ] ); @@ -190,6 +190,16 @@ side: THREE.DoubleSide } ); + materialVelocity = new THREE.MeshVelocityMaterial( { + displacementMap: displacementMap, + displacementScale: SCALE, + displacementBias: BIAS, + + //flatShading: true, + + side: THREE.DoubleSide + } ); + // const loader = new OBJLoader(); @@ -260,6 +270,7 @@ case 'depthBasic': material = materialDepthBasic; break; case 'depthRGBA': material = materialDepthRGBA; break; case 'normal': material = materialNormal; break; + case 'velocity': material = materialVelocity; break; } @@ -295,8 +306,16 @@ controlsPerspective.update(); controlsOrtho.update(); // must update both controls for damping to complete + materialVelocity.previousProjectionViewMatrix.copy(materialVelocity.currentProjectionViewMatrix); + materialVelocity.currentProjectionViewMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); + renderer.render( scene, camera ); + scene.traverse( obj => { + if (obj.isObject3D) { + obj.matrixWorldPrevious.copy(obj.matrixWorld); + } + }); } diff --git a/src/core/Object3D.js b/src/core/Object3D.js index c315bbda6ab33e..a45b70808d96d7 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -94,6 +94,7 @@ class Object3D extends EventDispatcher { this.matrix = new Matrix4(); this.matrixWorld = new Matrix4(); + this.matrixWorldPrevious = new Matrix4(); this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; this.matrixWorldNeedsUpdate = false; diff --git a/src/materials/Materials.js b/src/materials/Materials.js index c3d39fc4c867f4..4234bec4c7c865 100644 --- a/src/materials/Materials.js +++ b/src/materials/Materials.js @@ -10,6 +10,7 @@ import { MeshToonMaterial } from './MeshToonMaterial.js'; import { MeshNormalMaterial } from './MeshNormalMaterial.js'; import { MeshLambertMaterial } from './MeshLambertMaterial.js'; import { MeshDepthMaterial } from './MeshDepthMaterial.js'; +import { MeshVelocityMaterial } from './MeshVelocityMaterial.js'; import { MeshDistanceMaterial } from './MeshDistanceMaterial.js'; import { MeshBasicMaterial } from './MeshBasicMaterial.js'; import { MeshMatcapMaterial } from './MeshMatcapMaterial.js'; @@ -30,6 +31,7 @@ export { MeshNormalMaterial, MeshLambertMaterial, MeshDepthMaterial, + MeshVelocityMaterial, MeshDistanceMaterial, MeshBasicMaterial, MeshMatcapMaterial, @@ -51,6 +53,7 @@ const materialLib = { MeshNormalMaterial, MeshLambertMaterial, MeshDepthMaterial, + MeshVelocityMaterial, MeshDistanceMaterial, MeshBasicMaterial, MeshMatcapMaterial, diff --git a/src/materials/MeshVelocityMaterial.js b/src/materials/MeshVelocityMaterial.js index b2ebfb27b401fa..3f4c05a5f4c0f0 100644 --- a/src/materials/MeshVelocityMaterial.js +++ b/src/materials/MeshVelocityMaterial.js @@ -2,12 +2,13 @@ import { Material } from './Material.js'; import { Vector2 } from '../math/Vector2.js'; import { Matrix4 } from '../math/Matrix4.js'; import { Color } from '../math/Color.js'; +import { BasicDepthPacking } from '../constants.js'; class MeshVelocityMaterial extends Material { constructor( parameters ) { - Material.call( this ); + super(); this.type = 'MeshVelocityMaterial'; @@ -20,6 +21,8 @@ class MeshVelocityMaterial extends Material { this.map = null; this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; this.alphaMap = null; @@ -38,7 +41,6 @@ class MeshVelocityMaterial extends Material { this.clearColor = new Color( 1.0, 1.0, 1.0 ); this.clearAlpha = 1.0; - this.blending = NoBlending; this.flatShading = false; this.setValues( parameters ); @@ -50,15 +52,17 @@ class MeshVelocityMaterial extends Material { super.copy( source ); - this.currentProjectionViewMatrix.copy( this.currentProjectionViewMatrix ); - this.previousProjectionViewMatrix.copy( this.previousProjectionViewMatrix ); + this.currentProjectionViewMatrix.copy( source.currentProjectionViewMatrix ); + this.previousProjectionViewMatrix.copy( source.previousProjectionViewMatrix ); this.opacity = source.opacity; - this.mapSlot.copy( source.mapSlot ); + this.map.copy( source.map ); - this.displacementMapSlot.copy( source.displacementMapSlot ); + this.displacementMap.copy( source.displacementMap ); + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; - this.alphaMapSlot.copy( source.alphaMapSlot ); + this.alphaMap.copy( source.alphaMap ); this.depthPacking = source.depthPacking; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 35d616b649cbf2..2985587901b558 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1752,8 +1752,8 @@ function WebGLRenderer( parameters = {} ) { // nothing yet - m_uniforms.currentProjectionViewMatrix.value = material.currentProjectionViewMatrix; - m_uniforms.previousProjectionViewMatrix.value = material.previousProjectionViewMatrix; + m_uniforms.currentProjectionViewMatrix.value.copy( material.currentProjectionViewMatrix ); + m_uniforms.previousProjectionViewMatrix.value.copy( material.previousProjectionViewMatrix ); } @@ -1761,8 +1761,10 @@ function WebGLRenderer( parameters = {} ) { p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix ); p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix ); + p_uniforms.setValue( _gl, 'modelMatrixPrev', object.matrixWorldPrevious ); p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld ); + return program; } diff --git a/src/renderers/shaders/ShaderChunk.js b/src/renderers/shaders/ShaderChunk.js index ffbcd12944e5b2..43c9f41267dd09 100644 --- a/src/renderers/shaders/ShaderChunk.js +++ b/src/renderers/shaders/ShaderChunk.js @@ -112,6 +112,7 @@ import * as meshbasic from './ShaderLib/meshbasic.glsl.js'; import * as meshlambert from './ShaderLib/meshlambert.glsl.js'; import * as meshmatcap from './ShaderLib/meshmatcap.glsl.js'; import * as meshnormal from './ShaderLib/meshnormal.glsl.js'; +import * as meshvelocity from './ShaderLib/meshvelocity.glsl.js'; import * as meshphong from './ShaderLib/meshphong.glsl.js'; import * as meshphysical from './ShaderLib/meshphysical.glsl.js'; import * as meshtoon from './ShaderLib/meshtoon.glsl.js'; @@ -244,6 +245,8 @@ export const ShaderChunk = { meshmatcap_frag: meshmatcap.fragment, meshnormal_vert: meshnormal.vertex, meshnormal_frag: meshnormal.fragment, + meshvelocity_vert: meshvelocity.vertex, + meshvelocity_frag: meshvelocity.fragment, meshphong_vert: meshphong.vertex, meshphong_frag: meshphong.fragment, meshphysical_vert: meshphysical.vertex, diff --git a/src/renderers/shaders/ShaderChunk/packing.glsl.js b/src/renderers/shaders/ShaderChunk/packing.glsl.js index 620d2564b6ab73..8bae84e1df6306 100644 --- a/src/renderers/shaders/ShaderChunk/packing.glsl.js +++ b/src/renderers/shaders/ShaderChunk/packing.glsl.js @@ -26,25 +26,11 @@ float unpackRGBAToDepth( const in vec4 v ) { } vec2 packDepthToRG( in highp float v ) { - v = v * (1. - EDGE_DISTANCE * 2.) + EDGE_DISTANCE; - v += 0.5 / ( 255.0 ); - - const highp vec4 packFactor = vec4( 1.0, 255.0, 65025.0, 16581375.0 ); - highp vec4 res = fract( v * packFactor ); - res.xy -= res.yz * (1.0/255.0); - - res.zw = vec2( 0.0 ); - - return res.yx; + return packDepthToRGBA( v ).yx; } - float unpackRGToDepth( const in highp vec2 v ) { - const highp vec2 unpackFactor = 1.0 / vec2( 1.0, 255.0 ); - highp float depth = dot( v.yx, unpackFactor ); - depth -= 0.5 / ( 255.0 ); - depth = (depth - EDGE_DISTANCE) * (1. / (1. - EDGE_DISTANCE * 2.)); - return depth; + return unpackRGBAToDepth( vec4( v.xy, 0.0, 0.0 ) ); } vec4 pack2HalfToRGBA( vec2 v ) { diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 2cea805dd49645..b7cb1e47b4e35f 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -5,6 +5,7 @@ import { Vector3 } from '../../math/Vector3.js'; import { UniformsLib } from './UniformsLib.js'; import { Color } from '../../math/Color.js'; import { Matrix3 } from '../../math/Matrix3.js'; +import { Matrix4 } from '../../math/Matrix4.js'; const ShaderLib = { @@ -204,8 +205,8 @@ const ShaderLib = { UniformsLib.common, UniformsLib.displacementmap, { - currentProjectionViewMatrix: { value: null }, - previousProjectionViewMatrix: { value: null } + currentProjectionViewMatrix: { value: new Matrix4() }, + previousProjectionViewMatrix: { value: new Matrix4() } } ] ), diff --git a/src/renderers/shaders/ShaderLib/meshvelocity.glsl.js b/src/renderers/shaders/ShaderLib/meshvelocity.glsl.js index 8bc50b74d1663e..dd5fabd81c4e1c 100644 --- a/src/renderers/shaders/ShaderLib/meshvelocity.glsl.js +++ b/src/renderers/shaders/ShaderLib/meshvelocity.glsl.js @@ -1,8 +1,18 @@ export const vertex = /* glsl */` + +#define NORMAL + +#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP ) + + varying vec3 vViewPosition; + +#endif + #include #include #include #include +#include #include #include #include @@ -19,9 +29,15 @@ void main() { #include + #include + #include #include + #include + #include + #include #include + #include #include #include #include diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 8056a637c38c3e..2bf5e605a09300 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -517,6 +517,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) { ( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '', 'uniform mat4 modelMatrix;', + 'uniform mat4 modelMatrixPrev;', 'uniform mat4 modelViewMatrix;', 'uniform mat4 projectionMatrix;', 'uniform mat4 viewMatrix;', diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index 556189a19de737..4059ec226180c5 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -28,6 +28,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities MeshToonMaterial: 'toon', MeshStandardMaterial: 'physical', MeshPhysicalMaterial: 'physical', + MeshVelocityMaterial: 'velocity', MeshMatcapMaterial: 'matcap', LineBasicMaterial: 'basic', LineDashedMaterial: 'dashed', From 9b426960eb93d6c152a2592f986d226ddc81ec67 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Thu, 24 Mar 2022 17:43:40 -0400 Subject: [PATCH 05/15] update default channel in example. --- examples/webgl_materials_channels.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/webgl_materials_channels.html b/examples/webgl_materials_channels.html index 1c15027291fd2b..1715dc2335daf0 100644 --- a/examples/webgl_materials_channels.html +++ b/examples/webgl_materials_channels.html @@ -40,7 +40,7 @@ let camera, scene, renderer; const params = { - material: 'velocity', + material: 'normal', camera: 'perspective', side: 'double' }; From 522e4b53eaada494fe015bc12c3b54d1bc83660c Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Fri, 25 Mar 2022 10:28:03 +0100 Subject: [PATCH 06/15] Update MeshVelocityMaterial.js --- src/materials/MeshVelocityMaterial.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/materials/MeshVelocityMaterial.js b/src/materials/MeshVelocityMaterial.js index 3f4c05a5f4c0f0..76ef5920fb1da2 100644 --- a/src/materials/MeshVelocityMaterial.js +++ b/src/materials/MeshVelocityMaterial.js @@ -1,5 +1,4 @@ import { Material } from './Material.js'; -import { Vector2 } from '../math/Vector2.js'; import { Matrix4 } from '../math/Matrix4.js'; import { Color } from '../math/Color.js'; import { BasicDepthPacking } from '../constants.js'; From b32daf060e47ccbeb36084767a26438056c314f7 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Fri, 25 Mar 2022 10:28:23 +0100 Subject: [PATCH 07/15] Update ShaderLib.js --- src/renderers/shaders/ShaderLib.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index b7cb1e47b4e35f..631ec04bfbfdc4 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -206,7 +206,7 @@ const ShaderLib = { UniformsLib.displacementmap, { currentProjectionViewMatrix: { value: new Matrix4() }, - previousProjectionViewMatrix: { value: new Matrix4() } + previousProjectionViewMatrix: { value: new Matrix4() } } ] ), From f106090022a775e8b00373fd3f1a76df24d90469 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 25 Mar 2022 07:42:18 -0400 Subject: [PATCH 08/15] add mention of velocity in channel example description --- examples/webgl_materials_channels.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/webgl_materials_channels.html b/examples/webgl_materials_channels.html index 1715dc2335daf0..5c26ac0f878078 100644 --- a/examples/webgl_materials_channels.html +++ b/examples/webgl_materials_channels.html @@ -9,7 +9,7 @@
- three.js - Normal, Depth, DepthRGBA, DepthRGBAUnpacked, Materials
+ three.js - Normal, Velocity, Depth, DepthRGBA, DepthRGBAUnpacked, Materials
by Ben Houston. ninja head from AMD GPU MeshMapper
From 61401913356897b4a641dab3d01ed1cb5df832f6 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Fri, 25 Mar 2022 07:47:13 -0400 Subject: [PATCH 09/15] clean up MeshVelocityMaterial class. --- src/materials/MeshVelocityMaterial.js | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/materials/MeshVelocityMaterial.js b/src/materials/MeshVelocityMaterial.js index 76ef5920fb1da2..27846fa10a68b2 100644 --- a/src/materials/MeshVelocityMaterial.js +++ b/src/materials/MeshVelocityMaterial.js @@ -11,14 +11,9 @@ class MeshVelocityMaterial extends Material { this.type = 'MeshVelocityMaterial'; - this.depthPacking = BasicDepthPacking; - this.currentProjectionViewMatrix = new Matrix4(); this.previousProjectionViewMatrix = new Matrix4(); - this.color = new Color( 0xffffff ); // diffuse - this.map = null; - this.displacementMap = null; this.displacementScale = 1; this.displacementBias = 0; @@ -28,18 +23,9 @@ class MeshVelocityMaterial extends Material { this.skinning = false; this.morphTargets = false; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; - this.fog = false; this.lights = false; - // far clipping plane in both RGBA and Basic encoding - this.clearColor = new Color( 1.0, 1.0, 1.0 ); - this.clearAlpha = 1.0; - this.flatShading = false; this.setValues( parameters ); @@ -54,30 +40,17 @@ class MeshVelocityMaterial extends Material { this.currentProjectionViewMatrix.copy( source.currentProjectionViewMatrix ); this.previousProjectionViewMatrix.copy( source.previousProjectionViewMatrix ); - this.opacity = source.opacity; - this.map.copy( source.map ); - this.displacementMap.copy( source.displacementMap ); this.displacementScale = source.displacementScale; this.displacementBias = source.displacementBias; this.alphaMap.copy( source.alphaMap ); - this.depthPacking = source.depthPacking; - this.skinning = source.skinning; this.morphTargets = source.morphTargets; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.wireframeLinecap = source.wireframeLinecap; - this.wireframeLinejoin = source.wireframeLinejoin; - this.flatShading = source.flatShading; - this.clearColor = source.clearColor; - this.clearAlpha = source.clearAlpha; - return this; } From f651890d713518a50deb1b3a575cfa73f047790d Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Fri, 25 Mar 2022 15:13:36 +0100 Subject: [PATCH 10/15] Update MeshVelocityMaterial.js --- src/materials/MeshVelocityMaterial.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/materials/MeshVelocityMaterial.js b/src/materials/MeshVelocityMaterial.js index 27846fa10a68b2..2c5d8926d3db77 100644 --- a/src/materials/MeshVelocityMaterial.js +++ b/src/materials/MeshVelocityMaterial.js @@ -1,7 +1,5 @@ import { Material } from './Material.js'; import { Matrix4 } from '../math/Matrix4.js'; -import { Color } from '../math/Color.js'; -import { BasicDepthPacking } from '../constants.js'; class MeshVelocityMaterial extends Material { From 4dcaa572ae8640c794aef4459184a1ddb56dc3c6 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Thu, 31 Mar 2022 14:32:36 -0400 Subject: [PATCH 11/15] move velocity shader out of core and into examples. --- .../jsm/shaders/MeshVelocityShader.js | 59 +++++++++++------- examples/webgl_materials_channels.html | 16 ++--- src/materials/Materials.js | 3 - src/materials/MeshVelocityMaterial.js | 60 ------------------- src/renderers/WebGLRenderer.js | 12 ---- src/renderers/shaders/ShaderChunk.js | 3 - src/renderers/shaders/ShaderLib.js | 16 ----- src/renderers/webgl/WebGLPrograms.js | 1 - 8 files changed, 48 insertions(+), 122 deletions(-) rename src/renderers/shaders/ShaderLib/meshvelocity.glsl.js => examples/jsm/shaders/MeshVelocityShader.js (59%) delete mode 100644 src/materials/MeshVelocityMaterial.js diff --git a/src/renderers/shaders/ShaderLib/meshvelocity.glsl.js b/examples/jsm/shaders/MeshVelocityShader.js similarity index 59% rename from src/renderers/shaders/ShaderLib/meshvelocity.glsl.js rename to examples/jsm/shaders/MeshVelocityShader.js index dd5fabd81c4e1c..5e922fc0f55791 100644 --- a/src/renderers/shaders/ShaderLib/meshvelocity.glsl.js +++ b/examples/jsm/shaders/MeshVelocityShader.js @@ -1,5 +1,25 @@ -export const vertex = /* glsl */` - +import { + UniformsLib, + mergeUniforms, + Matrix4 +} from 'three'; + +/** + * Mesh Velocity Shader + */ + +const VelocityShader = { + + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.displacementMap, + { + currentProjectionViewMatrix: { value: new Matrix4() }, + previousProjectionViewMatrix: { value: new Matrix4() } + } + ] ), + + vertexShader: /* glsl */` #define NORMAL #if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP ) @@ -45,26 +65,24 @@ void main() { #ifdef USE_SKINNING vec4 mvPosition = modelViewMatrix * skinned; - clipPositionCurrent = currentProjectionViewMatrix * modelMatrix * skinned; - clipPositionPrevious = previousProjectionViewMatrix * modelMatrixPrev * skinned; + clipPositionCurrent = currentProjectionViewMatrix * modelMatrix * skinned; + clipPositionPrevious = previousProjectionViewMatrix * modelMatrixPrev * skinned; #else vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 ); - clipPositionCurrent = currentProjectionViewMatrix * modelMatrix * vec4( transformed, 1.0 ); - clipPositionPrevious = previousProjectionViewMatrix * modelMatrixPrev * vec4( transformed, 1.0 ); + clipPositionCurrent = currentProjectionViewMatrix * modelMatrix * vec4( transformed, 1.0 ); + clipPositionPrevious = previousProjectionViewMatrix * modelMatrixPrev * vec4( transformed, 1.0 ); #endif - gl_Position = projectionMatrix * mvPosition; + gl_Position = projectionMatrix * mvPosition; #include #include } - -`; - -export const fragment = /* glsl */` +`, + fragmentShader: /* glsl */` #define NORMAL uniform float opacity; @@ -89,18 +107,19 @@ void main() { #include #include - vec2 ndcPositionCurrent = clipPositionCurrent.xy/clipPositionCurrent.w; - vec2 ndcPositionPrevious = clipPositionPrevious.xy/clipPositionPrevious.w; - vec2 vel = ( ndcPositionCurrent - ndcPositionPrevious ) * 0.5; - vel = vel * 0.5 + 0.5; - vec2 v1 = packDepthToRG(vel.x); - vec2 v2 = packDepthToRG(vel.y); - gl_FragColor = vec4(v1.x, v1.y, v2.x, v2.y); + vec2 ndcPositionCurrent = clipPositionCurrent.xy/clipPositionCurrent.w; + vec2 ndcPositionPrevious = clipPositionPrevious.xy/clipPositionPrevious.w; + vec2 vel = ( ndcPositionCurrent - ndcPositionPrevious ) * 0.5; + vel = vel * 0.5 + 0.5; + vec2 v1 = packDepthToRG(vel.x); + vec2 v2 = packDepthToRG(vel.y); + gl_FragColor = vec4(v1.x, v1.y, v2.x, v2.y); #include } -`; - +` +}; +export { NormalMapShader }; diff --git a/examples/webgl_materials_channels.html b/examples/webgl_materials_channels.html index 5c26ac0f878078..381912eef35ab6 100644 --- a/examples/webgl_materials_channels.html +++ b/examples/webgl_materials_channels.html @@ -34,6 +34,7 @@ import { GUI } from './jsm/libs/lil-gui.module.min.js'; import { OBJLoader } from './jsm/loaders/OBJLoader.js'; import { OrbitControls } from './jsm/controls/OrbitControls.js'; + import { MeshVelocityShader } from './jsm/shaders/MeshVelocityShader.js'; let stats; @@ -190,15 +191,16 @@ side: THREE.DoubleSide } ); - materialVelocity = new THREE.MeshVelocityMaterial( { - displacementMap: displacementMap, - displacementScale: SCALE, - displacementBias: BIAS, - - //flatShading: true, - + materialVelocity = new THREE.ShaderMaterial( { + uniforms: THREE.UniformsUtils.clone( MeshVelocityShader.uniforms ), + vertexShader: MeshVelocityShader.vertexShader, + fragmentShader: MeshVelocityShader.fragmentShader, side: THREE.DoubleSide } ); + materialVelocity.uniforms[displacementMap].value = displacementMap; + materialVelocity.uniforms[displacementScale].value = SCALE; + materialVelocity.uniforms[displacementBias].value = BIAS; + materialVelocity.extensions.derivatives = true; // diff --git a/src/materials/Materials.js b/src/materials/Materials.js index 4234bec4c7c865..c3d39fc4c867f4 100644 --- a/src/materials/Materials.js +++ b/src/materials/Materials.js @@ -10,7 +10,6 @@ import { MeshToonMaterial } from './MeshToonMaterial.js'; import { MeshNormalMaterial } from './MeshNormalMaterial.js'; import { MeshLambertMaterial } from './MeshLambertMaterial.js'; import { MeshDepthMaterial } from './MeshDepthMaterial.js'; -import { MeshVelocityMaterial } from './MeshVelocityMaterial.js'; import { MeshDistanceMaterial } from './MeshDistanceMaterial.js'; import { MeshBasicMaterial } from './MeshBasicMaterial.js'; import { MeshMatcapMaterial } from './MeshMatcapMaterial.js'; @@ -31,7 +30,6 @@ export { MeshNormalMaterial, MeshLambertMaterial, MeshDepthMaterial, - MeshVelocityMaterial, MeshDistanceMaterial, MeshBasicMaterial, MeshMatcapMaterial, @@ -53,7 +51,6 @@ const materialLib = { MeshNormalMaterial, MeshLambertMaterial, MeshDepthMaterial, - MeshVelocityMaterial, MeshDistanceMaterial, MeshBasicMaterial, MeshMatcapMaterial, diff --git a/src/materials/MeshVelocityMaterial.js b/src/materials/MeshVelocityMaterial.js deleted file mode 100644 index 2c5d8926d3db77..00000000000000 --- a/src/materials/MeshVelocityMaterial.js +++ /dev/null @@ -1,60 +0,0 @@ -import { Material } from './Material.js'; -import { Matrix4 } from '../math/Matrix4.js'; - -class MeshVelocityMaterial extends Material { - - constructor( parameters ) { - - super(); - - this.type = 'MeshVelocityMaterial'; - - this.currentProjectionViewMatrix = new Matrix4(); - this.previousProjectionViewMatrix = new Matrix4(); - - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; - - this.alphaMap = null; - - this.skinning = false; - this.morphTargets = false; - - this.fog = false; - this.lights = false; - - this.flatShading = false; - - this.setValues( parameters ); - - } - - - copy( source ) { - - super.copy( source ); - - this.currentProjectionViewMatrix.copy( source.currentProjectionViewMatrix ); - this.previousProjectionViewMatrix.copy( source.previousProjectionViewMatrix ); - - this.displacementMap.copy( source.displacementMap ); - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - - this.alphaMap.copy( source.alphaMap ); - - this.skinning = source.skinning; - this.morphTargets = source.morphTargets; - - this.flatShading = source.flatShading; - - return this; - - } - -} - -MeshVelocityMaterial.prototype.isMeshVelocityMaterial = true; - -export { MeshVelocityMaterial }; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 2985587901b558..830d1e60b9bc35 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1614,7 +1614,6 @@ function WebGLRenderer( parameters = {} ) { material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshStandardMaterial || - material.isMeshVelocityMaterial || material.envMap ) { const uCamPos = p_uniforms.map.cameraPosition; @@ -1633,7 +1632,6 @@ function WebGLRenderer( parameters = {} ) { material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || - material.isMeshVelocityMaterial || material.isShaderMaterial ) { p_uniforms.setValue( _gl, 'isOrthographic', camera.isOrthographicCamera === true ); @@ -1645,7 +1643,6 @@ function WebGLRenderer( parameters = {} ) { material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || - material.isMeshVelocityMaterial || material.isShaderMaterial || material.isShadowMaterial || object.isSkinnedMesh ) { @@ -1748,15 +1745,6 @@ function WebGLRenderer( parameters = {} ) { } - if ( material.isMeshVelocityMaterial ) { - - // nothing yet - - m_uniforms.currentProjectionViewMatrix.value.copy( material.currentProjectionViewMatrix ); - m_uniforms.previousProjectionViewMatrix.value.copy( material.previousProjectionViewMatrix ); - - } - // common matrices p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix ); diff --git a/src/renderers/shaders/ShaderChunk.js b/src/renderers/shaders/ShaderChunk.js index 43c9f41267dd09..ffbcd12944e5b2 100644 --- a/src/renderers/shaders/ShaderChunk.js +++ b/src/renderers/shaders/ShaderChunk.js @@ -112,7 +112,6 @@ import * as meshbasic from './ShaderLib/meshbasic.glsl.js'; import * as meshlambert from './ShaderLib/meshlambert.glsl.js'; import * as meshmatcap from './ShaderLib/meshmatcap.glsl.js'; import * as meshnormal from './ShaderLib/meshnormal.glsl.js'; -import * as meshvelocity from './ShaderLib/meshvelocity.glsl.js'; import * as meshphong from './ShaderLib/meshphong.glsl.js'; import * as meshphysical from './ShaderLib/meshphysical.glsl.js'; import * as meshtoon from './ShaderLib/meshtoon.glsl.js'; @@ -245,8 +244,6 @@ export const ShaderChunk = { meshmatcap_frag: meshmatcap.fragment, meshnormal_vert: meshnormal.vertex, meshnormal_frag: meshnormal.fragment, - meshvelocity_vert: meshvelocity.vertex, - meshvelocity_frag: meshvelocity.fragment, meshphong_vert: meshphong.vertex, meshphong_frag: meshphong.fragment, meshphysical_vert: meshphysical.vertex, diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 631ec04bfbfdc4..e1ab88c5f2da16 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -199,22 +199,6 @@ const ShaderLib = { }, - velocity: { - - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.displacementmap, - { - currentProjectionViewMatrix: { value: new Matrix4() }, - previousProjectionViewMatrix: { value: new Matrix4() } - } - ] ), - - vertexShader: ShaderChunk.meshvelocity_vert, - fragmentShader: ShaderChunk.meshvelocity_frag - - }, - sprite: { uniforms: mergeUniforms( [ diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index 4059ec226180c5..556189a19de737 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -28,7 +28,6 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities MeshToonMaterial: 'toon', MeshStandardMaterial: 'physical', MeshPhysicalMaterial: 'physical', - MeshVelocityMaterial: 'velocity', MeshMatcapMaterial: 'matcap', LineBasicMaterial: 'basic', LineDashedMaterial: 'dashed', From bee1b43535b73c81bce0d831cf9a4679c08f8eea Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Thu, 31 Mar 2022 14:44:27 -0400 Subject: [PATCH 12/15] channel example working again. --- ...MeshVelocityShader.js => VelocityShader.js} | 10 +++++----- examples/webgl_materials_channels.html | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) rename examples/jsm/shaders/{MeshVelocityShader.js => VelocityShader.js} (95%) diff --git a/examples/jsm/shaders/MeshVelocityShader.js b/examples/jsm/shaders/VelocityShader.js similarity index 95% rename from examples/jsm/shaders/MeshVelocityShader.js rename to examples/jsm/shaders/VelocityShader.js index 5e922fc0f55791..bd3956398c3786 100644 --- a/examples/jsm/shaders/MeshVelocityShader.js +++ b/examples/jsm/shaders/VelocityShader.js @@ -1,18 +1,18 @@ import { UniformsLib, - mergeUniforms, + UniformsUtils, Matrix4 } from 'three'; /** - * Mesh Velocity Shader + * Mesh Velocity Shader @bhouston */ const VelocityShader = { - uniforms: mergeUniforms( [ + uniforms: UniformsUtils.merge( [ UniformsLib.common, - UniformsLib.displacementMap, + UniformsLib.displacementmap, { currentProjectionViewMatrix: { value: new Matrix4() }, previousProjectionViewMatrix: { value: new Matrix4() } @@ -122,4 +122,4 @@ void main() { ` }; -export { NormalMapShader }; +export { VelocityShader }; diff --git a/examples/webgl_materials_channels.html b/examples/webgl_materials_channels.html index 381912eef35ab6..b8efa6258cd84a 100644 --- a/examples/webgl_materials_channels.html +++ b/examples/webgl_materials_channels.html @@ -34,7 +34,7 @@ import { GUI } from './jsm/libs/lil-gui.module.min.js'; import { OBJLoader } from './jsm/loaders/OBJLoader.js'; import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { MeshVelocityShader } from './jsm/shaders/MeshVelocityShader.js'; + import { VelocityShader } from './jsm/shaders/VelocityShader.js'; let stats; @@ -192,14 +192,14 @@ } ); materialVelocity = new THREE.ShaderMaterial( { - uniforms: THREE.UniformsUtils.clone( MeshVelocityShader.uniforms ), - vertexShader: MeshVelocityShader.vertexShader, - fragmentShader: MeshVelocityShader.fragmentShader, + uniforms: THREE.UniformsUtils.clone( VelocityShader.uniforms ), + vertexShader: VelocityShader.vertexShader, + fragmentShader: VelocityShader.fragmentShader, side: THREE.DoubleSide } ); - materialVelocity.uniforms[displacementMap].value = displacementMap; - materialVelocity.uniforms[displacementScale].value = SCALE; - materialVelocity.uniforms[displacementBias].value = BIAS; + materialVelocity.uniforms.displacementMap.value = displacementMap; + materialVelocity.uniforms.displacementScale.value = SCALE; + materialVelocity.uniforms.displacementBias.value = BIAS; materialVelocity.extensions.derivatives = true; // @@ -308,8 +308,8 @@ controlsPerspective.update(); controlsOrtho.update(); // must update both controls for damping to complete - materialVelocity.previousProjectionViewMatrix.copy(materialVelocity.currentProjectionViewMatrix); - materialVelocity.currentProjectionViewMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); + materialVelocity.uniforms.previousProjectionViewMatrix.value.copy(materialVelocity.uniforms.currentProjectionViewMatrix.value); + materialVelocity.uniforms.currentProjectionViewMatrix.value.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); renderer.render( scene, camera ); From 63a05401397fd55108d573fcb6b0ed2ef69741ac Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Thu, 31 Mar 2022 14:53:29 -0400 Subject: [PATCH 13/15] make Object3D.matrixWorldPrevious optional. --- examples/jsm/shaders/VelocityShader.js | 1 + examples/webgl_materials_channels.html | 52 +++++++++++++++++--------- src/core/Object3D.js | 1 - src/renderers/WebGLRenderer.js | 1 - 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/examples/jsm/shaders/VelocityShader.js b/examples/jsm/shaders/VelocityShader.js index bd3956398c3786..5a101e8b5c7e21 100644 --- a/examples/jsm/shaders/VelocityShader.js +++ b/examples/jsm/shaders/VelocityShader.js @@ -14,6 +14,7 @@ const VelocityShader = { UniformsLib.common, UniformsLib.displacementmap, { + modelMatrixPrev: { value: new Matrix4() }, currentProjectionViewMatrix: { value: new Matrix4() }, previousProjectionViewMatrix: { value: new Matrix4() } } diff --git a/examples/webgl_materials_channels.html b/examples/webgl_materials_channels.html index b8efa6258cd84a..07cf92aa67b945 100644 --- a/examples/webgl_materials_channels.html +++ b/examples/webgl_materials_channels.html @@ -2,20 +2,35 @@ three.js webgl - materials - channels - - - + + + -
- three.js - Normal, Velocity, Depth, DepthRGBA, DepthRGBAUnpacked, Materials
- by Ben Houston. ninja head from AMD GPU MeshMapper + three.js + - + Normal, Velocity, Depth, DepthRGBA, DepthRGBAUnpacked, Materials
+ by Ben Houston. ninja head from + AMD GPU MeshMapper
- + - - diff --git a/src/core/Object3D.js b/src/core/Object3D.js index a45b70808d96d7..c315bbda6ab33e 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -94,7 +94,6 @@ class Object3D extends EventDispatcher { this.matrix = new Matrix4(); this.matrixWorld = new Matrix4(); - this.matrixWorldPrevious = new Matrix4(); this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; this.matrixWorldNeedsUpdate = false; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 830d1e60b9bc35..4bb2185f77f25c 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1749,7 +1749,6 @@ function WebGLRenderer( parameters = {} ) { p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix ); p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix ); - p_uniforms.setValue( _gl, 'modelMatrixPrev', object.matrixWorldPrevious ); p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld ); From fd043787b4f614b9cec6df0e2e1bcd0bb7eabb89 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Thu, 31 Mar 2022 15:01:21 -0400 Subject: [PATCH 14/15] cleanup of PR. --- examples/jsm/shaders/VelocityShader.js | 2 ++ examples/webgl_materials_channels.html | 2 +- src/renderers/WebGLRenderer.js | 1 - src/renderers/shaders/ShaderLib.js | 1 - src/renderers/webgl/WebGLProgram.js | 1 - 5 files changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/jsm/shaders/VelocityShader.js b/examples/jsm/shaders/VelocityShader.js index 5a101e8b5c7e21..624ffe634d446c 100644 --- a/examples/jsm/shaders/VelocityShader.js +++ b/examples/jsm/shaders/VelocityShader.js @@ -42,6 +42,8 @@ const VelocityShader = { uniform mat4 previousProjectionViewMatrix; uniform mat4 currentProjectionViewMatrix; +uniform mat4 modelMatrixPrev; + varying vec4 clipPositionCurrent; varying vec4 clipPositionPrevious; diff --git a/examples/webgl_materials_channels.html b/examples/webgl_materials_channels.html index 07cf92aa67b945..bffe5e44ef4433 100644 --- a/examples/webgl_materials_channels.html +++ b/examples/webgl_materials_channels.html @@ -335,7 +335,7 @@ scene.traverse( function( object ) { if ( object.isMesh ) { - if ( object.matrixWorldPrevious === undefined ) object.matrixWorldPrevious = new Matrix4(); + if ( object.matrixWorldPrevious === undefined ) object.matrixWorldPrevious = new THREE.Matrix4(); object.matrixWorldPrevious.copy( object.matrixWorld ); } } ); diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 4bb2185f77f25c..e90d9568fcefb2 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1751,7 +1751,6 @@ function WebGLRenderer( parameters = {} ) { p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix ); p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld ); - return program; } diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index e1ab88c5f2da16..0eb045a995d6ec 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -5,7 +5,6 @@ import { Vector3 } from '../../math/Vector3.js'; import { UniformsLib } from './UniformsLib.js'; import { Color } from '../../math/Color.js'; import { Matrix3 } from '../../math/Matrix3.js'; -import { Matrix4 } from '../../math/Matrix4.js'; const ShaderLib = { diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 2bf5e605a09300..8056a637c38c3e 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -517,7 +517,6 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) { ( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '', 'uniform mat4 modelMatrix;', - 'uniform mat4 modelMatrixPrev;', 'uniform mat4 modelViewMatrix;', 'uniform mat4 projectionMatrix;', 'uniform mat4 viewMatrix;', From d28bd9d5359e0f60d18ab3963369d589ed8f30d1 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Sat, 22 Oct 2022 11:45:28 +0200 Subject: [PATCH 15/15] Update webgl_materials_channels.html --- examples/webgl_materials_channels.html | 69 ++++++++++++-------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/examples/webgl_materials_channels.html b/examples/webgl_materials_channels.html index bffe5e44ef4433..4001ba8aa06083 100644 --- a/examples/webgl_materials_channels.html +++ b/examples/webgl_materials_channels.html @@ -2,40 +2,26 @@ three.js webgl - materials - channels - - - + + + +
- three.js - - - Normal, Velocity, Depth, DepthRGBA, DepthRGBAUnpacked, Materials
- by Ben Houston. ninja head from - AMD GPU MeshMapper + three.js - Normal, Velocity, Depth, DepthRGBA, DepthRGBAUnpacked, Materials
+ by Ben Houston. ninja head from AMD GPU MeshMapper
- + @@ -44,12 +30,12 @@ import * as THREE from 'three'; - import Stats from './jsm/libs/stats.module.js'; + import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from './jsm/libs/lil-gui.module.min.js'; - import { OBJLoader } from './jsm/loaders/OBJLoader.js'; - import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { VelocityShader } from './jsm/shaders/VelocityShader.js'; + import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; + import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; + import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + import { VelocityShader } from 'three/addons/shaders/VelocityShader.js'; let stats; @@ -228,6 +214,7 @@ mesh = new THREE.Mesh( geometry, materialNormal ); mesh.scale.multiplyScalar( 25 ); + mesh.userData.matrixWorldPrevious = new THREE.Matrix4(); // for velocity scene.add( mesh ); } ); @@ -323,23 +310,33 @@ controlsPerspective.update(); controlsOrtho.update(); // must update both controls for damping to complete - // remember camera projection changes. + // remember camera projection changes + materialVelocity.uniforms.previousProjectionViewMatrix.value.copy( materialVelocity.uniforms.currentProjectionViewMatrix.value ); materialVelocity.uniforms.currentProjectionViewMatrix.value.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); - if( mesh && mesh.matrixWorldPrevious ) { - materialVelocity.uniforms.modelMatrixPrev.value.copy( mesh.matrixWorldPrevious ); + if ( mesh && mesh.userData.matrixWorldPrevious ) { + + materialVelocity.uniforms.modelMatrixPrev.value.copy( mesh.userData.matrixWorldPrevious ); + } renderer.render( scene, camera ); - scene.traverse( function( object ) { - if ( object.isMesh ) { - if ( object.matrixWorldPrevious === undefined ) object.matrixWorldPrevious = new THREE.Matrix4(); - object.matrixWorldPrevious.copy( object.matrixWorld ); - } + scene.traverse( function ( object ) { + + if ( object.isMesh ) { + + object.userData.matrixWorldPrevious.copy( object.matrixWorld ); + + } + } ); + } + + +