欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

荐 布加迪奇龙Blender雕刻、shading,并导入Three.js ,3DWEB模型【Three.js+Blender建模+web前端+可视化】

程序员文章站 2022-03-13 18:13:48
本文主要探索blender建模渲染后导入到threejs,呈现web3D效果第一部分:3D 建模,Shading官网:blender版本2.83blender 分两个部分:建模,也就是常说的雕刻;然后是shading也就是贴图渲染。对blender,threejs不熟悉的可先自行百度,bilibili上有很多油管上的blender优秀的教程,可以自己去对着教程操练一下,有*可以去油管官网上去找适合自己的教程(不建议从0开始,直接对着别人的教程操练,会很快),找个合适视屏的一起......

 

本文主要探索blender建模、渲染、导入到three.js,并在页面呈现、交互,为下步深入应用积累经验,呈现web3D效果

 

第一部分:3D 建模,Shading

官网:blender版本2.83 

blender 分两个部分:建模,也就是常说的雕刻;然后是shading也就是贴图渲染。

对blender,threejs不熟悉的可先自行百度,bilibili上有很多油管上的blender优秀的教程,可以自己去对着教程操练一下,有*可以去油管官网上去找适合自己的教程(不建议从0开始,直接对着别人的教程操练,会很快),找个合适视屏的一起操练就行,我就是这么过来的。这个算是成品,雕刻,渲染的时候没有截图,主要是练习blender 的曲面,材质,镜像及各种快捷键使用。汽车在周围的环境是新建圆球,放大后把汽车移动到圆内,并给圆shading一个全景图像,

先上图:

荐
                                                        布加迪奇龙Blender雕刻、shading,并导入Three.js ,3DWEB模型【Three.js+Blender建模+web前端+可视化】

荐
                                                        布加迪奇龙Blender雕刻、shading,并导入Three.js ,3DWEB模型【Three.js+Blender建模+web前端+可视化】

荐
                                                        布加迪奇龙Blender雕刻、shading,并导入Three.js ,3DWEB模型【Three.js+Blender建模+web前端+可视化】荐
                                                        布加迪奇龙Blender雕刻、shading,并导入Three.js ,3DWEB模型【Three.js+Blender建模+web前端+可视化】荐
                                                        布加迪奇龙Blender雕刻、shading,并导入Three.js ,3DWEB模型【Three.js+Blender建模+web前端+可视化】荐
                                                        布加迪奇龙Blender雕刻、shading,并导入Three.js ,3DWEB模型【Three.js+Blender建模+web前端+可视化】

建模完成后导出glb格式:

荐
                                                        布加迪奇龙Blender雕刻、shading,并导入Three.js ,3DWEB模型【Three.js+Blender建模+web前端+可视化】

第二部分:在three.js页面中引入:

主要依赖:

1,threejs版本V96,

2,FirstPersonControls第一人称视角控制

3,OrbitControls轨道控制器

4,gltf导入依赖GLTFLoader_src.js,glb或者gltf文件引入到threejs

1,页面依赖:
        <script src="https://cdn.bootcss.com/jquery/2.0.0/jquery.min.js"></script>
        <script src="./libs/three-V96.js"></script>
        <script type="text/javascript" src="./assets/models/gltf-wlii/FirstPersonControls.js"></script>
        <script type="text/javascript" src="./assets/models/gltf-wlii/physi.js"></script>
       <!-- <script src="./libs/threeBSP.js"></script> -->
        <script src="./libs/OrbitControls.js"></script>
        <script src="./libs/dat.gui.min.js"></script>
        <script src="./libs/stats.min.js"></script>
        <script src="./libs/GLTFLoader_src.js"></script>

