0

I see other people demo has light but my local 5173 cannot see the light on some sides for the MeshPhongMaterial. I tested light position , tested pointlight , tested ambientlight and still cannot find the reason. I checked the code of other people demo, people usually use let in the website online for the demo instead of const but I think it does not matter. I cannot find the reason why the cube is always black and single color without light effect when rotating.

import './style.css'
import * as THREE from 'three';
import WebGL from 'three/addons/capabilities/WebGL.js';

// Initialize Three.js
const scene = new THREE.Scene();

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xeeeeee, 1.0) 
renderer.shadowMap.enabled = true 


document.body.appendChild(renderer.domElement);

const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(10, 10, 10); 
camera.lookAt(scene.position); 



// Add an ambient light to provide overall illumination
const ambientLight = new THREE.AmbientLight(0x404040, 1, 1000)
ambientLight.position.set(10, 10, -10)
scene.add(ambientLight)

const pointLight = new THREE.PointLight(0xffffff, 1,1000)
pointLight.position.set(5, 5, 5)
scene.add(pointLight)
     
const geometry = new THREE.BoxGeometry(1, 1, 1) 
const material = new THREE.MeshPhongMaterial({
    color: 0x0000ff
  })
const cube = new THREE.Mesh(geometry, material) 
cube.position.set(0, 1 , 0)
scene.add(cube)

const wireframeCube = new THREE.Mesh(
    new THREE.BoxGeometry(2, 2, 2),
    new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true })
);
scene.add(wireframeCube);

function animate() {
    cube.rotation.x += 0.01
    cube.rotation.y += 0.01
  }

function render() {
    animate()
    requestAnimationFrame(render)
    renderer.render(scene, camera)
}

// Render the scene
renderer.render(scene, camera);

window.addEventListener('resize', function() {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
  })


if ( WebGL.isWebGL2Available() ) {

    // Initiate function or other initializations here
    render()

} else {
    const warning = WebGL.getWebGL2ErrorMessage();
    document.getElementById( 'container' ).appendChild( warning );
  console.log('Not Support webgl');

}

[![a cube with no light][1]][1] [1]: https://i.sstatic.net/65p8brtB.png

3
  • Try setting ` wireframe: false` on the cube. Commented Aug 7, 2024 at 7:03
  • @swatchai If I didn't use import * as THREE from 'three'; but using <script src="cdnjs.cloudflare.com/ajax/libs/three.js/109/…> in index.html. The cube can has blue color at some side. I install three by npm install --save three, and I don't know why this didn't work. How can I know when "cdnjs.cloudflare.com/ajax/libs/three.js/109/three.min.js" will not work or removed if using that way instead. And I still dont know why the installed package does not work. Commented Aug 7, 2024 at 8:32
  • @Raii You use r109, from r155 was made major changes. Switch you version of Three, and try solution from my answer. Also look at this topic Commented Aug 7, 2024 at 9:08

1 Answer 1

0

You have a few issues in your code. A combination of camera position, light intensity and material type.

First, change the intensity of the PointLight:

const pointLight = new THREE.PointLight(0xffffff, 1000, 1000);

Secondly, it is true that PhongMaterial reacts to light, but it is quite specific and if you look closely, when you zoom in on the cube, there is a certain moment of rotation of the cube where the cube looks flat. Even with the light used, if you add the distance of the camera, it is more visible. This is due to the fact that PhongMaterial uses simpler shading, while Standard material uses PBR. Generally this isn't a big deal and both materials should give you some light reflections, but it's worth keeping in mind especially with the PointLight combination or longer camera distances.

Try set:

const material = new THREE.MeshStandardMaterial({
    color: 0x0000ff
});

Thirdly, try change camera position:

camera.position.z = 5;

<script type="importmap">
  {
"imports": {
  "three": "https://unpkg.com/[email protected]/build/three.module.js",
  "three/addons/": "https://unpkg.com/[email protected]/examples/jsm/"
}
  }
</script>

<script type="module">
import * as THREE from "three";
import WebGL from 'three/addons/capabilities/WebGL.js';

// Initialize Three.js
const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.z = 5;

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xeeeeee, 1.0);


document.body.appendChild(renderer.domElement);


camera.lookAt(scene.position);
renderer.shadowMap.enabled = true;


// Add ambient light
const ambientLight = new THREE.AmbientLight(0x404040, 1);
scene.add(ambientLight);

// Add point light
const pointLight = new THREE.PointLight(0xffffff, 1000, 1000);
pointLight.position.set(5, 5, 5);
scene.add(pointLight);

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({
    color: 0x0000ff
});
const cube = new THREE.Mesh(geometry, material);
cube.position.set(0, 1, 0);
scene.add(cube);

const wireframeCube = new THREE.Mesh(
    new THREE.BoxGeometry(2, 2, 2),
    new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true })
);
scene.add(wireframeCube);

function animate() {
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;
}

function render() {
    animate();
    requestAnimationFrame(render);
    renderer.render(scene, camera);
}

// Render the scene
render();

window.addEventListener('resize', function() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
});

if (WebGL.isWebGL2Available()) {
    // WebGL2 is available, nothing else needed here
} else {
    const warning = WebGL.getWebGL2ErrorMessage();
    document.body.appendChild(warning); // Ensure 'container' element is present or use document.body
    console.log('WebGL2 not supported');
}


</script>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.