{"record":{"id":"fc6d0c3fc908f21e","repo":"BabylonJS/Babylon.js","slug":"framegraphmotionblurtask-this-name-velocityt","errorCode":null,"errorMessage":"FrameGraphMotionBlurTask \"${this.name}\": velocityTexture is required for object-based motion blur","messagePattern":"FrameGraphMotionBlurTask \"(.+?)\": velocityTexture is required for object-based motion blur","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/FrameGraph/Tasks/PostProcesses/motionBlurTask.ts","lineNumber":46,"sourceCode":"     */\r\n    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinMotionBlurPostProcess) {\r\n        super(name, frameGraph, thinPostProcess || new ThinMotionBlurPostProcess(name, frameGraph.scene));\r\n    }\r\n\r\n    public override getClassName(): string {\r\n        return \"FrameGraphMotionBlurTask\";\r\n    }\r\n\r\n    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {\r\n        if (this.sourceTexture === undefined) {\r\n            throw new Error(`FrameGraphMotionBlurTask \"${this.name}\": sourceTexture is required`);\r\n        }\r\n\r\n        const pass = super.record(skipCreationOfDisabledPasses, undefined, (context) => {\r\n            if (this.velocityTexture) {\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"velocitySampler\", this.velocityTexture);\r\n            } else if (this.postProcess.isObjectBased) {\r\n                throw new Error(`FrameGraphMotionBlurTask \"${this.name}\": velocityTexture is required for object-based motion blur`);\r\n            }\r\n\r\n            if (this.depthTexture) {\r\n                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, \"depthSampler\", this.depthTexture);\r\n            } else if (!this.postProcess.isObjectBased) {\r\n                throw new Error(`FrameGraphMotionBlurTask \"${this.name}\": depthTexture is required for screen-based motion blur`);\r\n            }\r\n        });\r\n\r\n        pass.addDependencies(this.velocityTexture);\r\n        pass.addDependencies(this.depthTexture);\r\n\r\n        this.postProcess.textureWidth = this._sourceWidth;\r\n        this.postProcess.textureHeight = this._sourceHeight;\r\n\r\n        return pass;\r\n    }\r\n}\r","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/FrameGraph/Tasks/PostProcesses/motionBlurTask.ts#L28-L64","documentation":"Thrown from the bindings callback of FrameGraphMotionBlurTask.record() when the post-process is configured for object-based motion blur (isObjectBased === true) but velocityTexture is undefined. Object-based motion blur samples per-object velocity from a velocity render target, so that texture is mandatory in this mode.","triggerScenarios":"Creating a motion blur task with object-based mode (default or explicitly) and building the graph without assigning task.velocityTexture to a velocity texture handle (e.g. from an ObjectRendererTask with velocity enabled).","commonSituations":"Leaving the task in its default object-based mode while only wiring a depth texture (screen-based setup); forgetting to enable velocity output on the object renderer; switching pipelines and not realizing the mode/texture pairing must match.","solutions":["Assign task.velocityTexture to a velocity texture handle from a task that produces velocities.","Alternatively, switch to screen-based motion blur (set the post-process mode so isObjectBased is false) if you intend to use depth-only blur.","Verify the upstream velocity task is added to the graph and rendered before the motion blur task.","Check that the velocity texture handle was not reset to undefined during reconfiguration."],"exampleFix":"// before\nconst mb = new FrameGraphMotionBlurTask(frameGraph, \"motionBlur\"); // object-based\nmb.sourceTexture = colorTask.outputTexture;\nmb.depthTexture = depthTask.outputTexture;\n\n// after\nconst mb = new FrameGraphMotionBlurTask(frameGraph, \"motionBlur\");\nmb.sourceTexture = colorTask.outputTexture;\nmb.velocityTexture = objectRendererTask.outputTexture; // velocity RT\nmb.depthTexture = depthTask.outputTexture;","handlingStrategy":"validation","validationCode":"if (mbTask.postProcess.isObjectBased && mbTask.velocityTexture === undefined) {\n  throw new Error(\"Object-based motion blur requires velocityTexture before build\");\n}","typeGuard":"function velocityWiredForMode(t: { postProcess: { isObjectBased: boolean }; velocityTexture?: unknown; depthTexture?: unknown }): boolean {\n  return !t.postProcess.isObjectBased || t.velocityTexture !== undefined;\n}","tryCatchPattern":"try {\n  frameGraph.build();\n} catch (e) {\n  if (String(e?.message).includes(\"velocityTexture is required for object-based motion blur\")) {\n    console.error(\"Wire a velocity texture or switch to screen-based mode:\", e.message);\n  } else { throw e; }\n}","preventionTips":["Decide the motion blur mode up front and wire the matching texture (velocity vs depth).","Enable velocity output on the ObjectRendererTask when using object-based blur.","Add a mode/texture consistency check in your graph setup helper."],"tags":["babylonjs","frame-graph","motion-blur","velocity-texture","configuration"],"backgroundTag":"framegraph-task-missing-texture","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}