基础环境搭建:
拷贝相应obj模型到models文件夹下
导入并设置.obj模型:
.boundingSphere : Sphere
当前 bufferGeometry 的外边界球形,可以通过 .computeBoundingSphere() 计算。
object.traverse():It is basically the iterator through your loaded object. You can pass the function to the traverse() function which will be called for every child of the object being traversed. If you call traverse() on scene. you traverse through the complete scene graph.
const loader = new OBJLoader()
loader.load(
'models/obj/tree.obj',
function (object) {
let scale = 1.0
object.traverse(function (child) {
console.log(child)
if (child instanceof THREE.Mesh) {
child.geometry.center()
child.geometry.computeBoundingSphere()
scale = 0.2 * child.geometry.boundingSphere.radius
child.material = new THREE.MeshPhongMaterial({
color: 0xffffff,
specular: 0x111111,
shininess: 5
})
child.castShadow = true
child.receiveShadow = true
}
})
object.scale.divideScalar(scale)
object.position.set(0, 1, 0)
obj3d.add(object)
}
)
场景中添加几个模型:
outline当鼠标移到模型时显示物体边界线条:
- 光线投射raycaster进行鼠标拾取
.intersectObject ( object : Object3D, recursive : Boolean, optionalTarget : Array ) : Array
object —— 检查与射线相交的物体。
recursive —— 若为true,则同时也会检查所有的后代。否则将只会检查对象本身。默认值为true。
检测所有在射线与物体之间,包括或不包括后代的相交部分。返回结果时,相交部分将按距离进行排序,最近的位于第一个。
该方法返回一个包含有交叉部分的数组:
[ { distance, point, face, faceIndex, object }, … ]
object —— 相交的物体
const mouse = new THREE.Vector2()
let raycaster = new THREE.Raycaster()
...
renderer.domElement.style.touchAction = 'none'
renderer.domElement.addEventListener('pointermove', function (event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
})
...
raycaster.setFromCamera(mouse, camera)
const intersects = raycaster.intersectObject(scene, true)
if (intersects.length > 0) {
const selectedObject = intersects[0].object
}
- 将鼠标指向的第一个物体使用OutLine过程处理
outline构造函数:
outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera)
composer.addPass(outlinePass)
...
raycaster.setFromCamera(mouse, camera)
const intersects = raycaster.intersectObject(scene, true)
if (intersects.length > 0) {
const selectedObject = intersects[0].object
outlinePass.selectedObjects = []
outlinePass.selectedObjects.push(selectedObject)
}
else {
outlinePass.selectedObjects = []
}
添加各种控制面板:
gui = new GUI({ width: 280 })
params = {
edgeStrength: 3.0,
edgeGlow: 0.0,
edgeThickness: 1.0,
pulsePeriod: 0,
visibleEdgeColor: '#ffffff',
hiddenEdgeColor: '#190a05'
}
gui.add(params, 'edgeStrength', 0.01, 10).onChange(function (value) {
outlinePass.edgeStrength = Number(value)
})
gui.add(params, 'edgeGlow', 0.0, 1.0).onChange(function (value) {
outlinePass.edgeGlow = Number(value)
})
gui.add(params, 'edgeThickness', 1, 4).onChange(function (value) {
outlinePass.edgeThickness = Number(value)
})
gui.add(params, 'pulsePeriod', 0, 5).onChange(function (value) {
outlinePass.pulsePeriod = Number(value)
})
gui.addColor(params, 'visibleEdgeColor').onChange(function (value) {
outlinePass.visibleEdgeColor.set(value)
})
gui.addColor(params, 'hiddenEdgeColor').onChange(function (value) {
outlinePass.hiddenEdgeColor.set(value)
})
const textureLoader = new THREE.TextureLoader()
textureLoader.load(
'textures/tri_pattern.jpg',
function (texture) {
outlinePass.patternTexture = texture
texture.wrapS = texture.wrapT = THREE.RepeatWrapping
}
)
...
gui.add(params, 'rotate')
gui.add(params, 'usePatternTexture').onChange(function (value) {
outlinePass.usePatternTexture = value
})
...
const timer = performance.now()
if (params.rotate) {
group.rotation.y = 0.001 * timer
}
添加shaderPass:
effectFXAA = new ShaderPass(FXAAShader)
effectFXAA.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight)
composer.addPass(effectFXAA)
没看出什么鸟球变化: