three.js实现一个汽车3D实景(颜色交互)

news/2025/2/1 13:05:12/

问题来源:
    和导师交流后决定以这个来做毕业设计,于是就开始了three.js的学习,经过半个多月的基础学习,终于入门,下面来看看成果。

代码演示:
html部分

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>3D(颜色交互)</title><script src="js/jquery-3.3.1.min.js"></script><script src="three.js/build/three.js"></script><script src="js/OrbitControls.js"></script><script src="three.js/examples/js/loaders/GLTFLoader.js"></script>
</head>
<body>
<div id="contorl"><input class="color" type="color">
</div>
<script src="js/model.js"></script>
</body>
</html>

model.css

body {margin: 0 ;padding: 0 ;overflow: hidden; /* 溢出隐藏 */
}
#contorl{position: absolute;width: 15%;height: 20%;right: 20px;top: 20px;background-color: white;
}
.select{font-family: "微软雅黑";background: rgba(0,0,0,0);width: 70%;height: 30%;font-size: 12px;color: black;text-align: center;border: 1px #1a1a1a solid;border-radius: 5px;
}
.select > option{color: black;background: #fff;line-height: 20px;
}
.select:focus{border: 2px #0000ff solid;box-shadow: 0 0 15px 1px #DDDDDD;
}
.select > option:hover{background: #EBCCD1;
}
.color{border: none;outline: none;
}
::-webkit-color-swatch-wrapper{background-color:#ffffff;}
::-webkit-color-swatch{position: relative;}

model.js(此处才是重点)

 let scene, camera, renderer, controls, guiControls;// let stats = initStats();/* 场景 */function initScene() {scene = new THREE.Scene();var skySphereGeometry = new THREE.SphereGeometry( 500, 30, 100 );var texture = new THREE.TextureLoader().load("images/timg.jpg");var skySphereMaterial = new THREE.MeshBasicMaterial( { map:texture, side: THREE.DoubleSide } );var skySphere = new THREE.Mesh( skySphereGeometry, skySphereMaterial );scene.add(skySphere);}/* 相机 */function initCamera() {camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);camera.position.set(70, 50, 100);camera.lookAt(new THREE.Vector3(0, 0, 0));}/* 渲染器 */function initRender() {renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(window.innerWidth, window.innerHeight);renderer.setClearColor(0xffffff);renderer.shadowMap.enabled = true;document.body.appendChild(renderer.domElement);}/* 灯光 */function initLight() {// var axes = new THREE.AxesHelper(20);// scene.add(axes);var planeGeometry = new THREE.PlaneGeometry(200,200,100,1);var texture = new THREE.TextureLoader().load("images/5.png");var planeMaterial = new THREE.MeshLambertMaterial({map:texture});var plane = new THREE.Mesh(planeGeometry, planeMaterial);// plane.rotation.x = -0.5*Math.PI;// plane.name ='plane';// plane.position.set(0,0,0);// plane.receiveShadow = true;// scene.add(plane);var ambiColor = "#ffffff";var ambientLight = new THREE.AmbientLight(ambiColor);//设置颜色scene.add(ambientLight);var pointColor = "#ffffff";var directionalLight = new THREE.DirectionalLight(pointColor);directionalLight.position.set(-50, 60, 200);directionalLight.castShadow = true;directionalLight.shadow.camera.near = 20;directionalLight.shadow.camera.far = 200;directionalLight.shadow.camera.left = -50;directionalLight.shadow.camera.right = 50;directionalLight.shadow.camera.top = 50;directionalLight.shadow.camera.bottom = -50;directionalLight.distance = 0;directionalLight.intensity = 5;directionalLight.shadow.mapSize.height = 1024;directionalLight.shadow.mapSize.width = 1024;scene.add(directionalLight);}/* 控制器 */function initControls() {controls = new THREE.OrbitControls(camera, renderer.domElement);// 如果使用animate方法时,将此函数删除//controls.addEventListener( 'change', render );// 使动画循环使用时阻尼或自转 意思是否有惯性controls.enableDamping = true;//动态阻尼系数 就是鼠标拖拽旋转灵敏度controls.dampingFactor = 0.95;//是否可以缩放controls.enableZoom = true;//是否自动旋转// controls.autoRotate = true;//设置相机距离原点的最远距离controls.minDistance = 70;//设置相机距离原点的最远距离controls.maxDistance = 250;//是否开启右键拖拽controls.enablePan = false;//设置聚焦坐标// controls.target = new THREE.Vector3()}/* 调试插件 */function initGui() {guiControls = new function () {this.rotationSpeed = 0;};}/* 场景中的内容 */function initContent() {// 加载 glTF 格式的模型let loader = new THREE.GLTFLoader();/*实例化加载器*/loader.load('./example/11/scene.gltf',function (obj) {obj.scene.name = 'zp';var car = obj.scene;console.log(car.children[0].children[0].children[0].children[0]);scene.add(car);},function (xhr) {console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );},function (error) {console.log(error)// console.log('load error!'+error.getWebGLErrorMessage());})}/* 性能插件 */function initStats() {let stats = new Stats();document.body.appendChild(stats.domElement);return stats;}/* 窗口变动触发 */function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);}/* 数据更新 */function update() {// stats.update();}/* 初始化 */function init() {initScene();initCamera();initRender();initLight();initControls();initContent();initGui();/* 监听事件 */window.addEventListener('resize', onWindowResize, false);}/* 循环渲染 */function animate() {requestAnimationFrame(animate);renderer.render(scene, camera);update();}/* 初始加载 */(function () {console.log("three init start...");init();animate();console.log("three init send...");})();window.onload = function() {var color = document.getElementsByClassName('color')[0];color.onchange = function(e){var change_thing = scene.getObjectByName('confirm');colors = change_thing.material.color;var hex = document.getElementsByClassName('color')[0].value;var c = hex_rgb(hex);colors.r = c[0];colors.g = c[1];colors.b = c[2];};function hex_rgb(hex){var r = parseInt(hex[1]+ hex[2],16)/255;var g = parseInt(hex[3]+ hex[4],16)/255;var b = parseInt(hex[5]+ hex[6],16)/255;return [r, g, b];}function get_hex(x){var e = parseInt(x*255).toString(16);var z = e;if (e === 0){z = '00';}if (e.length === 1){z = '0'+ e;}return z;}function rgb_hex(r, g, b){var result = '#'+ get_hex(r) + get_hex(g) + get_hex(b);return result;}var raycaster = new THREE.Raycaster();var	mouse = new THREE.Vector3();var canvas = document.getElementsByTagName('canvas')[0];canvas.addEventListener('click', onDocumentMouseClick, false);function onDocumentMouseClick(event) {event.preventDefault();//将鼠标点击位置的屏幕坐标转成threejs中的标准坐标,具体解释见代码释义mouse.x = (event.clientX / window.innerWidth) * 2 - 1;mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;//新建一个三维单位向量 假设z方向就是0.5//根据照相机,把这个向量转换到视点坐标系var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5).unproject(camera);//在视点坐标系中形成射线,射线的起点向量是照相机, 射线的方向向量是照相机到点击的点,这个向量应该归一标准化。var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());//     //射线和模型求交,选中一系列直线var intersects = raycaster.intersectObjects(scene.children[3].children[0].children[0].children[0].children[0].children)[0].object;var car = scene.getObjectByName('zp').children[0].children[0].children[0].children[0].children;for(var i = 0 ;i < car.length; i++){car[i].name = '';}new_color = intersects.material.color;color.value = rgb_hex(new_color.r, new_color.g, new_color.b);intersects.name = 'confirm';}}

网页显示:
[外链图片转存失败(img-JJ42GWf9-1563801784739)(https://raw.githubusercontent.com/zpwyl/images/master/TIM图片20190405161647.png)]
[外链图片转存失败(img-gkN7jNo9-1563801784741)(https://raw.githubusercontent.com/zpwyl/images/master/TIM图片20190405161710.png)]
本人直男一枚,对于美工方面的确没什么天赋,最后做出来的效果差强人意。原本是准备做成点击车上的部位进而改变颜色,希望有看到鄙人拙作的大佬能指点一二,同时也是对自己过去这段时间的一个总结。

下面分享一些我在学习过程中遇到的问题和一些学习网站:
其他类型的3D文件的加载:
OBJ:

var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath('exapmle/4/');
mtlLoader.load('car.mtl', function(materials) {console.log(materials);materials.preload();var objLoader = new THREE.OBJLoader();objLoader.setMaterials(materials);objLoader.setPath('exapmle/4/');objLoader.load('car.obj', function(object) {console.log(object, 'obj');object.position.y = 0;object.rotation.y = 0.5;object.scale.set(0.05, 0.05, 0.05);console.log(object);scene.add(object);}, onProgress, onError);});

VTK:

var loader = new THREE.VTKLoader();
loader.addEventListener( 'load', function ( event ) {var geometry = event.content;var mesh = new THREE.Mesh( geometry, material );mesh.position.setY( - 0.09 );scene.add( mesh );} );
loader.load( "models/vtk/bunny.vtk" );

WebGL中文网           http://www.hewebgl.com/
Three.js官方文档       https://threejs.org/
3D模型下载               https://sketchfab.com


http://www.ppmy.cn/news/356848.html

相关文章

Three.js实现汽车3D展示/开关门/变色/运动/视角切换/波动热点/汽车模型

1&#xff0c;介绍 该示例使用Three.js库 r141版本。 主要实现功能&#xff1a;使用Three.js实现引入汽车模型&#xff0c;汽车3D展示&#xff0c;开门关门动画&#xff0c;运动&#xff0c;变色&#xff0c;视角切换&#xff0c;显示波动热点标签。 效果图如下&#xff1a; 参…

东风日产到访CASAIM,双方联合开展运用高精度3D打印技术制造汽车产线相关的工装夹具、检具及治具的技术应用研究

3月中旬&#xff0c;东风日产乘用车有限公司&#xff08;简称&#xff1a;东风日产&#xff09;制造技术部一行到访CASAIM&#xff0c;CASAIM副主任、产品总监刘颖鹏对东风日产一行到访表示热烈欢迎。会上&#xff0c;CASAIM副主任、产品总监刘颖鹏围绕3D打印技术工艺、材料及创…

目标检测YOLO实战应用案例100讲-网联自动驾驶中感知图像隐私目标分类与检测方法

目录 前言 基础知识 2.1 深度学习知识 2.1.1 卷积神经网络 2.1.2 残差神经网络模型

爬虫:requests+pymysql+BeautifulSoup+re

爬虫网站限于学习&#xff01;&#xff01; 功能实现&#xff1a;扫描站点目录、按目录分页扫描页面【提取数据并正则过滤特殊符号】、数据保存到数据库&#xff0c;可按多线程、多进程进行爬取内容 import requests,os,xml,pymysql,threading,time,queue,_thread from bs4 im…

python爬虫快速添加请求头、随机生成user-agent

一、快速添加请求头 import re # 下方引号内添加替换掉请求头内容 headers_str """ accept: text/html,application/xhtmlxml,application/xml;q0.9,image/avif,image/webp,image/apng,*/*;q0.8,application/signed-exchange;vb3;q0.9 accept-encoding: gzip…

百度指数python爬虫的简单应用

这个是“关键词”爬取&#xff0c;如果mysql数据库不会改&#xff0c;建议把mysql有关的代码注释或删除。 注意&#xff0c;时间为我自己添加上去的&#xff0c;如果时间跨度较长&#xff0c;百度指数时间会变为一个星期一次数据&#xff0c;而我添加的为每天&#xff0c;需自…

python多进程实战——4k图片抓取

技术交流贴&#xff1a;不可用于违法违规用途 成果图&#xff1a; 背景&#xff1a;疫情宅家太无聊了&#xff0c;练习了一下爬虫&#xff0c;里面用到了伪装请求头、多进程、代理IP等技术 开始&#xff1a; 首先我们来分析一下网页&#xff0c;只要找到我们需要的清析度的图…