three.js之光源

专栏目录请点击

简介

光源是对于自然界光照的模拟,往往为了更好的渲染场景,需要设置不同的光源,设置不同的光照强度

分类

一般光源可以分成以下类别

  1. 环境光(AmbientLight)
  2. 平行光(DirectionalLight)
  3. 点光源(PointLight)
  4. 聚光灯光源(SpotLight)

环境光

环境光是没有特定方向的光源,主要是均匀改变物体明暗的效果,如果没有设置环境光,那么物体会是一个全黑的对象

  • 没有环境光

在这里插入图片描述

  • 有环境光
//环境光:环境光颜色RGB成分分别和物体材质颜色RGB成分分别相乘
var ambient = new THREE.AmbientLight(0x888888);
scene.add(ambient);//环境光对象添加到scene场景中

当环境光打上之后,物体立马改变了颜色

在这里插入图片描述

点光源

  1. 点光源就像我们生活中的灯泡,当设置点光源的时候,必须设置光源的位置属性position
  2. 他会呈现出阴暗面,我们可以设置光源的位置来感受点光源的特点
var point = new THREE.PointLight(0xffffff);
point.position.set(400, 200, 300);
scene.add(point);

在这里插入图片描述
3. 我们修改点光源的位置,看一下他的渲染效果

point.position.set(-400, -200, -300);

在这里插入图片描述
我们拖动一下物体就会发现,亮面在另一面

平行光

  1. 平行光的光线是平行的,也就是说物体的每一个区域接收到的入射角是相同的
  2. 在设置的时候,使用positiontarget两个属性来一起确定平行光的方向
    • target的属性值可以是threejs场景中任何一个三维模型
// 平行光设置
var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
// 两点确定一条直线,我们要找两个点,一个是我们设置的点(position),一个是物体(target)
directionalLight.position.set(80, 100, 50);
directionalLight.target = mesh;
scene.add(directionalLight);

在这里插入图片描述
平行光如果不设置position和target属性,那么光线默认从上往下照射,也就可以认为是从(0,1,0)(0,0,0)两个点确定的直线

聚光灯

  • 聚光灯是一个会沿着特定方向逐渐发散的光源,在一个立体空间会构成一个圆锥体
  • 通过属性angle可以设置聚光灯发散的角度,照射位置和平行光相同是由positiontarget两个属性实现的
// 聚光灯设置
var spotLight = new THREE.SpotLight(0xffffff);
// 两点确定一条直线,我们要找两个点,一个是我们设置的点(position),一个是物体(target)
spotLight.position.set(200, 200, 200);
spotLight.target = mesh;
// 设置发散的角度
spotLight.angle = Math.PI / 100

scene.add(spotLight);

在这里插入图片描述

光源辅助对象

光源辅助对象,就像AxesHelper一样可以可视化显示坐标,他可以大致显示光照的方向

辅助对象构造函数名
聚光源辅助对象SpotLightHelper
点光源辅助对象PointLightHelper
平行光光源辅助对象DirectionalLightHelper
// 光源对象设置
const sphereSize = 2;
const pointLightHelper = new THREE.PointLightHelper( point, sphereSize,"#000" );
scene.add( pointLightHelper );

在这里插入图片描述

相关计算

颜色计算

  1. 当不同颜色的光源照射到有颜色的材质上面去的时候,当光源的颜色和网格模型材质的颜色值mesh.material.color和光源的颜色值light.color会进行简单的相乘,也就是RGB三个分量分别进行相乘
  2. 平行光漫反射的数学模型:漫反射光的颜色 = 网格模型材质颜色值 x 光线颜色 x 光线入射角余弦值
  3. 漫反射数学模型RGB分量表示:(R2,G2,B2) = (R1,G1,B1) x (R0,G0,B0) x cosθ
R2 = R1 * R0 * cosθ
G2 = G1 * G0 * cosθ
B2 = B1 * B0 * cosθ

阴影

有方向的光源的作用下,物体都会形成隐形,想要产生阴影,需要有三个要素

  1. 首先要有光源
  2. 要有投影的模型
  3. 要有接收投影的模型
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <style>
    body {
      margin: 0;
      overflow: hidden;
      /* 隐藏body窗口区域滚动条 */
    }
  </style>
  <!--引入three.js三维引擎-->
  <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script>
  <!-- 引入threejs扩展控件OrbitControls.js -->
  <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/controls/OrbitControls.js"></script>
</head>

