如何使用Three.js导入带有纹理的Blender 3D模型?

时间:2018-05-21 22:50:26

标签: node.js three.js blender

我使用Blender创建了一个非常简单的多维数据集,并使用Three.js Blender Exporter将其导出。

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

'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":[]
}

1 个答案:

答案 0 :(得分:0)

好吧,我得到了一些近乎可行的东西:

'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。