为什么three.js点光源添加后不起作用?

新手上路,请多包涵
// 引入threejs
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

// 1.创建一个三维场景scene
const scene = new THREE.Scene();

const geometry = new THREE.BoxGeometry(100, 100, 100);
// * 添加光照
// ! MeshBasicMaterial 不受光材质
// ! MeshLambertMaterial 漫反射 受光材质
const material = new THREE.MeshLambertMaterial({color: 0x0000ff});

// 2。创建网格模型
const mesh = new THREE.Mesh(geometry, material);
// mesh.position.set(0, 0, 0); // * 集合体的位置 默认原点
scene.add(mesh);

// * 创建一个三维坐标轴
const axesHelper = new THREE.AxesHelper(250);
scene.add(axesHelper);

// * 创建一个光源
const light = new THREE.PointLight(0xffffff, 1);
light.position.set(100, 100, 30); // * 设置光源位置
scene.add(light); // * 添加光源

const pointLightHelper = new THREE.PointLightHelper(light, 10);
scene.add(pointLightHelper);

// 3.用来设置canvas的宽高
const sizes = {
  width: 1200,
  height: 800,
};

// 4.透视相机设置
const camera = new THREE.PerspectiveCamera(
  45,
  sizes.width / sizes.height,
  1,
  30000,
);
// * 改变相机位置
camera.position.set(400, 400, 400); // * 斜对角位置
camera.lookAt(0, 0, 0);

// 5.创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(sizes.width, sizes.height); // 设置渲染区域尺寸
renderer.render(scene, camera);
// 把结果canvas画布添加到网页上
document.getElementById('main').appendChild(renderer.domElement);

const orbitControls = new OrbitControls(camera, renderer.domElement);
orbitControls.addEventListener('change', () => {
  renderer.render(scene, camera);
});
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script type="importmap">
    {
      "imports": {
        "three": "../../build/three.module.js",
        "three/addons/": "../../jsm/"
      }
    }
  </script>
  <style>
    .mainCanvas {
      width: 100%;
      height: 100%;
    }
  </style>
</head>
<body>
  <div id="main" class="mainCanvas"></div>
</body>
</html>
<script src="./script.js" type="module"></script>

把PointLight改成平行光就可以显示出来。

阅读 2.7k
avatarAI BotBETA

在three.js中,PointLight(点光源)和DirectionalLight(平行光)都是用来照亮场景的光源类型,但它们的工作方式有所不同。

PointLight是从一个点向所有方向发射光线的光源,它会产生一个逐渐减弱的光照效果,离光源越远,光照强度越小。而DirectionalLight是从一个无限远的方向照射过来的光源,它产生的是一个恒定的光照效果,无论物体离光源多远,光照强度都不会改变。

在你的代码中,点光源没有产生预期的效果,可能是因为点光源的位置设置得不够远离物体,导致光照强度在物体上减弱得太快,几乎看不到效果。另外,由于你使用的是MeshLambertMaterial材质,这种材质是漫反射材质,它会产生更加平滑的光照效果,但也可能因为光照强度不足而看不出效果。

为了解决这个问题,你可以尝试调整点光源的位置,让它远离物体一些,或者增加它的强度(通过修改light.intensity属性)。另外,你也可以尝试使用其他类型的材质,比如MeshPhongMaterial或MeshStandardMaterial,看看是否能够看到光照效果。

如果调整点光源的位置和强度后仍然无法看到光照效果,那么可能是你的场景中缺少其他需要光照的物体,或者光照方向与相机视线方向一致,导致光照效果不明显。你可以尝试添加更多的物体,或者调整相机和光源的位置和角度,以便更好地观察光照效果。

3 个回答

const geometry = new THREE.BoxGeometry(100, 100, 100);
light.position.set(100, 100, 30);

从坐标看,这个点光源在 Box 的内部
Box 加上了材质,内部的光也透不出来,所以就没效果了

创建的几何体挡住了点光源,调一下点光源的position就行了,

添加一个 PointLightHelper 标出光源的位置, 设置光源衰减为0, 增大光源亮度看看.

有时候光源离物体太远, 就看不出来效果.

测试了一下, 修改一下点光源参数, 可以看见了, 就是光源亮度不够. 默认才1, 而且还衰减.

// * 创建一个光源
const light = new THREE.PointLight(0xffffff, 1000, 0, 0);

image.png

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进