ThreeJS 官方案例学习(webgl_framebuffer_texture)
1.效果图
2.源码
< template>
< div>
< div id= "container" >
< / div>
< div id= "selection" >
< div> < / div>
< / div>
< / div>
< / template>
< script>
import * as THREE from 'three' ;
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' ;
import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment.js' ;
import Stats from 'three/examples/jsm/libs/stats.module.js' ;
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js' ;
import gsap from 'gsap' ;
import * as GeometryUtils from 'three/examples/jsm/utils/GeometryUtils.js' ;
const dpr = window. devicePixelRatio;
const textureSize = 128 * dpr;
export default {
data ( ) {
return {
container : null ,
scene : null ,
camera : null ,
renderer : null ,
controller : null ,
stats : null ,
mixer : null ,
clock : new THREE. Clock ( ) ,
vector : new THREE. Vector2 ( ) ,
color : new THREE. Color ( ) ,
offset : 0 ,
line : null ,
sprite : null ,
texture : null ,
cameraOrtho : null ,
sceneOrtho : null ,
} ;
} ,
mounted ( ) {
this . init ( )
this . animate ( )
window. addEventListener ( "resize" , this . onWindowSize)
} ,
beforeUnmount ( ) {
console. log ( 'beforeUnmount===============' ) ;
this . container = null
this . scene = null
this . camera = null
this . renderer = null
this . controller = null
this . stats = null
this . mixer = null
this . model = null
} ,
methods : {
init ( ) {
this . container = document. getElementById ( 'container' )
this . setScene ( )
this . setCamera ( )
this . setRenderer ( )
this . addHelper ( )
this . setController ( )
this . setPMREMGenerator ( )
this . setLight ( )
this . setGltfLoader ( )
} ,
setScene ( ) {
this . scene = new THREE. Scene ( )
this . sceneOrtho = new THREE. Scene ( ) ;
} ,
setCamera ( ) {
this . camera = new THREE. PerspectiveCamera ( 70 , this . container. clientWidth / this . container. clientHeight, 1 , 1000 )
this . camera. position. set ( 0 , 0 , 20 )
this . camera. aspect = this . container. clientWidth / this . container. clientHeight;
this . camera. updateProjectionMatrix ( ) ;
this . camera. lookAt ( new THREE. Vector3 ( 0 , 0 , 0 ) )
this . scene. add ( this . camera)
this . cameraOrtho = new THREE. OrthographicCamera ( - this . container. clientWidth / 2 , this . container. clientWidth / 2 , this . container. clientHeight / 2 , - this . container. clientHeight / 2 , 1 , 10 ) ;
this . cameraOrtho. position. z = 10 ;
} ,
setRenderer ( ) {
this . renderer = new THREE. WebGLRenderer ( {
antialias : true ,
logarithmicDepthBuffer : true ,
} )
this . renderer. setSize ( this . container. clientWidth, this . container. clientHeight) ;
this . renderer. autoClear = false ;
this . container. appendChild ( this . renderer. domElement) ;
} ,
setController ( ) {
this . controller = new OrbitControls ( this . camera, document. getElementById ( 'selection' ) ) ;
this . controller. enablePan = false ;
this . controller. enableDamping = true ;
this . controller. dampingFactor = 0.04 ;
} ,
addHelper ( ) {
let helper = new THREE. CameraHelper ( this . camera) ;
let axisHelper = new THREE. AxesHelper ( 150 ) ;
this . scene. add ( axisHelper)
let gridHelper = new THREE. GridHelper ( 100 , 30 , 0x2C2C2C , 0x888888 ) ;
} ,
setPMREMGenerator ( ) {
const pmremGenerator = new THREE. PMREMGenerator ( this . renderer) ;
this . scene. environment = pmremGenerator. fromScene ( new RoomEnvironment ( this . renderer) , 0.04 ) . texture;
} ,
setLight ( ) {
const ambientLight = new THREE. AmbientLight ( 0x404040 , 4 ) ;
const directionalLight = new THREE. DirectionalLight ( 0xffffff , 100 ) ;
const test = new THREE. PointLight ( "#ffffff" , 10 , 2 ) ;
const testHelperMap = new THREE. PointLightHelper ( test) ;
} ,
addStatus ( ) {
this . stats = new Stats ( ) ;
this . container. appendChild ( this . stats. dom) ;
} ,
setGltfLoader ( ) {
const points = GeometryUtils. gosper ( 8 )
const geometry = new THREE. BufferGeometry ( )
const positionAttribute = new THREE. Float32BufferAttribute ( points, 3 )
geometry. setAttribute ( 'position' , positionAttribute)
geometry. center ( )
const colorAttribute = new THREE. BufferAttribute ( new Float32Array ( positionAttribute. array. length) , 3 )
colorAttribute. setUsage ( THREE . DynamicDrawUsage) ;
geometry. setAttribute ( 'color' , colorAttribute) ;
const material = new THREE. LineBasicMaterial ( { vertexColors : true } ) ;
this . line = new THREE. Line ( geometry, material)
this . line. scale. setScalar ( 0.05 )
this . scene. add ( this . line)
this . texture = new THREE. FramebufferTexture ( textureSize, textureSize) ;
const spriteMaterial = new THREE. SpriteMaterial ( { map : this . texture } ) ;
this . sprite = new THREE. Sprite ( spriteMaterial) ;
this . sprite. scale. set ( textureSize, textureSize, 1 ) ;
this . sceneOrtho. add ( this . sprite)
this . updateSpritePosition ( )
this . updateColors ( colorAttribute) ;
} ,
updateSpritePosition ( ) {
const halfWidth = this . container. clientWidth / 2 ;
const halfHeight = this . container. clientHeight / 2 ;
const halfImageWidth = textureSize / 2 ;
const halfImageHeight = textureSize / 2 ;
this . sprite. position. set ( - halfWidth + halfImageWidth, halfHeight - halfImageHeight, 1 ) ;
} ,
updateColors ( colorAttribute ) {
const l = colorAttribute. count;
for ( let i = 0 ; i < l; i++ ) {
const h = ( ( this . offset + i) % l) / l;
this . color. setHSL ( h, 1 , 0.5 ) ;
colorAttribute. setX ( i, this . color. r) ;
colorAttribute. setY ( i, this . color. g) ;
colorAttribute. setZ ( i, this . color. b) ;
}
colorAttribute. needsUpdate = true ;
this . offset -= 10 ;
} ,
onWindowSize ( ) {
this . camera. aspect = this . container. clientWidth / this . container. clientHeight;
this . camera. updateProjectionMatrix ( ) ;
this . renderer. setSize ( this . container. clientWidth, this . container. clientHeight) ;
this . renderer. setPixelRatio ( window. devicePixelRatio)
const width = this . container. clientWidth;
const height = this . container. clientHeight;
this . cameraOrtho. left = - width / 2 ;
this . cameraOrtho. right = width / 2 ;
this . cameraOrtho. top = height / 2 ;
this . cameraOrtho. bottom = - height / 2 ;
this . cameraOrtho. updateProjectionMatrix ( ) ;
this . updateSpritePosition ( )
} ,
animate ( ) {
requestAnimationFrame ( this . animate) ;
this . controller. update ( ) ;
const colorAttribute = this . line. geometry. getAttribute ( 'color' ) ;
this . updateColors ( colorAttribute) ;
this . renderer. clear ( ) ;
this . renderer. render ( this . scene, this . camera) ;
this . vector. x = ( this . container. clientWidth * dpr / 2 ) - ( textureSize / 2 ) ;
this . vector. y = ( this . container. clientHeight * dpr / 2 ) - ( textureSize / 2 ) ;
this . renderer. copyFramebufferToTexture ( this . vector, this . texture) ;
this . renderer. clearDepth ( ) ;
this . renderer. render ( this . sceneOrtho, this . cameraOrtho) ;
} ,
} ,
} ;
< / script>
< style>
#container {
position : absolute;
width : 100 % ;
height : 100 % ;
}
#selection {
position : fixed;
display : flex;
flex- direction: column;
justify- content: center;
align- items: center;
height : 100 % ;
width : 100 % ;
top : 0 ;
z- index: 999 ;
}
#selection> div {
height : 128px;
width : 128px;
border : 1px solid white;
}
< / style>
r {
position : absolute;
width : 100 % ;
height : 100 % ;
}
#selection {
position : fixed;
display : flex;
flex- direction: column;
justify- content: center;
align- items: center;
height : 100 % ;
width : 100 % ;
top : 0 ;
z- index: 999 ;
}
#selection> div {
height : 128px;
width : 128px;
border : 1px solid white;
}
< / style>