<body>
  <script>
    /**
     * 创建场景对象Scene
     */
    var scene = new THREE.Scene();
    /**
     * 创建网格模型
     */
    var geometry = new THREE.BoxGeometry(40, 100, 40); //创建一个立方体几何对象Geometry
    var material = new THREE.MeshLambertMaterial({
      color: 0x0000ff
    }); //材质对象Material
    var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
    scene.add(mesh); //网格模型添加到场景中
    // 设置产生投影的网格模型
    mesh.castShadow = true;
    // mesh.position.set(0,0,0)

    //创建一个平面几何体作为投影面
    var planeGeometry = new THREE.PlaneGeometry(300, 200);
    var planeMaterial = new THREE.MeshLambertMaterial({
      color: 0x999999
    }); //材质对象Material

    // 平面网格模型作为投影面
    var planeMesh = new THREE.Mesh(planeGeometry, planeMaterial); //网格模型对象Mesh
    scene.add(planeMesh); //网格模型添加到场景中
    planeMesh.rotateX(-Math.PI / 2); //旋转网格模型
    planeMesh.position.y = -50; //设置网格模型y坐标
    // 设置接收阴影的投影面
    planeMesh.receiveShadow = true;
    /**
     * 光源设置
     */
    //环境光   环境光颜色RGB成分分别和物体材质颜色RGB成分分别相乘
    var ambient = new THREE.AmbientLight(0x444444);
    scene.add(ambient); //环境光对象添加到scene场景中

    // 方向光
    var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
    // 设置光源位置
    directionalLight.position.set(60, 100, 40);
    scene.add(directionalLight);
    // 设置用于计算阴影的光源对象
    directionalLight.castShadow = true;
    // 设置计算阴影的区域,最好刚好紧密包围在对象周围
    // 计算阴影的区域过大:模糊  过小:看不到或显示不完整
    directionalLight.shadow.camera.near = 0.5;
    directionalLight.shadow.camera.far = 300;
    directionalLight.shadow.camera.left = -50;
    directionalLight.shadow.camera.right = 50;
    directionalLight.shadow.camera.top = 200;
    directionalLight.shadow.camera.bottom = -100;
    // 设置mapSize属性可以使阴影更清晰,不那么模糊
    // directionalLight.shadow.mapSize.set(1024,1024)
    console.log(directionalLight.shadow.camera);
    /**
     * 相机设置
     */
    var width = window.innerWidth; //窗口宽度
    var height = window.innerHeight; //窗口高度
    var k = width / height; //窗口宽高比
    var s = 150; //三维场景显示范围控制系数,系数越大,显示的范围越大
    //创建相机对象
    var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
    camera.position.set(200, 300, 200); //设置相机位置
    camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
    /**
     * 创建渲染器对象
     */
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(width, height); //设置渲染区域尺寸
    renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
    document.body.appendChild(renderer.domElement); //body元素中插入canvas对象
    // 设置渲染器,允许场景中使用阴影贴图
    renderer.shadowMap.enabled = true;
    // 渲染函数
    function render() {
      renderer.render(scene, camera); //执行渲染操作
    }
    render();
    //创建控件对象  相机对象camera作为参数   控件可以监听鼠标的变化,改变相机对象的属性
    var controls = new THREE.OrbitControls(camera, renderer.domElement);
    //监听鼠标事件,触发渲染函数,更新canvas画布渲染效果
    controls.addEventListener('change', render);
  </script>
</body>

</html>

我们可以将上面的代码进行复制,渲染出来的效果如下
在这里插入图片描述

  1. 在这里,我们设置了投影面,并让投影面接收阴影
// 平面网格模型作为投影面
var planeMesh = new THREE.Mesh(planeGeometry, planeMaterial); //网格模型对象Mesh
scene.add(planeMesh); //网格模型添加到场景中
planeMesh.rotateX(-Math.PI / 2); //旋转网格模型
planeMesh.position.y = -50; //设置网格模型y坐标
// 设置接收阴影的投影面
planeMesh.receiveShadow = true;
  1. 然后设置了阴影的计算区域
// 设置用于计算阴影的光源对象
directionalLight.castShadow = true;
// 设置计算阴影的区域,最好刚好紧密包围在对象周围
// 计算阴影的区域过大:模糊  过小:看不到或显示不完整
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 300;
directionalLight.shadow.camera.left = -50;
directionalLight.shadow.camera.right = 50;
directionalLight.shadow.camera.top = 200;
directionalLight.shadow.camera.bottom = -100;
// 设置mapSize属性可以使阴影更清晰,不那么模糊
// directionalLight.shadow.mapSize.set(1024,1024)

相关属性

castShadow

  • 模型和光源都有这个属性,且都是布尔值
  • 如果是模型的castShadow,它主要用来设置模型对象在光源下是否产生阴影
  • 如果是光源的castShadow,那么光源将会设置动态的阴影,这需要消耗很多动态资源,使投影看起正确

receiveShadow

  • 他也是一个布尔值,用于设置一个模型对象是否在光照下接受其他模型的投影

shadow

  • 光源的shadow属性是一个对象,不同光源的属性值,他们的光阴影对象也是不同的
