目录

1、光源

光源特点

AmbientLight 环境光

PointLight 点光源

DirectionalLight 平行光

SpotLight 聚光灯

方向光

半球光

平面光

2. 阴影投影

2.1 阴影支持

2.2 调整阴影效果

3. 其他高级概念


1、光源

光源特点

当使用MeshLambertMaterial材质时,会受到光线的影响, 我们代码里面如果没有设置光线,则使用MeshLambertMaterial材质修饰的模型不可见,这个时候,我们添加光线后,便可以看见。

AmbientLight 环境光

定义:环境光是一种均匀照亮整个场景的光源,它没有特定的方向

特点:环境光通常用于模拟环境光照,如天空光或者漫反射。它默认不会产生阴影,但可以为场景提供一个基本的照明,使物体能够被看见。

属性:主要属性包括颜色和强度。颜色决定了环境光的色调,强度决定了环境光的亮度

示例

const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); 
// 创建一个白色的环境光,强度为0.5
scene.add(ambientLight); // 将环境光添加到场景中

PointLight 点光源

定义:点光源 PointLight (opens new window) 可以类比为一个发光点,就像生活中一个灯泡,以灯泡为中心向四周发射光线

特点:点光源可以模拟现实世界中的灯泡、蜡烛等光源效果。它默认不会产生阴影(但新版本可能支持),但可以通过设置属性来控制其颜色、强度、照射距离等、

属性:主要属性包括颜色、强度、照射距离、衰减等。

示例

// 导入点光源
import { PointLight } from "three";

// 创建点光源并设置白色光、光照强度200、最远照射距离10
const light = new PointLight(0xffffff, 200, 10);

// 设置点光源的位置,x轴5,y轴5,z轴3
light.position.set(5, 5, 3);

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

DirectionalLight 平行光

定义:平行光是一种模拟无限远光源(如太阳)的光源。所有光线都是平行的,有一个统一的方向

特点:

光线平行:所有光线从光源发出后保持平行,不会因距离而发散。

无限远:光源被视为在无限远处,因此光线方向在整个场景中保持一致。

阴影一致:由于光线方向固定,物体产生的阴影在不同位置保持一致。

常用于户外场景:平行光特别适用于模拟日光,常用于户外场景或需要一致光照方向的室内场景。

属性:

方向(Direction):定义光线的方向。通常通过向量表示,例如(0, -1, 0)表示光线从上到下照射。

颜色(Color):定义光线的颜色。可以使用RGB或RGBA值来设置。

强度(Intensity):定义光线的亮度。通常是一个浮点数,值越大表示光线越强。

阴影(Shadows):是否启用阴影效果。启用后,光源将投射阴影到场景中。

阴影质量(Shadow Quality):设置阴影的分辨率和细节程度。

阴影距离(Shadow Distance):定义阴影投射的最大距离

示例:

// 伪代码示例,具体实现可能因渲染引擎而异
DirectionalLight sunLight;
sunLight.direction = Vector3(0.5f, -1.0f, 0.5f); 
// 光线方向,例如从右上角斜向下
sunLight.color = Color(1.0f, 1.0f, 1.0f); // 白色光线
sunLight.intensity = 1.5f; // 稍微增加亮度以模拟日光
sunLight.shadowsEnabled = true; // 启用阴影
sunLight.shadowQuality = High; // 设置高阴影质量
sunLight.shadowDistance = 100.0f; 
// 设置阴影投射的最大距离为100单位

// 将平行光添加到场景中
scene.addLight(sunLight);

// 渲染场景
scene.render();

SpotLight 聚光灯

定义:聚光灯是一种从一个点向特定方向发射追星光线的光源。

特点:聚光灯可以产生阴影,常用于模拟手电筒、台灯、舞台灯光等效果。它具有光锥角度、边缘模糊半径、衰减等属性,可以精确控制光照范围和阴影效果。

属性:主要属性包括颜色、强度、距离、角度、边缘模糊半径、衰减等。

示例

const spotLight = new THREE.SpotLight(0xffffff, 1); 
// 创建一个白色的聚光灯,强度为1
spotLight.position.set(-10, 10, 0); // 设置聚光灯的位置
spotLight.angle = Math.PI / 10; // 设置光锥角度
spotLight.penumbra = 0.2; // 设置边缘模糊半径
scene.add(spotLight); // 将聚光灯添加到场景中

方向光

定义:方向光又称为平行光,是一种类似于太阳光的光源。

特点:方向光从一个方向发射光线,并且光线是平行的。它不会随着距离的增加而衰减,常用于模拟太阳光、月光等远距离光源的效果。

属性:主要属性包括颜色、强度和方向。方向通常通过设置光源的位置来确定(但实际上光源位于无限远处,因此位置属性仅用于确定方向)。

