diff --git a/packages/dev/core/src/PostProcesses/motionBlurPostProcess.ts b/packages/dev/core/src/PostProcesses/motionBlurPostProcess.ts index 57d3e774c65..a8dfe7b5047 100644 --- a/packages/dev/core/src/PostProcesses/motionBlurPostProcess.ts +++ b/packages/dev/core/src/PostProcesses/motionBlurPostProcess.ts @@ -1,6 +1,6 @@ import type { Nullable } from "../types"; import { Logger } from "../Misc/logger"; -import { Matrix, Vector2 } from "../Maths/math.vector"; +import { Matrix, TmpVectors, Vector2 } from "../Maths/math.vector"; import type { Camera } from "../Cameras/camera"; import type { Effect } from "../Materials/effect"; import type { PostProcessOptions } from "./postProcess"; @@ -135,8 +135,8 @@ export class MotionBlurPostProcess extends PostProcess { super( name, "motionBlur", - ["motionStrength", "motionScale", "screenSize", "inverseViewProjection", "prevViewProjection"], - ["velocitySampler", "textureSampler", "depthSampler"], + ["motionStrength", "motionScale", "screenSize", "inverseViewProjection", "prevViewProjection", "projection"], + ["velocitySampler", "depthSampler"], options, camera, samplingMode, @@ -250,7 +250,7 @@ export class MotionBlurPostProcess extends PostProcess { this.onApply = (effect: Effect) => this._onApplyObjectBased(effect); } else { this._invViewProjection = Matrix.Identity(); - this._previousViewProjection = Matrix.Identity(); + this._previousViewProjection = this._scene.getTransformMatrix().clone(); if (this._prePassRenderer && this._prePassEffectConfiguration) { this._prePassEffectConfiguration.texturesRequired[0] = Constants.PREPASS_DEPTH_TEXTURE_TYPE; @@ -284,13 +284,16 @@ export class MotionBlurPostProcess extends PostProcess { * @param effect */ private _onApplyScreenBased(effect: Effect): void { - const viewProjection = this._scene.getProjectionMatrix().multiply(this._scene.getViewMatrix()); + const viewProjection = TmpVectors.Matrix[0]; + viewProjection.copyFrom(this._scene.getTransformMatrix()); viewProjection.invertToRef(this._invViewProjection!); effect.setMatrix("inverseViewProjection", this._invViewProjection!); effect.setMatrix("prevViewProjection", this._previousViewProjection!); - this._previousViewProjection = viewProjection; + this._previousViewProjection!.copyFrom(viewProjection); + + effect.setMatrix("projection", this._scene.getProjectionMatrix()); effect.setVector2("screenSize", new Vector2(this.width, this.height)); diff --git a/packages/dev/core/src/Shaders/motionBlur.fragment.fx b/packages/dev/core/src/Shaders/motionBlur.fragment.fx index 190b1c6a76b..f921a7927ff 100644 --- a/packages/dev/core/src/Shaders/motionBlur.fragment.fx +++ b/packages/dev/core/src/Shaders/motionBlur.fragment.fx @@ -13,6 +13,7 @@ uniform sampler2D depthSampler; uniform mat4 inverseViewProjection; uniform mat4 prevViewProjection; +uniform mat4 projection; #endif @@ -49,12 +50,14 @@ void main(void) #else vec2 texelSize = 1.0 / screenSize; float depth = texture2D(depthSampler, vUV).r; + depth = projection[2].z + projection[3].z / depth; // convert from view linear z to NDC z vec4 cpos = vec4(vUV * 2.0 - 1.0, depth, 1.0); - cpos = cpos * inverseViewProjection; + cpos = inverseViewProjection * cpos; + cpos /= cpos.w; - vec4 ppos = cpos * prevViewProjection; - ppos.xyz /= ppos.w; + vec4 ppos = prevViewProjection * cpos; + ppos /= ppos.w; ppos.xy = ppos.xy * 0.5 + 0.5; vec2 velocity = (ppos.xy - vUV) * motionScale * motionStrength;