学习threejs,使用PointLight点光源

👨‍⚕️ 主页: gis分享者

👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍⚕️ 收录于专栏:threejs gis工程师


文章目录


一、🍀前言

本文详细介绍如何基于threejs在三维场景中使用PointLight点光源,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️THREE.PointLight

THREE.PointLight 点光源,从一个点向各个方向发射的光源。
该光源可以投射阴影。

构造函数:

PointLight( color : Integer, intensity : Float, distance : Number, decay : Float )

  • color - (可选参数)) 十六进制光照颜色。 缺省值 0xffffff (白色)。
  • intensity - (可选参数) 光照强度。 缺省值 1。
  • distance - 这个距离表示从光源到光照强度为0的位置。 当设置为0时,光永远不会消失(距离无穷大)。缺省值 0.
  • decay - 沿着光照距离的衰退量。缺省值 2。

创建一个新的点光源(PointLight)。

属性

.color : Color

光源的颜色。如果构造的时候没有传递,默认会创建一个新的 Color 并设置为白色。

.intensity : Float

光照的强度,或者说能量。 在 physically correct 模式下, color 和强度 的乘积被解析为以坎德拉(candela)为单位的发光强度。 默认值 - 1.0

.isLigh t : Boolean

只读标志,用于检查给定对象是否为 Light 类型。

.castShadow : Boolean

如果设置为真光将投射动态阴影。警告:这很昂贵并且需要调整以使阴影看起来正确。有关详细信息,请参见 PointLightShadow。默认为假。

.decay : Float

灯光沿灯光距离变暗的量。默认值为 2。在物理正确渲染的上下文中,不应更改默认值。

.distance : Float

如果非零,那么光强度将会从最大值当前灯光位置处按照距离线性衰减到0。 缺省值为 0.0。

.power : Float

光功率在 physically correct 模式中, 表示以"流明(光通量单位)"为单位的光功率。 缺省值 - 4Math.PI。

该值与 intensity 直接关联

javascript 复制代码
power = intensity * 4π

修改该值也会导致光强度的改变。

.shadow : PointLightShadow

PointLightShadow用与计算此光照的阴影。此对象的摄像机被设置为 fov 为90度,aspect为1, 近裁剪面 near 为0,远裁剪面far 为500的透视摄像机 PerspectiveCamera。

方法
.copy ( source : HemisphereLight ) : this

将所有属性的值从源 source 复制到此点光源对象。

.toJSON ( meta : Object ) : Object

以JSON格式返回光数据。

meta -- 包含有元数据的对象,例如该对象的材质、纹理或图片。 将该light对象转换为 three.js JSON Object/Scene format(three.js JSON 物体/场景格式)。

二、🍀使用PointLight点光源

1. ☘️实现思路

  • 1、初始化renderer渲染器。
  • 2、初始化Scene三维场景scene。
  • 3、初始化camera相机,定义相机位置 camera.position.set,设置相机方向camera.lookAt。
  • 4、创建THREE.AmbientLight环境光源ambientLight,设置环境光ambientLight颜色,scene场景加入环境光源ambientLight。创建THREE.PointLight点光源pointLight,设置点光源颜色和光强衰减距离,scene场景加入pointLight。
  • 5、加载几何模型:创建二维平面网格对象plane,设置plane的旋转角度,scene场景加入plane。创建立方体网格对象cube,设置cube的位置和投影,scene场景加入cube。创建球体网格对象sphere,设置sphere的位置和投影,scene场景加入sphere。创建球体网格对象sphereLightMesh,用于模拟点光源pointLight的位置,设置sphereLightMesh的位置和投影,scene场景加入sphereLightMesh。定义render方法,实现立方体cube旋转,球体sphere跳动,模拟点光源位置的球体sphereLightMesh环绕动画,同步更新点光源pointLight位置的方法。具体代码参考下面代码样例。
  • 6、加入gui控件,控制点光源pointLight的颜色、光强、光强衰减距离等信息。加入stats监控器,监控帧数信息。

2. ☘️代码样例

html 复制代码
<!DOCTYPE html>

<html>