2,threejs引入Glb模型核心代码:

 function gltfLoader(){
                   var groupFloor1 = new THREE.Group(),groupFloor1Arr;
                    var groupFloor2 = new THREE.Group();
                    var groupFloor3 = new THREE.Group();
                    var groupFloor4 = new THREE.Group();
                    var stairs = new THREE.Group();
                    var baseGroup = new THREE.Group();
                    
                   let loader = new THREE.GLTFLoader();
                   
                   loader.load('./assets/models/gltf-wlii/bujiadi.glb',function (obj) {
                          var objChildren  = obj.scene.children;
                          
                          for(var i=0; i<objChildren.length;i++){
                              var floorName = objChildren[i].name;
                              addGroup(floorName)
                          }
                           
                          function addGroup(floorName){
                              var r1 = /floar1/g;
                              var r2 = /floar2/g;
                              var r3 = /floar3/g;
                              var r4 = /floar4/g;
                              var s = /stairs/g;
                              if(r1.test(floorName) !=false){
                                  groupFloor1.children.push(objChildren[i]);
                              }else if(r2.test(floorName) !=false){
                                  groupFloor2.children.push(objChildren[i]);
                              }else if(r3.test(floorName) !=false){
                                  groupFloor3.children.push(objChildren[i]);
                              }else if(r4.test(floorName) !=false){
                                  groupFloor4.children.push(objChildren[i]);
                              }else if(s.test(floorName) !=false){
                                  stairs.children.push(objChildren[i]);
                              }else{
                                  baseGroup.children.push(objChildren[i]);
                              }
                          }
                          
                          this.scene.add(groupFloor1);
                          this.scene.add(groupFloor2);
                          this.scene.add(groupFloor3);
                          this.scene.add(groupFloor4);
                           this.scene.add(baseGroup);
                          
                          this.scene.add(stairs);
                          console.log(scene)
                       document.getElementById('loading').style.display = 'none';
                   },function (xhr) {
                       console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );    
                   },function (error) {
                       console.log('load error!'+error.getWebGLErrorMessage());
                   })
               }

3,页面代码全:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
        <script src="https://cdn.bootcss.com/jquery/2.0.0/jquery.min.js"></script>
        <script src="./libs/three-V96.js"></script>
        <script type="text/javascript" src="./assets/models/gltf-wlii/FirstPersonControls.js"></script>
        <script type="text/javascript" src="./assets/models/gltf-wlii/physi.js"></script>
       <!-- <script src="./libs/threeBSP.js"></script> -->
        <script src="./libs/OrbitControls.js"></script>
        <script src="./libs/dat.gui.min.js"></script>
        <script src="./libs/stats.min.js"></script>
        <script src="./libs/GLTFLoader_src.js"></script>
            
