学习threejs,使用设置lightMap光照贴图创建阴影效果

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


文章目录

  • 一、🍀前言
    • 1.1 ☘️THREE.MeshLambertMaterial漫反射材质
    • 1.2 ☘️光照贴图(Lightmap)
  • 二、🍀使用设置lightMap光照贴图创建阴影效果
    • 1. ☘️实现思路
    • 2. ☘️代码样例


一、🍀前言

本文详细介绍如何基于threejs在三维场景中设置lightMap光照贴图创建阴影效果,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️THREE.MeshLambertMaterial漫反射材质

THREE.MeshLambertMaterial 是 Three.js 中的一种材质类型,用于模拟物体表面的漫反射效果。这种材质遵循 Lambertian 反射模型,这意味着它会均匀地将接收到的光照散射到各个方向,从而产生较为自然的光照效果。THREE.MeshLambertMaterial 适用于需要模拟漫反射材质的场景,如墙面、木头、纸张等非金属材料。
常用属性:
THREE.MeshLambertMaterial 继承自 THREE.Material,并具有一些特定的属性,可以用来控制材质的外观:
color:材质的颜色,默认为白色(0xffffff)。可以是一个整数,表示十六进制颜色值。
map:基础颜色贴图,可以用来替代材质的颜色。可以是一个 THREE.Texture 对象。
alphaMap:透明度贴图,可以用来定义材质的透明度。可以是一个 THREE.Texture 对象。
emissive:自发光颜色,默认为黑色(0x000000)。即使在没有光源的情况下,也会显示这个颜色。
emissiveMap:自发光贴图,可以用来定义自发光的颜色。可以是一个 THREE.Texture 对象。
specular:高光颜色,默认为白色(0x111111),但在 THREE.MeshLambertMaterial 中不会生效。
shininess:高光强度,默认为 30,但在 THREE.MeshLambertMaterial 中不会生效。
opacity:材质的全局透明度,默认为 1(不透明)。
transparent:是否开启透明模式,默认为 false。如果设置为 true,则需要设置 opacity 或者使用 alphaMap。
side:指定材质在哪一面渲染,可以是 THREE.FrontSide(正面)、THREE.BackSide(背面)或 THREE.DoubleSide(双面)。
wireframe:是否启用线框模式,默认为 false。
visible:是否渲染该材质,默认为 true。
depthTest:是否进行深度测试,默认为 true。
depthWrite:是否写入深度缓冲区,默认为 true。
blending:混合模式,默认为 THREE.NormalBlending。可以设置为 THREE.AdditiveBlending、THREE.SubtractiveBlending 等。
vertexColors:是否启用顶点颜色,默认为 THREE.NoColors。可以设置为 THREE.VertexBasicColors、THREE.VertexColors 或 THREE.FaceColors。
flatShading:是否使用平滑着色,默认为 false。如果设置为 true,则每个面片都将使用平均法线。
envMap:环境贴图,可以用来模拟环境光照。可以是一个 THREE.Texture 对象。
reflectivity:环境光反射率,默认为 1。
refractionRatio:折射率,默认为 0.98。
combine:环境贴图的组合方式,默认为 THREE.MixOperation。

1.2 ☘️光照贴图(Lightmap)

光照贴图(Lightmap)是计算机图形学中用于存储场景中光照信息的纹理贴图。它们通常用于预计算静态光照,以提高实时渲染的性能。光照贴图的数据格式和解析方法可能因具体的渲染引擎和工具而异,但一般来说,光照贴图的数据格式和解析方法可以概括如下:
数据格式
光照贴图通常存储为图像文件,常见的格式包括:
PNG:无损压缩格式,适合存储高质量的光照信息。
JPEG:有损压缩格式,文件较小,但可能会丢失一些细节。
HDR:高动态范围图像格式,适合存储高精度的光照信息。
EXR:一种常用于电影和视觉特效的高动态范围图像格式。
光照贴图的每个像素通常存储光照信息,可能包括以下内容:
RGB值:表示光照的颜色和强度。
Alpha通道:有时用于存储额外的信息,如光照的透明度或遮挡信息。

二、🍀使用设置lightMap光照贴图创建阴影效果

