8682|3

37

帖子

0

TA的资源

一粒金砂(中级)

手把手教你实现聚光灯效果 [复制链接]

聚光灯是一种特殊的点光源,它能够朝着一个方向投射光线。聚光灯投射出的是类似圆锥形的光线,这与我们现实中看到的聚光灯是一致的。其灯光从一点发出,沿着某一个方向照射出一个锥形光照范围。聚光灯近似于一个有夹角范围限定的点光源。聚光灯可用于数字孪生可视化场景中模拟舞台、汽车车头灯,手电筒,台灯等光源效果,可添加至3D容器、摄像机等对象下方,对其中所有对应的数字孪生可视化对象生效。

在数字孪生可视化场景中因为项目需要聚光灯是最常使用的光源之一,特别是如果我们想要使用阴影的话也需要用到聚光灯。ThingJS内的聚光灯可以用来模拟手电筒、车灯、等线性光照效果,从一个点向锥形范围内发射光线,官方类型是spotlight。

如果数字孪生可视化场景中目标物体是动态的,采用mousemove鼠标移动事件来实现目标物体运动。mousemove 事件是一个实时响应的事件,当鼠标指针的位置发生变化时(至少移动一个像素),就会触发 mousemove 事件。该事件响应的灵敏度主要参考鼠标指针移动速度的快慢以及浏览器跟踪更新的速度。官方在数字孪生可视化物体上方5米创建一个聚光灯,并让物体沿着路径方向不断循环,实现“跟随物体”的聚光灯效果。光打在了移动的物体上,照射范围和角度随着物体移动变化而变化。

但是要注意数字孪生可视化场景中聚光灯过多会影响渲染性能。

具体代码如下:

 
var app = new THING.App({
    url: 'https://www.thingjs.com/static/models/storehouse',
});

// 参数
var dataObj = {
    'type': 'SpotLight',
    'lightAngle': 30,
    'intensity': 1,
    'penumbra': 0.5,
    'castShadow': false,
    'position': null,
    'height': 0,
    'color': 0xFFFFFF,
    'distance': null,
    'target': null,
    'helper': true,
    'follow': true,
};
// 叉车
let car1;
let car2;
// 当前灯光
let curLight;
let curLightPosition;
// 创建聚光灯方法
function createSpotLight(position, target) {
    dataObj['lightAngle'] = 30;
    dataObj['intensity'] = 0.5;
    dataObj['penumbra'] = 0.5;
    dataObj['castShadow'] = false;
    dataObj['position'] = position;
    dataObj['distance'] = 25;
    dataObj['color'] = 0xFFFFFF;
    dataObj['helper'] = true;
    dataObj['follow'] = true;
    //创建聚光灯
    var spotLight = app.create(dataObj);
    curLight = spotLight;
    curLightPosition = spotLight.position;
    createSpotLightControlPanel(spotLight);
    curLight.lookAt(car1);
}

/**
 * 灯光控制面板
 */
function createSpotLightControlPanel() {
    var panel = new THING.widget.Panel({
        isDrag: true,
        titleText: "灯光参数调整",
        width: '260px',
        hasTitle: true
    });
    // 设置 panel 位置    
    panel.position = [10, 35];
    panel.addNumberSlider(dataObj, 'lightAngle').caption('灯光角度').step(1).min(0).max(180).isChangeValue(true).on('change', function(value) {
        curLight.lightAngle = value;
    });
    panel.addNumberSlider(dataObj, 'intensity').caption('亮度').step(0.01).min(0).max(1).isChangeValue(true).on('change', function(value) {
        curLight.intensity = value;
    });
    panel.addNumberSlider(dataObj, 'penumbra').caption('半影').step(0.01).min(0).max(1).isChangeValue(true).on('change', function(value) {
        curLight.penumbra = value;
    });
    panel.addNumberSlider(dataObj, 'distance').caption('距离').step(0.1).min(0).max(200).isChangeValue(true).on('change', function(value) {
        curLight.distance = value;
    });
    panel.addNumberSlider(dataObj, 'height').caption('高度').step(0.1).min(0).max(200).isChangeValue(true).on('change', function(value) {
        curLight.position = [curLightPosition[0], curLightPosition[1] + value, curLightPosition[2]];
    });
    panel.addBoolean(dataObj, 'castShadow').caption('影子').on('change', function(value) {
        curLight.castShadow = value;
    });
    panel.addBoolean(dataObj, 'helper').caption('辅助线').on('change', function(value) {
        curLight.helper = value;
    });
    panel.addBoolean(dataObj, 'follow').caption('跟随物体').on('change', function(value) {
        if (value) {
            curLight.lookAt(car1);
        } else {
            curLight.lookAt(null);
        }
    });
    panel.addColor(dataObj, 'color').caption('颜色').on('change', function(value) {
        curLight.lightColor = value;
    });

}

/**
 * 注册鼠标移动事件,检查是否按下'shift'键, 按下设置聚光灯跟随鼠标位置
 */
app.on('mousemove', function(ev) {
    if (!curLight) {
        return;
    }

    if (!ev.shiftKey) {
        return;
    }

    var pickedPosition = ev.pickedPosition;
    if (pickedPosition) {
        curLight.lookAt(pickedPosition);
    }
})

/**
 * 注册场景load事件
 */
app.on('load', function(ev) {
    // createTip();
    // 主灯强度设置为0,突出聚光灯效果
    app.lighting = {
        mainLight: {
            intensity: 0
        }
    };

    // 获取场景内id为'car01' 和 'car02' 的叉车
    car1 = app.query('car01')[0];
    car2 = app.query('car02')[0];

    // 参数1: 在car2上方5米创建一个聚光灯
    // 参数2: 初始target设置为car1的位置
    createSpotLight(THING.Math.addVector(car2.position, [0, 5, 0]), car1.position);

    // 创建一个圆形路径
    var path = [];
    var radius = 6;
    for (var degree = 0; degree <= 360; degree += 10) {
        var x = Math.cos(degree * 2 * Math.PI / 360) * radius;
        var z = Math.sin(degree * 2 * Math.PI / 360) * radius;
        path.push(THING.Math.addVector(car1.position, [x, 0, z]));
    }
    // 让 car1 沿圆形路径运动
    car1.movePath({
        orientToPath: true, // 物体移动时沿向路径方向
        path: path,
        time: 10 * 1000,
        loopType: THING.LoopType.Repeat // 循环类型
    });

    initThingJsTip("左侧面板可对灯光参数进行调整。按住 shift 键,聚光灯可追踪鼠标位置");
    $(".warninfo3").css("left", "55%");
})

 

—————————————————

数字孪生可视化:https://www.thingjs.com/

此帖出自LED专区论坛

最新回复

真不错,看到做游戏乐趣也挺多~   详情 回复 发表于 2021-7-7 17:12

回复
举报

6636

帖子

0

TA的资源

五彩晶圆(高级)

聚光灯效果很逼真

需要代码?

此帖出自LED专区论坛

点评

有简单的前端开发经验就完全可以  详情 回复 发表于 2021-7-8 15:20

回复

1942

帖子

3

TA的资源

版主

真不错,看到做游戏乐趣也挺多~

此帖出自LED专区论坛

回复

37

帖子

0

TA的资源

一粒金砂(中级)

Jacktang 发表于 2021-7-7 15:21 聚光灯效果很逼真 需要代码?

有简单的前端开发经验就完全可以

此帖出自LED专区论坛

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表