threejs-法线向量

news2024/10/22 9:37:04
一、介绍
1.介绍

1.在3D计算机图形中,‘法向量’是一个向量,表示3d模型表面在某一点的方向。在每个顶点上,都会有一个关联的法向量,这个向量通常被归一化,也就是说它的长度为1。

2.使用:定点的法向属性在很多计算图形的领域都有应用,通常用于光照计算,它们决定了光线照射到模型表面时的反射和折射特性。在Three.js中,如果不指定法向量,几何体的面会使用默认的法向量来推断出光照效果,这可能导致不理想的视觉效果。

2.属性
// 计算法线向量
// geomentry.computeVertexNormals()
// 设置法线向量
const normals = new Float32Array([
  0, 0, 1,  0, 0, 1,  0, 0, 1,  0, 0, 1
])
geomentry.setAttribute('normal', new three.BufferAttribute(normals, 3))



// 导入定点法向量辅助器
import { VertexNormalsHelper } from 'three/examples/jsm/helpers/VertexNormalsHelper.js'

// 创建法向量辅助器
const vertexNormalHelper = new VertexNormalsHelper(cube,0.2,0xff0000) // 0.2表示长度  0xff0000表示法向量颜色 
scene.add(vertexNormalHelper)
二、展示
1.效果

2.代码
// 导入threejs文件
import * as three from 'three'
// 导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'
// hdr加载器
import { RGBELoader } from 'three/examples/jsm/loaders/RGBEloader.js'
// 导入定点法向量辅助器
import { VertexNormalsHelper } from 'three/examples/jsm/helpers/VertexNormalsHelper.js'
// 创建场景
const scene = new three.Scene()
// 创建相机
const camera = new three.PerspectiveCamera(
  45, //视角 值越多视野越大
  window.innerWidth / window.innerHeight, //宽高比
  0.1, //近平面(相机最近能看到的物体)
  1000 //远平面(相机最远能看到的物体)
)
// 创建渲染器
const renderer = new three.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
// 添加背景颜色
scene.background = new three.Color(0x999999)
//创建纹理加载器
const textureLoader = new three.TextureLoader()

// 加载hdr贴图
let hdrLoader = new RGBELoader()
let envMap = hdrLoader.load('./textureImage/pz.hdr', (envMap) => {
  // 设置球形映射
  envMap.mapping = three.EquirectangularReflectionMapping
  // 设置环境贴图
  scene.background = envMap
  // 设置环境贴图
  scene.environment = envMap
  // 设置plane的环境贴图
  planeMaterial.envMap = envMap
  material.envMap = envMap
})
// 设置高光贴图
let specularMap = textureLoader.load('./textureImage/southeast.jpg')

// 创建平面几何
const planeGeometry = new three.PlaneGeometry(2,2)

// 创建uv贴图
let uvTexture = new three.TextureLoader().load('./textureImage/UV.png')
// 创建平面材质
const planeMaterial = new three.MeshBasicMaterial({
  // color: 0xcccccc, // 平面的颜色
  // Wireframe:true,
  map: uvTexture
})

// 创建平面网格
const planeMesh = new three.Mesh(planeGeometry, planeMaterial)
planeMesh.position.x = -2
// 加入场景
scene.add(planeMesh)


// 创建几何体
const geomentry = new three.BufferGeometry()
// // 创建顶端数据,定点是存在顺序的每三个为一个顶点,逆时针为正面
// const vertices = new Float32Array([
//   -1, -1, 0, 1, -1, 0, 1, 1, 0,
//   1, 1, 0, -1, 1, 0, -1, -1, 0
// ])
// // 创建定点属性
// geomentry.setAttribute('position', new three.BufferAttribute(vertices, 3))

// 使用索引绘制
const vertices = new Float32Array([-1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 1, 0])
// 创建顶点属性
geomentry.setAttribute('position', new three.BufferAttribute(vertices, 3))
// 创建索引
const indices = new Uint16Array([0, 1, 2, 2, 3, 0])
// 创建索引属性
geomentry.setIndex(new three.BufferAttribute(indices, 1))
// 设置uv坐标
const uvs = new Float32Array([
  0, 0, 1, 0, 1, 1, 0, 1
])
geomentry.setAttribute('uv', new three.BufferAttribute(uvs, 2))
// 计算法线向量
// geomentry.computeVertexNormals()
// 设置法线向量
const normals = new Float32Array([
  0, 0, 1,  0, 0, 1,  0, 0, 1,  0, 0, 1
])
geomentry.setAttribute('normal', new three.BufferAttribute(normals, 3))

