Old Version Updated to New Version Renders Differently

Hopefully someone can tell me why it renders differently if the threejs version is updated to the latest version.

The colours are different, the colour on the flag looks brighter also.

I posted the two versions of the code.

If anyone can tell me how I can fix the code on the latest version to give me same results I would be appreciated.

Old version code

   <script src="https://josephg.github.io/noisejs/perlin.js"></script>
    <script type="module">
    import * as THREE from "https://cdn.jsdelivr.net/npm/three@0.118.3/build/three.module.js";
    import {OrbitControls} from "https://cdn.jsdelivr.net/npm/three@0.118.3/examples/jsm/controls/OrbitControls.js";

    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
    camera.position.set(-1, 0.5, 2).setLength(2.5);
    var renderer = new THREE.WebGLRenderer({
    antialias: true
    });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor(0x401000);
    document.body.appendChild(renderer.domElement);

    var controls = new OrbitControls(camera, renderer.domElement);

    var light = new THREE.DirectionalLight(0xff5500, 2);
    light.position.setScalar(10);
    scene.add(light);
    scene.add(new THREE.AmbientLight(0xff0000, 1));

    var loader = new THREE.TextureLoader();

    // flag
    var flagGeom = new THREE.PlaneGeometry(4, 2, 40, 20);
    flagGeom.translate(2, 1, 0);
    flagGeom.vertices.forEach(v => {
    v.init = v.clone()
    });

    var flagMat = new THREE.MeshStandardMaterial({
    color: 0x777777,
    map: loader.load("http://4.bp.blogspot.com/-CtBZ0q07Itw/VY4nDetKzcI/AAAAAAAAAiE/wrY2DVPq2t0/s1600/american-flag.png"),
    alphaMap: loader.load("https://cywarr.github.io/small-shop/PW_flag/PW_flag_alphaMap.png"),
    alphaTest: 0.5,
    side: THREE.DoubleSide,
    metalness: 0.5,
    roughness: 0.5
    });
    var flag = new THREE.Mesh(flagGeom, flagMat);
    flag.position.set(-2, -1, 0);
    flag.rotation.x = THREE.Math.degToRad(-18);
    scene.add(flag);

    // staff
    var staff = new THREE.Mesh(new THREE.CylinderGeometry(0.04, 0.04, 4, 8), new THREE.MeshStandardMaterial({
    color: "black"
    }));
    flag.add(staff);

    // background canvas texture
    var canvas = document.createElement("canvas");
    canvas.width = 128;
    canvas.height = 64;

    var ctx = canvas.getContext('2d');

    var image = ctx.createImageData(canvas.width, canvas.height);
    var data = image.data;

    var canvasTexture = new THREE.CanvasTexture(canvas);
    scene.background = canvasTexture;

    var clock = new THREE.Clock();
    var delta = 0;
    var time = 0;

    render();

    function render() {
    requestAnimationFrame(render);
    delta = clock.getDelta();
    time += delta;
    flagGeom.vertices.forEach(v => {

        let yFade = Math.sin(v.init.y / flagGeom.parameters.height * Math.PI) * 0.25;
        v.x = v.init.x + yFade;
        let xFade = (v.x / flagGeom.parameters.width);
        v.z = noise.perlin2((v.x - (time * 2)) / flagGeom.parameters.width * 4, v.init.y / flagGeom.parameters.height * 2) * xFade;
    });
    flagGeom.computeVertexNormals();
    flagGeom.verticesNeedUpdate = true;

    drawFrame(time);
    canvasTexture.needsUpdate = true;
    renderer.render(scene, camera);
    }

    function drawFrame(time) {

    var cWidth = canvas.width;
    var cHeight = canvas.height;

    for (var x = 0; x < cWidth; x++) {
        for (var y = 0; y < cHeight; y++) {
        var value = Math.abs(noise.simplex3(x / cWidth, y / cHeight, time * 0.25));

        var cell = (x + y * cWidth) * 4;
        data[cell] = 128 + Math.floor(128 * value);
        data[cell + 1] = Math.floor(256 * value);
        data[cell + 2] = 0;
        data[cell + 3] = 255; // alpha.
        }
    }

    ctx.fillColor = 'black';
    ctx.fillRect(0, 0, 100, 100);
    ctx.putImageData(image, 0, 0);

    }
    function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight
            camera.updateProjectionMatrix()

            renderer.setSize(window.innerWidth, window.innerHeight)
        }
    </script>

