WebGL笔记(六)_Three.js渲染obj模型并同时渲染全景图

时间:2024-03-26 21:16:22

基本思路简述:一个模型的渲染的流程是,创建一个场景,并将模型和相机放到场景中合适的位置;然后就会呈现出一个3D模型在屏幕上。全景图的呈现其实就是在创建一个场景、相机、几何球。模型和全景同时被呈现在屏幕上就会出现模型被放在全景环境下的样子。效果图在后面。

第一步:创建一个demo.html文件将必要的js文件导入。
  • three.js:渲染模型的必要类库,去threejs官网下载即可。
  • OrbitControls.js:模型控制器,这个类库可以让模型随着鼠标进行一些交互操作,例如:随着鼠标进行旋转、伸缩等操作。
  • OBJLoader.js:用来加载.obj格式的模型文件。
  • jquery.js
  • 加入必要的代码,
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script src="three.js"></script>
    <script src="OrbitControls.js"></script>
    <script src="OBJLoader.js"></script>
    <script src="jquery.js"></script>

</head>
<body>
</body>


<script>

    //创建一个div,用来盛放渲染模型的canvas
    var width = window.innerWidth || 2;
    var height = window.innerHeight || 2;
    container = document.createElement( 'div' );
    document.body.appendChild( container );
    var info = document.createElement( 'div' );
    info.style.position = 'absolute';
    info.style.top = '30px';
    info.style.width = '100%';
    info.style.textAlign = 'center';
    container.appendChild( info );


    //帧动画事件,这个方法模型渲染是用到的必要方法,因为模型渲染的过程中是不断对canvas进行重绘。
    var requestAnimationFrame = (function () {
        return window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            function (callback) {
                window.setTimeout(callback, 1000 / 60);
            };
    })();


</script>
</html>

后面的代码是真正调用threejs的api的部分,放在demo.html文件的<script>之间的追加的位置,后面介绍的过程中,省略上面那部分的代码。

第二步:声明必要的变量。
<script>

	    var scene; //用来盛放模型的场景
	    var camera; //呈现模型的相机
	    var renderer; //渲染模型的渲染器
	    var control; //操作模型的控制器
	    var objLoader; //加载obj模型的加载器
</script>
第三步:初始化变量。
<script>

	   var scene; //用来盛放模型的场景
	    var camera; //呈现模型的相机
	    var renderer; //渲染模型的渲染器
	    var control; //操作模型的控制器
	    var objLoader; //加载obj模型的加载器

	//场景内模型渲染准备
	    function prepareRender() {
	
	        scene = new THREE.Scene();
	        camera = new THREE.PerspectiveCamera( 70, width / height, 1, 10000000000 );
	        renderer = new THREE.WebGLRenderer();

			renderer.autoClear = false;
	
		//初始化相机位置。
	        camera.position.x = 150;
	        camera.position.y = 150;
	        camera.position.z = 150;
	        renderer.setSize( width, height );
			
		//将渲染画布放到dom元素中,即前面声明的div。
	        info.appendChild(renderer.domElement);
	
		//声明控制器,传入相机和被控制的dom节点。
	        control = new THREE.OrbitControls(camera, renderer.domElement.parentNode);
	
		//控制器在控制元素时围绕的中心位置。
	        control.target=new THREE.Vector3(0,0,0);
	
		//相机的朝向
	        camera.aspect = window.innerWidth / window.innerHeight;
	    }

</script>
第四步:向场景中加载模型。
<script>

//向场景内添加obj模型
    function insertObj() {
		
	//初始化OBJLoader加载器。
        objLoader = new THREE.OBJLoader();

	//创建模型的纹理(贴图)加载器。
        var textureLoader = new THREE.TextureLoader();
        var texture = textureLoader.load( 'demo_jinyu.jpg' );

	//加载模型
        objLoader.load( 'demo02.obj',function ( object ) {

                object.traverse( function ( child ) {
					
				//将加载到的纹理给模型的材质
                    if ( child instanceof THREE.Mesh ) {
                        child.material.map = texture;
                    }

                } );

		//为了呈现更清晰。将模型放大20倍
                object.scale.set(20,20,20);

		//将模型的位置始终定位在中心点(0,0,0)
		//这一步的操作是为了配合模型控制器的效果,前面的模型控制器就是中心点就是设置在(0,0,0)位置的。
		//用户在用鼠标旋转模型时,好像在围绕着模型的中心旋转。
                var box = new THREE.Box3().setFromObject(object);
                var center = box.getCenter();//用一个Box获取到模型的当前位置。
                object.position.set(-center.x, -center.y, -center.z);//将模型移回原点。


                scene.add( object );
            },
            
           //进度回调函数
            function ( xhr ) {
                console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
            },
           // called when loading has errors
            function ( error ) {
                console.log( 'An error happened' );
            }
        );

    }
</script>
第五步:向场景中添加灯。
<script>

 //场景内添加灯
    function insertOther(){

	//环境光
        var light = new THREE.AmbientLight( 0x404040 ); // soft white light
        scene.add( light );

	//方向光
        var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
        scene.add( directionalLight );

    }
</script>
第六步:渲染
<script>

  function render() {
        renderer.render(scene, camera);
    }

    function animate() {
        control.update();
        requestAnimationFrame( animate );
        render();
    }

    function init() {
        prepareRender();//变量声明,渲染准备工作
        insertObj();//加载obj模型并加入到场景中
        insertOther();//像场景中添加光。
        animate();//动画
    }
	
//调用代码
	init();

</script>

到此为止,模型已经可以呈现出来了。
WebGL笔记(六)_Three.js渲染obj模型并同时渲染全景图

第七步:像场景添加全景图片
基本流程与模型渲染一致,直接给出代码。
<script>

  var sceneB;//放全景球的场景
    var cameraB;//呈现全景的相机
    var controlB;//控制全景的控制器

//初始化,构造全景球的函数
	function initBackgroud() {

        sceneB = new THREE.Scene();
        cameraB = new THREE.PerspectiveCamera(70, width / height, 1, 1000);

	//全景相机位置
        cameraB.position.set(0,100,0);

        controlB = new THREE.OrbitControls(cameraB, renderer.domElement.parentNode);

        controlB.enableZoom = false;

        controlB.target = new THREE.Vector3(0, 0, 0);

	//定义了一个几何体,球。
        var geometry = new THREE.SphereBufferGeometry( 500, 60, 40 );
        // invert the geometry on the x-axis so that all of the faces point inward
        geometry.scale( - 1, 1, 1 );

	//加载全景图片资源
        var texture = new THREE.TextureLoader().load("1_View02.jpg");
        texture.minFilter = THREE.LinearFilter;
        texture.format = THREE.RGBFormat;

        var material   = new THREE.MeshBasicMaterial();

        material.map = texture;

        var meshB = new THREE.Mesh( geometry, material );

        sceneB.add( meshB );

    }
</script>
第八步:修改原有的渲染代码
<script>

	function init() {
        prepareRender();
        insertObj();
        initBackgroud();//添加背景渲染的初始化代码。
        insertOther();
        animate();
    }

	function render() {
        renderer.render(sceneB,cameraB);//添加背景渲染代码。
        renderer.render(scene, camera);
    }
</script>

WebGL笔记(六)_Three.js渲染obj模型并同时渲染全景图