// 创建材质
const material = new three.MeshBasicMaterial({
  // color: 0xff0000,
  // side: three.DoubleSide //正反面都能看到
  // wireframe: true //线框模式
    map: uvTexture
})
// 创建网格
const cube = new three.Mesh(geomentry, material)
cube.position.x = 2
// 加入场景
scene.add(cube)
// 创建法向量辅助器
const vertexNormalHelper = new VertexNormalsHelper(cube,0.2,0xff0000) // 0.2表示长度  0xff0000表示法向量颜色 
scene.add(vertexNormalHelper)
// 相机位置
camera.position.z = 5 //设置在z轴位置
// 看向位置
camera.lookAt(0, 0, 0) //看向原点
// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true // 启用阻尼系数:值越大,阻尼越明显
controls.dampingFactor = 0.5 //设置阻尼值
controls.enableZoom = true // 启用缩放:值为false时禁止缩放
// controls.autoRotate = true // 启用自动旋转:值为true时禁止手动旋转
controls.autoRotateSpeed = 0.5 // 自动旋转速度
// 渲染函数
const animate = () => {
  controls.update()
  requestAnimationFrame(animate) //每一帧调用函数
  // 旋转
  // cube.rotation.x += 0.01 // X轴转
  // cube.rotation.y += 0.01 // Y轴转
  renderer.render(scene, camera) // 重新渲染
}
animate()

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

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

相关文章

lammps统计一个原子周围不同类型原子数量的方法

本文介绍lammps统计一个原子周围不同类型原子数量的方法。 在之前的专栏中,曾介绍过动态统计某一个固定区域内原子数量的方法,也介绍过动态统计某一个原子周围原子数量的方法: 下面介绍第三种类型:动态统计某一个原子周围不同类型原子数量的方法。 以小球的随机碰撞为例,原…

【2024.10.14练习】生命之树

题目描述 题目分析 对于求树的子区域最大和,考虑使用树形DP求解。 假设以树的某一结点为根节点来深度优先搜索整棵树,搜索到每个结点时都会有两种决策状态:加入该节点和不加入该节点。定义代表选择此结点所能得到最大权值和,代表…

【Linux】解析信号的本质&相关函数及指令的介绍

前言 大家好吖,欢迎来到 YY 滴Linux系列 ,热烈欢迎! 本章主要内容面向接触过C的老铁 主要内容含: 欢迎订阅 YY滴C专栏!更多干货持续更新!以下是传送门! YY的《C》专栏YY的《C11》专栏YY的《Lin…

动态规划-简单多状态dp问题——LCR.091.粉刷房子

1.题目来源 题目来源:LCR.091.粉刷房子——力扣 测试用例 2.算法原理 下列矩阵表示粉刷每个房子的费用,对应颜色表示粉刷的油漆颜色 1.状态表示 创建一个n3的dp表,每一列代表第i个房子刷三个颜色中任意颜色的情况下花费的费用 dp[i][0]:第…

c语言字符函数

1,字符分类函数: 例如:写一个代码将字符串中的小写字母转化成大写字母 就可以用到上述islower函数判断字符是否是小写 2.字符转换函数 c语言提供了两个字符转换函数 1.int tolower (int c); //将输入进去的大写字母转化成小写 2,int …

AI开发者工具的双子星:Cursor与ChatGPT Canvas的区别

01—Cursor:沉浸式的开发体验 Cursor是一款旨在为开发者提供无缝编程体验的工具。它将AI的功能深度嵌入到开发者熟悉的环境中,便于在编码过程中获得即时帮助。开发者无需离开自己的操作界面,AI就能自动为其提供代码补全、错误检查和优化建议…

荣耀、中国移动、京东三强联合,开启产业链升级的“价值跃迁”

市场最大的不变就是变化,能够赢得跨越式发展的,往往是最能适应变化,并且开拓创新的企业。 在全行业数字化转型的当下,线上智能终端销售模式,正在迎来新的篇章。 10月12日,在2024中国移动全球合作伙伴大会…

买自动猫砂盆怎么不花冤枉钱?双十一高性价比自动猫砂盆推荐

平时出门在外面,真的有点来不及照顾猫咪的猫砂盆,导致粪便堆积的时间过长,污染干净的猫砂,猫砂盆长时间不清理,会增加细菌滋生的机会,从而增加猫咪尿路感染的风险。自动猫砂盆的自动铲屎很方便实用&#xf…