1. ☘️实现思路

  • 1、初始化renderer渲染器
  • 2、初始化Scene三维场景
  • 3、初始化camera相机,定义相机位置 camera.position.set。
  • 4、初始化THREE.AmbientLight环境光源,scene场景加入环境光源,初始化THREE.DirectionalLight平行光源,设置平行光源位置,设置平行光源投影,scene添加平行光源。
  • 5、加载几何模型:创建THREE.AxesHelper坐标辅助工具,创建THREE.PlaneGeometry平面几何体groundGeom,scene场景中加入坐标辅助工具。创建光照纹理贴图lightMap和地板贴图map,传入lightMap和map参数创建THREE.MeshLambertMaterial漫反射材质material,传入groundGeom和material参数创建THREE.Mesh网格对象groudMesh,设置groudMesh的旋转角度,scene场景中加入groudMesh对象。
  • 6、加入controls、gui控制(控制创建的两个立方体是否显示、以及光照贴图的光照强度,具体实现参考下面代码样例),加入stats监控器,监控帧数信息。

2. ☘️代码样例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>learn54(使用设置LIGHTMAP光照贴图创建阴影效果,不能随着模型位置变化而变化)</title>
    <!--<script src="lib/threejs/127/three.js-master/build/three.js"></script>
    <script src="lib/threejs/127/three.js-master/examples/js/controls/OrbitControls.js"></script>-->
    <script src="lib/threejs/91/three.js"></script>
    <script src="https://johnson2heng.github.io/three.js-demo/lib/js/controls/OrbitControls.js"></script>
    <script src="lib/threejs/127/three.js-master/examples/js/libs/stats.min.js"></script>
    <script src="lib/threejs/127/three.js-master/examples/js/libs/dat.gui.min.js"></script>
    <script src="lib/js/Detector.js"></script>
</head>
<style type="text/css">
    html, body {
        margin: 0;
        height: 100%;
    }

    canvas {
        display: block;
    }
</style>
<body onload="draw()">
</body>
<script>
  var renderer, camera, scene, gui, light, stats, controls, mesh, material
  var initRender = () => {
    renderer = new THREE.WebGLRenderer({antialias: true})
    renderer.setPixelRatio(window.devicePixelRatio)
    renderer.setSize(window.innerWidth, window.innerHeight)
    renderer.setClearColor(0xeeeeee)
    renderer.shadowMap.enabled = true
    document.body.appendChild(renderer.domElement)
  }
  var initScene = () => {
    scene = new THREE.Scene()
    scene.backgroundColor = new THREE.Color(0xa0a0a0)
    scene.fog = new THREE.Fog(0xa0a0a0, 50, 500)
  }
  var initCamera = () => {
    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200)
    camera.position.set(0, 12, 15)
  }
  var initGui = () => {
    gui = {
      showBox: () => {
        var material = new THREE.MeshPhongMaterial({color: 0x00ffff})

        // 创建大的立方体
        var geometry = new THREE.BoxGeometry(1.2, 1.2, 1.2)
        var cubeBig = new THREE.Mesh(geometry, material)
        cubeBig.position.y += 0.6
        scene.add(cubeBig)

        var geometrySm = new THREE.BoxGeometry(0.7, 0.7, 0.7)
        var cubeSm = new THREE.Mesh(geometrySm, material)
        cubeSm.position.set(-1.4, 0.35, 0)
        scene.add(cubeSm)
      },
      lightMapIntensity: 1
    }
    var datGui = new dat.GUI()
    datGui.add(gui, 'showBox')
    datGui.add(gui, 'lightMapIntensity', 0, 5).onChange(e => {
      material.lightMapIntensity = e
    })
  }
  var initLight = () => {
    scene.add(new THREE.AmbientLight(0x444444))
    light = new THREE.DirectionalLight(0xffffff)
    light.position.set(-20, 20, -20)
    light.castShadow = true
    scene.add(light)
  }
  var initModel = () => {
    var helper = new THREE.AxesHelper(50)
    scene.add(helper)

    var groundGeom = new THREE.PlaneGeometry(10, 10, 1, 1)
    var lightMap = new THREE.TextureLoader().load('data/texture/lightMap/lm-1.png')
    var map = new THREE.TextureLoader().load('data/texture/lightMap/floor-wood.jpg')
    material = new THREE.MeshLambertMaterial({
      color: 0x777777,
      lightMap: lightMap,
      map: map
    })
    groundGeom.faceVertexUvs[1] = groundGeom.faceVertexUvs[0]

    var groudMesh = new THREE.Mesh(groundGeom, material)
    groudMesh.rotation.x = -0.5 * Math.PI
    scene.add(groudMesh)
  }
  var initStats = () => {
    stats = new Stats()
    document.body.appendChild(stats.dom)
  }
  var initControls = () => {
    controls = new THREE.OrbitControls(camera, renderer.domElement)
    controls.enableDamping = true
  }
  var render = () => {
    renderer.render(scene, camera)
  }
  var onWindowResize = () => {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
  }
  var animate = () => {
    render()
    stats.update()
    controls.update()
    requestAnimationFrame(animate)
  }
  var draw = () => {
    if(!Detector.webgl)Detector.addGetWebGLMessage()
    initGui()
    initRender()
    initScene()
    initCamera()
    initLight()
    initModel()
    initStats()
    initControls()

    animate()
    window.onresize = onWindowResize
  }
