Loading transparent objects in a glTF model

I’ve been exploring different ways of rendering transparent objects with opacity from within a glTF model and came across an unusual solution.

Upon traversing the scene I found that setting child.material.transparent equal to a new material solved my problem. I assumed this was because transparent expected a boolean value and that setting it to a new material might equal true but that’s not the case because child.material.transparent = true produces an entirely different result.

I understand that there has already been extensive discussion around rendering transparent objects, but I’m looking for any sort of explanation as to why my example seems to work.

Here’s the relevant code:

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'

const gltfLoader = new GLTFLoader(loadingManager)

/* Canvas */
const canvas = document.querySelector('canvas.webgl')

/* Scene */
const scene = new THREE.Scene()

/* Models */
gltfLoader.load(
    '/models/ARHouse/ar-house-glass.glb',
    (gltf) => {
        scene.add(gltf.scene)
        
        scene.traverse((child) => {
            if(child instanceof THREE.Mesh && child.material instanceof THREE.MeshStandardMaterial){
                child.material.transparent = new THREE.MeshStandardMaterial()
            }
        })
    }
)

/* Lights */
const ambientLight = new THREE.AmbientLight(0xffffff, 1)
const directionalLight = new THREE.DirectionalLight(0xffffff, 1)
directionalLight.position.set(10, 20, 5)
scene.add(ambientLight, directionalLight)

/* Sizes */
const sizes = {
    width: window.innerWidth,
    height: window.innerHeight
}

window.addEventListener('resize', () =>
{
    // Update sizes
    sizes.width = window.innerWidth
    sizes.height = window.innerHeight

    // Update camera
    camera.aspect = sizes.width / sizes.height
    camera.updateProjectionMatrix()

    // Update renderer
    renderer.setSize(sizes.width, sizes.height)
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})

/* Camera */
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 300)
camera.position.set(-47, 25, 72)
scene.add(camera)

/* Controls */
const controls = new OrbitControls(camera, canvas)
controls.enableDamping = true
controls.maxDistance = 150
controls.minDistance = 70
controls.rotateSpeed = 0.3
controls.maxPolarAngle = Math.PI / 2;

/* Renderer */
const renderer = new THREE.WebGLRenderer({
    canvas: canvas,
    antialias: true
})
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
renderer.setClearColor(0xcccccc)
renderer.physicallyCorrectLights = true
renderer.outputEncoding = THREE.sRGBEncoding

/* Animate */
const tick = () =>
{

    // Update controls
    controls.update()

    // Render
    renderer.render(scene, camera)

    // Call tick again on the next frame
    window.requestAnimationFrame(tick)

    stats.end()
}

tick()

For reference, here is the material setting in Blender.