<head>
    <title>学习threejs,使用PointLight点光源</title>
    <script type="text/javascript" src="../libs/three.js"></script>
    <script type="text/javascript" src="../libs/stats.js"></script>
    <script type="text/javascript" src="../libs/dat.gui.js"></script>
    <style>
        body {
            /* set margin to 0 and overflow to hidden, to go fullscreen */
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<div id="Stats-output">
</div>
<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

<!-- Js 代码-->
<script type="text/javascript">

    // 初始化
    function init() {

        var stats = initStats();

        // 创建三维场景
        var scene = new THREE.Scene();

        // 创建相机
        var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);

        // 创建渲染器并设置大小
        var renderer = new THREE.WebGLRenderer();

        renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
        renderer.setSize(window.innerWidth, window.innerHeight);
        // renderer.shadowMapEnabled = true;

        // 常见二维平面
        var planeGeometry = new THREE.PlaneGeometry(60, 20, 20, 20);
        var planeMaterial = new THREE.MeshPhongMaterial({color: 0xffffff});
        var plane = new THREE.Mesh(planeGeometry, planeMaterial);
        plane.receiveShadow = true;

        // 设置二维平面旋转角度和位置
        plane.rotation.x = -0.5 * Math.PI;
        plane.position.x = 15;
        plane.position.y = 0;
        plane.position.z = 0;

        // 添加二维平面
        scene.add(plane);

        // 创建立方体
        var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
        var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff7777});
        var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        cube.castShadow = true;

        // 设置立方体位置
        cube.position.x = -4;
        cube.position.y = 3;
        cube.position.z = 0;

        // 场景中添加立方体
        scene.add(cube);
		// 创建球体
        var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
        var sphereMaterial = new THREE.MeshLambertMaterial({color: 0x7777ff});
        var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);

        // 设置球体位置和投影
        sphere.position.x = 20;
        sphere.position.y = 0;
        sphere.position.z = 2;
        sphere.castShadow = true;

        // 场景中添加球体
        scene.add(sphere);

        // 设置相机位置和方向
        camera.position.x = -25;
        camera.position.y = 30;
        camera.position.z = 25;
        camera.lookAt(new THREE.Vector3(10, 0, 0));

        // 场景中添加环境光
        var ambiColor = "#0c0c0c";
        var ambientLight = new THREE.AmbientLight(ambiColor);
        scene.add(ambientLight);

        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40, 60, -10);
        spotLight.castShadow = true;
        // scene.add( spotLight );
		
		// 添加点光源,设置光强距离衰减,场景中添加点光源
        var pointColor = "#ccffcc";
        var pointLight = new THREE.PointLight(pointColor);
        pointLight.distance = 100;
        scene.add(pointLight);


        // 添加小球体模型点光源
        var sphereLight = new THREE.SphereGeometry(0.2);
        var sphereLightMaterial = new THREE.MeshBasicMaterial({color: 0xac6c25});
        var sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial);
        sphereLightMesh.castShadow = true;

        sphereLightMesh.position = new THREE.Vector3(3, 0, 3);
        scene.add(sphereLightMesh);


        // 绑定渲染器到html要素
        document.getElementById("WebGL-output").appendChild(renderer.domElement);

        var step = 0;

        var invert = 1;
        var phase = 0;

        var controls = new function () {
            this.rotationSpeed = 0.03;
            this.bouncingSpeed = 0.03;
            this.ambientColor = ambiColor;
            this.pointColor = pointColor;
            this.intensity = 1;
            this.distance = 100;
        };

        var gui = new dat.GUI();
        gui.addColor(controls, 'ambientColor').onChange(function (e) {
            ambientLight.color = new THREE.Color(e);
        });

        gui.addColor(controls, 'pointColor').onChange(function (e) {
            pointLight.color = new THREE.Color(e);
        });

        gui.add(controls, 'intensity', 0, 3).onChange(function (e) {
            pointLight.intensity = e;
        });

        gui.add(controls, 'distance', 0, 100).onChange(function (e) {
            pointLight.distance = e;
        });


        render();

        function render() {
            stats.update();
            // 立方体旋转动画
            cube.rotation.x += controls.rotationSpeed;
            cube.rotation.y += controls.rotationSpeed;
            cube.rotation.z += controls.rotationSpeed;

            // 球体跳跃动画
            step += controls.bouncingSpeed;
            sphere.position.x = 20 + ( 10 * (Math.cos(step)));
            sphere.position.y = 2 + ( 10 * Math.abs(Math.sin(step)));

            // 模拟点光源的球体动画
            if (phase > 2 * Math.PI) {
                invert = invert * -1;
                phase -= 2 * Math.PI;
            } else {
                phase += controls.rotationSpeed;
            }
            sphereLightMesh.position.z = +(7 * (Math.sin(phase)));
            sphereLightMesh.position.x = +(14 * (Math.cos(phase)));
            sphereLightMesh.position.y = 5;

            if (invert < 0) {
                var pivot = 14;
                sphereLightMesh.position.x = (invert * (sphereLightMesh.position.x - pivot)) + pivot;
            }

            pointLight.position.copy(sphereLightMesh.position);

            requestAnimationFrame(render);
            renderer.render(scene, camera);
        }

        function initStats() {

            var stats = new Stats();

            stats.setMode(0);

            stats.domElement.style.position = 'absolute';
            stats.domElement.style.left = '0px';
            stats.domElement.style.top = '0px';

            document.getElementById("Stats-output").appendChild(stats.domElement);

            return stats;
        }
    }
    window.onload = init


</script>
</body>
</html>

效果如下:

相关推荐
gis分享者7 天前
学习threejs,使用HemisphereLight半球光
threejs·hemispherelight·半球光
gis分享者11 天前
学习threejs,使用Lensflare模拟镜头眩光
threejs·lensflare·眩光
gis分享者14 天前
学习threejs,tga格式图片文件贴图
threejs·贴图·tga·tgaloader
gis分享者14 天前
学习threejs,pvr格式图片文件贴图
threejs·贴图·pvr
gis分享者1 个月前
学习threejs,使用OrbitControls相机控制器
threejs·相机·相机控制器·orbitcontrols
不系舟1781 个月前
threejs 实现镜面反射,只反射指定物体,背景透明
threejs
gis分享者1 个月前
学习threejs,使用RollControls相机控制器
threejs·相机控制器·rollcontrols
gis分享者1 个月前
学习threejs,使用FlyControls相机控制器
threejs·相机控制器·flycontrols
gis分享者1 个月前
学习threejs,使用TrackballControls相机控制器
threejs·trackball·相机控制器