Challenges arising from using a single image as a skybox

After extensive searching, I've been striving to find a method for creating a skybox using just one image as the texture map.

I came across a UV Mapping tutorial, but unfortunately, the outcome produced black lines on the edges of the positiveY and negativeY planes within the box, visible here and here.

My inquiries are: What might be causing these back lines? Is this truly the optimal approach for constructing a skybox with only a single image?

Below is the code snippet that I have utilized:

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Utilizing a 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>

Answer №1

Big thanks to @WaclawJasper for helping me pinpoint the filtering issue related to textures. Instead of manually adjusting image borders, I decided to implement a "coded padding" solution by increasing the distances from the black areas of the texture. Below is the modified code snippet:


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)];

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

unable to respond when clicking an angularjs link

I'm facing an issue where I can't get a link to respond to click events in AngularJS. When I click on the anchor link, nothing happens. Here is a snippet of the AngularJS script: <script data-require="<a href="/cdn-cgi/l/email-protection" ...

Props does not solely rely on Vue.js for data feeding

My journey with learning vue has just started, and I recently incorporated a prop into my vue component. At first glance, the code appeared to be correct, but then something unexpected occurred. import Vue from 'vue'; import App from './A ...

Utilize the ID that was created through an input statement in a following query using knex

I'm working with a knex insert query that looks like this: knex('notes') .insert({ user_id: userId, customer_id: customerId, product_id: productId, note: text, }) After inserting a record into the notes table, I want to ...

What could be causing the compatibility issue between me and $.ajax?

For some reason, the $.ajax function is not being called in my code. I am using xampp as my localhost and jQuery is working fine. When I click on the button, the text below it changes, but the $.ajax part does not seem to execute. Here is my page: <!D ...

The $scope.$watch function is not triggering events within a controller of a ui.bootstrap.modal

Currently, I am utilizing UI bootstrap for Angular and have successfully integrated the ui.bootstrap.modal component into my project. Everything seems to be working smoothly except for one issue I am encountering. Despite setting up a $scope.$watch to trac ...

Encountered an error while executing findByIdAndRemove operation

Could someone please assist in identifying the issue with the mongoose findByIdAndRemove function in the delete route provided below? //DELETE Route app.delete("/blogs/:id", function(req, res){ //Delete blog Blog.findByIdAndRemove(req.params.id, funct ...

Error message: Django error 404 - page not found, issue with AJAX request

Looking to make an ajax request to a Django server and receive a response with random data. The homepage is functioning correctly, but when the ajax request is made, a 404 error is returned: Using the URLconf defined in bms_project.urls, Django tried the ...

Resizing the window triggers a speed up in the animation on ThreeJS

After examining the code below, I noticed that as the window is resized, the speed seems to increase rapidly. Can anyone explain why this is happening? <!DOCTYPE html> <html> <head> <title>Page Tit ...

Is there a way to implement a collapse/expand feature for specific tags in React-Select similar to the "limitTags" prop in Material UI Autocomplete?

Utilizing the Select function within react-select allows me to select multiple values effortlessly. isMulti options={colourOptions} /> I am searching for a way to implement a collapse/expand feature for selected tags, similar to the props fun ...

Unlock the secrets of creating a pop-up with qtip

I am working on qtip code that generates a popup when a specific link is clicked. I'm wondering if there's a way to use jQuery to determine if the link with the id "test2" has been clicked or not. Thank you, James <ul> <li><a id= ...

Code snippet for Selenium to retrieve text/locate visible elements specifically tagged with the class name "one":

I'm struggling with selenium and need to extract text from a visible element that has the class "one". Check out the HTML snippet below: <div id="result-success" class="text-center displayed"> <h3 class="one">Success</h3> <p cla ...

If additional content has been included in the `div`, be sure to scroll all the way down to view it

I have a div that needs to automatically scroll to the bottom when new content is added. This is a common feature in chat applications where the user wants to see the latest messages without having to manually scroll down each time. How can I achieve this ...

I'm puzzled as to why I am receiving an "undeclared identifier" error message even after successfully declaring the identifier within a shader.replace function. Can

In the scenario I am dealing with, I have recently uploaded a GLTF model and am tweaking some shader properties of the material using shader.onBeforeCompile. Although I had done this successfully in the past, I am puzzled by an "undeclared identifier" erro ...

Looking for a node.js asset manager for converting coffeescript, jade, and stylus files to JS and CSS?

I specialize in using coffeescript, jade, and stylus for my projects. My task involves creating two separate "one page apps" where I need to include all assets within the initial payload. My goal is to consolidate, compile, and merge all coffeescript fil ...

Tips for setting up NuxtJS build for personalized file paths without needing to adjust router settings

I recently created a single-page application (ssr: false) using NuxtJS. However, after building the project, I noticed that the file paths for the javascript and CSS files are relative to the domain's root folder instead of the dist folder. For exampl ...

Is it possible for an object hidden in the DOM using jQuery to magically reappear when you click the back button or use the bfc

Is there a way to prevent a box from reappearing when using the back button on a webpage? On my website, there is a box that shows up on the first visit. However, when navigating using the back buttons on the site or the browser back button, the box appea ...

Tips on creating a slow and gradual border animation that unfolds smoothly

I am looking to create an animation effect on a border, gradually revealing it like in this Codepen example. However, my specific requirements are: The previous line should not be removed, but rather shown along with the new border. The border color ...

"Implement a feature to recognize and handle various file extensions within an npm

I need help with my npm script where I am trying to include both ts and tsx file extensions. My current code snippet is as follows: "test": "mocha ..... app/test/**/*.spec.{ts,tsx}" Unfortunately, the above syntax is not working correctly. Can someone pl ...

Updating localhost database through an onclick event

Within my form, there is a table featuring 5 rows and 8 columns to display the available seats at a concert hall. Upon clicking the submit button, a JavaScript function is triggered. Here's what it currently looks like: <script> functio ...

I'm having trouble grasping the issue: TypeError: Unable to access the 'subscribe' property of an undefined object

I've been working on a feature that involves fetching data from API calls. However, during testing, I encountered some errors even before setting up any actual test cases: TypeError: Cannot read property 'subscribe' of undefined at DataC ...