种类对象阴影对象
平行光DirectionalLightDirectionalLightShadow
聚光源SpotLightSpotLightShadow
LightShadow

LightShadow是所有阴影对象的基类,他有一个属性叫做camera

  • 这个是观察光源的相机对象。这里可以看官网的解释 点击,他用于生成场景的深度图

基类

  • 光源都有一个共同的基类,那就是Light
  • 而Light也有一个基类叫做Object3D
  • 在基类中,光源有两个常用的属性
    • color:他的默认值是0xffffff
    • intensity:他的默认值是1.0
    • 光照计算的时候会把两个属性值进行相乘
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 要在 three.js 中实现点光源,你可以使用 `THREE.PointLight` 类。 首先,你需要创建一个 `PointLight` 对象,并设置它的颜色和强度。例如: ``` let pointLight = new THREE.PointLight(0xffffff, 1, 100); ``` 然后,你可以设置点光源的位置,这样它才能对场景中的物体产生影响。例如: ``` pointLight.position.set(50, 50, 50); ``` 最后,你需要将点光源添加到场景中。例如: ``` scene.add(pointLight); ``` 现在,你就可以看到点光源在场景中产生的效果了。 ### 回答2: 在three.js中,我们可以通过使用PointLight对象来实现点光源效果。点光源是一种发出光线的光源,类似于灯泡。下面是一个简单的示例代码,演示了如何在three.js中创建和使用点光源: ```javascript // 创建场景 var scene = new THREE.Scene(); // 创建相机 var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // 创建渲染器 var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 创建点光源 var pointLight = new THREE.PointLight(0xFFFFFF, 1); pointLight.position.set(0, 0, 0); // 设置光源位置 scene.add(pointLight); // 创建几何体 var geometry = new THREE.BoxGeometry(1, 1, 1); var material = new THREE.MeshPhongMaterial({ color: 0x00ff00 }); // 使用Phong材质 var cube = new THREE.Mesh(geometry, material); scene.add(cube); // 渲染循环 function animate() { requestAnimationFrame(animate); // 使几何体绕y轴旋转 cube.rotation.y += 0.01; renderer.render(scene, camera); } animate(); ``` 在上面的代码中,我们首先创建了一个场景、相机和渲染器。然后使用`THREE.PointLight`创建了一个点光源,并设置了它的位置为(0, 0, 0)。接下来,我们创建了一个立方体几何体,并添加到场景中。最后,使用渲染循环来实时更新和渲染场景。 需要注意的是,我们还使用了`THREE.MeshPhongMaterial`来为几何体指定使用Phong材质。这是为了使几何体能够反射和接受光线,从而呈现出光照效果。 通过以上步骤,我们就可以在three.js中实现点光源的效果了。您可以根据需要调整点光源的颜色、强度、位置等参数,以及几何体和材质的设置,以达到您想要的效果。 ### 回答3: three.js 是一个用于在Web浏览器中创建和显示3D图形的JavaScript库。要实现点光源,可以按照以下步骤进行: 1. 首先,我们需要借助 three.js 创建一个场景和一个相机。可以使用如下代码创建一个基本的场景和相机: ```javascript var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); // 设置相机位置 camera.position.z = 5; ``` 2. 接下来,我们需要创建一个点光源。点光源是从一个点向四面八方发射的光线。可以使用如下代码创建一个点光源: ```javascript var pointLight = new THREE.PointLight(0xffffff, 1, 100); // 设置光源位置 pointLight.position.set(0, 0, 0); // 将光源添加到场景中 scene.add(pointLight); ``` 这段代码创建了一个颜色为白色的点光源,亮度为1,传播范围为100。你可以根据需要调整光源的颜色、亮度和传播范围。 3. 最后,我们需要创建一个可渲染的物体,例如一个立方体,以使点光源的影响可见。可以使用以下代码创建一个立方体并将其添加到场景中: ```javascript var geometry = new THREE.BoxGeometry(); var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); var cube = new THREE.Mesh(geometry, material); // 将立方体添加到场景中 scene.add(cube); ``` 这段代码创建了一个绿色的立方体。你可以根据需要调整立方体的颜色和形状。 4. 最后,我们需要在渲染循环中更新场景和相机,以便在屏幕上渲染出光源和物体。可以使用以下代码创建一个简单的渲染循环: ```javascript function animate() { requestAnimationFrame(animate); // 旋转立方体 cube.rotation.x += 0.01; cube.rotation.y += 0.01; // 渲染场景和相机 renderer.render(scene, camera); } animate(); ``` 这段代码会每帧更新立方体的旋转角度,并将更新后的场景和相机渲染到屏幕上。 通过上述步骤,我们可以使用 three.js 创建一个带有点光源的场景,并在屏幕上渲染出来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值