示例

const directionalLight = new THREE.DirectionalLight(0xffffff, 1); 
// 创建一个白色的方向光,强度为1
directionalLight.position.set(0, 0, 1); // 设置方向光的位置(确定方向)
scene.add(directionalLight); // 将方向光添加到场景中

半球光

定义:半球光是一种特殊的光源,它可以模拟天空光和地面反射光的效果。

特点:半球光为室内或室外场景创建更加自然的光照效果。它的颜色是从天空到地面两个颜色之间的渐变,与物体材质的颜色作叠加后得到最终的颜色效果。

属性:主要属性包括天空颜色、地面颜色、强度和位置

示例

const hemisphereLight = new THREE.HemisphereLight(0xffffff, 0x000000, 1);
// 创建一个半球光,天空为白色,地面为黑色,强度为1
hemisphereLight.position.set(0, 10, 0); 
// 设置半球光的位置(虽然位置对光照效果影响不大,但可以用于调整光源的参考点)
scene.add(hemisphereLight); // 将半球光添加到场景中

平面光

定义:平面光是一种从矩形平面均匀发射光线的光源。

特点:平面光可以模拟明亮的窗户或条状灯光等效果,常用于室内和家具建模等场景。它提供特定方向和范围的光照,使物体产生明暗变化和阴影效果。

属性:主要属性包括颜色、强度、宽度和高度。

注意:在WebGLRenderer中使用AreaLight可能会有性能问题,因此可能需要使用特定的渲染器或优化技术。

示例

// 创建场景
const scene = new Scene();
scene.background = new THREE.Color(0xeeeeee);

// 创建相机
const camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 
0.1, 1000);
camera.position.z = 5;

// 创建渲染器
const renderer = new WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建平面光
const width = 10;
const height = 10;
const intensity = 1;
const rectLight = new RectAreaLight(0xffffff, intensity, width, height);
rectLight.position.set(2.5, 2.5, 5);
rectLight.lookAt(0, 0, 0);
scene.add(rectLight);

// 可选:创建平面光辅助器,用于可视化平面光的位置和大小
const rectLightHelper = new RectAreaLightHelper(rectLight);
scene.add(rectLightHelper);

// 添加一个简单的几何体以查看光照效果
const geometry = new PlaneBufferGeometry(5, 5);
const material = new MeshBasicMaterial({ color: 0x00ff00 });
const plane = new Mesh(geometry, material);
plane.position.set(0, 0, 0);
plane.rotation.x = -Math.PI / 2;
scene.add(plane);

// 添加控制器
const controls = new OrbitControls(camera, renderer.domElement);

// 渲染循环
function animate() {
    requestAnimationFrame(animate);
    controls.update();
    renderer.render(scene, camera);
}
animate();

当然,以下是针对您提供的Three.js内容的一些补充和完善,包括材质、阴影和其他相关概念:

2. 阴影投影

在 Three.js 中,阴影对于创建逼真的场景至关重要。通过为场景添加阴影投影,我们可以为 3D 对象增加真实感和深度。本文将详细介绍如何在 Three.js 中使用阴影投影。

2.1 阴影支持

要在 Three.js 中使用阴影,首先需要确保渲染器支持阴影,并为光源启用阴影。然后,需要设置物体的 castShadow 和 receiveShadow 属性。

2.1.1 启用阴影支持

首先,在创建渲染器时启用阴影支持:

const renderer = new THREE.WebGLRenderer(); 
renderer.shadowMap.enabled = true; 
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

2.1.2 为光源启用阴影

要使光源能够产生阴影,需要为其启用阴影。以聚光灯为例:

const spotLight = new THREE.SpotLight(0xffffff, 1); 
spotLight.position.set(0, 10, 0); 
spotLight.castShadow = true; 
spotLight.angle = Math.PI / 6; 
spotLight.penumbra = 0.1; 
spotLight.distance = 20; 
spotLight.decay = 2; 
scene.add(spotLight);

2.1.3 设置物体投射和接收阴影

要使物体能够投射阴影,需要为其设置 castShadow 属性。要使物体能够接收阴影,需要为其设置 receiveShadow 属性。

const geometry = new THREE.BoxGeometry(); 
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); 
const cube = new THREE.Mesh(geometry, material); 
cube.castShadow = true; cube.receiveShadow = true; 
scene.add(cube); ​ 
const planeGeometry = new THREE.PlaneGeometry(10, 10); 
const planeMaterial = new THREE.MeshStandardMaterial({ 
    color: 0x808080 
}); 
const plane = new THREE.Mesh(planeGeometry, planeMaterial); 
plane.receiveShadow = true; 
plane.rotation.x = -Math.PI / 2; 
plane.position.y = -1; 
scene.add(plane);