<!--       <script src="./libs/RGBELoader.js"></script>
        <script src="./libs/PMREMGenerator.js"></script> -->
        
        <style>
            body {
                /* set margin to 0 and overflow to hidden, to go fullscreen */
                margin: 0;
                overflow: hidden;
            }
            #left-bar{ width: 200px; height: 100vh; position: absolute; left: 0; top: 0; z-index: 1; background: rgba(0,0,0,0.1);}
        </style>
    </head>
    <body>
        <div id="container"></div>
       <script>
               var stats = initStats();
               var scene, camera, renderer, controls, light, composer,camControls;
               var group = new THREE.Group();
               var clock = new THREE.Clock();
               // 初始化场景
               function initScene() {
                   scene = new THREE.Scene();
               }
               // 初始化相机
               function initCamera() {
                   camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100);
                   camera.position.set(5, 5,5);
                   camera.lookAt(new THREE.Vector3(0, 0, 0));
                   
                   camControls = new THREE.FirstPersonControls(camera);
                   camControls.lookSpeed = 0.1;
                   camControls.movementSpeed = 20;
                   camControls.noFly = true;
                   camControls.lookVertical = true;
                   camControls.constrainVertical = true;
                   camControls.verticalMin = 1.0;
                   camControls.verticalMax = 2.0;
                   camControls.lon = 0;
                   camControls.lat = 0;
               }
               // 初始化灯光
               function initLight() {
                   var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.7 );//模拟远处类似太阳的光源
                   directionalLight.color.setHSL( 0.1, 1, 0.95 );
                   directionalLight.position.set( 0, 200, 0).normalize();
                   scene.add( directionalLight );
       
                   var ambient = new THREE.AmbientLight( 0xffffff, 1 ); //AmbientLight,影响整个场景的光源
                   ambient.position.set(0,0,0);
                   scene.add( ambient );
                   
                   var light = new THREE.DirectionalLight( 0xdfebff, 1);
                   light.position.set( 50, 200, 100 );
                   light.position.multiplyScalar( 1.3 );
                   
                   light.castShadow = true;
                   
                   light.shadow.mapSize.width = 1024;
                   light.shadow.mapSize.height = 1024;
                   
                   var d = 300;
                   
                   light.shadow.camera.left = - d;
                   light.shadow.camera.right = d;
                   light.shadow.camera.top = d;
                   light.shadow.camera.bottom = - d;
                   
                   light.shadow.camera.far = 1000;
                   scene.add( light );
               }
               // 初始化性能插件
               function initStats() {
                   var stats = new Stats();
       
                   stats.domElement.style.position = 'absolute';
                   stats.domElement.style.left = '1px';
                   stats.domElement.style.top = '1px';
       
                   document.body.appendChild(stats.domElement);
                   return stats;
               }
               // 初始化渲染器
               function initRenderer() {
                   renderer = new THREE.WebGLRenderer({antialias: true});
                   renderer.setSize(window.innerWidth, window.innerHeight);
                   renderer.setClearColor(0x000000,1.0);
                   document.body.appendChild(renderer.domElement);
               }
             
               // 初始化轨迹球控件
               function initControls() {
                    controls = new THREE.OrbitControls( camera, renderer.domElement );
                    controls.enableDamping = true;
                    controls.dampingFactor = 0.5;
                   controls.minDistance = 10;
                   controls.maxDistance = 150;
                   controls.maxPolarAngle = Math.PI/2.2;
               }
               
               //GLTF-GLTFLoader_src
               function gltfLoader(){
                   var groupFloor1 = new THREE.Group(),groupFloor1Arr;
                    var groupFloor2 = new THREE.Group();
                    var groupFloor3 = new THREE.Group();
                    var groupFloor4 = new THREE.Group();
                    var stairs = new THREE.Group();
                    var baseGroup = new THREE.Group();
                    
                   let loader = new THREE.GLTFLoader();
                   
                   loader.load('./assets/models/gltf-wlii/bujiadi.glb',function (obj) {
                          var objChildren  = obj.scene.children;
                          
                          for(var i=0; i<objChildren.length;i++){
                              var floorName = objChildren[i].name;
                              addGroup(floorName)
                          }
                           
                          function addGroup(floorName){
                              var r1 = /floar1/g;
                              var r2 = /floar2/g;
                              var r3 = /floar3/g;
                              var r4 = /floar4/g;
                              var s = /stairs/g;
                              if(r1.test(floorName) !=false){
                                  groupFloor1.children.push(objChildren[i]);
                              }else if(r2.test(floorName) !=false){
                                  groupFloor2.children.push(objChildren[i]);
                              }else if(r3.test(floorName) !=false){
                                  groupFloor3.children.push(objChildren[i]);
                              }else if(r4.test(floorName) !=false){
                                  groupFloor4.children.push(objChildren[i]);
                              }else if(s.test(floorName) !=false){
                                  stairs.children.push(objChildren[i]);
                              }else{
                                  baseGroup.children.push(objChildren[i]);
                              }
                          }
                          
                          this.scene.add(groupFloor1);
                          this.scene.add(groupFloor2);
                          this.scene.add(groupFloor3);
                          this.scene.add(groupFloor4);
                           this.scene.add(baseGroup);
                          
                          this.scene.add(stairs);
                          console.log(scene)
                       document.getElementById('loading').style.display = 'none';
                   },function (xhr) {
                       console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );    
                   },function (error) {
                       console.log('load error!'+error.getWebGLErrorMessage());
                   })
               }
               
               // 更新控件
               function update() {
                   stats.update();
               }

           // 初始化
           function init() {
               initScene();
               initCamera();
               initRenderer();
               initLight();
                initControls();//干扰第一人称视角
               gltfLoader();
               console.log(scene)
           }

           //声明raycaster和mouse变量
           var raycaster = new THREE.Raycaster();
           var mouse = new THREE.Vector2(), INTERSECTED;
           function onMouseClick( event ) {
               mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
               mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
               raycaster.setFromCamera( mouse, camera );
               //var intersects = raycaster.intersectObjects(child);
               var intersects = raycaster.intersectObjects( scene.children,true);
                if ( intersects.length >0){
                    if ( INTERSECTED != intersects[ 0 ].object ) {
                            if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
                            INTERSECTED = intersects[ 0 ].object;
                            if(INTERSECTED.name != '平面'){
                                INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
                                INTERSECTED.material.emissive.setHex( 0xff0000 );
                            }
                    }
                } else {
                    if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
                    INTERSECTED = null;
                }
           }
           document.addEventListener( 'click', onMouseClick, false );
           
               // 窗口变动触发的方法
               function onWindowResize() {
                   camera.aspect = window.innerWidth / window.innerHeight;
                   camera.updateProjectionMatrix();
                   renderer.setSize(window.innerWidth, window.innerHeight);
               }
        
               function animate() {
                //camControls.update(clock.getDelta());
                   
                   requestAnimationFrame(animate);
                   renderer.render(scene, camera);
                   update();
               }
               init();
               animate();
           </script>
       </body>
</html>

荐
                                                        布加迪奇龙Blender雕刻、shading,并导入Three.js ,3DWEB模型【Three.js+Blender建模+web前端+可视化】

本文主要是对Three.jsWeb3D+Blender建模渲染+web前端+可视化的事件和应用,为下步深入更深入的交互做经验积累

需要出视频的话,大家给我留言,可以出视频教程分享给大家的。

本文地址:https://blog.csdn.net/rexfow/article/details/107288336