23

我正在尝试使用 Three.js 创建一个小型第一人称游戏,但我遇到了照明问题。基本上,我想模拟太阳并让它围绕在所有东西上投射光而旋转。我THREE.DirectionalLight目前正在使用它,它只照亮一个方向,因此立方体的侧面保持黑色/深色。

我必须使用多个灯才能点亮所有东西吗?或者我可以以某种方式反射地面/物体上的光吗?

4

3 回答 3

21

是的,你必须使用多个灯来实现这一点,伪造反射光。计算真实反射光不是内置的(计算上非常复杂/昂贵)。您有多种选择。

第二个定向灯,它可能始终处于与太阳相反的位置和方向。

保持恒定的半球光。半球照明获得天空颜色和地面颜色和强度,并为您的照明增加了额外的深度。

//                                    sky color ground color intensity 
hemiLight = new THREE.HemisphereLight( 0x0000ff, 0x00ff00, 0.6 ); 

这是一个工作示例https://threejs.org/examples/#webgl_lights_hemisphere

您可以使用不同灯光的任意组合,但要注意性能权衡。

还值得一提的是通过在材质中将 wrapAround 属性设置为 true 来启用半朗伯着色。这可以更好地衰减黑色,从而减少刺眼的照明。更多的中间色调和更少的黑色。

于 2013-03-18T15:00:13.400 回答
21

我使用这两种灯的组合来制作这个视频:http ://www.youtube.com/watch?v=m68FDmU0wGw

            var hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 0.6 );
            hemiLight.color.setHSV( 0.6, 0.75, 0.5 );
            hemiLight.groundColor.setHSV( 0.095, 0.5, 0.5 );
            hemiLight.position.set( 0, 500, 0 );
            scene.add( hemiLight );

            var dirLight = new THREE.DirectionalLight( 0xffffff, 1 );
            dirLight.position.set( -1, 0.75, 1 );
            dirLight.position.multiplyScalar( 50);
            dirLight.name = "dirlight";
            // dirLight.shadowCameraVisible = true;

            scene.add( dirLight );

            dirLight.castShadow = true;
            dirLight.shadowMapWidth = dirLight.shadowMapHeight = 1024*2;

            var d = 300;

            dirLight.shadowCameraLeft = -d;
            dirLight.shadowCameraRight = d;
            dirLight.shadowCameraTop = d;
            dirLight.shadowCameraBottom = -d;

            dirLight.shadowCameraFar = 3500;
            dirLight.shadowBias = -0.0001;
            dirLight.shadowDarkness = 0.35;
于 2013-03-20T17:45:35.523 回答
0

你可以使用 scene.environment 来完成这项工作,这里已经有一个很好的例子:

https://gltf-viewer.donmccurdy.com/

在此处查看 gltf-viewer 的代码,它在阳光下做得很好。

https://github.com/donmccurdy/three-gltf-viewer/blob/main/src/viewer.js

注意环境变量,它们使用 venice_sunset_1k.hdr 作为默认背景。

更详细地说,他们使用背景作为他们的环境,但他们没有“显示”它们,你可以使用下面的代码

    this.pmremGenerator = new PMREMGenerator( this.renderer );
    this.pmremGenerator.compileEquirectangularShader();
    var rgbe_loader = new RGBELoader();
    var that = this;
    rgbe_loader.setDataType(UnsignedByteType).load("/environment/venice_sunset_2k.hdr", function(texture) {

        var envMap = that.pmremGenerator.fromEquirectangular(texture).texture;

        that.scene.environment = envMap;

        texture.dispose();
        that.pmremGenerator.dispose();

    });

可以在https://polyhaven.com/a/venice_sunset中找到 hdr 文件

于 2022-02-11T17:18:53.883 回答