three 灯光介绍

256 阅读5分钟

导言:由于工作比较清闲,所有在上班时间能够闲下下每天写一两篇技术类文章,学习一些新的知识,增强技术能力,今天介绍下 three 中的灯光,以及灯光的基本应用场景有哪些。如何调整灯光

需要注意的是想要物体显示出当前光源对应的颜色需要选择能够反射光源材质 例如 MeshPhongMaterial 就可以反光 使用 MeshBasicMaterial 就是不行的,这个是不反光材质,还有只有材质颜色的RGB 存在灯光中的RGB色值才会显示颜色,例材质颜色为 0xfffff 就可以显示任意颜色 当材质颜色为 0x0000ff 只会显示蓝色相关的颜色

AmbientLight 环境光会照亮当前环境中的所有物体,不会因为物体遮挡或距离而产生差异

// 这是一个好的示例
    // 添加环境光来补充场景的整体光照
    const ambientLight = new THREE.AmbientLight(0x404040); // 环境光
    scene.add(ambientLight);
    // 创建一个立方体
    const cubeGeometry = new THREE.BoxGeometry(10, 10, 10);
    const cubeMaterial = new THREE.MeshPhongMaterial ({ color: 0xffffff });
    const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
    scene.add(cube);
// 这是一个错误的示例 材质中没有灯光的颜色不显示
    // 添加环境光来补充场景的整体光照
    const ambientLight = new THREE.AmbientLight(0xff0000); // 环境光
    scene.add(ambientLight);
    // 创建一个立方体
    const cubeGeometry = new THREE.BoxGeometry(10, 10, 10);
    const cubeMaterial = new THREE.MeshPhongMaterial ({ color: 0x0000ff });
    const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
    scene.add(cube);

DirectionalLight 平行光 能够产生阴影,有方向性,有距离性,只有光源在物体上方时才显示阴影,否则只在此朝向上显示光照

// 这是一个好的示例
    // 创建一个立方体
    const cubeGeometry = new THREE.BoxGeometry(10, 10, 10);
    const cubeMaterial = new THREE.MeshPhongMaterial ({ color: 0xffffff });
    const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
    cube.position.set(0, 20, 0);
    cube.castShadow = true; // 使立方体投射阴影
    scene.add(cube);
    // 从上方照射的白色平行光,强度为 0.5。
    const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
    directionalLight.position.set(0, 50, 0);
    directionalLight.castShadow = true; 
    scene.add( directionalLight );
    // 添加环境光来补充场景的整体光照 使得反光物体能显示
    const ambientLight = new THREE.AmbientLight(0x404040); // 环境光
    scene.add(ambientLight);
// 这是一个坏的示例 光源的距离在物体下方无法显示阴影
    // 创建一个立方体
    const cubeGeometry = new THREE.BoxGeometry(10, 10, 10);
    const cubeMaterial = new THREE.MeshPhongMaterial ({ color: 0xffffff });
    const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
    cube.position.set(0, 20, 0);
    cube.castShadow = true; // 使立方体投射阴影
    scene.add(cube);
    // 从上方照射的白色平行光,强度为 0.5。
    const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
    directionalLight.position.set(0, 10, 0);
    directionalLight.castShadow = true; 
    scene.add( directionalLight );
    // 添加环境光来补充场景的整体光照 使得反光物体能显示
    const ambientLight = new THREE.AmbientLight(0x404040); // 环境光
    scene.add(ambientLight);

HemisphereLight 半球光 分为三个部分, 上半球 下半球 与斜面 不会产生阴影

要注意的是立方体上方显示上半球即红色 就是空中照出的光,立方体的下方显示下半球的颜色即蓝色 也是地面反射的光,斜面显示两着的混合颜色 半球光不会因为光源位置的变化而使光线效果产生差异

    // 创建一个立方体
    const cubeGeometry = new THREE.BoxGeometry(10, 10, 10);
    const cubeMaterial = new THREE.MeshPhongMaterial ({ color: 0xffffff });
    const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
    cube.position.set(0, 20, 0);
    cube.castShadow = true; // 使立方体投射阴影
    scene.add(cube);
    
    const light = new THREE.HemisphereLight( 0xff0000, 0x0000ff, 1 );
    light.position.set(0,50,0)
    scene.add( light );

Light 灯光的基类 所有的灯光都继承这个类的属性 color 设置颜色 intensity 设置光照强度 isLight 设置是否只读 dispose 销毁方法 copy 考贝 toJSON 转换为JSON

LightProbe 光照探测用于增加光照信息

