👨⚕️ 主页: gis分享者
👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!
👨⚕️ 收录于专栏:threejs gis工程师
文章目录
- 一、🍀前言
- 1.1 ☘️THREE.MeshBasicMaterial网格材质
- 2.2 ☘️THREE.MeshLambertMaterial漫反射材质
- 二、🍀THREE.MeshBasicMaterial网格材质、THREE.MeshLambertMaterial漫反射材质效果
- 1. ☘️实现思路
- 2. ☘️代码样例
一、🍀前言
本文详细介绍如何基于threejs在三维场景中实现THREE.MeshBasicMaterial网格材质、THREE.MeshLambertMaterial漫反射材质效果,亲测可用。希望能帮助到您。一起学习,加油!加油!
1.1 ☘️THREE.MeshBasicMaterial网格材质
THREE.MeshBasicMaterial 是 Three.js 中的一种基本材质类型,用于渲染网格对象(THREE.Mesh)。这种材质不考虑光源的影响,因此无论场景中有多少光源,材质的颜色和外观都不会改变。这使得 THREE.MeshBasicMaterial 非常适合用于不需要光照效果的场景,或者作为调试工具来检查模型的形状和纹理。
常用属性:
color:材质的颜色,默认为白色(0xffffff)。可以是一个整数,表示十六进制颜色值。
map:基础颜色贴图,可以用来替代材质的颜色。可以是一个 THREE.Texture 对象。
alphaMap:透明度贴图,可以用来定义材质的透明度。可以是一个 THREE.Texture 对象。
emissive:自发光颜色,默认为黑色(0x000000)。即使在没有光源的情况下,也会显示这个颜色。
emissiveMap:自发光贴图,可以用来定义自发光的颜色。可以是一个 THREE.Texture 对象。
specular:高光颜色,默认为白色(0x111111),但在 THREE.MeshBasicMaterial 中不会生效。
shininess:高光强度,默认为 30,但在 THREE.MeshBasicMaterial 中不会生效。
opacity:材质的全局透明度,默认为 1(不透明)。
transparent:是否开启透明模式,默认为 false。如果设置为 true,则需要设置 opacity 或者使用 alphaMap。
side:指定材质在哪一面渲染,可以是 THREE.FrontSide(正面)、THREE.BackSide(背面)或 THREE.DoubleSide(双面)。
wireframe:是否启用线框模式,默认为 false。
visible:是否渲染该材质,默认为 true。
depthTest:是否进行深度测试,默认为 true。
depthWrite:是否写入深度缓冲区,默认为 true。
blending:混合模式,默认为 THREE.NormalBlending。可以设置为 THREE.AdditiveBlending、THREE.SubtractiveBlending 等。
vertexColors:是否启用顶点颜色,默认为 THREE.NoColors。可以设置为 THREE.VertexBasicColors、THREE.VertexColors 或 THREE.FaceColors。
flatShading:是否使用平滑着色,默认为 false。如果设置为 true,则每个面片都将使用平均法线。
2.2 ☘️THREE.MeshLambertMaterial漫反射材质
THREE.MeshLambertMaterial 是 Three.js 中的一种材质类型,用于模拟物体表面的漫反射效果。这种材质遵循 Lambertian 反射模型,这意味着它会均匀地将接收到的光照散射到各个方向,从而产生较为自然的光照效果。THREE.MeshLambertMaterial 适用于需要模拟漫反射材质的场景,如墙面、木头、纸张等非金属材料。
常用属性:
THREE.MeshLambertMaterial 继承自 THREE.Material,并具有一些特定的属性,可以用来控制材质的外观:
color:材质的颜色,默认为白色(0xffffff)。可以是一个整数,表示十六进制颜色值。
map:基础颜色贴图,可以用来替代材质的颜色。可以是一个 THREE.Texture 对象。
alphaMap:透明度贴图,可以用来定义材质的透明度。可以是一个 THREE.Texture 对象。
emissive:自发光颜色,默认为黑色(0x000000)。即使在没有光源的情况下,也会显示这个颜色。
emissiveMap:自发光贴图,可以用来定义自发光的颜色。可以是一个 THREE.Texture 对象。
specular:高光颜色,默认为白色(0x111111),但在 THREE.MeshLambertMaterial 中不会生效。
shininess:高光强度,默认为 30,但在 THREE.MeshLambertMaterial 中不会生效。
opacity:材质的全局透明度,默认为 1(不透明)。
transparent:是否开启透明模式,默认为 false。如果设置为 true,则需要设置 opacity 或者使用 alphaMap。
side:指定材质在哪一面渲染,可以是 THREE.FrontSide(正面)、THREE.BackSide(背面)或 THREE.DoubleSide(双面)。
wireframe:是否启用线框模式,默认为 false。
visible:是否渲染该材质,默认为 true。
depthTest:是否进行深度测试,默认为 true。
depthWrite:是否写入深度缓冲区,默认为 true。
blending:混合模式,默认为 THREE.NormalBlending。可以设置为 THREE.AdditiveBlending、THREE.SubtractiveBlending 等。
vertexColors:是否启用顶点颜色,默认为 THREE.NoColors。可以设置为 THREE.VertexBasicColors、THREE.VertexColors 或 THREE.FaceColors。
flatShading:是否使用平滑着色,默认为 false。如果设置为 true,则每个面片都将使用平均法线。
envMap:环境贴图,可以用来模拟环境光照。可以是一个 THREE.Texture 对象。
reflectivity:环境光反射率,默认为 1。
refractionRatio:折射率,默认为 0.98。
combine:环境贴图的组合方式,默认为 THREE.MixOperation。
二、🍀THREE.MeshBasicMaterial网格材质、THREE.MeshLambertMaterial漫反射材质效果
1. ☘️实现思路
- 1、初始化renderer渲染器
- 2、初始化Scene三维场景
- 3、初始化camera相机,定义相机位置 camera.position.set,设置相机方向camera.lookAt
- 4、初始化THREE.AmbientLight环境光源,scene场景加入环境光源,初始化THREE.DirectionalLight平行光源,设置平行光源位置,设置平行光源投影,scene添加平行光源。
- 5、加载几何模型:创建SphereGeometry球体、BoxGeometry立方体、PlaneGeometry地面几何体以及AxisHelper辅助工具坐标系,Scene场景加入以上几何体和工具,其中SphereGeometry使用THREE.MeshBasicMaterial网格材质,其他几何体使用THREE.MeshLambertMaterial漫反射材质。
- 6、加入controls控制、gui控制,加入stats监控器,监控帧数信息。
2. ☘️代码样例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>learn19(THREE.MeshBasicMaterial材质、THREE.MeshLambertMaterial材质)</title>
<script src="lib/threejs/127/three.js-master/build/three.js"></script>
<script src="lib/threejs/127/three.js-master/examples/js/controls/OrbitControls.js"></script>
<script src="lib/threejs/127/three.js-master/examples/js/libs/stats.min.js"></script>
<script src="lib/threejs/127/three.js-master/examples/js/libs/dat.gui.min.js"></script>
</head>
<style>
body {
margin: 0;
}
canvas {
width: 100%;
height: 100%;
display: block;
}
</style>
<body onload="draw()">
</body>
<script>
var renderer
var initRender = () => {
renderer = new THREE.WebGLRenderer({antialias: true})
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFSoftShadowMap
document.body.appendChild(renderer.domElement)
}
var scene
var initScene = () => {
scene = new THREE.Scene()
}
var camera
var initCamera = () => {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(0, 40, 100)
camera.lookAt(new THREE.Vector3(0, 0, 0))
}
var ambientLight, directionalLight
var initLight = () => {
ambientLight = new THREE.AmbientLight('#111111')
scene.add(ambientLight)
directionalLight = new THREE.DirectionalLight('#ffffff')
directionalLight.position.set(-40, 60, -10)
directionalLight.shadow.camera.near = 20 //产生阴影的最近距离
directionalLight.shadow.camera.far = 200 //产生阴影的最远距离
directionalLight.shadow.camera.left = -50 //产生阴影距离位置的最左边位置
directionalLight.shadow.camera.right = 50 //最右边
directionalLight.shadow.camera.top = 50 //最上边
directionalLight.shadow.camera.bottom = -50 //最下面
directionalLight.shadow.mapSize.height = 1024
directionalLight.shadow.mapSize.width = 1024
directionalLight.castShadow = true
scene.add(directionalLight)
}
var cube, plane, meshMaterial
var initModel = () => {
var helper = new THREE.AxisHelper(10)
scene.add(helper)
var sphereGeometry = new THREE.SphereGeometry(10, 30, 30)
meshMaterial = new THREE.MeshBasicMaterial({color: 0xaaafff})
var sphere = new THREE.Mesh(sphereGeometry, meshMaterial)
sphere.position.set(-20, 20, 0)
sphere.castShadow = true
scene.add(sphere)
var cubeGeometry = new THREE.BoxGeometry(10, 10, 10)
var cubeMaterial = new THREE.MeshLambertMaterial({color: 0x00ffff})
cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
cube.position.set(30, 5, -5)
cube.castShadow = true
scene.add(cube)
var planeGeometry = new THREE.PlaneGeometry(5000, 5000, 20, 20)
var planeMaterial = new THREE.MeshLambertMaterial({color: 0xaaaaaa})
plane = new THREE.Mesh(planeGeometry, planeMaterial)
plane.rotation.x = -0.5 * Math.PI
plane.position.y = -0
plane.receiveShadow = true
scene.add(plane)
}
var params
var initGui = () => {
params = {
rotationSpeed: 0.02,
bouncingSpeed: 0.03,
opacity: meshMaterial.opacity,
transparent: meshMaterial.transparent,
overdraw: meshMaterial.overdraw,
visible: meshMaterial.visible,
side: "front",
color: meshMaterial.color.getStyle(),
wireframe: meshMaterial.wireframe,
wireframeLinewidth: meshMaterial.wireframeLinewidth,
wireFrameLineJoin: meshMaterial.wireframeLinejoin,
}
var gui = new dat.GUI()
var spGui = gui.addFolder('Mesh')
spGui.add(params, 'opacity', 0, 1).onChange(e => {
meshMaterial.opacity = e
})
spGui.add(params, 'transparent').onChange(e => {
meshMaterial.transparent = e
})
spGui.add(params, 'wireframe').onChange(e => {
meshMaterial.wireframe = e
})
spGui.add(params, 'wireframeLinewidth', 0, 20).onChange(e => {
meshMaterial.wireframeLinewidth = e
})
spGui.add(params, 'visible').onChange(e => {
meshMaterial.visible = e
})
spGui.add(params, 'side', ['front', 'back', 'double']).onChange(e => {
switch (e) {
case 'front':
meshMaterial.side = THREE.FrontSide
break
case 'back':
meshMaterial.side = THREE.BackSide
break
case 'double':
meshMaterial.side = THREE.DoubleSide
break
}
meshMaterial.needsUpdate = true
})
spGui.addColor(params, 'color').onChange(e => {
meshMaterial.color.setStyle(e)
})
spGui.open()
}
var stats
var initStats = () => {
stats = new Stats()
document.body.appendChild(stats.dom)
}
var controls
var initControls = () => {
controls = new THREE.OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
}
var render = () => {
renderer.render(scene, camera)
}
var onWindowResize = () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
render()
renderer.setSize(window.innerWidth, window.innerHeight)
}
var animate = () => {
render()
stats.update()
controls.update()
requestAnimationFrame(animate)
}
var draw = () => {
initRender()
initScene()
initCamera()
initLight()
initModel()
initStats()
initControls()
initGui()
animate()
window.onresize = onWindowResize
}
</script>
</html>
效果如下: