web端渲染3d模型,ply,stl

说论金 2024-10-10 10:14:52

最近在公司里面做一个web功能,需要在页面上渲染3d模型,主要是做口腔扫描。

做web3d,可用的js库还是很多,首先想到的就是vue-3d-model

方便快捷,但是呢ply模型的颜色显示不出来,没有着色。当然渲染的时候可以自己加颜色,但是不是我想要的。

下图是用其他3d浏览软件打开的效果

以为是js库的问题,直接换threeJs,这老大哥,很强大,也很流行了。

实际渲染效果也是一样,都是纯色。

经过我不断尝试,查找资料,终于找到了缘由。

load模型数据之后,里面有属性,我这边的口扫数据属于不同的扫描厂家,有些厂家会把着色的颜色属性打包放数据文件里面,有些厂家是直接生成材质图片,数据文件里面就给出了渲染坐标属性

包含颜色的

包含贴图坐标的

贴图材质

含贴图的,在ply 文件头部会指定贴图名称,如下图

不含贴图的打开如下

附上最终代码,说不定哪天己还来看

<!DOCTYPE html>

<html lang="en">

<head>

<title>three.js webgl - exporter - ply</title>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

<link type="text/css" rel="stylesheet" href="main.css">

</head>

<body>

<div id="info">

<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - exporter - ply

</div>

<script type="importmap">

{

"imports": {

"three": "../build/three.module.js",

"three/addons/": "./jsm/"

}

}

</script>

<script type="module">

import * as THREE from 'three';

import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

import { GUI } from 'three/addons/libs/lil-gui.module.min.js';

import { PLYLoader } from 'three/addons/loaders/PLYLoader.js';

let scene, camera, renderer, mesh;

init();

function init() {

camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 100 );

camera.position.set( 4, 2, 4 );

scene = new THREE.Scene();

scene.background = new THREE.Color( 0xa0a0a0 );

scene.fog = new THREE.Fog( 0xa0a0a0, 4, 20 );

const hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444, 3 );

hemiLight.position.set( 0, 20, 0 );

scene.add( hemiLight );

const ground = new THREE.Mesh( new THREE.PlaneGeometry( 40, 40 ), new THREE.MeshPhongMaterial( { color: 0xcbcbcb, depthWrite: false } ) );

ground.rotation.x = - Math.PI / 2;

ground.receiveShadow = true;

scene.add( ground );

const grid = new THREE.GridHelper( 40, 20, 0x000000, 0x000000 );

grid.material.opacity = 0.2;

grid.material.transparent = true;

scene.add( grid );

let uvTexture = new THREE.TextureLoader().load("./models/ply/test/zp/UpperJaw.jpg");

const loader = new PLYLoader();

loader.load( './models/ply/test/zp/240930055-upperjaw.ply', function ( geometry) {

console.log('ply',geometry)

geometry.computeVertexNormals();

const material = new THREE.MeshStandardMaterial({

map: uvTexture,

transparent: true

});

const mesh = new THREE.Mesh( geometry, material );

mesh.position.y = - 0;

mesh.position.z = 0;

mesh.rotation.x = - Math.PI / 2;

mesh.scale.multiplyScalar( 0.01 );

mesh.castShadow = true;

mesh.receiveShadow = true;

scene.add( mesh );

});

loader.load( './models/ply/test/yes.ply', function ( geometry) {

console.log('ply',geometry,'color',geometry.getAttribute('color'))

geometry.computeVertexNormals();

const material = new THREE.PointsMaterial({

size: 0.01, vertexColors: true

});

const mesh = new THREE.Points( geometry, material );

mesh.position.y = - 0;

mesh.position.z = 0;

mesh.rotation.x = - Math.PI / 2;

mesh.scale.multiplyScalar( 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.setAnimationLoop( animate );

renderer.shadowMap.enabled = true;

document.body.appendChild( renderer.domElement );

//

const controls = new OrbitControls( camera, renderer.domElement );

controls.target.set( 0, 0.5, 0 );

controls.update();

//

window.addEventListener( 'resize', onWindowResize );

}

function onWindowResize() {

camera.aspect = window.innerWidth / window.innerHeight;

camera.updateProjectionMatrix();

renderer.setSize( window.innerWidth, window.innerHeight );

}

function animate() {

renderer.render( scene, camera );

}

</script>

</body>

</html>

最终渲染效果,一个是贴图,一个是颜色。

0 阅读:0