Pool performance on CSS3DRenderer iframe in Chrome with mixed mode

Hi All,

I try to add 100% size of iframe into CSS3DRenderer, but the performance is slow and iframe plane is kept flickering.

Three.js version is 0.129.0.
I tested on Chrome, Safari, Firefox, only Chrome (tested version “91.0.4472.101”) has this issue.
You can just orbit control the camera or zoom in and out, then the page is slowly, and web plane is flickering, then fps drop a lot.
Issue Video: issue.mov - Google Drive
Demo Site: https://css3d-issue.web.app/
Codepen: https://codepen.io/skypu3/full/jOBQbNe
Here is snippet code:


const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.01, 30000)
camera.position.set(2, 2, 2)
scene.add(camera)

// Controls
const controls = new OrbitControls(camera, canvas)

const cssRenderer = new CSS3DRenderer()
cssRenderer.setSize(sizes.width, sizes.height)
cssRenderer.domElement.style.position = 'absolute'
cssRenderer.domElement.style.top = 0
document.querySelector( '#css3d' ).appendChild( cssRenderer.domElement )

const renderer = new THREE.WebGLRenderer({
    canvas: canvas,
    alpha: true, 
    antialias: true
})
renderer.domElement.style.position = 'absolute'
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFSoftShadowMap
renderer.setSize(sizes.width, sizes.height)
renderer.setClearColor(0x000000, 0.0)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
controls.domElement = renderer.domElement;
controls.target.set(0, 0, 0)
controls.enableDamping = true
controls.dampingFactor =  0.023
controls.panSpeed = 0.05
controls.damping = 0.05
controls.update()

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)
    cssRenderer.setSize(sizes.width, sizes.height)
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})

const width = 1792
const height = 1120

const element = document.createElement('div')
element.style.width = width + 'px'
element.style.height = height + 'px'
element.style.backgroundColor = 'transparent'

const iframe = document.createElement('iframe')
iframe.src = 'https://fr.wikipedia.org/wiki/Main_Page'
iframe.style.width = '100%'
iframe.style.height = '100%'
iframe.style.border = 'none'
iframe.style.backgroundColor = 'transparent'
element.append(iframe)

const css3dObject = new CSS3DObject(element)
const ratio = height / width
css3dObject.scale.set(1 / width, (1 / height) * ratio, 1)
const imgGeometry = new THREE.PlaneBufferGeometry(1, ratio)
const imgMaterial = new THREE.MeshBasicMaterial({
    opacity: 0,
    color: new THREE.Color(0xffffff),
    blending: THREE.NoBlending,
    side: THREE.DoubleSide,
    transparent: true,
})

const webMesh = new THREE.Mesh(imgGeometry, imgMaterial)
webMesh.add(css3dObject)
webMesh.scale.set(5, 5, 5)
webMesh.position.set(0, 3, 0)
scene.add(webMesh)

const geometry = new THREE.SphereGeometry( 1, 32, 32 );
const material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
const sphere = new THREE.Mesh( geometry, material );
sphere.position.set(0, 1, 0)
scene.add( sphere );

const clock = new THREE.Clock()
let previousTime = 0

const tick = () => {
    const elapsedTime = clock.getElapsedTime()
    const deltaTime = elapsedTime - previousTime
    previousTime = elapsedTime
  
    // Update controls
    controls.update()

    // Render
    renderer.render(scene, camera)
    cssRenderer.render(scene, camera)

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

I’ve tested your app on macOS today. Safari looks as expected. FF does not show the iFrame (you just see a white plane) but performance is okay. Chrome does indeed flicker and has a bad performance. Besides, after the first flicker, the text seems to appear a bit blurred.

It’s probably best to report the issue to the browser vendors. Could be a bug in the compositor:

FF: https://bugzilla.mozilla.org/
Chrome: Monorail - chromium - An open-source project to help move the web forward. - Monorail

Ok, the performance issue also can be tested on this:

Not sure why, but when Css3dObjects are closer to the camera than 1 some browsers stop showing (parts of the) the content. Maybe you can try placing your scene a bit further away from the camera and scale the Css3dObject according to your needs?
Furthermore you might consider setting the background color of the containing div to black (don’t know if that helps with the performance).