单个图像天空盒的问题

时间:2022-03-26 06:35:17

I've been searching a lot for a way to create a skybox using one single image as a texture map.

我一直在寻找一种使用单个图像作为纹理贴图来创建天空盒的方法。

I found a UV Mapping tutorial, but the results generated black lines in the edges of positiveY and negativeY planes in the box, as shown here and here.

我找到了一个UV Mapping教程,但结果在框中的positiveY和negativeY平面的边缘产生了黑线,如此处和此处所示。

My questions are: What could be causing these back lines? Is this the best way to create a skybox using only single image?

我的问题是:什么可能导致这些背线?这是仅使用单个图像创建天空盒的最佳方法吗?

Here is my code:

这是我的代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Using an skybox!</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.js"></script>
<script src="http://threejs.org/examples/js/controls/TrackballControls.js">        </script>
<style>
    body {margin:0; overflow:hidden}
    canvas {width:100%; height:100%}
</style>
</head>
<body>
<div id="threejs"></div>
<script>
    var scene, renderer;
    var camera, controls;
    var width, height;
    var light, ambient;
    var cube;

    init();

    function init() {
        width = window.innerWidth;
        height = window.innerHeight;

        loadScene();
        loadMeshes();
        loadLights();
        render();
    };

    function loadScene() {
        scene = new THREE.Scene();
        camera = new THREE.PerspectiveCamera(45, width/height, 0.1, 2000);
        camera.position.z = 15;
        camera.lookAt(scene.position);
        renderer = new THREE.WebGLRenderer({antialias:true} );
        renderer.setSize(width, height);
        renderer.setClearColor(0xdfdfdf);
        renderer.shadowMap.enabled = true;
        renderer.shadowMapSoft = true;
        document.getElementById("threejs").appendChild(renderer.domElement);

        controls = new THREE.TrackballControls( camera, renderer.domElement);
    };

    function loadMeshes(){  
        var boxMap = new THREE.TextureLoader().load('skybox3.jpg');

        var material = new THREE.MeshPhongMaterial({
            map: boxMap,
            side: THREE.BackSide        
        });

        var posx = [new THREE.Vector2(0.5,  .666), new THREE.Vector2(0.5,  .333),
                    new THREE.Vector2(0.75, .333),  new THREE.Vector2(0.75, .666)];
        var negx = [new THREE.Vector2(0,    .666), new THREE.Vector2(0,    .333),
                    new THREE.Vector2(0.25, .333),  new THREE.Vector2(0.25, .666)];

        var posz = [new THREE.Vector2(0.25,  .666), new THREE.Vector2(0.25, .333),  
                    new THREE.Vector2(0.5,   .333),  new THREE.Vector2(0.5,  .666)];
        var negz = [new THREE.Vector2(0.75,  .666), new THREE.Vector2(0.75, .333), 
                    new THREE.Vector2(1  ,   .333),  new THREE.Vector2(1,    .666)];

        var posy = [new THREE.Vector2(0.25,  1),    new THREE.Vector2(0.25, .666),
                    new THREE.Vector2(0.5,  .666),  new THREE.Vector2(0.5,   1)];
        var negy = [new THREE.Vector2(0.25, .333), new THREE.Vector2(0.25, 0), 
                    new THREE.Vector2(0.5,  0),     new THREE.Vector2(0.5,  .333)];

        var cubeGeometry = new THREE.BoxGeometry(1000, 1000, 1000);

        cubeGeometry.faceVertexUvs[0] = [];

        cubeGeometry.faceVertexUvs[0][0] = [ posx[0], posx[1], posx[3]];
        cubeGeometry.faceVertexUvs[0][1] = [ posx[1], posx[2], posx[3]];
        cubeGeometry.faceVertexUvs[0][2] = [ negx[0], negx[1], negx[3]];
        cubeGeometry.faceVertexUvs[0][3] = [ negx[1], negx[2], negx[3]];

        cubeGeometry.faceVertexUvs[0][4] = [ posy[0], posy[1], posy[3]];
        cubeGeometry.faceVertexUvs[0][5] = [ posy[1], posy[2], posy[3]];
        cubeGeometry.faceVertexUvs[0][6] = [ negy[0], negy[1], negy[3]];
        cubeGeometry.faceVertexUvs[0][7] = [ negy[1], negy[2], negy[3]];

        cubeGeometry.faceVertexUvs[0][8] = [ posz[0], posz[1], posz[3]];
        cubeGeometry.faceVertexUvs[0][9] = [ posz[1], posz[2], posz[3]];
        cubeGeometry.faceVertexUvs[0][10] = [ negz[0], negz[1], negz[3]];
        cubeGeometry.faceVertexUvs[0][11] = [ negz[1], negz[2], negz[3]];


        cube = new THREE.Mesh(cubeGeometry, material);
        scene.add(cube);

    };

    function loadLights() {
        ambient = new THREE.AmbientLight(0xbbbbbb);
        light = new THREE.SpotLight(0x5555555);
        light.castShadow = true;
        light.shadowCameraNear = 8;
        light.shadowCameraFar = 400;
        light.shadowDarkness = 1;
        light.shadowMapWidth = 2048;
        light.shadowMapHeight = 2048;
        light.position.set(8, 15, 15);

        scene.add(ambient);
        scene.add(light);
    };

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

    window.addEventListener("resize", function() {
        width = window.innerWidth;
        height = window.innerHeight;
        renderer.setSize(width, height);
        camera.aspect = width/height;
        camera.updateProjectionMatrix();
    });
