当前位置: 首页 > article >正文

学习threejs,使用PointLight点光源

👨‍⚕️ 主页: gis分享者
👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!
👨‍⚕️ 收录于专栏:threejs gis工程师


文章目录

  • 一、🍀前言
    • 1.1 ☘️THREE.PointLight
  • 二、🍀使用PointLight点光源
    • 1. ☘️实现思路
    • 2. ☘️代码样例


一、🍀前言

本文详细介绍如何基于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

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

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

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

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

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

该值与 intensity 直接关联

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. ☘️代码样例

<!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>

效果如下:
在这里插入图片描述


http://www.kler.cn/a/550350.html

相关文章:

  • Lua | 面试题每日一练 (1)
  • AIP-146 泛化域
  • CentOS环境搭建DeepSeek本地知识库
  • LeetCode-633. 平方数之和
  • BeeWorks:安全专属的im即时通讯与协同办公平台
  • midjourney 一 prompt 提示词
  • 基于单片机的多功能热水器设计(论文+源码)
  • 6.2.4 基本的数据模型
  • Jenkins同一个项目不同分支指定不同JAVA环境
  • 【Python 打造高效文件分类工具】
  • 数值分析与科学计算导引——误差与算法举例
  • Java每日精进·45天挑战·Day20
  • 游戏引擎学习第107天
  • 06_Machine Vision_图像分割
  • string类详解(上)
  • Redis日志分析
  • git在工作流程中的使用
  • 箭头函数的this指向谁
  • 用React实现一个登录界面
  • 文档处理控件TX Text Control系列教程:使用 .NET C# 从 PDF 文档中提取基于模板的文本