在three.js编辑器中,对象更亮

4

我在编辑器中导入了一个FBX对象,它的外观如下所示:

enter image description here

完美,这正是我期望的!

但是当我制作场景并导入相同的对象时,它看起来像这样:

enter image description here

更暗了,但为什么呢?

即使我使用了与两者相同强度的直接光线!

这些是我的编辑器对象:

enter image description here

而这是我的简单额外代码:

var scene = new THREE.Scene();
scene.background = new THREE.Color( 0x9A9A9A );
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

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

camera.position.z = 5;


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

//controls.update() must be called after any manual changes to the camera's transform
camera.position.set( 0, 20, 100 );
controls.update();

var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );
scene.add( directionalLight );
directionalLight.position.set(5,10,8);
var helper = new THREE.DirectionalLightHelper( directionalLight, 5 );
scene.add( helper );

var loader = new THREE.FBXLoader();

loader.load( '/assets/village/village_update.fbx', function ( object ) {
    object.traverse( function ( child ) {
        console.info( 'loaded' );
        if (child.isMesh) {
            child.receiveShadow = true;
            child.material.color.set( 0xffffff );
        }
    } );
    object.name = "village";
    console.log( 'adding it to scene' );
    scene.add( object );
});

var animate = function () {

    requestAnimationFrame( animate );
    renderer.render( scene, camera );
};

我在这里漏掉了什么?

编辑:

对于想要检查该对象的任何人,您可以从以下链接下载: object texture

3个回答

10
如果两个场景中的灯光相同,则可能是伽马值设置不正确引起的问题。尝试设置renderer.outputEncoding = THREE.sRGBEncoding;,假设您使用的是three.js的最新版本。在旧版本中,此设置应为 renderer.gammaOutput = true;
有关更多详细信息,请参见three.js中的颜色管理
three.js版本为r.112。

1
好的,我有一个地面纹理想要应用到一个平面上,这是否意味着每当我将纹理应用到材质上时都需要添加 material.map.encoding = THREE.sRGBEncoding; - shamaseen
1
如果纹理用于颜色数据(.map.emissive),那么是的,对于其他纹理(例如.normalMap),请坚持使用LinearEncoding。理想情况下,对于所有颜色纹理,您都应该这样做,并设置renderer.outputEncoding = sRGBEncoding,如上所示(“线性工作流程”)。一种替代方案,对于PBR来说不太好,但对于其他用例来说还不错,是将所有纹理和outputEncoding保持线性(“伽马工作流程”)。当您混合两者时,因此纹理设置与渲染器设置不匹配,您将遇到像在此问题中遇到的问题。 - Don McCurdy
我需要将 outputEncoding = 3000 设置为了解决在使用 React Fiber 的项目中的颜色问题。 - Jacksonkr
1
那是 THREE.LinearEncoding,相当于上面提到的“伽马工作流”。它通常不是您想要的东西——除非您正在进行后期处理中的伽马校正,否则它表明其他一些设置可能不太正确。但如果对于您的项目看起来不错,那么我就不会太担心它。 - Don McCurdy

2
对我而言,移除renderer.toneMapping = THREE.ReinhardToneMapping;让图像更加明亮。

2

经过多天的搜索和调试,我在FBXLoader中找到了这段代码:

switch ( type ) {

                case 'Bump':
                    parameters.bumpMap = self.getTexture( textureMap, child.ID );
                    break;

                case 'Maya|TEX_ao_map':
                    parameters.aoMap = self.getTexture( textureMap, child.ID );
                    break;

                case 'DiffuseColor':
                case 'Maya|TEX_color_map':
                    parameters.map = self.getTexture( textureMap, child.ID );
                    parameters.map.encoding = THREE.sRGBEncoding;
                    break;

                case 'DisplacementColor':
                    parameters.displacementMap = self.getTexture( textureMap, child.ID );
                    break;

                case 'EmissiveColor':
                    parameters.emissiveMap = self.getTexture( textureMap, child.ID );
                    parameters.emissiveMap.encoding = THREE.sRGBEncoding;
                    break;

                case 'NormalMap':
                case 'Maya|TEX_normal_map':
                    parameters.normalMap = self.getTexture( textureMap, child.ID );
                    break;

                case 'ReflectionColor':
                    parameters.envMap = self.getTexture( textureMap, child.ID );
                    parameters.envMap.mapping = THREE.EquirectangularReflectionMapping;
                    parameters.envMap.encoding = THREE.sRGBEncoding;
                    break;

                case 'SpecularColor':
                    parameters.specularMap = self.getTexture( textureMap, child.ID );
                    parameters.specularMap.encoding = THREE.sRGBEncoding;
                    break;

                case 'TransparentColor':
                    parameters.alphaMap = self.getTexture( textureMap, child.ID );
                    parameters.transparent = true;
                    break;

                case 'AmbientColor':
                case 'ShininessExponent': // AKA glossiness map
                case 'SpecularFactor': // AKA specularLevel
                case 'VectorDisplacementColor': // NOTE: Seems to be a copy of DisplacementColor
                default:
                    console.warn( 'THREE.FBXLoader: %s map is not supported in three.js, skipping texture.', type );
                    break;

            }

如果DiffuseColor,则明确地将纹理的编码转换为THREE.sRGBEncoding。通过控制台输出,我发现对象连接状态指示纹理已经扩散,因此正在更改编码,从而导致了黑暗着色器。

将编码改回3000(正常编码)并运行material.needUpdates = true将解决此问题,或者只需正确重新导出该对象即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接