</script>
</html>

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/923474.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Cocos编辑器

1、下载 下载地址&#xff1a;https://www.cocos.com/creator-download 2、编辑器界面介绍 官方链接&#xff1a;https://docs.cocos.com/creator/3.8/manual/zh/editor/ 3、项目结构 官方链接&#xff1a;https://docs.cocos.com/creator/3.8/manual/zh/getting-started/…

C++11特性(详解)

目录 1.C11简介 2.列表初始化 3.声明 1.auto 2.decltype 3.nullptr 4.范围for循环 5.智能指针 6.STL的一些变化 7.右值引用和移动语义 1.左值引用和右值引用 2.左值引用和右值引用的比较 3.右值引用的使用场景和意义 4.右值引用引用左值及其一些更深入的使用场景分…

Notepad++ 替换所有数字给数字加单引号

前言 今天遇到这样一个场景&#xff1a; 要去更新某张表里 code1,2,3,4,5,6 的数据&#xff0c;把它的 name 设置为 ‘张三’ 但是 code在数据库里面的字段类型是 vachar(64)&#xff0c;它自身携带索引 原本可以这样写 SQL: update tableA set namezhangsan where code in …

Django 路由层

1. 路由基础概念 URLconf (URL 配置)&#xff1a;Django 的路由系统是基于 urls.py 文件定义的。路径匹配&#xff1a;通过模式匹配 URL&#xff0c;并将请求传递给对应的视图处理函数。命名路由&#xff1a;每个路由可以定义一个名称&#xff0c;用于反向解析。 2. 基本路由配…

工作中可以用到的前端小知识(不定时更新)

1、split 结合 filter(Boolean)使用&#xff0c;可以过滤空字符 2、分割 Unicode 字符 用 Array.from() 实现 const text "&#x1f44d;&#x1f60a;&#x1f468;‍&#x1f469;‍&#x1f466;"; const result Array.from(text); console.log(result); // 输…

第R4周:LSTM-火灾温度预测(TensorFlow版)

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊]** 往期文章可查阅&#xff1a; 深度学习总结 任务说明&#xff1a;数据集中提供了火灾温度&#xff08;Tem1&#xff09;、一氧化碳浓度…

CTF-Hub SQL 报错注入(纯手动注入)

​ 当输入1时&#xff0c;发现只有查询正确&#xff0c;基本上可以判断出没有回显 开始注入(工具hackerBar) 题目是报错注入&#xff0c;方向就比较明显&#xff0c;大致说一下用到的函数和原理。 常见报错注入函数&#xff1a; 通过 floor() 报错注入通过 extractValue() …

创建HTTPS网站

每天&#xff0c;我们都会听到网络上发生身份盗窃和数据侵权的案例&#xff0c;这导致用户对自己访问的网站更加怀疑。他们开始更加了解自己将个人信息放在哪里以及信任哪些类型的网站。了解如何使网站使用HTTPS变得比以往任何时候都更加重要。 解读缩略词&#xff1a;HTTP与HT…

计算(a+b)/c的值

