学习threejs,使用MeshLambertMaterial漫反射材质

server/2025/3/18 8:50:18/

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


文章目录


一、🍀前言

本文详细介绍如何基于threejs在三维场景中使用MeshLambertMaterial漫反射材质,亲测可用。希望能帮助到您。一起学习,加油!加油!

LambertMaterialfont_10">1.1 ☘️THREE.MeshLambertMaterial

一种非光泽表面的材质,没有镜面高光。
材质使用基于非物理的Lambertian模型来计算反射率。 这可以很好地模拟一些表面(例如未经处理的木材或石材),但不能模拟具有镜面高光的光泽表面(例如涂漆木材)。
代码示例:
基本用法:

// 创建材质(绿色,带自发光)
const material = new THREE.MeshLambertMaterial({color: 0x00ff00,emissive: 0x004400, // 暗绿色自发光emissiveIntensity: 0.8
});// 应用材质到立方体
const geometry = new THREE.BoxGeometry();
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);// 必须添加光源才能生效!
const light = new THREE.PointLight(0xffffff, 1);
light.position.set(10, 10, 10);
scene.add(light);

使用贴图:

// 加载漫反射贴图和环境遮挡贴图
const textureLoader = new THREE.TextureLoader();
const diffuseMap = textureLoader.load('textures/brick_diffuse.jpg');
const aoMap = textureLoader.load('textures/brick_ao.jpg');// 创建材质
const material = new THREE.MeshLambertMaterial({map: diffuseMap,aoMap: aoMap,aoMapIntensity: 0.5 // 调整环境遮挡强度
});

1.1.1 ☘️构造函数

MeshLambertMaterial( parameters : Object )
parameters - (可选)用于定义材质外观的对象,具有一个或多个属性。 材质的任何属性都可以从此处传入(包括从Material继承的任何属性)。

属性color例外,其可以作为十六进制字符串传递,默认情况下为 0xffffff(白色),内部调用Color.set(color)。

1.1.2 ☘️属性

共有属性请参见其基类Material。

属性类型默认值描述
colorTHREE.Color0xffffff材质基础颜色,接受十六进制、RGB 字符串或颜色名称。
emissiveTHREE.Color0x000000自发光颜色(不受光照影响),常用于模拟光源或发光体。
emissiveIntensitynumber1自发光强度(0.0 ~ 1.0),需配合 emissive 使用。
mapTHREE.Texturenull漫反射贴图(表面颜色纹理)。
lightMapTHREE.Texturenull光照贴图(预计算光照信息),需第二组 UV 坐标。
aoMapTHREE.Texturenull环境遮挡贴图(增强阴影细节),需第二组 UV 坐标。
specularMapTHREE.Texturenull无效属性(Lambert 模型无镜面反射)。保留仅为兼容性。
alphaMapTHREE.Texturenull透明度贴图(黑色透明,白色不透明)。
envMapTHREE.Texturenull环境贴图(反射周围环境),需场景设置立方体贴图。
wireframebooleanfalse是否以线框模式渲染几何体。
transparentbooleanfalse是否启用透明度(需配合 opacity)。
opacitynumber1不透明度(0.0 ~ 1.0),需 transparent: true 生效。
fogbooleantrue是否受场景雾效 (THREE.Fog) 影响。

.alphaMap : Texture
alpha贴图是一张灰度纹理,用于控制整个表面的不透明度。(黑色:完全透明;白色:完全不透明)。 默认值为null。

仅使用纹理的颜色,忽略alpha通道(如果存在)。 对于RGB和RGBA纹理,WebGL渲染器在采样此纹理时将使用绿色通道, 因为在DXT压缩和未压缩RGB 565格式中为绿色提供了额外的精度。 Luminance-only以及luminance/alpha纹理也仍然有效。

.aoMap : Texture
该纹理的红色通道用作环境遮挡贴图。默认值为null。aoMap需要第二组UV。

.aoMapIntensity : Float
环境遮挡效果的强度。默认值为1。零是不遮挡效果。

.bumpMap : Texture
用于创建凹凸贴图的纹理。黑色和白色值映射到与光照相关的感知深度。凹凸实际上不会影响对象的几何形状,只影响光照。如果定义了法线贴图,则将忽略该贴图。

.bumpScale : Float
凹凸贴图会对材质产生多大影响。典型范围是0-1。默认值为1。

.color : Color
材质的颜色(Color),默认值为白色 (0xffffff)。

