赞
踩
记录一下自己在django框架下实现网页端显示3d模型的过程
three.js官网链接: link
直接点击Code那里的download即可下载,然后解压缩three.js-master.zip文件夹
这里如果想要直接运行three.js的例子,需要部署node.js环境
笔者是参考这篇文章部署: link
如果不安装node.js直接进行后面django的部署是否会有问题,暂未验证
打开控制台,cd到three.js-master文件夹,运行npm install
如果成功,该目录下会创建一个node_modules文件夹
接着打开package.json文件,可以看到很多运行指令
这里在控制台输入npm run dev
Ctrl + 单击打开任意链接,打开后点击example文件夹,即可看到自带的各种例子
后续笔者显示stl文件重点参考了 load/gltf/sheel、load/stl、和lights/spotlight
<!DOCTYPE html> <html lang="en"> <head> <title>three.js webgl - GLTFloader + Sheen</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <style> body { background: #bbbbbb; } </style> </head> <body> <script type="importmap"> { "imports": { "three": "./build/three.module.js", "three/addons/": "./examples/jsm/" } } </script> <script type="module"> import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; import { STLLoader } from 'three/addons/loaders/STLLoader.js'; import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer, controls; init(); animate(); function init() { const container = document.createElement( 'div' ); document.body.appendChild( container ); camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 20 ); camera.position.set( - 2,2,3 ); //cameraTarget = new THREE.Vector3( 3, 3, 3); //camera.position.set( -0.25,0.25, -0.5 ); scene = new THREE.Scene(); scene.background = new THREE.Color( 0x808080); //scene.fog = new THREE.Fog( 0x72645b, 2, 15 ); addShadowedLight( 1, 0.5, 1, 0xffffff, 10 ); addShadowedLight( -1, -0.5, - 1, 0xffffff, 10 ); // model const loader = new STLLoader(); const material = new THREE.MeshPhongMaterial( { color: 0x000080,specular:0x000080,shininess:100} ); loader.load('../../model.stl', function (geometry) { const mesh = new THREE.Mesh( geometry, material ); mesh.position.set( 0, 0, 0 ); //mesh.rotation.set( - Math.PI / 2, 0.3, 0 ); mesh.scale.set( 0.01, 0.01, 0.01 ); mesh.castShadow = true; mesh.receiveShadow = true; scene.add( mesh ); } ); renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.toneMapping = THREE.ACESFilmicToneMapping; renderer.toneMappingExposure = 1; renderer.outputEncoding = THREE.sRGBEncoding; container.appendChild( renderer.domElement ); const environment = new RoomEnvironment(); const pmremGenerator = new THREE.PMREMGenerator( renderer ); //scene.background = new THREE.Color( 0xbbbbbb ); scene.environment = pmremGenerator.fromScene( environment ).texture; controls = new OrbitControls( camera, renderer.domElement ); controls.enableDamping = true; controls.minDistance = 0.1; controls.maxDistance = 10; controls.target.set( 0, 0.35, 0 ); controls.update(); window.addEventListener( 'resize', onWindowResize ); //GUI const gui = new GUI(); const params = { color: material.color.getHex(), }; gui.addColor( params, 'color' ).onChange( function ( val ) { material.color.setHex( val ); } ); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } // function animate() { requestAnimationFrame( animate ); controls.update(); // required if damping enabled render(); } function render() { renderer.render( scene, camera ); //camera.lookAt( cameraTarget ); } function addShadowedLight( x, y, z, color, intensity ) { const directionalLight = new THREE.DirectionalLight( color, intensity ); directionalLight.position.set( x, y, z ); scene.add( directionalLight ); directionalLight.castShadow = true; const d = 1; directionalLight.shadow.camera.left = - d; directionalLight.shadow.camera.right = d; directionalLight.shadow.camera.top = d; directionalLight.shadow.camera.bottom = - d; directionalLight.shadow.camera.near = 1; directionalLight.shadow.camera.far = 4; directionalLight.shadow.bias = - 0.002; } </script> </body> </html>
笔者将这个html文件夹放到three.js和package.json同一级
model文件的路径大家改成自己的就好,因为自己的模型太大,所以mesh.scale.set( 0.01, 0.01, 0.01 ),设置尺寸很小
注意这里直接运行会报错
我使用vscode编译,下载Live Server扩展,然后右键open with live server
弹出网页
笔者直接用已有项目,不再从零开始
将three文件夹放到static/js文件夹下,将add_test_stl.html放到templetes/myapp文件夹下
将three.js文件夹下对应位置的文件分别移动到新建的three文件夹下
controls/OrbitControls.js
environments/RoomEnvironment.js
loaders/STLLoader.js’
libs/lil-gui.module.min.js’
笔者有个templetes文件夹存放项目所有的html文件
在这里新建一个add_test_stl.html
代码如下
<!DOCTYPE html> {% load static %} <html lang="en"> <head> <title>three.js test</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <style> body { background: #bbbbbb; } </style> </head> <body> <div style="float:left; width:50%;"> <h2>随机文章</h2> <p id="article">这里是随机文章的内容</p> </div> <div style="float:right; width:50%;"> <h2>随机配图</h2> <img id="image" height="250" src="{% static 'chuanganqi.jpg' %}" class="card-img-top" alt="..."> </div> <!-- Import maps polyfill --> <!-- Remove this when import maps will be widely supported --> <script type="importmap"> { "imports": { "three": "../../static/js/three/three.module.js", "three/addons/": "../../static/js/three/" } } </script> <script type="module"> import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; import { STLLoader } from 'three/addons/loaders/STLLoader.js'; import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; let camera, scene, renderer, controls; init(); animate(); function init() { const container = document.createElement( 'div' ); document.body.appendChild( container ); camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 20 ); camera.position.set( - 2,2,3 ); scene = new THREE.Scene(); scene.background = new THREE.Color( 0x808080); //scene.fog = new THREE.Fog( 0x72645b, 2, 15 ); addShadowedLight( 1, 0.5, 1, 0xffffff, 10 ); addShadowedLight( -1, -0.5, - 1, 0xffffff, 10 ); // model const loader = new STLLoader(); const material = new THREE.MeshPhongMaterial( { color: 0x000080,specular:0x000080,shininess:100} ); loader.load( '../../static/js/three/model.stl', function (geometry) { const mesh = new THREE.Mesh( geometry, material ); mesh.position.set( 0, 0, 0 ); mesh.scale.set( 0.01, 0.01, 0.01 ); mesh.castShadow = true; mesh.receiveShadow = true; scene.add( mesh ); } ); renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( 0.5*window.innerWidth, 0.5*window.innerHeight ); renderer.toneMapping = THREE.ACESFilmicToneMapping; renderer.toneMappingExposure = 1; renderer.outputEncoding = THREE.sRGBEncoding; container.appendChild( renderer.domElement ); const environment = new RoomEnvironment(); const pmremGenerator = new THREE.PMREMGenerator( renderer ); //scene.background = new THREE.Color( 0xbbbbbb ); scene.environment = pmremGenerator.fromScene( environment ).texture; controls = new OrbitControls( camera, renderer.domElement ); controls.enableDamping = true; controls.minDistance = 0.1; controls.maxDistance = 10; controls.target.set( 0, 0.35, 0 ); controls.update(); window.addEventListener( 'resize', onWindowResize ); //GUI const gui = new GUI(); const params = { color: material.color.getHex(), }; gui.addColor( params, 'color' ).onChange( function ( val ) { material.color.setHex( val ); } ); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight ); } // function animate() { requestAnimationFrame( animate ); controls.update(); // required if damping enabled render(); } function render() { renderer.render( scene, camera ); //camera.lookAt( cameraTarget ); } function addShadowedLight( x, y, z, color, intensity ) { const directionalLight = new THREE.DirectionalLight( color, intensity ); directionalLight.position.set( x, y, z ); scene.add( directionalLight ); directionalLight.castShadow = true; const d = 1; directionalLight.shadow.camera.left = - d; directionalLight.shadow.camera.right = d; directionalLight.shadow.camera.top = d; directionalLight.shadow.camera.bottom = - d; directionalLight.shadow.camera.near = 1; directionalLight.shadow.camera.far = 4; directionalLight.shadow.bias = - 0.002; } </script> </body> </html>
在view.py文件中添加
def add_stl(request):
return render(request, 'myapp/add_test_stl.html')
在urls.py文件中添加路径到urlpatterns 中
def add_stl(request):
path('add_stl/', views.add_stl, name='add_stl'),
最后在控制台
第一步:python manage.py makemigrations
第二步:python manage.py migrate
第三步:python manage.py runserver
打开地址并定位到
http://127.0.0.1:8000/add_stl/
最终结果如下
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。