threeJs版本为0.145.0
<template>
<div>
<div id="threeContained_5_1"></div>
</div>
</template>
<script>
// 参考示例: D:\tyler\learning\threejs\three.js-dev\examples\webgl_materials_subsurface_scattering.html
import * as THREE from 'three' // 引入Threejs
import Stats from 'three/examples/jsm/libs/stats.module.js'
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { SubsurfaceScatteringShader } from 'three/examples/jsm/shaders/SubsurfaceScatteringShader.js'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'
export default {
name: 'ThreeDExample5',
data () {
return {
showType: 1,
threeJs: {
container: '',
stats: '',
camera: '',
scene: '',
renderer: '',
model: ''
}
}
},
mounted () {
this.init()
this.animate()
},
methods: {
changeShow (type) {
this.showType = type
},
init () {
this.threeJs.camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 5000)
this.threeJs.camera.position.set(0.0, 300, 400 * 4)
this.threeJs.scene = new THREE.Scene()
// Lights
this.threeJs.scene.add(new THREE.AmbientLight(0x888888))
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.03)
directionalLight.position.set(0.0, 0.5, 0.5).normalize()
this.threeJs.scene.add(directionalLight)
const pointLight1 = new THREE.Mesh(new THREE.SphereGeometry(4, 8, 8), new THREE.MeshBasicMaterial({ color: 0x888888 }))
pointLight1.add(new THREE.PointLight(0x888888, 7.0, 300))
this.threeJs.scene.add(pointLight1)
pointLight1.position.x = 0
pointLight1.position.y = -50
pointLight1.position.z = 350
const pointLight2 = new THREE.Mesh(new THREE.SphereGeometry(4, 8, 8), new THREE.MeshBasicMaterial({ color: 0x888800 }))
pointLight2.add(new THREE.PointLight(0x888800, 1.0, 500))
this.threeJs.scene.add(pointLight2)
pointLight2.position.x = -100
pointLight2.position.y = 20
pointLight2.position.z = -260
this.threeJs.renderer = new THREE.WebGLRenderer({ antialias: true })
this.threeJs.renderer.setPixelRatio(window.devicePixelRatio)
this.threeJs.renderer.setSize(window.innerWidth, window.innerHeight)
this.threeJs.container = document.getElementById('threeContained_5_1')
this.threeJs.container.appendChild(this.threeJs.renderer.domElement)
this.threeJs.renderer.outputEncoding = THREE.sRGBEncoding
//
this.threeJs.stats = new Stats()
this.threeJs.container.appendChild(this.threeJs.stats.dom)
const controls = new OrbitControls(this.threeJs.camera, this.threeJs.container)
controls.minDistance = 500
controls.maxDistance = 3000
window.addEventListener('resize', this.onWindowResize)
this.initMaterial()
},
initMaterial () {
const that = this
const loader = new THREE.TextureLoader()
const imgTexture = loader.load('http://localhost:3002/public/getFile?filename=white.jpg')
const thicknessTexture = loader.load('http://localhost:3002/public/getFile?filename=bunny_thickness.png') // default.png bunny_thickness.jpg guge.png
imgTexture.wrapS = imgTexture.wrapT = THREE.RepeatWrapping
const shader = SubsurfaceScatteringShader
const uniforms = THREE.UniformsUtils.clone(shader.uniforms)
console.log('uniforms', uniforms)
uniforms.map.value = imgTexture
uniforms.diffuse.value = new THREE.Vector3(1.0, 0.2, 0.2)
uniforms.shininess.value = 500
uniforms.thicknessMap.value = thicknessTexture
uniforms.thicknessColor.value = new THREE.Vector3(0.5, 0.3, 0.0)
uniforms.thicknessDistortion.value = 0.1
uniforms.thicknessAmbient.value = 0.4
uniforms.thicknessAttenuation.value = 0.8
uniforms.thicknessPower.value = 2.0
uniforms.thicknessScale.value = 16.0
const material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader,
lights: true
})
material.extensions.derivatives = true
// LOADER guge.fbx stanford-bunny.fbx
const loaderFBX = new FBXLoader()
loaderFBX.load('http://localhost:3002/public/getFile?filename=stanford-bunny.fbx', function (object) {
that.threeJs.model = object.children[0]
that.threeJs.model.position.set(0, 0, 10)
that.threeJs.model.scale.setScalar(1)
that.threeJs.model.material = material
that.threeJs.scene.add(that.threeJs.model)
})
that.initGUI(uniforms)
},
initGUI (uniforms) {
const gui = new GUI({ title: 'Thickness Control' })
const ThicknessControls = function () {
this.distortion = uniforms.thicknessDistortion.value
this.ambient = uniforms.thicknessAmbient.value
this.attenuation = uniforms.thicknessAttenuation.value
this.power = uniforms.thicknessPower.value
this.scale = uniforms.thicknessScale.value
}
const thicknessControls = new ThicknessControls()
gui.add(thicknessControls, 'distortion').min(0.01).max(1).step(0.01).onChange(function () {
uniforms.thicknessDistortion.value = thicknessControls.distortion
console.log('distortion')
})
gui.add(thicknessControls, 'ambient').min(0.01).max(5.0).step(0.05).onChange(function () {
uniforms.thicknessAmbient.value = thicknessControls.ambient
})
gui.add(thicknessControls, 'attenuation').min(0.01).max(5.0).step(0.05).onChange(function () {
uniforms.thicknessAttenuation.value = thicknessControls.attenuation
})
gui.add(thicknessControls, 'power').min(0.01).max(16.0).step(0.1).onChange(function () {
uniforms.thicknessPower.value = thicknessControls.power
})
gui.add(thicknessControls, 'scale').min(0.01).max(50.0).step(0.1).onChange(function () {
uniforms.thicknessScale.value = thicknessControls.scale
})
},
onWindowResize () {
this.threeJs.camera.aspect = window.innerWidth / window.innerHeight
this.threeJs.camera.updateProjectionMatrix()
this.threeJs.renderer.setSize(window.innerWidth, window.innerHeight)
},
animate () {
requestAnimationFrame(this.animate)
this.render()
this.threeJs.stats.update()
},
render () {
if (this.threeJs.model) {
this.threeJs.model.rotation.y = performance.now() / 5000
}
this.threeJs.renderer.render(this.threeJs.scene, this.threeJs.camera)
}
}
}
</script>
<style scoped>
</style>