现在,场景中的物体将会根据光源的位置和类型产生阴影效果。

2.2 调整阴影效果

在 Three.js 中,可以通过调整光源和渲染器的参数来优化阴影效果。

2.21 调整光源阴影参数

光源具有 shadow 属性,用于调整阴影的质量和范围。以下是一些常用的阴影参数设置:

shadow.mapSize: 控制阴影贴图的大小。值越大,阴影质量越高,但计算成本也更高。通常设为 2 的次方值,如 512、1024 或 2048。

shadow.bias: 用于修复阴影投射中的阴影锯齿状或漂浮阴影的问题。根据场景和光源类型,需要小心调整这个值,以避免产生不自然的阴影效果。

以下是一个调整聚光灯阴影参数的示例:

spotLight.shadow.mapSize.width = 1024; 
spotLight.shadow.mapSize.height = 1024; 
spotLight.shadow.bias = -0.001;

2.22 调整渲染器阴影类型

Three.js 提供了两种渲染器阴影类型:THREE.BasicShadowMap 和 THREE.PCFShadowMap。THREE.BasicShadowMap 是简单的阴影效果,而 THREE.PCFShadowMap 提供了更柔和的阴影效果。根据需求选择合适的阴影类型:

renderer.shadowMap.type = THREE.PCFShadowMap;

2.23 使用自定义阴影贴图

在某些情况下,为了实现特定的阴影效果,可以考虑使用自定义阴影贴图。自定义阴影贴图可以让你更精确地控制阴影效果,但需要更高的技能水平和对 Three.js 的深入了解。

const customShadowTexture = new THREE.TextureLoader()
.load('path/to/shadow/texture.png'); 
const customShadowMaterial = new THREE.ShadowMaterial({ 
    map: customShadowTexture 
}); 
const customShadowMesh = new THREE.Mesh(geometry, customShadowMaterial); 
scene.add(customShadowMesh);

2.24 阴影的分辨率和性能

阴影贴图的大小(shadow.mapSize)直接影响阴影的质量和渲染性能。较大的贴图能提供更清晰、更精细的阴影,但会增加渲染时间和内存消耗。在实际应用中,需要根据场景大小和复杂度,以及目标设备的性能来平衡。

2.25 阴影的柔和度

除了使用THREE.PCFShadowMap来得到更柔和的阴影外,还可以通过调整光源的shadow.radius来增加阴影边缘的柔和度。这适用于所有类型的平行光和点光源。

spotLight.shadow.radius = 2; // 越大越柔和,但也会增加计算成本


在某些情况下,你可能需要控制阴影是否被物体的背面或其他非预期表面接收。这可以通过调整渲染器的shadowMap.depthTest属性来实现。2.26 阴影的深度测试

renderer.shadowMap.depthTest = true; 
// 默认为true,确保阴影仅投射到正确深度位置的物体上


3. 其他高级概念

3.1 后期处理效果

为了进一步增强场景的真实感,可以使用后期处理效果,如环境光遮蔽(AO)、屏幕空间反射(SSR)、景深(DOF)等。这些效果通常通过渲染后期处理的插件或库来实现,如three.js的postprocessing库。

3.2 物理渲染(PBR)的深入

MeshStandardMaterial和MeshPhysicalMaterial(MeshStandardMaterial的改进版)都是基于物理的渲染(PBR)材质。它们提供了更丰富的参数来控制金属性、粗糙度、反射率等,适合创建高度逼真的材质效果。

import { MeshPhysicalMaterial } from 'three';
const material = new MeshPhysicalMaterial({
color: 0xff0000,
metalness: 0.0,
roughness: 0.5,
reflectivity: 0.5,
});

3.3 自定义着色器

对于高级用户,Three.js允许使用自定义着色器来完全控制材质的行为。这需要使用WebGL的GLSL语言编写着色器代码,并通过ShaderMaterial应用。

import { ShaderMaterial } from 'three';

const uniforms = {
    time: { value: 1.0 },
    resolution: { value: new THREE.Vector2() },
};

const vertexShader = `
    varying vec2 vUv;
    void main() {
        vUv = uv;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
`;

const fragmentShader = `
    uniform float time;
    uniform vec2 resolution;
    varying vec2 vUv;
    void main() {
        gl_FragColor = vec4(vec3(sin(time + vUv.x * 10.0) * 0.5 + 0.5), 1.0);
    }
`;

const material = new ShaderMaterial({
    uniforms: uniforms,
    vertexShader: vertexShader,
    fragmentShader: fragmentShader,
});

码字不易,恳请各位大佬慷慨点赞,您的支持是我们不断前行的动力。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