计算&#xff08;ab&#xff09;/c的值 C语言代码C语言代码Java语言代码Python语言代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 给定3个整数a、b、c&#xff0c;计算表达式(ab)/c的值&#xff0c;/是整除运算。 输入 输入仅一行&…

Flink Sink的使用

经过一系列Transformation转换操作后&#xff0c;最后一定要调用Sink操作&#xff0c;才会形成一个完整的DataFlow拓扑。只有调用了Sink操作&#xff0c;才会产生最终的计算结果&#xff0c;这些数据可以写入到的文件、输出到指定的网络端口、消息中间件、外部的文件系统或者是…

Java【多线程】(1)进程与线程

目录 1.前言 2.正文 2.1什么是进程 2.2PCB&#xff08;进程控制块&#xff09; 2.2.1进程id 2.2.2内存指针 2.2.3文件描述符表 2.2.4进程状态 2.2.4.1就绪状态 2.2.4.2阻塞状态 2.2.5进程优先级 2.2.6进程上下文 2.2.7进程的记账信息 2.3CPU操作进程的方法 2.4什…

一个专为云原生环境设计的高性能分布式文件系统

大家好&#xff0c;今天给大家分享一款开源创新的分布式 POSIX 文件系统JuiceFS&#xff0c;旨在解决海量云存储与各类应用平台&#xff08;如大数据、机器学习、人工智能等&#xff09;之间高效对接的问题。 项目介绍 JuiceFS 是一款面向云原生设计的高性能分布式文件系统&am…

Jmeter中的断言

7&#xff09;断言 1--响应断言 功能特点 数据验证&#xff1a;验证响应数据是否包含或不包含特定的字符串、模式或值。多种匹配类型&#xff1a;支持多种匹配类型&#xff0c;如文本、正则表达式、文档等。灵活配置&#xff1a;可以设置多个断言条件&#xff0c;满足复杂的测…

游戏引擎学习第23天

实时代码编辑功能的回顾 当前实现的实时代码编辑功能已经取得了显著的成功&#xff0c;表现出强大的性能和即时反馈能力。该功能允许开发者在修改代码后几乎立即看到变化在运行中的程序中体现出来&#xff0c;极大提升了开发效率。尽管目前的演示内容较为简单&#xff0c;呈现…

排序算法之冒泡排序篇

冒泡排序的思想&#xff1a; 是一个把元素从小到大排的一个算法思想 相邻的两个元素两两比较&#xff0c;大的那一个元素向后移&#xff0c;小的那个元素向前移 核心逻辑&#xff1a; 比较所有相邻的两个项&#xff0c;如果第一个比第二个大&#xff0c;就交换它们 从头开始…

Java ArrayList 与顺序表:在编程海洋中把握数据结构的关键之锚

我的个人主页 我的专栏&#xff1a;Java-数据结构&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;点赞❤ 收藏❤ 前言&#xff1a;在 Java编程的广袤世界里&#xff0c;数据结构犹如精巧的建筑蓝图&#xff0c;决定着程序在数据处理与存储时的效率、灵活性以…

【笔记】自动驾驶预测与决策规划_Part8_数据驱动的规划方法

文章目录 0. 前言1.生成模型1.1 Diffusion-ES1. Diffusion-ES算法介绍2. Diffusion-ES算法具体流程Diffusion Model 是什么&#xff1f;Diffusion-ES: Evolutionary StrategiesDiffusion-ES MethodDiffusion-ES Mapping Language instructions to reward functions with LLM pr…

React中事件处理和合成事件:理解与使用

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Redis设计与实现第14章 -- 服务器 总结(命令执行器 serverCron函数 初始化)

14.1 命令请求的执行过程 一个命令请求从发送到获得回复的过程中&#xff0c;客户端和服务器都需要完成一系列操作。 14.1.1 发送命令请求 当用户在客户端中输入一个命令请求的时候&#xff0c;客户端会把这个命令请求转换为协议格式&#xff0c;然后通过连接到服务器的套接字…

【C语言】字符串左旋的三种解题方法详细分析

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 &#x1f4af;前言&#x1f4af;题目描述&#x1f4af;方法一&#xff1a;逐字符移动法&#x1f4af;方法二&#xff1a;使用辅助空间法&#x1f4af;方法三&#xff1a;三次反转法&#x1f4af;方法对…