.combine : Integer
如何将表面颜色的结果与环境贴图(如果有)结合起来。

选项为THREE.MultiplyOperation(默认值),THREE.MixOperation, THREE.AddOperation。如果选择多个,则使用.reflectivity在两种颜色之间进行混合。

.displacementMap : Texture
位移贴图会影响网格顶点的位置,与仅影响材质的光照和阴影的其他贴图不同,移位的顶点可以投射阴影,阻挡其他对象, 以及充当真实的几何体。位移纹理是指:网格的所有顶点被映射为图像中每个像素的值(白色是最高的),并且被重定位。

.displacementScale : Float
位移贴图对网格的影响程度(黑色是无位移,白色是最大位移)。如果没有设置位移贴图,则不会应用此值。默认值为1。

.displacementBias : Float
位移贴图在网格顶点上的偏移量。如果没有设置位移贴图,则不会应用此值。默认值为0。

.emissive : Color
材质的放射(光)颜色,基本上是不受其他光照影响的固有颜色。默认为黑色。

.emissiveMap : Texture
设置放射(发光)贴图。默认值为null。放射贴图颜色由放射颜色和强度所调节。 如果你有一个放射贴图,请务必将放射颜色设置为黑色以外的其他颜色。

.emissiveIntensity : Float
放射光强度。调节发光颜色。默认为1。

.envMap : Texture
环境贴图。默认值为null。

.flatShading : Boolean
定义材质是否使用平面着色进行渲染。默认值为false。

.fog : Boolean
材质是否受雾影响。默认为true。

.lightMap : Texture
光照贴图。默认值为null。lightMap需要第二组UV。

.lightMapIntensity : Float
烘焙光的强度。默认值为1。

.map : Texture
颜色贴图。可以选择包括一个alpha通道,通常与.transparent 或.alphaTest。默认为null。

.normalMap : Texture
用于创建法线贴图的纹理。RGB值会影响每个像素片段的曲面法线,并更改颜色照亮的方式。法线贴图不会改变曲面的实际形状,只会改变光照。 如果材质具有使用左手惯例创作的法线贴图,则应取反 normalScale 的 y 分量以补偿不同的手性。

.normalMapType : Integer
法线贴图的类型。

选项为THREE.TangentSpaceNormalMap(默认)和THREE.ObjectSpaceNormalMap。

.normalScale : Vector2
法线贴图对材质的影响程度。典型范围是0-1。默认值是Vector2设置为(1,1)。

.reflectivity : Float
环境贴图对表面的影响程度; 见.combine。默认值为1,有效范围介于0(无反射)和1(完全反射)之间。

.refractionRatio : Float
空气的折射率(IOR)(约为1)除以材质的折射率。它与环境映射模式THREE.CubeRefractionMapping 和THREE.EquirectangularRefractionMapping一起使用。 空气的折射率 (IOR)(大约 1)除以材料的折射率。它与环境映射模式 THREE.CubeRefractionMapping 一起使用。折射率不应超过1。默认值为0.98。

.specularMap : Texture
材质使用的高光贴图。默认值为null。

.wireframe : Boolean
将几何体渲染为线框。默认值为false(即渲染为平面多边形)。

.wireframeLinecap : String
定义线两端的外观。可选值为 ‘butt’,‘round’ 和 ‘square’。默认为’round’。

该属性对应2D Canvas lineJoin属性, 并且会被WebGL渲染器忽略。

.wireframeLinejoin : String
定义线连接节点的样式。可选值为 ‘round’, ‘bevel’ 和 ‘miter’。默认值为 ‘round’。

该属性对应2D Canvas lineJoin属性, 并且会被WebGL渲染器忽略。

.wireframeLinewidth : Float
控制线框宽度。默认值为1。

由于OpenGL Core Profile与 大多数平台上WebGL渲染器的限制,无论如何设置该值,线宽始终为1。

1.1.3 ☘️方法

共有方法请参见其基类Material。

LambertMaterialfont_172">二、🍀使用MeshLambertMaterial漫反射材质

