three 灯光,相机与投影的关系

101 阅读4分钟

在 three 中灯光,相机,投影这三个是配合使用的,相机决定投影的设置方式,例如正交相机就与透视相机的阴影设置方式不同,而灯光决定投影的位置与强度

在 three 中要启要阴影首先要在渲染上设置下列属性

  • renderer.shadowMap.enabled = true; 用于在 three 中启用阴影,默认是不启用的
  • renderer.shadowMap.type = THREE.PCFSoftShadowMap 阴影类型有四种 THREE.BasicShadowMap 性能最好但是锯齿明显,THREE.PCFShadowMap 性能与锯齿适中, THREE.PCFSoftShadowMap 性能较低,阴影更柔和,THREE.VSMShadowMap 性能更次,阴影更柔和

LightShadow 这个是阴影的基类 在启用阴影后所有产生阴影的灯光都会继承这个基类,这个有十二个属性,七个方法

  • autoUpdate 自动更新阴影 默认为 true;
  • camera 相机属性,决定了在指定范围内是否产生阴影 例 light.shadow.camera.near = 0.5;light.shadow.camera.far = 500; 这个可以设置物体的阴影程现在距离最近 0.5 与最远 500 处显示阴影
  • Bias 偏移量 light.shadow.bias = -0.0001;// 可能会使阴影靠近物体表面 light.shadow.bias = -0.01; // 可能会使阴影离物体表面较远
  • blurSamples 阴影的模似质量
  • intensity 阴影的强度 有效的值范围是 0 - 1
  • 值越大阴影越深
  • map 只读属性 阴影贴图 获取阴影效果图
  • mapPass 属性难解 内部使用
  • mapSize 这个属性决定了阴影的质量 这个有width,height 两个属性决定了阴影的分辨率
  • matrix 只读属性,查看和调试距阵属性
  • needsUpdate 用来标记是否需要新阴影 布尔属性
  • normalBias 设置正常偏移量,减少自阴问题 取值 0 - 1
  • radius 阴影的模糊半径
  • getFrameExtents 方法 内部使用
  • updateMatrices 方法 更新阴影矩阵 可以与 autoUpdate 配合 定义何时更新阴影
  • getFrustum 方法 创建一个视锥体对象用于可视化 使用示例
// 创建一个点光源
const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.castShadow = true;
scene.add(pointLight);

// 创建一个视锥体对象用于可视化
const frustum = pointLight.shadow.getFrustum();

// 创建一个几何体(如立方体)来可视化视锥体
const geometry = new THREE.BoxGeometry(
  frustum.right - frustum.left, 
  frustum.top - frustum.bottom, 
  frustum.far - frustum.near
);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

// 渲染场景
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();
  • getViewportCount 方法 就是获取有多少个相机观测
  • copy 方法 有一个参数 类型为 LightShadow 将参数的阴影设置复制到当前光源
  • clone 方法 克隆当前的灯光实例
  • toJSON 方法 将阴影转换为 JSON 也可以通过 fromJson 将JSON 恢复成阴影设置
// 创建一个点光源
const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.castShadow = true;

// 配置光源的阴影设置
pointLight.shadow.mapSize.width = 2048;
pointLight.shadow.mapSize.height = 2048;
pointLight.shadow.camera.near = 0.5;
pointLight.shadow.camera.far = 500;
pointLight.shadow.bias = -0.001;

// 将阴影设置转换为 JSON 格式
const shadowJSON = pointLight.shadow.toJSON();
console.log(shadowJSON);

// 从 JSON 数据恢复阴影设置
const restoredShadow = new THREE.PointLightShadow();
restoredShadow.fromJSON(shadowJSON);

// 应用恢复的阴影设置到新的光源
const newPointLight = new THREE.PointLight(0xffffff, 1);
newPointLight.castShadow = true;
newPointLight.shadow = restoredShadow;

PointLightShadow 设置点光源的阴影类 一个属性 一个方法

  • isPointLightShadow 判断是否为点光源
  • updateMatrices 方法 更新点光源距阵

使用示例

    // 创建一个点光源
    const pointLight = new THREE.PointLight(0xffffff, 1);
    pointLight.castShadow = true;

    // 获取点光源的阴影对象
    const pointLightShadow = pointLight.shadow;

    // 配置阴影设置
    pointLightShadow.mapSize.width = 2048;
    pointLightShadow.mapSize.height = 2048;
    pointLightShadow.camera.near = 0.5;
    pointLightShadow.camera.far = 500;
    pointLightShadow.bias = -0.001;

    // 在需要时手动更新矩阵
    pointLightShadow.updateMatrices();

    // 将点光源添加到场景中
    scene.add(pointLight);

DirectionalLightShadow 两个属性

  • camera 相机对象 定义相机投影的范围
  • isDirectionalLightShadow 判断当前光是否是平行光

使用示例

    // 创建一个方向光源
    const directionalLight = new THREE.DirectionalLight(0xffffff, 1);

    // 设置光源的阴影
    directionalLight.castShadow = true;

    // 获取方向光的阴影对象
    const directionalLightShadow = directionalLight.shadow;

    // 配置阴影设置
    directionalLightShadow.mapSize.width = 2048; // 阴影贴图的宽度
    directionalLightShadow.mapSize.height = 2048; // 阴影贴图的高度

    // 配置阴影相机
    const shadowCamera = directionalLightShadow.camera;
    shadowCamera.left = -500;
    shadowCamera.right = 500;
    shadowCamera.top = 500;
    shadowCamera.bottom = -500;
    shadowCamera.near = 1;
    shadowCamera.far = 1000;

    // 将方向光源添加到场景中
    scene.add(directionalLight);

SpotLightShadow 三个属性

  • camera 相机对象 定义相机投影的范围
  • focus 改变阴影的聚集程序
  • isSpotLightShadow 判断光源是否是取光灯

使用示例

    // 创建一个聚光灯
    const spotLight = new THREE.SpotLight(0xffffff, 1);
    spotLight.castShadow = true;

    // 获取聚光灯的阴影对象
    const spotLightShadow = spotLight.shadow;

    // 配置阴影设置
    spotLightShadow.mapSize.width = 2048;
    spotLightShadow.mapSize.height = 2048;

    // 配置聚光灯的焦距
    spotLightShadow.focus = 1; // 默认值,调节焦距可以影响阴影的聚焦效果

    // 设置聚光灯的其他属性
    spotLight.angle = Math.PI / 6; // 光束的角度
    spotLight.penumbra = 0.1; // 光束边缘的模糊程度
    spotLight.decay = 2; // 光的衰减程度

    // 将聚光灯添加到场景中
    scene.add(spotLight);

结语,在灯光使用中以上就是全部内容了,但是还有一些需要注意的部分,例如 新建一个物体 要通过设置物体是否接收阴影 receiveShadow,是否产生阴影 castShadow,还有材质相关 基些材质无法接收灯光。