Skip to content

法向量属性应用与法向量辅助器

代码

法量是用于计算反射的

js
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';
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
import  * as TWEEN from 'three/examples/jsm/libs/tween.module.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)

let uvTexture = new THREE.TextureLoader().load('./texture/uv_grid_opengl.jpg')
const planeGeometry = new THREE.PlaneGeometry(2, 2)
const planeMaterial = new THREE.MeshBasicMaterial({
  map: uvTexture
})

const planeMesh = new THREE.Mesh(planeGeometry, planeMaterial)
scene.add(planeMesh)
planeMesh.position.x = -3


const geometry = new THREE.BufferGeometry()
const vertices = new Float32Array([
  -1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0, -1.0, 1.0, 0
])

geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))

const indices = new Uint16Array([0, 1, 2, 2, 3, 0]) 

geometry.setIndex(new THREE.BufferAttribute(indices, 1))

const uv = new Float32Array([
  0, 0, 1, 0, 1, 1, 0, 1,
])

geometry.setAttribute('uv', new THREE.BufferAttribute(uv, 2))
// 第一种:通过函数自动,计算出法向向量
geometry.computeVertexNormals()

// 第二种:设置法向量
const normals = new Float32Array([
  0,
  0,
  1,
  0,
  0,
  1,
  0,
  0,
  1,
  0,
  0,
  1, // 正面
])
// 设置法向量属性
geometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3))


const material = new THREE.MeshBasicMaterial({
  map: uvTexture,
})

const plane = new THREE.Mesh(geometry, material)
scene.add(plane)
plane.position.x = 3

// 创建法向量辅助器
const helper = new VertexNormalsHelper(plane, 0.2, 0xff0000)
scene.add(helper)

camera.position.z = 15;
camera.position.y = 2;
camera.position.x = 2;
camera.lookAt(0, 0, 0)

const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;

function animate() {
  requestAnimationFrame(animate)
  controls.update()
  renderer.render(scene, camera)

  TWEEN.update()
}

animate()

window.addEventListener('resize', () => {
  renderer.setSize(window.innerWidth, innerHeight)
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
})

let eventObj = {
  Fullscreen: function () {
    document.body.requestFullscreen()
  },
  ExitFullscreen: function () {
    document.exitFullscreen()
  }
}

const gui = new GUI()
gui.add(eventObj, 'Fullscreen').name('全屏')
gui.add(eventObj, 'ExitFullscreen').name('退出全屏')

let rgbeLoader = new RGBELoader()
rgbeLoader.load('./texture/Alex_Hart-Nature_Lab_Bones_2k.hdr', (envMap) => {
  envMap.mapping = THREE.EquirectangularReflectionMapping
  scene.background = envMap
  scene.environment = envMap
  planeMaterial.envMap = envMap
  material.envMap = envMap
})

Released under the MIT License.