1. ☘️实现思路

  • 1、初始化renderer渲染器。
  • 2、初始化Scene三维场景scene。
  • 3、初始化camera相机,定义相机位置 camera.position.set,设置相机方向camera.lookAt。
  • 4、创建THREE.AmbientLight环境光源ambientLight,设置环境光ambientLight颜色,scene场景加入环境光源ambientLight。创建THREE.SpotLight聚光灯光源spotLight,设置聚光灯光源位置和投影,scene场景加入spotLight。
  • 5、加载几何模型:创建二维平面网格对象groundMesh,设置groundMesh的旋转角度和位置,scene场景加入groundMesh。创建THREE.MeshLambertMaterial漫反射材质meshMaterial,使用该材质创建立方体网格对象cube、球体网格对象sphere、二维平面网格对象plane,设置sphere的位置,cube和plane的位置设置为sphere的位置,场景scene中添加cube。定义render方法,实现立方体cube、球体sphere和二维平面plane的旋转动画。具体代码参考下面代码样例。
  • 6、加入gui控件,控制meshMaterial材质不同参数效果。加入stats监控器,监控帧数信息。

2. ☘️代码样例

<!DOCTYPE html><html><head><title>学习threejs,使用MeshLambertMaterial漫反射材质</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><script type="text/javascript" src="../libs/CanvasRenderer.js"></script><script type="text/javascript" src="../libs/Projector.js"></script><style>body {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;var webGLRenderer = new THREE.WebGLRenderer();webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));webGLRenderer.setSize(window.innerWidth, window.innerHeight);webGLRenderer.shadowMapEnabled = true;// var canvasRenderer = new THREE.CanvasRenderer();// canvasRenderer.setSize(window.innerWidth, window.innerHeight);renderer = webGLRenderer;var groundGeom = new THREE.PlaneGeometry(100, 100, 4, 4);var groundMesh = new THREE.Mesh(groundGeom, new THREE.MeshBasicMaterial({color: 0x555555}));groundMesh.rotation.x = -Math.PI / 2;groundMesh.position.y = -20;scene.add(groundMesh);var sphereGeometry = new THREE.SphereGeometry(14, 20, 20);var cubeGeometry = new THREE.BoxGeometry(15, 15, 15);var planeGeometry = new THREE.PlaneGeometry(14, 14, 4, 4);var meshMaterial = new THREE.MeshLambertMaterial({color: 0x7777ff});var sphere = new THREE.Mesh(sphereGeometry, meshMaterial);var cube = new THREE.Mesh(cubeGeometry, meshMaterial);var plane = new THREE.Mesh(planeGeometry, meshMaterial);// 设置球体位置sphere.position.x = 0;sphere.position.y = 3;sphere.position.z = 2;cube.position = sphere.position;plane.position = sphere.position;// 添加立方体scene.add(cube);// 设置相机位置和方向camera.position.x = -20;camera.position.y = 30;camera.position.z = 40;camera.lookAt(new THREE.Vector3(10, 0, 0));// 创建环境光源,scene场景添加环境光var ambientLight = new THREE.AmbientLight(0x0c0c0c);scene.add(ambientLight);// 创建聚光灯光源spotLight,scene场景添加spotLight,设置spotLight的位置和投影var spotLight = new THREE.SpotLight(0xffffff);spotLight.position.set(-30, 60, 60);spotLight.castShadow = true;scene.add(spotLight);// 渲染器绑定html要素document.getElementById("WebGL-output").appendChild(renderer.domElement);var step = 0;var controls = new function () {this.rotationSpeed = 0.02;this.bouncingSpeed = 0.03;this.opacity = meshMaterial.opacity;this.transparent = meshMaterial.transparent;this.overdraw = meshMaterial.overdraw;this.visible = meshMaterial.visible;this.emissive = meshMaterial.emissive.getHex();this.ambient = meshMaterial.ambient.getHex();this.side = "front";this.color = meshMaterial.color.getStyle();this.wrapAround = false;this.wrapR = 1;this.wrapG = 1;this.wrapB = 1;this.selectedMesh = "cube";};var gui = new dat.GUI();var spGui = gui.addFolder("Mesh");spGui.add(controls, 'opacity', 0, 1).onChange(function (e) {meshMaterial.opacity = e});spGui.add(controls, 'transparent').onChange(function (e) {meshMaterial.transparent = e});spGui.add(controls, 'visible').onChange(function (e) {meshMaterial.visible = e});spGui.addColor(controls, 'ambient').onChange(function (e) {meshMaterial.ambient = new THREE.Color(e)});spGui.addColor(controls, 'emissive').onChange(function (e) {meshMaterial.emissive = new THREE.Color(e)});spGui.add(controls, 'side', ["front", "back", "double"]).onChange(function (e) {console.log(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(controls, 'color').onChange(function (e) {meshMaterial.color.setStyle(e)});spGui.add(controls, 'selectedMesh', ["cube", "sphere", "plane"]).onChange(function (e) {scene.remove(plane);scene.remove(cube);scene.remove(sphere);switch (e) {case "cube":scene.add(cube);break;case "sphere":scene.add(sphere);break;case "plane":scene.add(plane);break;}scene.add(e);});spGui.add(controls, 'wrapAround').onChange(function (e) {meshMaterial.wrapAround = e;meshMaterial.needsUpdate = true;});spGui.add(controls, 'wrapR', 0, 1).step(0.01).onChange(function (e) {meshMaterial.wrapRGB.x = e;});spGui.add(controls, 'wrapG', 0, 1).step(0.01).onChange(function (e) {meshMaterial.wrapRGB.y = e;});spGui.add(controls, 'wrapB', 0, 1).step(0.01).onChange(function (e) {meshMaterial.wrapRGB.z = e;});render();function render() {stats.update();cube.rotation.y = step += 0.01;plane.rotation.y = step;sphere.rotation.y = step;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.ppmy.cn/server/175921.html