界面耻辱纪念堂--可视元素02

Leif Almberg 发给我们一个从 IBMs NetFinity(一个管理网络和远程计算机的程序)截取的图片。 这个图片由一大堆混乱的带边框的控件组成,这些控件占据了整个屏幕。由于他们希望把所有东西填充在一个单独对话框中,IBM 的设计者不得…

IPv6 DNS简介

IPv6网络中的每台主机都是由IPv6地址来标识的,用户只有获得待访问主机的IPv6地址,才能够成功实现访问操作。对于用户来讲,记住主机的IPv6地址是相当困难的,因此设计了一种字符串形式的主机命名机制,这就是域名系统。用…

HBuilder X 下载vue-router时 发生异常:npm ERR! code EPERM

一、异常 PS C:\Users\GL\Documents\HBuilderProjects\vj1> npm i vue-router3.6.5 npm ERR! code EPERM npm ERR! syscall mkdir npm ERR! path C:\Program Files\nodejs\node_cache\_cacache npm ERR! errno EPERM npm ERR! FetchError: Invalid response body while tr…

Vue3 集成 json-editor-vue3

简介 快速编辑json数据,还需要支持全屏编辑,以及json校验。 https://github.com/guyue88/json-editor-vue3 安装依赖 npm install json-editor-vue3 --save 引入 在 main.js中添加 import “jsoneditor”; 全局引入 import Vue from vue import Json…

【设计模式系列】模板方法模式

一、什么是模板方法模式 模板方法模式(Template Method Pattern)是一种行为型设计模式,它在父类中定义一个算法的框架,允许子类在不改变算法结构的情况下重写算法的某些特定步骤。这种模式非常适合于那些存在共同行为的类&#x…

CSS简单入门

一.简单概念 1.概念 层叠样式表&#xff0c;一种样式表语言&#xff0c;用来美化HTML文档的呈现。 2.书写位置 title标签下方添加style双标签&#xff0c;style标签里面书写CSS代码 &#xff08;1&#xff09;外部学习样式 <title>CSS使用</title> <sty…

【软件工程】数据流图DFD

文章目录 数据流图DFD概述一、数据流图的基本元素二、数据流图的绘制步骤三、数据流图的分层设计四、数据流图的绘制原则五、数据流图的应用 一个完整的数据流包含哪些要素从图中找出所有数据流1. **理解数据流图的结构**2. **识别外部实体**3. **追踪数据流**4. **记录数据流*…

在 MTT GPU 上使用 llama.cpp 推理

大语言模型因其出色的自然语言理解和生成能力而迅速被广泛使用&#xff0c;llama.cpp 大幅降低了进行大语言模型推理的门槛&#xff0c;MTT GPU 同样也是 llama.cpp 支持的运行平台&#xff0c;能够充分利用硬件的性能来助力用户的大语言模型应用。 本文主要介绍了如何在摩尔线…

如何设置JMeter界面的永久汉化?

1、找到jMeter安装目录下的bin目录 2、打开jmeter.properties文件&#xff0c;把第37行修改为"languagezh_CN"&#xff0c;保存&#xff0c;关闭 3、重启JMeter即可

程序员必读:精通ER图设计,解锁数据库高效构建秘籍

在信息技术的浩瀚星空中&#xff0c;数据库如同星辰般璀璨&#xff0c;而ER图&#xff08;Entity-Relationship Diagram&#xff0c;实体-关系图&#xff09;则是那把引领我们穿越数据迷雾的钥匙。对于每一位程序员而言&#xff0c;掌握ER图设计不仅是数据库设计的基础&#xf…

墙裂建议收藏,100道Python练手题目

目录 实例001&#xff1a;数字组合 实例002&#xff1a;“个税计算” 实例003&#xff1a;完全平方数 实例004&#xff1a;这天第几天 实例005&#xff1a;三数排序 实例006&#xff1a;斐波那契数列 实例007&#xff1a;copy 实例008&#xff1a;九九乘法表 实例009&…

【读书笔记·VLSI电路设计方法解密】问题14:什么是基底层和金属层

正如在问题13中讨论的,基底层用于前端工艺来制造NMOS和PMOS晶体管,而金属层用于后端工艺连接这些晶体管。在tapeout之后,每一层都需要专用的光掩膜来定义其图案。 基底层主要包括以下内容: n-well:用于定义n-well区域,这是硅晶片中的一种植入或扩散区域。有源区(active…