学习threejs,THREE.MeshBasicMaterial网格材质、THREE.MeshLambertMaterial漫反射材质

news2024/10/11 13:50:02

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


文章目录

  • 一、🍀前言
    • 1.1 ☘️THREE.MeshBasicMaterial网格材质
    • 2.2 ☘️THREE.MeshLambertMaterial漫反射材质
  • 二、🍀THREE.MeshBasicMaterial网格材质、THREE.MeshLambertMaterial漫反射材质效果
    • 1. ☘️实现思路
    • 2. ☘️代码样例


一、🍀前言

本文详细介绍如何基于threejs在三维场景中实现THREE.MeshBasicMaterial网格材质、THREE.MeshLambertMaterial漫反射材质效果,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️THREE.MeshBasicMaterial网格材质

THREE.MeshBasicMaterial 是 Three.js 中的一种基本材质类型,用于渲染网格对象(THREE.Mesh)。这种材质不考虑光源的影响,因此无论场景中有多少光源,材质的颜色和外观都不会改变。这使得 THREE.MeshBasicMaterial 非常适合用于不需要光照效果的场景,或者作为调试工具来检查模型的形状和纹理。
常用属性:
color:材质的颜色,默认为白色(0xffffff)。可以是一个整数,表示十六进制颜色值。
map:基础颜色贴图,可以用来替代材质的颜色。可以是一个 THREE.Texture 对象。
alphaMap:透明度贴图,可以用来定义材质的透明度。可以是一个 THREE.Texture 对象。
emissive:自发光颜色,默认为黑色(0x000000)。即使在没有光源的情况下,也会显示这个颜色。
emissiveMap:自发光贴图,可以用来定义自发光的颜色。可以是一个 THREE.Texture 对象。
specular:高光颜色,默认为白色(0x111111),但在 THREE.MeshBasicMaterial 中不会生效。
shininess:高光强度,默认为 30,但在 THREE.MeshBasicMaterial 中不会生效。
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,则每个面片都将使用平均法线。

2.2 ☘️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。

二、🍀THREE.MeshBasicMaterial网格材质、THREE.MeshLambertMaterial漫反射材质效果

1. ☘️实现思路

  • 1、初始化renderer渲染器
  • 2、初始化Scene三维场景
  • 3、初始化camera相机,定义相机位置 camera.position.set,设置相机方向camera.lookAt
  • 4、初始化THREE.AmbientLight环境光源,scene场景加入环境光源,初始化THREE.DirectionalLight平行光源,设置平行光源位置,设置平行光源投影,scene添加平行光源。
  • 5、加载几何模型:创建SphereGeometry球体、BoxGeometry立方体、PlaneGeometry地面几何体以及AxisHelper辅助工具坐标系,Scene场景加入以上几何体和工具,其中SphereGeometry使用THREE.MeshBasicMaterial网格材质,其他几何体使用THREE.MeshLambertMaterial漫反射材质。
  • 6、加入controls控制、gui控制,加入stats监控器,监控帧数信息。

2. ☘️代码样例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>learn19(THREE.MeshBasicMaterial材质、THREE.MeshLambertMaterial材质)</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/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>
</head>
<style>
    body {
        margin: 0;
    }

    canvas {
        width: 100%;
        height: 100%;
        display: block;
    }
