three.js 平行光与阴影及其相关属性

基础篇:three.js 基础认识与简单应用

纹理贴图:three.js 纹理贴图的使用

纹理贴图进阶: three.js纹理贴图进阶

一、灯光与阴影的关系与设置 -- 五个步骤缺一不可 (点、聚会再次赘述)

 目标:灯光与阴影

  • 环境光无阴影
  • 平行光(太阳光),点光源(电灯泡-四处发光),聚光灯(八)

 1、材质要满足能够对光照有反应

  •  最常用-标准网格材质(MeshStandardMaterial)
  •  更消耗性能-物理网格材质(MeshPhysicalMaterial)-MeshStandardMaterial的扩展,提供了更高级的基于物理的渲染属性:

 2、设置渲染器开启阴影的计算 renderer.shadowMap.enabled = true;

 3、设置光照投射阴影 directionalLight.castShadow = true;

 4、设置物体投射阴影 sphere.castShadow = true;

 5、设置物体接收阴影 plane.receiveShadow = true; 

示例:运行结果如下

 全部代码如下,解析见代码注释:

/*
 * @Description:  灯光与阴影的关系与设置 -- 五个步骤缺一不可
 */

import * as THREE from "three";
// 导入轨道控制器(鼠标控制)
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

/**
 * 目标:灯光与阴影--环境光无阴影,平行光(太阳光),点光源(电灯泡-四处发光),聚光灯(八)
 * 灯光阴影
 * 1、材质要满足能够对光照有反应
        --最常用-标准网格材质(MeshStandardMaterial)
 *      --更消耗性能-物理网格材质(MeshPhysicalMaterial)-MeshStandardMaterial的扩展,
         提供了更高级的基于物理的渲染属性:
 * 2、设置渲染器开启阴影的计算 renderer.shadowMap.enabled = true;
 * 3、设置光照投射阴影 directionalLight.castShadow = true;
 * 4、设置物体投射阴影 sphere.castShadow = true;
 * 5、设置物体接收阴影 plane.receiveShadow = true;
 */

/*
 *1. 创建场景
 */
const scene = new THREE.Scene();

/*
 * 2.创建相机(这里是 透视摄像机--用来模拟人眼所看到的景象)
 */
const camera = new THREE.PerspectiveCamera(
  75, // 视野角度
  window.innerWidth / window.innerHeight, // 长宽比
  0.1, // 进截面
  1000 // 远截面
);
// 设置相机位置
camera.position.set(7, 7, 7);
scene.add(camera); // 将相机添加到场景中

/*
 *  添加物体
 */
// 创建几何体
const sphereGeometry = new THREE.SphereBufferGeometry(1, 20, 20);

// 1). 设置材质-标准网格材质
const material = new THREE.MeshStandardMaterial();

// 生成几何体
const sphere = new THREE.Mesh(sphereGeometry, material);

// 4). 投射阴影 --对象是否被渲染到阴影贴图中--三维物体(Object3D)
sphere.castShadow = true;

scene.add(sphere);

/**
 * 创建底部平面
 */
const planeGeometry = new THREE.PlaneBufferGeometry(10, 10);
const plane = new THREE.Mesh(planeGeometry, material);
plane.position.set(0, -1, 0);
plane.rotation.x = -Math.PI / 2;

// 5). 接收阴影
plane.receiveShadow = true;

scene.add(plane);

/**
 * 灯光
 */
// 环境光
const light = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(light);
// 直线光源(平行光)
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
// 设置平行光的位置
directionalLight.position.set(10, 10, 10);

// 3). 设置平行光产生动态阴影
directionalLight.castShadow = true;

scene.add(directionalLight);

/**
 *  3.初始化渲染器
 */
const renderer = new THREE.WebGL1Renderer();
// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight);

// 2). 开启场景中的阴影贴图--允许在场景中使用阴影贴图
renderer.shadowMap.enabled = true;

// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

/**
 * 创建轨道控制器(OrbitControls)
 * 可以使得相机围绕目标进行轨道运动
 */
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼,让控制器更有真是效果,必须在动画循环render()中调用update()
controls.enableDamping = true;
// controls.autoRotate = true;
// controls.autoRotateSpeed = 2; // 自转速度

/**
 * 辅助三维坐标系
 * 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
 */
var axesHelper = new THREE.AxesHelper(7);
scene.add(axesHelper);

// 定义循环渲染方法
function render() {
  renderer.render(scene, camera); // 执行渲染操作
  controls.update(); // 加不加都行
  requestAnimationFrame(render); // 渲染下一帧的时候就会调用render函数
}
render();

