求助帖.Three.js - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技问题时复制粘贴 AI 生成的内容
yuxi521
V2EX    程序员

求助帖.Three.js

  •  
  •   yuxi521 2020-10-18 12:33:48 +08:00 3728 次点击
    这是一个创建于 1848 天前的主题,其中的信息可能已经有所发展或是发生改变。

    后端 boy 因业务需求不得不学习 Three.js.将三维模型加载到 web 浏览器展示即可.

    操作路线:

    1 下载官方 demo,打开,运行正常,可见效果 2 网上下载.obj .mtl 文件替换官方例子,打开,可见效果 试了二个 3 建模师提供的 obj 文件,使用电脑 3d 可打开,证明模型文件没问题,用 three.js 打开,看不到效果图,f12 也没报错信息,猜测:1 加载出错?2 灯光角度大小问题导致我看不到模型? 4 贴上控制台信息 Using OBJLoader2 version: 3.2.0 verify.html?_ijt=9h2s3381ah9lvusnfe2lvi6sk7:233 Starting initialisation phase... verify.html?_ijt=9h2s3381ah9lvusnfe2lvi6sk7:183 Progress: Loading: verificationCubes OBJLoader2.js:342 Parsing arrayBuffer... OBJLoader2Parser.js:324 OBJLoader.Parser configuration: materialNames: - attr_0 - defaultMaterial - defaultVertexColorMaterial - defaultLineMaterial - defaultPointMaterial materialPerSmoothingGroup: false useOAsMesh: true useIndices: false disregardNormals: false callbacks.onProgress: onProgress callbacks.onAssetAvailable: defaultOnAssetAvailable callbacks.onError: onError OBJLoader2Parser.js:1109 Global output object count: 1 OBJLoader2Parser.js:1116 Overall counts: Vertices: 1806 Faces: 1806 Multiple definitions: 0 OBJLoader2Parser.js:389 OBJLoader2Parser.execute: 23.46533203125 ms OBJLoader2.js:358 OBJLoader parse: verificationCubes: 24.51318359375 ms verify.html?_ijt=9h2s3381ah9lvusnfe2lvi6sk7:162 Loading complete: verificationCubes verify.html?_ijt=9h2s3381ah9lvusnfe2lvi6sk7:183 Progress: 

    现在不知道怎么办才好.初步的想法就是可以加载成功就行.后期再去完善其他.求大佬指点

    17 条回复    2020-10-19 15:28:32 +08:00
    misdake
        1
    misdake  
       2020-10-18 12:47:07 +08:00   1
    可以尝试一下导入到官方 editor 里看看效果: https://threejs.org/editor/
    如果能看到,说明 threejs 本身应该是支持的,但是可能是你的项目中的物体位置(比如三角形不在视野内)、相机(比如 clearcolor 黑色,物体也是黑色导致看不出来)或者灯光(比如物体本应不黑但是没有光照导致是黑的)有什么问题。
    如果看不到,说明导出的 obj 或 mtl 格式可能有某种不兼容(但不报错)的情况(比如材质透明了或者没设置上)。
    xiaoming1992
        2
    xiaoming1992  
       2020-10-18 12:54:14 +08:00 via Android   1
    你要注意,还有以下几种可能,会导致看不到模型:

    1. 模型的实际位置离摄像机很远,在摄像机的视野外
    2. 模型在 threejs 中的单位太小(例如 0.0001,只能看到一个小点,你肉眼看不到)或太大(摄像机视野内恰好只能看到模型的缝隙)
    3. 模型不在原点,且摄像头看向了其他方向

    以上情况我都实际碰见过的,所以要求导出模型时规范些
    xiaoming1992
        3
    xiaoming1992  
       2020-10-18 13:00:26 +08:00 via Android   1
    还有感觉 threejs 的问题可以发到官方论坛,一方面那里的人都是做这个的,另一方面官方论坛的气氛特别好,特别热心,基本很少有提问不被解答的,而 v2 接触过 threejs 的相对应该比较少吧。 以前经常逛的,现在不做这方面了才逛得少了
    beginor
        4
    beginor  
       2020-10-18 14:22:27 +08:00 via Android   1
    控制台信息应该是没有错误的, 但是仅凭这些信息很难诊断出具体的原因。

    如果有可能的话可以把网页脚本和文件都放在互联网上,这样大家才能更容易帮到你。
    beginor
        5
    beginor  
       2020-10-18 14:27:42 +08:00 via Android   1
    发错了, 应该是有错,因为出现了 onError
    hgjian
        6
    hgjian  
       2020-10-18 15:33:45 +08:00 via Android   1
    你可以看看 360 开源的框架哦:
    https://spritejs.org
    lhx880619
        7
    lhx880619  
       2020-10-18 16:29:38 +08:00 via Android   1
    现在建议直接 gltf 模型了 另外 BabylonJS 也是个不错的选择 对于没有 3d 基础的 感觉你还有很长的路走。。。
    yuxi521
        8
    yuxi521  
    OP
       2020-10-18 16:47:30 +08:00
    @lhx880619 仅仅是加载下模型展示出来 也不知道难度,公司没这方面技术的同事,领导就派我上了,哎
    tangchi695
        9
    tangchi695  
       2020-10-18 16:54:44 +08:00
    @lhx880619 没基础你让人用 Babylon
    tangchi695
        10
    tangchi695  
       2020-10-18 16:59:07 +08:00
    加载自己的模型看不到,先给灯光,再缩放模型,放大到 10 倍 100 倍率,或者缩小,或者加一个 axeshelper 定位看看在哪儿,加载器加载的回调里打印下结果,看看加载的结果是什么,成功和错误的回调都要打印。
    alw
        11
    alw  
       2020-10-19 08:39:02 +08:00
    1.windows10 自带 3d 查看器,可以直接双击打开看模型。
    2. 调灯光,否则有可能是黑色,黑色物体混在黑色背景,看个毛线。
    用这句统一变成不受光影响的基本色试试:
    `scene.overrideMaterial = new THREE.MeshBasicMaterial( { color: 'green' } );`

    3. 调摄像头坐标,模型太大,摄像头有可能有物体内部,或者超出了摄像头的可视范围。
    建议先用 3D 模型建一个 长宽高各一米的立方体来测试,验证以上三点之后,再调试设计师的模型,主要是搞清模型大小,摄像头应该放哪个位置等问题。
    LyleRockkk
        12
    LyleRockkk  
       2020-10-19 09:19:59 +08:00
    能不能贴一下加载模型的 js 代码,obj 格式的加载都不用过多设置,模型没问题多半是相机设置的有问题,画面中看不到模型
    yuxi521
        13
    yuxi521  
    OP
       2020-10-19 10:18:29 +08:00
    @LyleRockkk
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <title>three.js webgl - 2/OBJLoader verification</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 {
    font-family: Monospace;
    background-color: #F5F5F5;
    color: #fff;
    margin: 0 0 0 0;
    padding: 0 0 0 0;
    border: none;
    cursor: default;
    }
    #info {
    color: #fff;
    position: absolute;
    top: 10px;
    width: 100%;
    text-align: center;
    z-index: 100;
    display:block;
    }
    #info a {
    color: #f00;
    font-weight: bold;
    text-decoration: underline;
    cursor: pointer
    }
    #glFullscreen {
    width: 100%;
    height: 100vh;
    min-width: 640px;
    min-height: 360px;
    position: relative;
    overflow: hidden;
    z-index: 0;
    }
    #example {
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    background-color: #555555;
    }
    #feedback {
    color: darkorange;
    }
    #dat {
    user-select: none;
    position: absolute;
    left: 0;
    top: 0;
    z-Index: 200;
    }
    </style>
    </head>

    <body>
    <div id="glFullscreen">
    <canvas id="example"></canvas>
    </div>
    <div id="dat">

    </div>
    <div id="info">
    <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - OBJLoader2/OBJLoader verification
    <div id="feedback"></div>
    </div>

    <script type="module">

    'use strict';

    import {
    AmbientLight,
    DirectionalLight,
    GridHelper,
    PerspectiveCamera,
    Scene,
    Vector3,
    WebGLRenderer
    } from "../../../../build/three.module.js";

    import { TrackballControls } from "../../../jsm/controls/TrackballControls.js";

    import { MTLLoader } from "../../../jsm/loaders/MTLLoader.js";
    import { MtlObjBridge } from "../../../jsm/loaders/obj2/bridge/MtlObjBridge.js";
    import { OBJLoader } from "../../../jsm/loaders/OBJLoader.js";
    import { OBJLoader2 } from "../../../jsm/loaders/OBJLoader2.js";

    const OBJLoaderVerify = function ( elementToBindTo ) {
    this.renderer = null;
    this.canvas = elementToBindTo;
    this.aspectRatio = 1;
    this.recalcAspectRatio();

    this.scene = null;
    this.cameraDefaults = {
    posCamera: new Vector3( 0.0, 175.0, 500.0 ),
    posCameraTarget: new Vector3( 0, 0, 0 ),
    near: 0.1,
    far: 10000,
    fov: 45
    };
    this.camera = null;
    this.cameraTarget = this.cameraDefaults.posCameraTarget;

    this.cOntrols= null;
    };

    OBJLoaderVerify.prototype = {

    constructor: OBJLoaderVerify,

    initGL: function () {
    this.renderer = new WebGLRenderer( {
    canvas: this.canvas,
    antialias: true,
    autoClear: true
    } );
    this.renderer.setClearColor( 0x050505 );

    this.scene = new Scene();

    this.camera = new PerspectiveCamera( this.cameraDefaults.fov, this.aspectRatio, this.cameraDefaults.near, this.cameraDefaults.far );
    this.resetCamera();
    this.cOntrols= new TrackballControls( this.camera, this.renderer.domElement );

    let ambientLight = new AmbientLight( 0x404040 );
    let directionalLight1 = new DirectionalLight( 0xC0C090 );
    let directionalLight2 = new DirectionalLight( 0xC0C090 );

    directionalLight1.position.set( -100, -50, 100 );
    directionalLight2.position.set( 100, 50, -100 );

    this.scene.add( directionalLight1 );
    this.scene.add( directionalLight2 );
    this.scene.add( ambientLight );

    let helper = new GridHelper( 1200, 60, 0xFF4444, 0x404040 );
    this.scene.add( helper );
    },

    initContent: function () {
    let modelName = 'verificationCubes';
    this._reportProgress( { detail: { text: 'Loading: ' + modelName } } );

    let objLoader = new OBJLoader();

    let objLoader2 = new OBJLoader2();
    objLoader2.setModelName( modelName );
    objLoader2.setLogging( true, false );
    objLoader2.setUseOAsMesh( true );

    let scope = this;
    let callbackOnLoad= function ( object3d ) {
    scope.scene.add( object3d );
    console.log( 'Loading complete: ' + modelName );
    scope._reportProgress( { detail: { text: '' } } );
    };
    let OnLoadMtl= function ( mtlParseResult ) {
    objLoader.setMaterials( mtlParseResult );
    objLoader.load( './mod1.obj', function ( object ) {
    object.position.y = -100;
    scope.scene.add( object );
    } );

    objLoader2.addMaterials( MtlObjBridge.addMaterialsFromMtlLoader( mtlParseResult ) );
    objLoader2.load( './mod1.obj', callbackOnLoad, null, null, null );
    };

    let mtlLoader = new MTLLoader();
    mtlLoader.load( './mod1.mtl', onLoadMtl );
    },

    _reportProgress: function( event ) {
    let output = ( event.detail !== undefined && event.detail !== null && event.detail.text !== undefined && event.detail.text !== null ) ? event.detail.text : '';
    console.log( 'Progress: ' + output );
    document.getElementById( 'feedback' ).innerHTML = output;
    },

    resizeDisplayGL: function () {
    this.controls.handleResize();

    this.recalcAspectRatio();
    this.renderer.setSize( this.canvas.offsetWidth, this.canvas.offsetHeight, false );

    this.updateCamera();
    },

    recalcAspectRatio: function () {
    this.aspectRatio = ( this.canvas.offsetHeight === 0 ) ? 1 : this.canvas.offsetWidth / this.canvas.offsetHeight;
    },

    resetCamera: function () {
    this.camera.position.copy( this.cameraDefaults.posCamera );
    this.cameraTarget.copy( this.cameraDefaults.posCameraTarget );

    this.updateCamera();
    },

    updateCamera: function () {
    this.camera.aspect = this.aspectRatio;
    this.camera.lookAt( this.cameraTarget );
    this.camera.updateProjectionMatrix();
    },

    render: function () {
    if ( ! this.renderer.autoClear ) this.renderer.clear();
    this.controls.update();
    this.renderer.render( this.scene, this.camera );
    }
    };

    let app = new OBJLoaderVerify( document.getElementById( 'example' ) );

    let resizeWindow = function () {
    app.resizeDisplayGL();
    };

    let render = function () {
    requestAnimationFrame( render );
    app.render();
    };

    window.addEventListener( 'resize', resizeWindow, false );

    console.log( 'Starting initialisation phase...' );
    app.initGL();
    app.resizeDisplayGL();
    app.initContent();

    render();

    </script>
    </body>
    </html>
    nsjs
        14
    nsjs  
       2020-10-19 14:31:09 +08:00
    微软自带的能打开并不能说明模型没有问题,每个模型解析器的实现都不一样的,微软的那个实现比较弱
    各家的东西都或多或少有些不兼容的情况的
    obj 在 3dmax 里导出的时候也有很多选项的,你得反复测试不同的组合

    threejs 的解析不出来你可以试试别家的,babylonjs 和 cesium 都可以解析 obj 模型文件,这 2 个都是 js 库
    桌面软件的话你可以下载一个 blender 试试能不能加载
    nsjs
        15
    nsjs  
       2020-10-19 14:35:08 +08:00
    看了你加载的代码,你是设置了相机位置并且看向原点的
    obj 格式是不含相机信息的,我觉得最有可能的就是模型没有归到原点
    你可以问问建模的人
    nsjs
        16
    nsjs  
       2020-10-19 14:38:53 +08:00
    然后是你的相机位置离中心 500 米开外,模型如果只有 1 米不到的大小看不见很正常
    还有建模软件里单位设置得设置成米,否则有缩放的
    GressJoe
        17
    GressJoe  
       2020-10-19 15:28:32 +08:00
    obj 用文本编辑器打开看看坐标是多大数量级的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     845 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 20:18 PVG 04:18 LAX 12:18 JFK 15:18
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86