ThreeJS-3D教学五-材质
我们在ThreeJS-3D教学二:基础形状展示中有简单介绍过一些常用的材质,这次我们举例来具体看下效果:

代码是这样的:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>body {width: 100%;height: 100%;}* {margin: 0;padding: 0;}.label {font-size: 20px;color: #000;font-weight: 700;}</style>
</head>
<body>
<div id="container"></div>
<script type="importmap">{"imports": {"three": "../three-155/build/three.module.js","three/addons/": "../three-155/examples/jsm/"}}
</script>
<script type="module">
import * as THREE from 'three';
import Stats from 'three/addons/libs/stats.module.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GPUStatsPanel } from 'three/addons/utils/GPUStatsPanel.js';
import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
let stats, labelRenderer, gpuPanel, spotLight;
let camera, scene, renderer, controls, earth;
const group = new THREE.Group();
let widthImg = 200;
let heightImg = 200;
let time = 0;
init();
initHelp();
initLight();
axesHelperWord();
animate();
// 添加平面
addPlane();
addBox();function addBox() {/*** 凹凸贴图可以使纹理也有厚度,看起来更立体。凹凸贴图一般使用一张灰度图,设置成材料的bumpMap属性* */const loader = new THREE.TextureLoader();loader.load("../materials/line_images/stone.jpg", texture => {loader.load("../materials/line_images/stone-bump.jpg",bumpTexture => {const boxGeo = new THREE.BoxGeometry(60, 60, 2);const material = new THREE.MeshStandardMaterial({map: texture,bumpMap: bumpTexture,bumpScale: 1});const box = new THREE.Mesh(boxGeo,material);box.position.set(-45, 10, 0);box.castShadow = true;scene.add(box);});});/*** 法向贴图使用一张法向图来表示纹理图片某个点的法向量。即用一张图片保存另一张图片的法向量信息,* 然后再在threejs中将这两个图片的信息合在一起,就形成了一个细节丰富的立体纹理* 设置材质的 normalMap 属性* */loader.load("../materials/line_images/normal2.jpg", texture => {loader.load("../materials/line_images/normal1.jpg", bumpTexture => {const boxGeo = new THREE.BoxGeometry(60, 60, 2);const material = new THREE.MeshStandardMaterial({map: texture,normalMap: bumpTexture});// material.normalScale.set(1, 1)const box = new THREE.Mesh(boxGeo,material);box.position.set(45, 10, 0);box.castShadow = true;scene.add(box);});});// 高光贴图loader.load("../materials/line_images/earth.jpg",textureNormal => {loader.load("../materials/line_images/earthSpec.png", textureSpec => {const meterial = new THREE.MeshPhongMaterial({shininess: 5, //高光部分的亮度,默认30map: textureNormal, // 普通纹理贴图specularMap: textureSpec, // 高光贴图specular: '#fff' // 高光部分的颜色});/**SphereGeometry(radius:浮点,widthSegments:整数,heightSegments:整数)radius——球体半径。默认值为1。widthSegments—水平线段的数量。最小值为3,默认值为32。heightSegments—垂直线段的数量。最小值为2,默认值为16。*/const earthGeo = new THREE.SphereGeometry(15, 50, 50);earth = new THREE.Mesh(earthGeo, meterial);earth.position.set(0, 15, 70);earth.castShadow = true;scene.add(earth);});});
}function addPlane() {// 创建一个平面 PlaneGeometry(width, height, widthSegments, heightSegments)const planeGeometry = new THREE.PlaneGeometry(widthImg, heightImg, 1, 1);// 创建 Lambert 材质:会对场景中的光源作出反应,但表现为暗淡,而不光亮。const planeMaterial = new THREE.MeshPhongMaterial({color: 0xb2d3e6,side: THREE.DoubleSide});const plane = new THREE.Mesh(planeGeometry, planeMaterial);// 以自身中心为旋转轴,绕 x 轴顺时针旋转 45 度plane.rotation.x = -0.5 * Math.PI;plane.position.set(0, -4, 0);plane.castShadow = true;plane.receiveShadow = true;scene.add(plane);
}function init() {camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 10, 1000 );camera.up.set(0, 1, 0);camera.position.set(60, 40, 60);camera.lookAt(0, 0, 0);scene = new THREE.Scene();scene.background = new THREE.Color( '#ccc' );renderer = new THREE.WebGLRenderer( { antialias: true } );renderer.setPixelRatio( window.devicePixelRatio );renderer.setSize( window.innerWidth, window.innerHeight );renderer.shadowMap.enabled = true;renderer.shadowMap.type = THREE.PCFSoftShadowMap;renderer.toneMapping = THREE.ACESFilmicToneMapping;// 色调映射的曝光级别renderer.toneMappingExposure = 1;document.body.appendChild( renderer.domElement );labelRenderer = new CSS2DRenderer();labelRenderer.setSize( window.innerWidth, window.innerHeight );labelRenderer.domElement.style.position = 'absolute';labelRenderer.domElement.style.top = '0px';labelRenderer.domElement.style.pointerEvents = 'none';document.getElementById( 'container' ).appendChild( labelRenderer.domElement );controls = new OrbitControls( camera, renderer.domElement );// 设置最大最小视距controls.minDistance = 20;controls.maxDistance = 1000;window.addEventListener( 'resize', onWindowResize );stats = new Stats();stats.setMode(1); // 0: fps, 1: msdocument.body.appendChild( stats.dom );gpuPanel = new GPUStatsPanel( renderer.getContext() );stats.addPanel( gpuPanel );stats.showPanel( 0 );scene.add( group );
}function initLight() {const targetObject = new THREE.Object3D();targetObject.position.set(0, 0, 0);scene.add(targetObject);spotLight = new THREE.SpotLight(0xffffff);spotLight.position.set(0, 80, 150);spotLight.target = targetObject;spotLight.angle = Math.PI / 4;spotLight.intensity = 500;spotLight.penumbra = 1;spotLight.decay = 1;spotLight.distance = 300;// spotLight.map = textures['uv_grid_opengl.jpg'];spotLight.castShadow = true;spotLight.shadow.mapSize.width = 1024;spotLight.shadow.mapSize.height = 1024;spotLight.shadow.camera.near = 1;spotLight.shadow.camera.far = 200;spotLight.shadow.focus = 1;scene.add(spotLight);const lightHelper = new THREE.SpotLightHelper(spotLight);scene.add(lightHelper);const AmbientLight = new THREE.AmbientLight(new THREE.Color('rgb(255, 255, 255)'));scene.add( AmbientLight );
}function initHelp() {// const size = 100;// const divisions = 5;// const gridHelper = new THREE.GridHelper( size, divisions );// scene.add( gridHelper );// The X axis is red. The Y axis is green. The Z axis is blue.const axesHelper = new THREE.AxesHelper( 100 );scene.add( axesHelper );
}function axesHelperWord() {let xP = addWord('X轴');let yP = addWord('Y轴');let zP = addWord('Z轴');xP.position.set(50, 0, 0);yP.position.set(0, 50, 0);zP.position.set(0, 0, 50);
}function addWord(word) {let name = `<span>${word}</span>`;let moonDiv = document.createElement( 'div' );moonDiv.className = 'label';// moonDiv.textContent = 'Moon';// moonDiv.style.marginTop = '-1em';moonDiv.innerHTML = name;const label = new CSS2DObject( moonDiv );group.add( label );return label;
}function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize( window.innerWidth, window.innerHeight );
}function animate() {requestAnimationFrame( animate );if (earth) {time += 0.00005;earth.rotateY(time);}stats.update();controls.update();labelRenderer.render( scene, camera );renderer.render( scene, camera );
}
</script>
</body>
</html>
图片我依次放进来,方便大家本地看效果
stone.jpg

stone-bump.jpg

normal2.jpg

normal1.jpg

earth.jpg

earthSpec.png

具体的注释也都放代码里了!感觉不错的点个赞,光白嫖可还行!
相关文章:
ThreeJS-3D教学五-材质
我们在ThreeJS-3D教学二:基础形状展示中有简单介绍过一些常用的材质,这次我们举例来具体看下效果: 代码是这样的: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8">&…...
递归
欢迎来到Cefler的博客😁 🕌博客主页:那个传说中的man的主页 🏠个人专栏:题目解析 🌎推荐文章:题目大解析(3) 目录 👉🏻汉诺塔 👉&…...
Vercel部署个人静态之DNS污染劫持问题
vercel是我第一次接触静态网站托管所使用的服务,类似的还有github以及Netfily。但是Vercel的自动化构建远比github page方便的多。通过github授权给Vercel就实现了自动拉取构建及发布的一系列流程。在本地推送代码可以使用小乌龟工具,线上代码发布使用Ve…...
Microsoft Defender Vulnerability部署方案
目录 前言 Microsoft Defender Vulnerability 的主要功能 Microsoft Defender Vulnerability部署方案 前言 Microsoft Defender Vulnerability 是微软公司提供的一种安全工具,用于检测和修复系统中的漏洞和弱点。它可以帮助用户保护他们的计算机免受潜在的威胁和攻击,提高…...
云服务器CVM_云主机_云计算服务器_弹性云服务器-腾讯云
腾讯云服务器CVM提供安全可靠的弹性计算服务,腾讯云明星级云服务器,弹性计算实时扩展或缩减计算资源,支持包年包月、按量计费和竞价实例计费模式,CVM提供多种CPU、内存、硬盘和带宽可以灵活调整的实例规格,提供9个9的数…...
PLC之间无线通信-不用编程实现多品牌PLC无线通讯的解决方案
本文是PLC设备之间基于IGT-DSER系列智能网关实现WIFI无线通讯的案例。采用西门子S7-1500系列的PLC作为主站,与其它品牌的PLC之间进行网络通讯。案例包括智能网关AP方式、现场WIFI信号两种方式。有线以太网方式实现PLC之间通讯的案例 一、智能网关AP方式 将网络中的其…...
第二证券:A股反弹已至?9月最牛金股涨超41%
进入10月,作为券商月度战略精华的新一期金股也连续宣布。 从各券商关于十月份的大势研判来看,一些券商达观地认为反弹行情正在打开,也有一些券商认为仍是轰动市。具体配备上,AI、科创相关的标的仍然遭到喜欢,一起不少…...
机器人革命:你一定没见过这些全新的机器人技术!
原创 | 文 BFT机器人 01 通过机器人协作推进危险测绘 在危险测绘领域,研究人员开发了一种合作方案,利用地面和空中机器人对污染区域进行危险测绘。该团队通过使用异构覆盖控制技术提高了密度图的质量并降低了误差。与同质替代方案相比,该策…...
vue前端项目中添加独立的静态资源
如果想要在vue项目中放一些独立的静态资源,比如html文件或者用于下载的业务模板或其他文件等,需要在vue打包的时候指定一下静态资源的位置和打包后的目标位置。 使用的是 copy-webpack-plugin 插件,如果没有安装则需要先安装一下,…...
外汇天眼:业务员离职,也不给出金!Sky Alliance Markets摆烂不玩了?
近段时间,外汇天眼收到Sky Alliance Markets的客诉激增已达10条,目前该平台的官网还能打开。但最近关于Sky Alliance Markets是否跑路的争议也越来越多,据来外汇天眼投诉的用户透露,Sky Alliance Markets的员工大部分已经离职&…...
chrome浏览器如何多开
在网上寻找关于Chrome浏览器多开的教程时,你可能会发现操作相对复杂。然而,最近我发现了一个名为EasyBR浏览器的工具,作者使用程序将繁琐的步骤简化了。 主要功能 EasyBR浏览器具有以下主要功能: 批量账号管理:可以…...
学习笔记|串口通信的基础知识|同步/异步|常见的串口软件的参数|STC32G单片机视频开发教程(冲哥)|第二十集:串口通信基础
目录 1.串口通信的基础知识串口通信(Serial Communication)同步/异步?全双工?常见的串口软件的参数 2.STC32的串口通信实现原理引脚选择模式选择 3.串口通信代码实现编写串口1通信程序测试 总结 1.串口通信的基础知识 百度百科:串口通信的概…...
Golang接口实现OCP原则
文章目录 Golang接口实现OCP原则实例 Golang接口实现OCP原则 OCP: Open-Closed Principle 开闭原则,对扩展是开发的,对修改是关闭的。 实例 package mainimport "fmt"type Pet interface {eat()sleep() } type Dog struct { } t…...
【论文笔记】SVDM: Single-View Diffusion Model for Pseudo-Stereo 3D Object Detection
原文链接:https://arxiv.org/abs/2307.02270 1. 引言 目前的从单目相机生成伪传感器表达的方法依赖预训练的深度估计网络。这些方法需要深度标签来训练深度估计网络,且伪立体方法通过图像正向变形合成立体图像,会导致遮挡区域的像素伪影、扭…...
C++之sqlite数据库读写
C之sqlite数据库读写 常用函数应用例程 常用函数 1、sqlite3_open() 用于打开SQLite数据库。该函数接受两个参数:数据库文件名和打开模式。成功打开数据库后,将返回一个sqlite3*对象。 2、sqlite3_close() 用于关闭SQLite数据库。该函数接受一个sqlite…...
大模型应用疯狂加速,洗牌却在静悄悄进行了
配图来自Canva可画 在被誉为“科技企业营销圣经”的《跨越鸿沟》一书中,杰弗里摩尔写道:“高科技产品面世过程中,最危险、最关键的一点,就是由少数有远见者所主宰的早期市场,向实用主义者占支配地位的主流市场过渡。”…...
oracle后台进程详解#进程结构
一、oracle进程结构 oracle体系结构主要有实例数据库; 实例由内存结构(SGAPGA..)和进程结构(服务器进程后台进程..)组成;本文主要介绍进程结构 二、服务器进程 Oracle数据库创建服务器进程来处理连接到该实…...
解决DDP的参数未参与梯度计算
将find_unused_parameters改成False之后,如果出现模型有些参数未参与loss计算等错误。 可以用环境变量来debug查看log。 export TORCH_DISTRIBUTED_DEBUGDETAIL 代码上可以用以下方法查看。 # check parameters with no grad for n, p in model.named_parameters(…...
cpp primer笔记100-拷贝控制
如果拷贝构造函数如果传递的参数不是引用类型,则调用拷贝永远不成功,因为如果调用了拷贝构造函数,则必须拷贝它的实参,但是为了拷贝实参,我们又需要调用拷贝构造函数,如此循环。 如果想要删除默认构造函数…...
【数据库——MySQL】(16)游标和触发器习题及讲解
目录 1. 题目1.1 游标1.2 触发器 2. 解答2.1 游标2.2 触发器 1. 题目 1.1 游标 创建存储过程,利用游标依次显示某部门的所有员工的实际收入。(分别用使用 计数器 来循环和使用 标志变量 来控制循环两种方法实现) 创建存储过程,将某部门的员工工资按工作…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
HTTPS证书一年多少钱?
HTTPS证书作为保障网站数据传输安全的重要工具,成为众多网站运营者的必备选择。然而,面对市场上种类繁多的HTTPS证书,其一年费用究竟是多少,又受哪些因素影响呢? 首先,HTTPS证书通常在PinTrust这样的专业平…...
篇章一 论坛系统——前置知识
目录 1.软件开发 1.1 软件的生命周期 1.2 面向对象 1.3 CS、BS架构 1.CS架构编辑 2.BS架构 1.4 软件需求 1.需求分类 2.需求获取 1.5 需求分析 1. 工作内容 1.6 面向对象分析 1.OOA的任务 2.统一建模语言UML 3. 用例模型 3.1 用例图的元素 3.2 建立用例模型 …...
循环语句之while
While语句包括一个循环条件和一段代码块,只要条件为真,就不断 循环执行代码块。 1 2 3 while (条件) { 语句 ; } var i 0; while (i < 100) {console.log(i 当前为: i); i i 1; } 下面的例子是一个无限循环,因…...
