three.js学习记录(第四节:材质外观)
1、为几何体设置贴图
MeshBasicMaterial的属性:map,颜色贴图。
1.1> 导入一张图片
import boxBg from '@/assets/images/7.jpg'
1.2> 通过加载器TextureLoader加载当前图片
1.3> 将加载后的图片赋给map,相当于给几何体的面贴了图。
const geomery = new THREE.BoxGeometry(1,1,1)
const imgTexture = new THREE.TextureLoader()
const boxImg = imgTexture.load(boxBg)
// map:颜色贴图。
const material = new THREE.MeshBasicMaterial({
map:boxImg
})
const mesh = new THREE.Mesh(geomery,material)
scene.add(mesh)
效果入下:
2、设置材质外观
MeshBasicMaterial 基础网格材质不受光源影响(添加光源,没有任何光影效果,几何体不会有任何变化),所以如果添加光源,可以使用MeshStandardMaterial材质。
MeshStandardMaterial 标准网格材质必须要有光照才能展示几何体。
材质属性:
1> metalness: 材质与金属的相似度。非金属材质,如木材或石材,使用0.0,金属使用1.0,通常没有中间值。 默认值为0.0。0.0到1.0之间的值可用于生锈金属的外观。如果还提供了metalnessMap,则两个值相乘。
2> roughness:材质的粗糙程度。0.0表示平滑的镜面反射,1.0表示完全漫反射。默认值为1.0。如果还提供roughnessMap,则两个值相乘。
3> emissive:材质的放射(光)颜色,基本上是不受其他光照影响的固有颜色。默认为黑色。
const material = new THREE.MeshStandardMaterial({color:0xaaf6dd, // 物体反射的光色metalness:0.5,roughness:0.5,// emissive:0x666333, // 通过emissive设置物体的自发光颜色
})
3、设置光源
1> AmbientLight是环境光,散射光。环境光会均匀的照亮场景中的所有物体。环境光不能用来投射阴影,因为它没有方向。
const light = new THREE.AmbientLight(0xffffff)
scene.add(light)
2> DirectionalLight平行光。平行光是沿着特定方向发射的光。这种光的表现像是无限远,从它发出的光线都是平行的。常常用平行光来模拟太阳光的效果。 太阳足够远,因此我们可以认为太阳的位置是无限远,所以我们认为从太阳发出的光线也都是平行的。
const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set(5,5,5)
scene.add( directionalLight );
效果如下:
4、上述示例中正方体不够直观的话,可通过球体几何体进行展示
球缓冲几何体:SphereGeometry(radius , widthSegments , heightSegments , phiStart , phiLength , thetaStart , thetaLength)
radius — 球体半径,默认为1。
widthSegments — 水平分段数(沿着经线分段),最小值为3,默认值为32。
heightSegments — 垂直分段数(沿着纬线分段),最小值为2,默认值为16。
phiStart — 指定水平(经线)起始角度,默认值为0。。
phiLength — 指定水平(经线)扫描角度的大小,默认值为 Math.PI * 2。
thetaStart — 指定垂直(纬线)起始角度,默认值为0。
thetaLength — 指定垂直(纬线)扫描角度大小,默认值为 Math.PI。
const geomery = new THREE.SphereGeometry(1,30,30)
const material = new THREE.MeshStandardMaterial({color:0xaaf6dd, // 物体反射的光色metalness:0.5,roughness:0.5,
})const light = new THREE.AmbientLight(0xffffff)
scene.add(light)const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set(5,5,5)
scene.add( directionalLight );const mesh = new THREE.Mesh(geomery,material)
scene.add(mesh)
球体效果如下:
完整代码:
<template><div><div id="cav" style="width: 100%; height: 900px;"></div></div>
</template><script setup>
import * as THREE from 'three'
import { ref, onMounted } from 'vue'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import imgBg from '@/assets/images/view.png'
import boxBg from '@/assets/images/7.jpg'const initCanvas = () => {// 1.场景const scene = new THREE.Scene()const loader = new THREE.TextureLoader()loader.load(imgBg,texture => {scene.background = texturecanvas.render(scene,camera)})// 2.相机const camera = new THREE.PerspectiveCamera(45,1,1,1000)camera.position.set(5,5,5)camera.lookAt(0,0,0)scene.add(camera)// 4. 添加几何体const geomery = new THREE.SphereGeometry(1,30,30)// 5. 添加光源// MeshBasicMaterial 基础网格材质不受光源影响(添加光源,没有任何光影效果,几何体不会有任何变化)// MeshStandardMaterial 标准网格材质必须要有光照才能展示几何体// emissive 材质的放射(光)颜色,基本上是不受其他光照影响的固有颜色。默认为黑色。const material = new THREE.MeshStandardMaterial({color:0xaaf6dd, // 物体反射的光色metalness:0.5,roughness:0.5,// emissive:0x666333, // 通过emissive设置物体的自发光颜色})// AmbientLight是环境光,散射光。环境光会均匀的照亮场景中的所有物体。环境光不能用来投射阴影,因为它没有方向。const light = new THREE.AmbientLight(0xffffff) scene.add(light)// DirectionalLight平行光。平行光是沿着特定方向发射的光。这种光的表现像是无限远,从它发出的光线都是平行的。常常用平行光来模拟太阳光的效果。 太阳足够远,因此我们可以认为太阳的位置是无限远,所以我们认为从太阳发出的光线也都是平行的。const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );directionalLight.position.set(5,5,5)scene.add( directionalLight );// map:颜色贴图。通过加载器TextureLoader加载一张图片// const imgTexture = new THREE.TextureLoader()// const boxImg = imgTexture.load(boxBg)// const material = new THREE.MeshStandardMaterial({// map:boxImg,// })const mesh = new THREE.Mesh(geomery,material)scene.add(mesh)// 3.渲染器const canvas = new THREE.WebGLRenderer()const content = document.querySelector('#cav')content.appendChild(canvas.domElement)canvas.setSize(content.offsetWidth,content.offsetHeight)canvas.render(scene,camera)const controls = new OrbitControls(camera,canvas.domElement)controls.enableDamping = truecontrols.update()function animate(){requestAnimationFrame(animate)controls.update()camera.lookAt(0,0,0)canvas.render(scene,camera)}requestAnimationFrame(animate)
}onMounted(() => {initCanvas()
})
</script><style lang="scss" scoped></style>