【问题标题】:How can I import a Blender 3D model with a texture using Three.js?如何使用 Three.js 导入带有纹理的 Blender 3D 模型?
【发布时间】:2018-10-31 14:57:06
【问题描述】:

我使用 Blender 创建了一个非常简单的立方体,并使用 Three.js Blender Exporter 将其导出。

我现在正在尝试加载导出的模型并使用 Node.js 应用纹理。当我运行脚本时,我看不到任何错误。我究竟做错了什么?

'use strict';

const JSDOM = require('jsdom').JSDOM;
const THREE = require('three');

const dom = new JSDOM(`<!DOCTYPE html><html><head></head><body></body></html>`);

global.window = dom.window;
global.document = dom.window.document;
global.XMLHttpRequest = require('xhr2');

const loadTexture = (path) => {
    return new Promise((resolve, reject) => {
        const loader = new THREE.TextureLoader();

        loader.load(
            path,

            // success
            (texture) => resolve(texture),

            // progress
            undefined,

            // error
            (error) => reject(error)
        );
    });
};

const loadGeometry = (path) => {
    const loader = new THREE.JSONLoader();

    return new Promise((resolve, reject) => {
        loader.load(
            path,

            // success
            (geometry) => resolve(geometry),

            // progress
            undefined,

            // error
            (error) => reject(error)
        );
    });
};

const createObject = () => {
    return Promise.all([
        loadTexture('./image.jpg'),
        loadGeometry('./cube.json')
    ]).then(results => {
        const texture = results[0];
        const material = new THREE.MeshBasicMaterial({map: texture});
        const geometry = results[1];
        const object = new THREE.Mesh(geometry, material);

        return object;
    });
};

const scene = new THREE.Scene();

createObject()
    .then(object => {
        scene.add(object);

        console.log('Success!');
    })
    .catch(error => console.error(error.message));

这是我正在使用的模型:

{
    "normals":[-5.32907e-15,-1,2.98023e-08,1.06581e-14,1,-2.98023e-08,1,4.47034e-08,2.83122e-07,-2.83122e-07,-7.45059e-08,1,-1,-1.3411e-07,-2.23517e-07,2.38419e-07,1.78814e-07,-1],
    "faces":[33,0,1,2,3,0,0,0,0,33,4,7,6,5,1,1,1,1,33,0,4,5,1,2,2,2,2,33,1,5,6,2,3,3,3,3,33,2,6,7,3,4,4,4,4,33,4,0,3,7,5,5,5,5],
    "metadata":{
        "normals":6,
        "faces":6,
        "type":"Geometry",
        "vertices":8,
        "generator":"io_three",
        "uvs":0,
        "version":3
    },
    "vertices":[1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,0.999999,1,1,-1,1,1,-1,1,-1],
    "uvs":[]
}

【问题讨论】:

  • 我在您的代码中没有看到渲染器,所以什么都不会出现...您是否完全看不到任何输出但期待Success!?另请注意,jsdom 可能不支持 WebGL,您可能需要 node-webgl 或无头浏览器。
  • 您好,唐,感谢您的反馈。你没有渲染器是对的。目前,我的目标是测试模型和纹理的加载。一旦成功,我将继续实现渲染。我想知道是否需要 node-webgl 才能加载模型?似乎有些东西阻止了模型加载。
  • 既然别人没有你的模型就无法运行这段代码,你看到了什么?是否出现任何console.log 输出?考虑在纹理和模型加载或失败时记录日志,而不是立即解决/拒绝以缩小问题范围。
  • @DonMcCurdy 刚刚用模型更新了问题:) console.log() 没有输出。但我刚刚在createObject() 中添加了一个.catch(),然后“瞧,我现在收到一条错误消息:THREE.Object3D.add: object not an instance of THREE.Object3D。然后似乎是scene.add(object) 导致了这个问题。
  • 啊,没关系。我收到该错误是因为在 .catch() 块中 undefined 被返回。

标签: node.js three.js blender


【解决方案1】:

好吧,我得到了一些几乎可以工作的东西:

'use strict';

const fs = require('fs');
const JSDOM = require('jsdom').JSDOM;
const THREE = global.THREE = require('three');
require('three/examples/js/renderers/Projector');
const CanvasRenderer = require('three/examples/js/renderers/CanvasRenderer');
const Canvas = require('canvas');

const dom = new JSDOM(`<!DOCTYPE html><html><head></head><body></body></html>`);

global.window = dom.window;
global.document = dom.window.document;
global.XMLHttpRequest = require('xhr2');

const loadTexture = (url) => {
    const loader = new THREE.FileLoader();

    return new Promise((resolve, reject) => {
        console.log('loading texture');

        loader.load(
            url,

            // success
            (texture) => {
                console.log('loaded texture');
                resolve(texture);
            },

            // progress
            undefined,

            // error
            (error) => {
                console.log('error loading texture');
                reject(error);
            }
        );
    });
};

const loadGeometry = (url) => {
    const loader = new THREE.JSONLoader();

    return new Promise((resolve, reject) => {
        console.log('loading geometry');

        loader.load(
            url,

            // success
            (geometry) => {
                console.log('loaded geometry');
                resolve(geometry);
            },

            // progress
            undefined,

            // error
            (error) => {
                console.log('error loading geometry');
                reject(error);
            }
        );
    });
};

const createObject = () => {
    return Promise.all([
        loadTexture('http://localhost:8000/image.jpg'),
        loadGeometry('http://localhost:8000/cube.json')
    ]).then(results => {
        const texture = results[0];
        const geometry = results[1];
        const material = new THREE.MeshBasicMaterial({map: texture});
        const object = new THREE.Mesh(geometry, material);

        return object;
    });
};

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const canvas = new Canvas(800, 800);
const renderer = new THREE.CanvasRenderer({
    canvas: canvas
});

camera.position.z = 5;

canvas.style = {};

renderer.setClearColor(0xffffff, 0);
renderer.setSize(800, 800);

createObject()
    .then(object => {
        scene.add(object);

        renderer.render(scene, camera);

        const out = fs.createWriteStream('./rendered.png');
        const canvasStream = canvas.pngStream();
        canvasStream.on('data', function (chunk) { out.write(chunk); });
        canvasStream.on('end', function () { console.log('done'); });
    })
    .catch(error => console.error(error.message));

除非它呈现一个空白的透明 PNG。

【讨论】:

    猜你喜欢
    • 2016-02-27
    • 2019-03-07
    • 2014-09-12
    • 2013-11-05
    • 2013-12-08
    • 2012-06-24
    • 1970-01-01
    • 2023-03-03
    • 2017-05-11
    相关资源
    最近更新 更多