PointLight 点光源 一种灯似于灯泡的光源从一个点射向四面八方

    // 创建一个立方体
    const cubeGeometry = new THREE.BoxGeometry(10, 10, 10);
    const cubeMaterial = new THREE.MeshPhongMaterial ({ color: 0xffffff });
    const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
    cube.position.set(0, 20, 0);
    cube.castShadow = true; // 使立方体投射阴影
    scene.add(cube);

    const light = new THREE.PointLight( 0xff0000, 100, 100 );
    light.position.set( 0, 50, 0 );// 启用阴影
    light.castShadow = true;
    scene.add( light );
    const sphereSize = 1;
    const pointLightHelper = new THREE.PointLightHelper( light, sphereSize );
    scene.add( pointLightHelper );
    
    // 添加环境光来补充场景的整体光照
    const ambientLight = new THREE.AmbientLight(0x404040); // 环境光
    scene.add(ambientLight);

RectAreaLight 平面光源 一种 要注意的是 平面光可以设置照射地点这点与聚光灯类似 需要注意的是 需要使用的材质类型 MeshStandardMaterial

// 这是一个好的使用示例
    const geometry = new THREE.PlaneGeometry( 400, 400 );
    const planeMaterial = new THREE.MeshStandardMaterial({ color: 0xffffff });
    const plane = new THREE.Mesh(geometry, planeMaterial);
    plane.rotation.x = -Math.PI / 2;
    plane.position.y = -0.5;
    plane.receiveShadow = true; // 设置接收阴影
    scene.add( plane );


    // 创建一个立方体
    const cubeGeometry = new THREE.BoxGeometry(10, 10, 10);
    const cubeMaterial = new THREE.MeshStandardMaterial({ color: 0xffffff });
    const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
    cube.position.set(0, 20, 0);
    cube.castShadow = true; // 使立方体投射阴影
    scene.add(cube);

    const rectLight = new THREE.RectAreaLight( 0xff0000, 1,  100, 100 );
    rectLight.position.set( 5, 50, 0 );
    rectLight.castShadow = true;
    rectLight.lookAt( 0, 0, 0 );
    scene.add( rectLight )
    // 添加 RectAreaLightHelper
    const rectLightHelper = new RectAreaLightHelper(rectLight);
    scene.add(rectLightHelper);
// 这是一个块的使用示例 材质使会光源无法反射
    const geometry = new THREE.PlaneGeometry( 400, 400 );
    const planeMaterial = new THREE.MeshPhongMaterial({ color: 0xffffff });
    const plane = new THREE.Mesh(geometry, planeMaterial);
    plane.rotation.x = -Math.PI / 2;
    plane.position.y = -0.5;
    plane.receiveShadow = true; // 设置接收阴影
    scene.add( plane );


    // 创建一个立方体
    const cubeGeometry = new THREE.BoxGeometry(10, 10, 10);
    const cubeMaterial = new THREE.MeshPhongMaterial({ color: 0xffffff });
    const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
    cube.position.set(0, 20, 0);
    cube.castShadow = true; // 使立方体投射阴影
    scene.add(cube);

    const rectLight = new THREE.RectAreaLight( 0xff0000, 1,  100, 100 );
    rectLight.position.set( 5, 50, 0 );
    rectLight.castShadow = true;
    rectLight.lookAt( 0, 0, 0 );
    scene.add( rectLight )
    // 添加 RectAreaLightHelper
    const rectLightHelper = new RectAreaLightHelper(rectLight);
    scene.add(rectLightHelper);

SpotLight 聚光灯 与其他类形的灯光不同聚光灯能够改变当照的大小 其他的与平面光源类似

    // 创建一个立方体
    const cubeGeometry = new THREE.BoxGeometry(10, 10, 10);
    const cubeMaterial = new THREE.MeshPhongMaterial ({ color: 0xffffff });
    const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
    cube.position.set(0, 20, 0);
    cube.castShadow = true; // 使立方体投射阴影
    scene.add(cube);


    // 创建聚光灯
    const spotLight = new THREE.SpotLight(0x00ff00);
    spotLight.position.set(0, 50, 0);
    spotLight.castShadow = true; // 使灯光投射阴影
    spotLight.angle = Math.PI / 10;
    spotLight.penumbra = 0.2; 
    spotLight.intensity = 100; // 光照强度
    spotLight.decay = 1; // 值越大在聚光灯作用距离之外衰减越快
    spotLight.distance = 60; // 聚光灯的作用距离
    spotLight.target = cube; // 聚光灯的目标设为立方体
    scene.add(spotLight);

    // 添加环境光来补充场景的整体光照
    const ambientLight = new THREE.AmbientLight(0x404040); // 环境光
    scene.add(ambientLight);