Model looks different on browser vs Editor

A question that is probably super beginner but no amount of document reading has helped.
I used the Editor to create a scene. It looks fabulous when I run it on the Editor. When I upload it on Sandbox, looks quite good but when I host it on my own website, it visually looks awful regarding lighting, materials and ambient occlusion.

My guess is that outside the Editor, the correct packages related to materials and ambient occlusion are not imported?
If so, how do I import these in the html.(?) file? Is there a list of packages and how to add them in the html. file?

I appreciate it.

Adding @julien-moreau the editor daddy :slight_smile:

But yes the editor is adding lots of extras you need to have setup locally.

Hi @Teo_T !

You are right, using scenes generated using the Editor may not look like in the Editor. In fact, the Editor can add a some metadata on objects (nodes, scene, etc.) that will be parsed in the project. In these metadata there are for example the post-processes such as SSAO, DefaultRenderingPipeline etc.

If you wanna use the Editor to build your scenes and use the outputed scene outside the Editor you’ll have to re-instantiate all the post-processes yourself by code, or use that one as an example: Editor/tools.ts at master · BabylonJS/Editor · GitHub

For the lights, can you show a difference between the scene you have in the editor and the one you have on your website?

Thanks ! :slight_smile:


Thank you for a thorough reply.
I probably miswrote the part about lights, and the difference is a result of lack of post processes.

On the right is the Editor view, left is when uploaded on website.

Right now I will probably opt for editing the scene in browser code rather than the Editor as having to set the post processes twice seems a bit cumbersome at this time.
Thanks again.

Ouch! It’s clearly missing image processing and SSAO :slight_smile:

@Deltakosh added way to include serialized post-processes and pipelines to the .babylon format in v5 of Babylon.js. Once the v5 is officially released, the Editor will take advantage of that feature and your problem will be fixed.

When you say “having to set the post processes twice”, the code I shared is the only one to include in your project and takes advantage of the parsing functions that already exist in Babylon.js v4.2.0. In other words, all serialized configurations in the Editor will be available in the metadata of the scene you exported as .babylon so you don’t have to set/configure post-processes twice, the code just parses them

You can then include the code I shared in your project and wait for the version 5.0 of the Editor to remove these lines of code, or as you said, don’t use the Editor

1 Like

Thank you very much for a thorough reply! Me being a beginner, could I ask how do I exactly make the tools.ts work with my project. In which folder do I put it in the editor (or server?) and do I need to load it via script? Thank you again and looking forward to v. 5.0.

Could I get a quick pointer, where exactly I should put the tools.ts file in project so it can look similar to the Editor view once I host the project on my site? I would kindly appreciate this quick pointer.

Hi @Teo_T, here is an example that you can use


import { Scene, SSAO2RenderingPipeline, ScreenSpaceReflectionPostProcess, DefaultRenderingPipeline, DefaultRenderingPipeline } from "@babylonjs/core";

export function configurePostProcesses(scene: Scene, rootUrl: string = null): void {
    if (rootUrl === null || !scene.metadata?.postProcesses) { return; }

    // Load  post-processes configuration
    const data = scene.metadata.postProcesses;

    if (data.ssao && !ssao2RenderingPipelineRef) {
        ssao2RenderingPipelineRef = SSAO2RenderingPipeline.Parse(data.ssao.json, scene, rootUrl);
        if (data.ssao.enabled) {
            scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(, scene.cameras);

    if (data.screenSpaceReflections?.json && !screenSpaceReflectionPostProcessRef) {
        screenSpaceReflectionPostProcessRef = ScreenSpaceReflectionPostProcess._Parse(data.screenSpaceReflections.json, scene.activeCamera!, scene, "");

    if (data.default && !defaultRenderingPipelineRef) {
        defaultRenderingPipelineRef = DefaultRenderingPipeline.Parse(data.default.json, scene, rootUrl);
        if (!data.default.enabled) {
            scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(, scene.cameras);

    if (data.motionBlur?.json) {
        motionBlurPostProcessRef = MotionBlurPostProcess._Parse(data.motionBlur.json, scene.activeCamera!, scene, "");

    scene.onDisposeObservable.addOnce(() => {
        ssao2RenderingPipelineRef = null;
        screenSpaceReflectionPostProcessRef = null;
        defaultRenderingPipelineRef = null;
        motionBlurPostProcessRef = null;

And then, where you load your scene that comes from the editor (index.ts for example):

import { SceneLoader } from "@babylonjs/core";
import { configurePostProcesses } from "./myTools.ts";

SceneLoader.Load("myRootUrl/", "scene.babylon", engine, (scene) => {
    configurePostProcesses(scene, "myRootUrl/");