【three.js】光源和投影
目录
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,
});
码字不易,恳请各位大佬慷慨点赞,您的支持是我们不断前行的动力。
更多推荐
所有评论(0)