</script>

1 个解决方案

#1


0  

Thanks to @WaclawJasper I could see that it was a filtering problem with the textures. So instead of padding the images borders, being necessary to edit it externally, I tried to execute a "codded padding" increasing the distances to the black parts of texture. Here is my alteration in original code:

感谢@WaclawJasper我可以看到它是纹理的过滤问题。因此,不是填充图像边框,而是需要在外部编辑它,我尝试执行“编码填充”,增加到纹理的黑色部分的距离。这是我对原始代码的修改:

        var posx = [new THREE.Vector2(0.5,  .665), new THREE.Vector2(0.5,  .334),
                    new THREE.Vector2(0.75, .334), new THREE.Vector2(0.75, .665)];
        var negx = [new THREE.Vector2(0,    .665), new THREE.Vector2(0,    .334),
                    new THREE.Vector2(0.25, .334), new THREE.Vector2(0.25, .665)];

        var posz = [new THREE.Vector2(0.25,  .665), new THREE.Vector2(0.25, .334),  
                    new THREE.Vector2(0.5,   .334), new THREE.Vector2(0.5,  .665)];
        var negz = [new THREE.Vector2(0.75,  .665), new THREE.Vector2(0.75, .334), 
                    new THREE.Vector2(1  ,   .334), new THREE.Vector2(1,    .665)];

        var posy = [new THREE.Vector2(0.251,  1),    new THREE.Vector2(0.251, .665),
                    new THREE.Vector2(0.499,  .665), new THREE.Vector2(0.499,   1)];
        var negy = [new THREE.Vector2(0.251, .334),  new THREE.Vector2(0.251, 0), 
                    new THREE.Vector2(0.499,  0),    new THREE.Vector2(0.499,  .334)];

#1


0  

Thanks to @WaclawJasper I could see that it was a filtering problem with the textures. So instead of padding the images borders, being necessary to edit it externally, I tried to execute a "codded padding" increasing the distances to the black parts of texture. Here is my alteration in original code:

感谢@WaclawJasper我可以看到它是纹理的过滤问题。因此,不是填充图像边框,而是需要在外部编辑它,我尝试执行“编码填充”,增加到纹理的黑色部分的距离。这是我对原始代码的修改:

        var posx = [new THREE.Vector2(0.5,  .665), new THREE.Vector2(0.5,  .334),
                    new THREE.Vector2(0.75, .334), new THREE.Vector2(0.75, .665)];
        var negx = [new THREE.Vector2(0,    .665), new THREE.Vector2(0,    .334),
                    new THREE.Vector2(0.25, .334), new THREE.Vector2(0.25, .665)];

        var posz = [new THREE.Vector2(0.25,  .665), new THREE.Vector2(0.25, .334),  
                    new THREE.Vector2(0.5,   .334), new THREE.Vector2(0.5,  .665)];
        var negz = [new THREE.Vector2(0.75,  .665), new THREE.Vector2(0.75, .334), 
                    new THREE.Vector2(1  ,   .334), new THREE.Vector2(1,    .665)];

        var posy = [new THREE.Vector2(0.251,  1),    new THREE.Vector2(0.251, .665),
                    new THREE.Vector2(0.499,  .665), new THREE.Vector2(0.499,   1)];
        var negy = [new THREE.Vector2(0.251, .334),  new THREE.Vector2(0.251, 0), 
                    new THREE.Vector2(0.499,  0),    new THREE.Vector2(0.499,  .334)];