当前位置: 首页 > news >正文

threejs-法线向量

一、介绍
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 = envMapmaterial.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.mrgr.cn/news/50167.html

相关文章:

  • 周易解读:推荐教材
  • 【C语言刷力扣】2206.将数组划分成相等数对
  • YOLOv11改进策略【Conv和Transformer】| ACmix 卷积和自注意力的结合,充分发挥两者优势
  • linux------缓冲区与C库的原理
  • cmake模板-支持编译动态/静态文件
  • Dmitri Shuralyov的全职开源之旅
  • c语言中使用(>> )运算替代(/ %)运算实现优化
  • 【MAUI】步进器
  • Avarra:革新企业销售培训的未来
  • SHA1算法学习
  • Product1M 深度理解 PPT
  • STL.string(上)
  • Linux内核 -- 多核数据同步原语言之 smp_load_acquire 的作用与使用
  • 当下的时代?
  • Kubernetes 节点清空
  • STM32中断
  • JAVA软开-面试经典题(7)-字符串常量池
  • MATLAB代码解析:利用DCGAN实现图像数据的生成
  • 【时间盒子】-【10.自定义弹窗】CustomDialogController
  • 扭亏年只是开始,赛力斯的成长性仍在继续