// 监听尺寸变化实现自适应画面
window.addEventListener("resize", () => {
  // console.log("画面变化了");
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新摄像机的投影矩阵
  camera.updateProjectionMatrix();
  // 更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 设置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});

 

二、平行光THREE.DirectionalLight

 介绍:

        平行光是沿着特定方向发射的光。这种光的表现像是无限远,从它发出的光线都是平行的。常常用平行光来模拟太阳光 的效果; 太阳足够远,因此我们可以认为太阳的位置是无限远,所以我们认为从太阳发出的光线也都是平行的。

构造器:        

        DirectionalLight( color : Integer, intensity : Float )

                color - (可选参数) 16进制表示光的颜色。 缺省值为 0xffffff (白色)。
                intensity - (可选参数) 光照的强度。缺省值为1。

与点光源和聚光灯的区别:

        最大的区别就是,点光源聚光灯光源距离物体越远光线越暗。光是从一点发出的。
而被平行光照亮的整个区域接收到的光强是一样的。光是平行的。

平行光的特点:

        由于模型的阴影渲染会消耗很多的性能,所以我们需要设置平行光相关的区域能够显示阴影,和阴影显示的良好程度。如下几个属性:

        

        //这两个值决定使用多少像素生成阴影 默认512
        directionalLight.shadow.mapSize.height = 2048;
        directionalLight.shadow.mapSize.width = 2048;

        或者 

        directionalLight.shadow.mapSize.set(2048, 2048);

        // 设置阴影贴图模糊度

        directionalLight.shadow.radius = 20;

        // 设置平行光投射相机的属性

        directionalLight.shadow.camera.near = 0.5; //产生阴影的最近距离
        directionalLight.shadow.camera.far = 500; //产生阴影的最远距离
        directionalLight.shadow.camera.left = -5; //产生阴影距离位置的最左边位置
        directionalLight.shadow.camera.right = 5; //最右边
        directionalLight.shadow.camera.top = 5; //最上边
        directionalLight.shadow.camera.bottom = -5; //最下面

 示例:运行结果如下

通过 near 的变化:

// 设置阴影贴图模糊度

directionalLight.shadow.radius = 20;

// 设置阴影贴图的分辨率

directionalLight.shadow.mapSize.set(2048, 2048);

// 设置平行光投射相机的属性

directionalLight.shadow.camera.near = 0.5;

directionalLight.shadow.camera.far = 500;

directionalLight.shadow.camera.top = 5;

directionalLight.shadow.camera.bottom = -5;

directionalLight.shadow.camera.left = -5;

directionalLight.shadow.camera.right = 5;

  通过更改分辨率(2048 --> 512):

// 设置阴影贴图模糊度

directionalLight.shadow.radius = 20;

// 设置阴影贴图的分辨率

directionalLight.shadow.mapSize.set(512, 512);

// 设置平行光投射相机的属性

directionalLight.shadow.camera.near = 0.5;

directionalLight.shadow.camera.far = 500;

directionalLight.shadow.camera.top = 5;

directionalLight.shadow.camera.bottom = -5;

directionalLight.shadow.camera.left = -5;

directionalLight.shadow.camera.right = 5;

通过更改模糊度(20 -- > 120):

// 设置阴影贴图模糊度

directionalLight.shadow.radius = 120;

// 设置阴影贴图的分辨率

directionalLight.shadow.mapSize.set(2048, 2048);

// 设置平行光投射相机的属性

directionalLight.shadow.camera.near = 0.5;

directionalLight.shadow.camera.far = 500;

directionalLight.shadow.camera.top = 5;

directionalLight.shadow.camera.bottom = -5;

directionalLight.shadow.camera.left = -5;

directionalLight.shadow.camera.right = 5;

  全部代码如下,解析见代码注释:

/*
 * @Description:  平行光(DirectionalLight)阴影属性与阴影相机原理
 */

// 导入dat.gui可视化工具
import * as dat from "dat.gui";
import * as THREE from "three";
// 导入轨道控制器(鼠标控制)
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

/**
 * 目标:灯光与阴影--环境光无阴影,平行光(太阳光),点光源(电灯泡-四处发光),聚光灯(八)
 * 灯光阴影
 * 1、材质要满足能够对光照有反应
        --最常用-标准网格材质(MeshStandardMaterial)
 *      --更消耗性能-物理网格材质(MeshPhysicalMaterial)-MeshStandardMaterial的扩展,
         提供了更高级的基于物理的渲染属性:
 * 2、设置渲染器开启阴影的计算 renderer.shadowMap.enabled = true;
 * 3、设置光照投射阴影 directionalLight.castShadow = true;
 * 4、设置物体投射阴影 sphere.castShadow = true;
 * 5、设置物体接收阴影 plane.receiveShadow = true;
 */
/*
 *1. 创建场景
 */
const scene = new THREE.Scene();

/*
 * 2.创建相机(这里是 透视摄像机--用来模拟人眼所看到的景象)
 */
const camera = new THREE.PerspectiveCamera(
  75, // 视野角度
  window.innerWidth / window.innerHeight, // 长宽比
  0.1, // 进截面
  1000 // 远截面
);
// 设置相机位置
camera.position.set(7, 7, 7);
scene.add(camera); // 将相机添加到场景中

/*
 *  添加物体
 */
// 创建几何体
const sphereGeometry = new THREE.SphereBufferGeometry(1, 20, 20);
// 1). 设置材质
const material = new THREE.MeshStandardMaterial();
// 生成几何体
const sphere = new THREE.Mesh(sphereGeometry, material);
// 4). 投射阴影 --对象是否被渲染到阴影贴图中--三维物体(Object3D)
sphere.castShadow = true;
scene.add(sphere);

/**
 * 创建平面
 */
const planeGeometry = new THREE.PlaneBufferGeometry(10, 10);
const plane = new THREE.Mesh(planeGeometry, material);
plane.position.set(0, -1, 0);
plane.rotation.x = -Math.PI / 2;
// 5). 接收阴影
plane.receiveShadow = true;
scene.add(plane);

/**
 * 灯光
 */
// 环境光
const light = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(light);

// 直线光源(平行光)
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
// 设置平行光的位置
directionalLight.position.set(10, 10, 10);
// 3). 设置平行光产生动态阴影
directionalLight.castShadow = true;

// 设置阴影贴图模糊度
directionalLight.shadow.radius = 20;
// 设置阴影贴图的分辨率
directionalLight.shadow.mapSize.set(2048, 2048);

// 设置平行光投射相机的属性
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 500;
directionalLight.shadow.camera.top = 5;
directionalLight.shadow.camera.bottom = -5;
directionalLight.shadow.camera.left = -5;
directionalLight.shadow.camera.right = 5;

scene.add(directionalLight);

const gui = new dat.GUI();
gui
  .add(directionalLight.shadow.camera, "near")
  .min(0)
  .max(20)
  .step(0.1)
  .onChange(() => {
    directionalLight.shadow.camera.updateProjectionMatrix();
  });

/**
 *  3.初始化渲染器
 */
const renderer = new THREE.WebGL1Renderer();
// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight);

// 2). 开启场景中的阴影贴图--允许在场景中使用阴影贴图
renderer.shadowMap.enabled = true;

// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

/**
 * 创建轨道控制器(OrbitControls)
 * 可以使得相机围绕目标进行轨道运动
 */
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼,让控制器更有真是效果,必须在动画循环render()中调用update()
controls.enableDamping = true;
// controls.autoRotate = true;
// controls.autoRotateSpeed = 2; // 自转速度

/**
 * 辅助三维坐标系
 * 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
 */
var axesHelper = new THREE.AxesHelper(7);
scene.add(axesHelper);

// 定义循环渲染方法
function render() {
  renderer.render(scene, camera); // 执行渲染操作
  controls.update(); // 加不加都行
  requestAnimationFrame(render); // 渲染下一帧的时候就会调用render函数
}
render();

// 监听尺寸变化实现自适应画面
window.addEventListener("resize", () => {
  // console.log("画面变化了");
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新摄像机的投影矩阵
  camera.updateProjectionMatrix();
  // 更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 设置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});

 

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要调节平行阴影的强度和明暗程度,你可以使用Three.js中的`THREE.DirectionalLight`类。这个类代表一个方向源,可以设置它的颜色、强度、位置等属性,来影响场景中的阴影和明暗程度。 下面是一个示例代码,演示如何使用`THREE.DirectionalLight`类来调节平行阴影的强度和明暗程度: ```javascript // 创建一个方向源 var light = new THREE.DirectionalLight(0xffffff, 1); // 设置源的位置 light.position.set(0, 1, 0); // 设置源的阴影属性 light.castShadow = true; // 调节阴影强度 light.shadow.mapSize.width = 1024; light.shadow.mapSize.height = 1024; light.shadow.camera.near = 0.5; light.shadow.camera.far = 500; // 将源添加到场景中 scene.add(light); ``` 在上面的代码中,我们创建了一个白色的方向源,并将它的位置设置为`(0, 1, 0)`。然后,我们将`castShadow`属性设置为`true`,表示这个源会产生阴影。接下来,我们调节了阴影的强度,使它更明显。最后,我们将源添加到场景中。 如果你想调节平行的明暗程度,可以简单地调节源的颜色和强度属性。例如,如果你想让场景变得更暗,可以将源的颜色设置为较暗的颜色,例如`0x333333`,并将强度设置为较小的值,例如`0.5`。相反,如果你想让场景变得更明亮,可以将源的颜色设置为较亮的颜色,例如`0xffffff`,并将强度设置为较大的值,例如`2.0`。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值