荐 布加迪奇龙Blender雕刻、shading,并导入Three.js ,3DWEB模型【Three.js+Blender建模+web前端+可视化】
本文主要探索blender建模、渲染、导入到three.js,并在页面呈现、交互,为下步深入应用积累经验,呈现web3D效果
第一部分:3D 建模,Shading
blender 分两个部分:建模,也就是常说的雕刻;然后是shading也就是贴图渲染。
对blender,threejs不熟悉的可先自行百度,bilibili上有很多油管上的blender优秀的教程,可以自己去对着教程操练一下,有*可以去油管官网上去找适合自己的教程(不建议从0开始,直接对着别人的教程操练,会很快),找个合适视屏的一起操练就行,我就是这么过来的。这个算是成品,雕刻,渲染的时候没有截图,主要是练习blender 的曲面,材质,镜像及各种快捷键使用。汽车在周围的环境是新建圆球,放大后把汽车移动到圆内,并给圆shading一个全景图像,
先上图:
建模完成后导出glb格式:
第二部分:在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>
本文主要是对Three.jsWeb3D+Blender建模渲染+web前端+可视化的事件和应用,为下步深入更深入的交互做经验积累
需要出视频的话,大家给我留言,可以出视频教程分享给大家的。
本文地址:https://blog.csdn.net/rexfow/article/details/107288336