</style>
<body onload="draw()">
</body>
<script>
  var renderer
  var initRender = () => {
    renderer = new THREE.WebGLRenderer({antialias: true})
    renderer.setSize(window.innerWidth, window.innerHeight)
    renderer.shadowMap.enabled = true
    renderer.shadowMap.type = THREE.PCFSoftShadowMap
    document.body.appendChild(renderer.domElement)
  }
  var scene
  var initScene = () => {
    scene = new THREE.Scene()
  }
  var camera
  var initCamera = () => {
    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
    camera.position.set(0, 40, 100)
    camera.lookAt(new THREE.Vector3(0, 0, 0))
  }
  var ambientLight, directionalLight
  var initLight = () => {
    ambientLight = new THREE.AmbientLight('#111111')
    scene.add(ambientLight)

    directionalLight = new THREE.DirectionalLight('#ffffff')
    directionalLight.position.set(-40, 60, -10)

    directionalLight.shadow.camera.near = 20 //产生阴影的最近距离
    directionalLight.shadow.camera.far = 200 //产生阴影的最远距离
    directionalLight.shadow.camera.left = -50 //产生阴影距离位置的最左边位置
    directionalLight.shadow.camera.right = 50 //最右边
    directionalLight.shadow.camera.top = 50 //最上边
    directionalLight.shadow.camera.bottom = -50 //最下面

    directionalLight.shadow.mapSize.height = 1024
    directionalLight.shadow.mapSize.width = 1024

    directionalLight.castShadow = true
    scene.add(directionalLight)
  }

  var cube, plane, meshMaterial
  var initModel = () => {
    var helper = new THREE.AxisHelper(10)
    scene.add(helper)

    var sphereGeometry = new THREE.SphereGeometry(10, 30, 30)
    meshMaterial = new THREE.MeshBasicMaterial({color: 0xaaafff})
    var sphere = new THREE.Mesh(sphereGeometry, meshMaterial)
    sphere.position.set(-20, 20, 0)
    sphere.castShadow = true
    scene.add(sphere)

    var cubeGeometry = new THREE.BoxGeometry(10, 10, 10)
    var cubeMaterial = new THREE.MeshLambertMaterial({color: 0x00ffff})
    cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
    cube.position.set(30, 5, -5)
    cube.castShadow = true
    scene.add(cube)

    var planeGeometry = new THREE.PlaneGeometry(5000, 5000, 20, 20)
    var planeMaterial = new THREE.MeshLambertMaterial({color: 0xaaaaaa})
    plane = new THREE.Mesh(planeGeometry, planeMaterial)
    plane.rotation.x = -0.5 * Math.PI
    plane.position.y = -0
    plane.receiveShadow = true
    scene.add(plane)
  }
  var params
  var initGui = () => {
    params = {
      rotationSpeed: 0.02,
      bouncingSpeed: 0.03,
      opacity: meshMaterial.opacity,
      transparent: meshMaterial.transparent,
      overdraw: meshMaterial.overdraw,
      visible: meshMaterial.visible,
      side: "front",
      color: meshMaterial.color.getStyle(),
      wireframe: meshMaterial.wireframe,
      wireframeLinewidth: meshMaterial.wireframeLinewidth,
      wireFrameLineJoin: meshMaterial.wireframeLinejoin,
    }
    var gui = new dat.GUI()
    var spGui = gui.addFolder('Mesh')
    spGui.add(params, 'opacity', 0, 1).onChange(e => {
      meshMaterial.opacity = e
    })
    spGui.add(params, 'transparent').onChange(e => {
      meshMaterial.transparent = e
    })
    spGui.add(params, 'wireframe').onChange(e => {
      meshMaterial.wireframe = e
    })
    spGui.add(params, 'wireframeLinewidth', 0, 20).onChange(e => {
      meshMaterial.wireframeLinewidth = e
    })
    spGui.add(params, 'visible').onChange(e => {
      meshMaterial.visible = e
    })
    spGui.add(params, 'side', ['front', 'back', 'double']).onChange(e => {
      switch (e) {
        case 'front':
          meshMaterial.side = THREE.FrontSide
          break
        case 'back':
          meshMaterial.side = THREE.BackSide
          break
        case 'double':
          meshMaterial.side = THREE.DoubleSide
          break
      }
      meshMaterial.needsUpdate = true
    })
    spGui.addColor(params, 'color').onChange(e => {
      meshMaterial.color.setStyle(e)
    })
    spGui.open()
  }
  var stats
  var initStats = () => {
    stats = new Stats()
    document.body.appendChild(stats.dom)
  }
  var controls
  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()
    render()
    renderer.setSize(window.innerWidth, window.innerHeight)
  }
  var animate = () => {
    render()
    stats.update()
    controls.update()
    requestAnimationFrame(animate)
  }
  var draw = () => {
    initRender()
    initScene()
    initCamera()
    initLight()
    initModel()
    initStats()
    initControls()
    initGui()

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Boot课程答疑:技术难题一网打尽

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

Nuxt.js 应用中的 kit:compatibility 事件钩子详解

title: Nuxt.js 应用中的 kit:compatibility 事件钩子详解 date: 2024/10/11 updated: 2024/10/11 author: cmdragon excerpt: kit:compatibility 是处理浏览器兼容性问题的有效工具。正如本篇文章中所述,合理地利用这一钩子可以提升用户体验,并确保应用在不同环境中都能…

回南天,即使没有除湿机,也能除湿

前几天收到网友私信&#xff0c;询问烘干机干衣吹热风&#xff0c;这个比较好理解&#xff0c;热气吹到衣服上加速水分蒸发。但空调除湿为什么不吹热风了&#xff0c;而吹冷风呢&#xff1f;以及除湿机的原理等的问题。 因为我在南京总是觉得干&#xff0c;加湿器24小时不停&a…

嵌入式面试——FreeRTOS篇(八) Tickless低功耗

本篇为&#xff1a;FreeRTOS Tickless 低功耗模式篇 一、低功耗模式简介 1、低功耗介绍 答&#xff1a; 很多应用场合对于功耗的要求很严格&#xff0c;比如可穿戴低功耗产品、物联网低功耗产品等&#xff1b;一般MCU都有相应的低功耗模式&#xff0c;裸机开发时可以使用MCU的…

【射频通信电子线路基础第八讲】射频小信号放大器

一、射频放大器 不失真放大射频信号 主要要求&#xff1a;最佳增益、噪声系数、功率、带宽——设计统筹考虑 能量转换器 有源器件&#xff08;晶体管&#xff09;是核心 二、射频放大器的位置 三、射频放大器的分类 1、导通角与基于工作点 2、基于信号大小 小信号模式&a…

海报设计用什么软件?一分钟掌握创意海报设计技巧

回想当初&#xff0c;什么都不懂的小编&#xff0c;随便在网上搜教程想自学海报设计&#xff0c;面对满屏的天花乱坠辅导班广告&#xff0c;打起了退堂鼓。 现在已经摸透了怎么完成海报制作设计的小编&#xff0c;准备来给同样想要学习海报设计的新手&#xff0c;分享能够在一…

Cherno游戏引擎笔记(73~90)

------- scene viewport ---------- 》》》》做了两件事&#xff1a;设置视口和设置相机比例 》》》》为什么要设置 m_ViewportSize 为 glm::vec2 而不是 ImVec2 ? 因为后面需要进行 ! 运算&#xff0c;而 ImVec2 没有这个运算符的定义&#xff0c;只有 glm::vec2 有这个运算…

Python JSON 操作中的四个高效小窍门

JSON&#xff08;JavaScript Object Notation&#xff09;作为一种轻量级的数据交换格式&#xff0c;在各种应用场景中扮演着重要角色。Python 中处理 JSON 数据非常便捷&#xff0c;主要通过内置的 json 模块来实现。本文将详细介绍如何使用 Python 进行 JSON 数据的操作&…

python list, tuple dict,set的区别 以及**kwargs 的基本用法

在python中, list, tuple, dict, set有什么区别, 主要应用在什么样的场景? 定义: list:链表,有序的项目, 通过索引进行查找,使用方括号”[]”; tuple:元组,元组将多样的对象集合到一起,不能修改,通过索引进行查找, 使用括号”()”; dict:字典,字典是一组键(key)和值(value…

MacOS编译和安装Poco库的方法

1.从官网git下载最新的poco源代码 在/usr/local路径下创建Poco文件夹&#xff0c;克隆Poco源代码 sudo git clone -b poco-1.13.3-release https://github.com/pocoproject/poco.git2.等了一会后&#xff0c;报错啦&#xff01;&#xff01;&#xff01; error: RPC failed…

耳机座接口会被TYPE-C取代吗?

耳机座接口&#xff0c;即传统的3.5mm耳机插孔&#xff0c;一直以来都是音频设备的标准配置。然而&#xff0c;随着科技的发展和用户需求的变化&#xff0c;TYPE-C接口逐渐崭露头角&#xff0c;成为许多设备的主流选择。这一趋势引发了一个重要问题&#xff1a;耳机座接口会被T…

前缀和算法——优选算法

个人主页&#xff1a;敲上瘾-CSDN博客 个人专栏&#xff1a;游戏、数据结构、c语言基础、c学习、算法 一、什么是前缀和&#xff1f; 前缀和是指从数组的起始位置到某一位置&#xff08;或矩阵的某个区域&#xff09;的所有元素的和。这种算法通过预处理数组或矩阵&#xff0c;…

[Git] 演示回退命令reset的三种模式soft、hard、mixed详解

前言 目录 git reset soft hard mixed git reset --soft commitId git reset --hard commitId git reset --mixed commitId git reset soft 移动本地库HEAD指针 hard 移动本地库HEAD指针 重置暂存区 重置工作区 mixed 移动本地库HEAD指针重置暂存区 执行reset命令后…

秒杀|基于springBoot的秒杀系统设计与实现(附项目源码+论文+数据库)

私信或留言即免费送开题报告和任务书&#xff08;可指定任意题目&#xff09; 摘要 社会发展日新月异&#xff0c;用计算机应用实现数据管理功能已经算是很完善的了&#xff0c;但是随着移动互联网的到来&#xff0c;处理信息不再受制于地理位置的限制&#xff0c;处理信息及…

游戏行业八大趋势解说(上)

今天&#xff0c;来看看游戏行业八大趋势~ 1. 跨平台发行 2. 单人游戏规模缩小 3. 移动应用生态系统开放 4. 社区管理、抢先体验成为主流 5. 免费游戏的时间占有率显著提高 6. 新AAA游戏面临挑战 7. 生成式AI的影响未完全显现 8. 新世代成为主流&#xff0c;用户生成内…

35岁零基础能转型AI大模型吗?来得及不?

以下从3个方面帮大家分析&#xff1a; 35岁转行会不会太晚&#xff1f;零基础学习AI大模型开发能不能学会&#xff1f;AI大模型开发行业前景如何&#xff0c;学完后能不能找到好工作&#xff1f; 一、35岁转行会不会太晚&#xff1f; 35岁正处于人生的黄金时期&#xff0c;拥…

VMWare vsphere ESXi 6.7在线升级至7.0.3

本文记录了VMWare vsphere ESXi 6.7在线升级至7.0.3的过程 一、当前环境 1、ESXi当前版本&#xff1a;6.7.0, 17499825 2、VCenter当前版本&#xff1a;7.0.3 二、导入升级包并新建基准 1、新版本ISO信息 VMware-VMvisor-Installer-7.0U3n-21930508.x86_64.iso【MD5SUM: 0c…

Python酷库之旅-第三方库Pandas(143)

目录 一、用法精讲 646、pandas.Timestamp.is_quarter_start属性 646-1、语法 646-2、参数 646-3、功能 646-4、返回值 646-5、说明 646-6、用法 646-6-1、数据准备 646-6-2、代码示例 646-6-3、结果输出 647、pandas.Timestamp.is_year_end属性 647-1、语法 647…

马斯克的Cybercab首秀!没有方向盘和踏板,26年量产,特斯拉这次又玩大的了

家人们&#xff01;今天是特斯卡开“We Robot”发布会的日子&#xff0c;从早上十点奶茶就搬一个小板凳蹲着了&#xff01; 这次发布会公开了没有方向盘、没有倒车镜、没有踏板制动器的自动驾驶出租车和Optimus机器人的最新进展&#xff0c;还是很震撼的&#xff5e;奶茶带大家…