相关文章

计算机网络基础:网络配置与管理

计算机网络基础&#xff1a;网络配置与管理 一、前言二、网络设备配置基础2.1 路由器配置2.1.1 路由器的基本概念2.1.2 路由器的初始配置2.1.3 路由器的接口配置2.1.4 路由配置 2.2 交换机配置2.2.1 交换机的基本概念2.2.2 交换机的初始配置2.2.3 交换机的端口配置2.2.4 VLAN 配…

盘库吧--搜索

网站介绍 网盘资源搜索&#xff0c;包含了百度、夸克、阿里、迅雷、115、天翼、UC 等网盘&#xff0c;支持链接有效性检测。 网站地址 https://panku8.com

如何进行技术选型?

前端技术发展速度快的看法 前端技术的更新换代确实非常快&#xff0c;几乎每年都会有新的框架、工具和最佳实践涌现。从 Vue 2 到 Vue 3、从 Webpack 到 Rspack/Vite、从 Redux 到 Zustand/Recoil&#xff0c;甚至前端工程化、微前端、Server Components 等方向也在快速演进。…

小程序网络大文件缓存方案

分享一个小程序网络大图加载慢的解决方案 用到的相关api getSavedFileList 获取已保存的文件列表&#xff1b;getStorageSync 获取本地缓存&#xff1b;downloadFile 下载网络图片&#xff1b;saveFile 保存文件到本地&#xff1b;setStorage 将数据储存到小程序本地缓存&…

电脑自动关机故障维修案例分享

电脑基本配置&#xff1a; C P U: AMD A10 9700 内存&#xff1a;8G 硬盘&#xff1a;金邦512G固态硬盘 主板&#xff1a;华硕 A320M-F 显卡&#xff1a;集成&#xff08;核心显卡&#xff09; 操作系统&#xff1a;Win10专业版 故障描述&#xff1a; 使用一段时间会黑屏…

边缘云原生操作系统的设计与思考

资料来源&#xff1a;火山引擎-开发者社区 边缘云行业现状和发展历程 从 06 年 AWS 推出 EC2 、S3 到今天已经过去了 18 年&#xff0c;云计算早已不是一个新鲜词汇&#xff0c;从当前业务来看&#xff0c;我们能看到云计算从中心到中心边缘的发展趋势&#xff0c;为什么会有 这…

4G模组Air780EPM:解锁物联网时代的硬件接口奥秘!

在物联网&#xff08;IoT&#xff09;技术飞速发展的当下&#xff0c;通信模组作为连接物理世界与数字网络的“桥梁”&#xff0c;其硬件接口的丰富性与兼容性已成为衡量其竞争力的核心指标。 一、ADC 接口设计指导 Air780EPM 模块(LuatOS 版本)支持 4 路通用 ADC 接口&#x…

SAP-ABAP:SAP锁冲突解决方案:MM_ENQUEUE_DOCUMENT错误处理指南

SAP锁冲突解决方案&#xff1a;MM_ENQUEUE_DOCUMENT错误处理指南 &#x1f50d; 问题诊断矩阵 症状可能原因检查方法典型场景“Document is locked”用户锁定SM12查看锁持有者多用户同时操作程序异常终止锁未释放ABAP调试检查CALL FUNCTION链未调用DEQUEUE后台作业失败系统残…