天天看點

threejs讓錄影機動起來

在webGL中文網學習threejs基礎篇——讓物體動起來中的第一個demo,入門到思考的路程(項目由vue編寫)

一、初入——直接使用課程中的例子

<template>
    <div id='demo3' class='demo'></div>
</template>
<script>
import * as THREE from 'three'
export default {
    data() {
        return {
            renderer:null,
            camera:null,
            scene:null,
            light:null,
            cube:null,
            width:0,
            heigh:0,
            r:800
        }
    },
    methods: {
        initThree(){
            this.width=document.getElementById('demo3').clientWidth
            this.height=document.getElementById('demo3').clientHeight
            this.renderer=new THREE.WebGLRenderer({
                antialias:true
            })
            this.renderer.setSize(this.width,this.height)
            document.getElementById('demo3').appendChild(this.renderer.domElement)
            this.renderer.setClearColor(0xf5f5f5,1.0)
        },
        initCamera(){
            this.camera=new THREE.PerspectiveCamera(45,this.width/this.height,1,10000)
            this.camera.position.x=this.r
            this.camera.position.y=0
            this.camera.position.z=0
            this.camera.up.x=0
            this.camera.up.y=1
            this.camera.up.z=0
            this.camera.lookAt(0,0,0)
        },
        initScene(){
            this.scene=new THREE.Scene()
        },
        initLight(){
            this.light=new THREE.AmbientLight(0xffffff)
            this.light.position.set(100,100,200)
            this.scene.add(this.light)
            this.light=new THREE.PointLight(0x00ff00)
            this.light.position.set(0,0,300)
            this.scene.add(this.light)
        },
        initObject(){
            let geometry=new THREE.CylinderGeometry(100,150,400)
            let material=new THREE.MeshLambertMaterial({color:0x00f600})
            let mesh=new THREE.Mesh(geometry,material)
            //mesh.position=new THREE.Vector3( 0, 1, 0 );
            mesh.position.x=0
            mesh.position.y=0
            mesh.position.z=0
            this.scene.add(mesh)
            
        },
        animations(){
            this.camera.position.x=this.camera.position.z+1
            this.renderer.render(this.scene,this.camera)
            requestAnimationFrame(this.animations)
        },
        threeStart(){
            this.initThree()
            this.initCamera()
            this.initScene()
            this.initLight()
            this.initObject()
            this.animations()
        }
    },
    mounted() {
        this.threeStart()
    },
}
</script>
           

我們現在結合圖檔來看下

threejs讓錄影機動起來

(ps:錄影機位置是800,0)

這個demo實作物體運動是讓錄影機運動沿着y軸運動,以此達到物體看起運動的效果。再次我就産生了一個想法,我能不能讓錄影機盯着物體做圓周運動,然後讓我們進入第二節

二、提升——錄影機做圓周運動

因為錄影機y軸不改變(即高度沒改變),是以就是簡單的二維幾何問題,廢話不多說,直接代碼

<template>
    <div id='demo3' class='demo'></div>
</template>
<script>
import * as THREE from 'three'
export default {
    data() {
        return {
            renderer:null,
            camera:null,
            scene:null,
            light:null,
            cube:null,
            width:0,
            heigh:0,
            r:800,
            angle:0
        }
    },
    methods: {
        initThree(){
            this.width=document.getElementById('demo3').clientWidth
            this.height=document.getElementById('demo3').clientHeight
            this.renderer=new THREE.WebGLRenderer({
                antialias:true
            })
            this.renderer.setSize(this.width,this.height)
            document.getElementById('demo3').appendChild(this.renderer.domElement)
            this.renderer.setClearColor(0xf5f5f5,1.0)
        },
        initCamera(){
            this.camera=new THREE.PerspectiveCamera(45,this.width/this.height,1,10000)
            this.camera.position.x=this.r
            this.camera.position.y=0
            this.camera.position.z=0
            this.camera.up.x=0
            this.camera.up.y=1
            this.camera.up.z=0
            this.camera.lookAt(0,0,0)
        },
        initScene(){
            this.scene=new THREE.Scene()
        },
        initLight(){
            this.light=new THREE.AmbientLight(0xffffff)
            this.light.position.set(100,100,200)
            this.scene.add(this.light)
            this.light=new THREE.PointLight(0x00ff00)
            this.light.position.set(0,0,300)
            this.scene.add(this.light)
        },
        initObject(){
            let geometry=new THREE.CylinderGeometry(100,150,400)
            let material=new THREE.MeshLambertMaterial({color:0x00f600})
            //mesh.position=new THREE.Vector3( 0, 1, 0 );
            mesh.position.x=0
            mesh.position.y=0
            mesh.position.z=0
            this.scene.add(mesh)
            
        },
        animations(){
            this.angle++
            this.camera.position.x=this.r*Math.cos(this.angle*Math.PI/180)
            this.camera.position.z=this.r*Math.sin(this.angle*Math.PI/180)
            this.renderer.render(this.scene,this.camera)
            requestAnimationFrame(this.animations)
        },
        threeStart(){
            this.initThree()
            this.initCamera()
            this.initScene()
            this.initLight()
            this.initObject()
            this.animations()
        }
    },
    mounted() {
        this.threeStart()
    },
}
</script>
           

但是實際情況似乎和我預想似乎不大一樣啊,怎麼回事,為什麼隻有一小段時間有看得見物體。經過一番思考,我覺定多添加幾個物體進行參考

initObject(){
            let geometry=new THREE.CylinderGeometry(100,150,400)
            let material=new THREE.MeshLambertMaterial({color:0x00f600})
            let pos=[[0,0,0],[-800,0,-800],[-800,1,800],[-1600,0,0]]
            for(var i=0;i<4;i++){
            let mesh=new THREE.Mesh(geometry,material)
            //mesh.position=new THREE.Vector3( 0, 1, 0 );
            mesh.position.x=pos[i][0]
            mesh.position.y=pos[i][1]
            mesh.position.z=pos[i][2]
            this.scene.add(mesh)
            }
        },
           

于是我增加了三個物體作為參照物,于是我确定了,原來是鏡頭沒有改變(參考圖)

threejs讓錄影機動起來

但我了解的是

this.camera.lookAt(0,0,0)

讓攝像頭看着原點啊,當我一籌莫展時,直覺驅使我增加了一行代碼

animations(){
            this.angle++
            this.camera.position.x=this.r*Math.cos(this.angle*Math.PI/180)
            this.camera.position.z=this.r*Math.sin(this.angle*Math.PI/180)
            //每幀都重新設定lookAt可以達到錄影機圍繞物體旋轉
            //this.camera.lookAt(0,0,0)
            this.renderer.render(this.scene,this.camera)
            requestAnimationFrame(this.animations)
        },
           

運作後我豁然開朗,修改位置後我需要重新制定攝像中心點,來調整偏轉角

繼續閱讀