Skip to content

WebGPURenderer: Incomplete support of MeshBasicMaterial. #28785

@Mugen87

Description

@Mugen87

Description

While working at the post processing nodes, I have noticed that scenes with MeshBasicMaterial lack some features when used with WebGPURenderer. E.g. the quite commonly MeshBasicMaterial.envMap is not supported with WebGPURenderer so far.

I've tried to fix it by myself but NodeMaterial.getEnvNode() is only evaluate for lit materials right now.

setupLights( builder ) {
const envNode = this.getEnvNode( builder );

Since MeshBasicNodeMaterial has set its lights properties to false, getEnvNode() is never called. I'm not sure where the best spot in NodeMaterial is for fixing that.

The more exotic lightMap and aoMap should also be supported since there are some baking workflows that make use of this combination. specularMap seems also missing.

Reproduction steps

  1. Open https://jsfiddle.net/p392kuho/
  2. See white spheres.
  3. Expected result is an environment mapped on the spheres.

Code

import * as THREE from 'three';

let camera, scene, renderer;

const spheres = [];

let mouseX = 0;
let mouseY = 0;

let windowHalfX = window.innerWidth / 2;
let windowHalfY = window.innerHeight / 2;

document.addEventListener( 'mousemove', onDocumentMouseMove );

init();

function init() {

  camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.01, 100 );
  camera.position.z = 3;

  const path = 'https://threejs.org/examples/textures/cube/pisa/';
  const format = '.png';
  const urls = [
    path + 'px' + format, path + 'nx' + format,
    path + 'py' + format, path + 'ny' + format,
    path + 'pz' + format, path + 'nz' + format
  ];

  const textureCube = new THREE.CubeTextureLoader().load( urls );

  scene = new THREE.Scene();
  scene.background = textureCube;

  const geometry = new THREE.SphereGeometry( 0.1, 32, 16 );
  const material = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap: textureCube } );

  for ( let i = 0; i < 500; i ++ ) {

    const mesh = new THREE.Mesh( geometry, material );

    mesh.position.x = Math.random() * 10 - 5;
    mesh.position.y = Math.random() * 10 - 5;
    mesh.position.z = Math.random() * 10 - 5;

    mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 3 + 1;

    scene.add( mesh );

    spheres.push( mesh );

  }

  //

  renderer = new THREE.WebGPURenderer();
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.setSize( window.innerWidth, window.innerHeight );
  renderer.setAnimationLoop( animate );
  document.body.appendChild( renderer.domElement );

  //

  window.addEventListener( 'resize', onWindowResize );

}

function onWindowResize() {

  windowHalfX = window.innerWidth / 2;
  windowHalfY = window.innerHeight / 2;

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  
  renderer.setSize( window.innerWidth, window.innerHeight );


}

function onDocumentMouseMove( event ) {

  mouseX = ( event.clientX - windowHalfX ) / 100;
  mouseY = ( event.clientY - windowHalfY ) / 100;

}

//

function animate() {

  const timer = 0.0001 * Date.now();

  camera.position.x += ( mouseX - camera.position.x ) * .05;
  camera.position.y += ( - mouseY - camera.position.y ) * .05;

  camera.lookAt( scene.position );

  for ( let i = 0, il = spheres.length; i < il; i ++ ) {

    const sphere = spheres[ i ];

    sphere.position.x = 5 * Math.cos( timer + i );
    sphere.position.y = 5 * Math.sin( timer + i * 1.1 );

  }

  renderer.render( scene, camera );

}

Live example

Live example: https://jsfiddle.net/p392kuho/

Screenshots

No response

Version

r167dev

Device

No response

Browser

No response

OS

No response

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions