1. 程式人生 > 其它 >THREE.js 入門(三)材質燈光和陰影

THREE.js 入門(三)材質燈光和陰影

材質

MeshLambertMaterial

一種非光澤表面的材質,沒有鏡面高光。
可以很好地模擬一些表面(例如未經處理的木材或石材),但不能模擬具有鏡面高光的光澤表面(例如塗漆木材)
在光源的照射下可以見併產生投影

燈光

聚光燈(SpotLight)

光線從一個點沿一個方向射出,隨著光線照射的變遠,光線圓錐體的尺寸也逐漸增大。
可以想象成手電筒
該光源可以投射陰影

幾何體

立方體(BoxGeometry)

四邊形的原始幾何類

構造器引數:
width — X軸上面的寬度,預設值為1。
height — Y軸上面的高度,預設值為1。
depth — Z軸上面的深度,預設值為1。
...

球體(SphereGeometry)

構造器引數:
radius — 球體半徑,預設為1。
...

投影

渲染器需要開啟投影屬性,預設關閉

// 開啟陰影
renderer.shadowMapEnabled = true

聚光燈需要開啟投影

/* 聚光燈 */
const spotLight = new THREE.SpotLight(0xffffff)
spotLight.position.set(-100, 340, -200)
// 開啟投影
spotLight.castShadow = true
scene.add(spotLight)

地面需要接受投影

/* 平面 */
const planeGeometry = new THREE.PlaneGeometry(200, 200)
const planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff})
const plane = new THREE.Mesh(planeGeometry, planeMaterial)
// 接受投影
plane.receiveShadow = true
plane.position.set(100, 0, 100)
plane.rotation.x = -0.5 * Math.PI
scene.add(plane)

幾何體要開啟投影 且材質不能為基礎材質(MeshBasicMaterial)

/* 立方體 */
const cubeGeometry = new THREE.BoxGeometry(50, 50, 50)
const cubeMaterial = new THREE.MeshLambertMaterial({color: 'blue'})
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
cube.position.set(25, 25, 25)
// 開啟投影
cube.castShadow = true
scene.add(cube)

完整程式碼

/*新增材質燈光和陰影*/
import * as THREE from 'three'

const {innerWidth: WIDTH, innerHeight: HEIGHT} = window
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(45, WIDTH / HEIGHT, 0.1, 1000)
camera.position.set(-200, 200, 300)
camera.lookAt(scene.position)

const axesHelper = new THREE.AxesHelper(250)
scene.add(axesHelper)

/* 聚光燈 */
const spotLight = new THREE.SpotLight(0xffffff)
spotLight.position.set(-100, 340, -200)
// 開啟投影
spotLight.castShadow = true
scene.add(spotLight)

/* 平面 */
const planeGeometry = new THREE.PlaneGeometry(200, 200)
const planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff})
const plane = new THREE.Mesh(planeGeometry, planeMaterial)
// 接受投影
plane.receiveShadow = true
plane.position.set(100, 0, 100)
plane.rotation.x = -0.5 * Math.PI
scene.add(plane)

/* 立方體 */
const cubeGeometry = new THREE.BoxGeometry(50, 50, 50)
const cubeMaterial = new THREE.MeshLambertMaterial({color: 'blue'})
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
cube.position.set(25, 25, 25)
// 開啟投影
cube.castShadow = true
scene.add(cube)

/* 球體 */
const sphereGeometry = new THREE.SphereGeometry(20)
const sphereMaterial = new THREE.MeshLambertMaterial({color: 'green'})
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
sphere.position.set(100 - 20, 20, 100 - 20)
sphere.castShadow = true
scene.add(sphere)

// antialias 抗鋸齒
const renderer = new THREE.WebGLRenderer({antialias: true})
renderer.setSize(WIDTH, HEIGHT)
// 開啟陰影
renderer.shadowMapEnabled = true
document.body.appendChild(renderer.domElement)
renderer.render(scene, camera)