New Version code

   <script src="https://josephg.github.io/noisejs/perlin.js"></script>
    <script type="importmap">
        {
            "imports": {
                "three": "https://threejs.org/build/three.module.js",
                "three/addons/": "./jsm/"
            }
        }
    </script>

    <script type="module">
        
        import * as THREE from 'three'
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js' 

        var scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
        camera.position.set(-1, 0.5, 2).setLength(2.5);
        var renderer = new THREE.WebGLRenderer({
        antialias: true
        });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setClearColor(0x401000);
        document.body.appendChild(renderer.domElement);

        var controls = new OrbitControls(camera, renderer.domElement);

        var light = new THREE.DirectionalLight(0xff5500, 2);
        light.position.setScalar(10);
        scene.add(light);
        scene.add(new THREE.AmbientLight(0xff0000, 1));

        var loader = new THREE.TextureLoader();

        // flag
        var flagGeom = new THREE.PlaneGeometry(4, 2, 40, 20);
        flagGeom.translate(2, 1, 0);
        let pos = flagGeom.attributes.position;
        flagGeom.userData = {
        init: []
        }
        for(let i = 0; i < pos.count; i++){
        flagGeom.userData.init.push(new THREE.Vector3().fromBufferAttribute(pos, i));
        }
        console.log(flagGeom.userData.init);

        var flagMat = new THREE.MeshStandardMaterial({
        color: 0x777777,
        map: loader.load("http://4.bp.blogspot.com/-CtBZ0q07Itw/VY4nDetKzcI/AAAAAAAAAiE/wrY2DVPq2t0/s1600/american-flag.png"),
        alphaMap: loader.load("https://cywarr.github.io/small-shop/PW_flag/PW_flag_alphaMap.png"),
        alphaTest: 0.5,
        side: THREE.DoubleSide,
        metalness: 0.5,
        roughness: 0.5
        });
        var flag = new THREE.Mesh(flagGeom, flagMat);
        flag.position.set(-2, -1, 0);
        flag.rotation.x = THREE.MathUtils.degToRad(-18);
        scene.add(flag);

        // staff
        var staff = new THREE.Mesh(new THREE.CylinderGeometry(0.04, 0.04, 4, 8), new THREE.MeshStandardMaterial({
        color: "black"
        }));
        flag.add(staff);

        // background canvas texture
        var canvas = document.createElement("canvas");
        canvas.width = 128;
        canvas.height = 64;

        var ctx = canvas.getContext('2d');

        var image = ctx.createImageData(canvas.width, canvas.height);
        var data = image.data;

        var canvasTexture = new THREE.CanvasTexture(canvas);
        scene.background = canvasTexture;

        window.addEventListener( 'resize', onWindowResize );

        var clock = new THREE.Clock();
        var delta = 0;
        var time = 0;
        var v = new THREE.Vector3();

        render();

        function render() {
        requestAnimationFrame(render);
        delta = clock.getDelta();
        time += delta;
        flagGeom.userData.init.forEach( (vi, idx) => {
            
            v.copy(vi);
            let yFade = Math.sin(v.y / flagGeom.parameters.height * Math.PI) * 0.25;
            v.x = v.x + yFade;
            let xFade = (v.x / flagGeom.parameters.width);
            v.z = noise.perlin2((v.x - (time * 2)) / flagGeom.parameters.width * 4, v.y / flagGeom.parameters.height * 2) * xFade;
            
            pos.setXYZ(idx, v.x, v.y, v.z);
        });
        flagGeom.computeVertexNormals();
        pos.needsUpdate = true;

        drawFrame(time);
        canvasTexture.needsUpdate = true;
        renderer.render(scene, camera);
        }

        function drawFrame(time) {

        var cWidth = canvas.width;
        var cHeight = canvas.height;

        for (var x = 0; x < cWidth; x++) {
            for (var y = 0; y < cHeight; y++) {
            var value = Math.abs(noise.simplex3(x / cWidth, y / cHeight, time * 0.25));

            var cell = (x + y * cWidth) * 4;
            data[cell] = 128 + Math.floor(128 * value);
            data[cell + 1] = Math.floor(256 * value);
            data[cell + 2] = 0;
            data[cell + 3] = 255; // alpha.
            }
        }

        ctx.fillColor = 'black';
        ctx.fillRect(0, 0, 100, 100);
        ctx.putImageData(image, 0, 0);

        }

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight
            camera.updateProjectionMatrix()

            renderer.setSize(window.innerWidth, window.innerHeight)
        }

    </script>

I would encourage you not to import directly from “https://threejs.org/build/three.module.js”, it will change every month, and can break at any time. If you aren’t using a bundler or self-hosting the code, than use a CDN like jsdelivr with a version number in the URL.

Every release of three.js comes with a migration guide entry here:

Upgrading from r118 to r164 (current) is about 4 years of changes, so that’s a lot. Some of the bigger changes happened in r152 and r155, related to color management and lighting, so I would have a look at those migration guide entries specifically.

1 Like

Thanks, will look at it.
If anyone has managed to find a quick fix for this please let me know.