材质渲染不自然(有光泽)

时间:2018-11-14 12:39:23

标签: javascript three.js

我正在尝试使用Three.js使用材质渲染对象,但与https://3dviewer.net这样的其他在线查看器(也使用幕后使用Three.js)看起来却有所不同

我尝试提高详细程度(LOD),并使用了NearestFilter / LinearFilter,但没有任何效果。

这是how it should look(3dviewer对象渲染的屏幕截图)。

这是how it looks in my app

在3dviewer版本中,它看起来更自然,而在我看来,它太有光泽和光泽了

我应该应用一些特定的滤镜(​​尽管在3dviewer的源代码中没有找到它)还是可能会点亮?

我当前的代码是:

let scene = new THREE.Scene();
scene.background = new THREE.Color( '#edeff2' );

let camera = new THREE.PerspectiveCamera( 100,   window.innerWidth/window.innerHeight, 1, 1000 );
camera.position.z = 100;

let renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

let controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = true;

let keyLight = new THREE.DirectionalLight(new THREE.Color('hsl(30, 100%, 75%)'), 1.0);
keyLight.position.set(-100, 0, 100);

let fillLight = new THREE.DirectionalLight(new THREE.Color('hsl(240, 100%, 75%)'), 0.75);
fillLight.position.set(100, 0, 100);

let backLight = new THREE.DirectionalLight(0xffffff, 1.0);
backLight.position.set(100, 0, -100).normalize();

scene.add(keyLight);
scene.add(fillLight);
scene.add(backLight);

let mtlLoader = new THREE.MTLLoader();
mtlLoader.setTexturePath('/examples/3d-obj-loader/assets/');
mtlLoader.setPath('/examples/3d-obj-loader/assets/');
mtlLoader.load('b.mtl', function (materials) {

materials.preload();

let objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('/examples/3d-obj-loader/assets/');
objLoader.load('b.obj', function (object) {

    scene.add(object);
    object.position.y -= 100;

    object.scale.x = 0.01;
    object.scale.y = 0.01;
    object.scale.z = 0.01;

    let boundingBox = new THREE.Box3().setFromObject(object)
    let size = boundingBox.getSize()
});
});

var animate = function () {
    requestAnimationFrame( animate );
    controls.update();
    renderer.render(scene, camera);
};

animate();

链接到对象,材料和纹理-dropbox

2 个答案:

答案 0 :(得分:0)

您可以轻松访问对象的材料。

objLoader.load('b.obj', function (object) {
    // Access material
    var mat = object.material;

    // Make material less shiny
    mat.metalness = 0;
    mat.roughness = 1;

    scene.add(object);
    object.position.y -= 100;

    object.scale.x = 0.01;
    object.scale.y = 0.01;
    object.scale.z = 0.01;

    let boundingBox = new THREE.Box3().setFromObject(object)
    let size = boundingBox.getSize()
});

如何访问资料取决于object的结构。取决于嵌套的方式,它可以是object.children[0].materialobject.children[0].children[0].material

答案 1 :(得分:0)

我遇到了同样的问题,必须对所有材料应用过滤器:

function getAllMaterials( object ) {
 var out = [];
 object.traverse( function( node ) {
  if ( node instanceof THREE.Mesh ) { out.push( node.material ) }
 } );
 return out;
}

getAllMaterials( <your-3D-Object-Here> ).forEach( function ( mat ) {
 if ( Array.isArray( mat ) ) {
  mat.forEach( function( cmat ) { cmat.shininess /= 19; } )
 }
 else { mat.shininess /= 19 }
} );

您可能需要将代码中的静态19更改为适合您的需要。如有任何疑问,我将为您设置现场示例。