camera equipped with a three.js skybox

I need help with creating a skybox attached to the player camera. When the camera moves, the skybox also moves causing the texture to stretch. How can I prevent this stretching issue?

Here is the code snippet I'm using:

var textureCube = THREE.ImageUtils.loadTextureCube( urls );
textureCube.format = THREE.RGBFormat;
var shader = THREE.ShaderUtils.lib[ "cube" ];
shader.uniforms[ "tCube" ].value = textureCube;

cubematerial = new THREE.ShaderMaterial({
    fragmentShader: shader.fragmentShader,
    vertexShader: shader.vertexShader,
    uniforms: shader.uniforms,
    depthWrite: false,
    side: THREE.BackSide
});
skyBox = new THREE.Mesh(new THREE.CubeGeometry(1000,1000,1000), cubematerial);
camera.add(skyBox);

Answer №1

After exploring various Three.js examples, I came across a solution for achieving a specific effect. The tutorial at is no longer up-to-date. Instead, the method used in these examples involves adding a skybox to a separate scene with a fixed camera, and then rendering both scenes simultaneously. For more details, refer to the webgl_materials_cars.html example.

Since I am utilizing a third-person camera linked to a character, it is necessary to synchronize the world rotation between the character's camera and the skybox camera. This synchronization can be achieved during the render process with the following code snippet:

function render(){
<...>
    skyboxCamera.rotation.setEulerFromRotationMatrix( new THREE.Matrix4().extractRotation( camera.matrixWorld ), skyboxCamera.eulerOrder );
    renderer.render(skyboxScene, skyboxCamera);
    renderer.render(scene, camera);
<...>
}

Answer №2

Although it's a closed question, I have an alternative solution that eliminates the need for an extra scene in case anyone is interested:

  1. Begin by following this tutorial closely:

  2. You can then implement the following shader (I've included it in three.js ShaderLib, but if you prefer not to modify three's source code, add it separately):

    'skybox': {
    
    uniforms: { "tCube": { type: "t", value: null },
                "tFlip": { type: "f", value: -1 } },
    
    vertexShader: [
    
        "varying vec3 vWorldPosition;",
        
        THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
        
        "void main() {",
        
        "   vec4 worldPosition = modelMatrix * vec4( position, 1.0 );",
        "   vWorldPosition = worldPosition.xyz;",
        
        "   gl_Position = projectionMatrix * modelViewMatrix * vec4( position + cameraPosition, 1.0 );",
        
            THREE.ShaderChunk[ "logdepthbuf_vertex" ],
        
        "}"
        
    ].join("\n"),
    
    fragmentShader: [
    
        "uniform samplerCube tCube;",
        "uniform float tFlip;",
        
        "varying vec3 vWorldPosition;",
        
        THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
    
        "void main() {",
        
        "   gl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );",
        
            THREE.ShaderChunk[ "logdepthbuf_fragment" ],
        
        "}"
        
    ].join("\n")
    

    },

  3. To create your skybox, follow these steps:

    // urls should contain the textures to be used
    var cubemap = THREE.ImageUtils.loadTextureCube(urls); 
    cubemap.format = THREE.RGBFormat; 
    
    var shader = THREE.ShaderLib['skybox']; // initialize the custom skybox shader
    shader.uniforms['tCube'].value = cubemap; // assign textures to shader
    
    // create shader material
    var skyBoxMaterial = new THREE.ShaderMaterial( {
      fragmentShader: shader.fragmentShader,
      vertexShader: shader.vertexShader,
      uniforms: shader.uniforms,
      depthWrite: false,
      side: THREE.BackSide
    });
    
    // create skybox mesh
    var skybox = new THREE.Mesh(
      new THREE.CubeGeometry(1000, 1000, 1000),
      skyBoxMaterial
    );
    
    // Ensuring the skybox remains visible even after moving the camera too far away
    skybox.frustumCulled = false;
    

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

Error: The property 'price' is not defined and cannot be read

As I work on setting up my online store for teaching node.js, I encountered an issue when trying to delete a product from the products.json file. Surprisingly, once a product is removed, the corresponding entry in cart.json gets deleted as well. The error ...

Having difficulty accessing a PHP ajax post request

I've scoured every resource but can't seem to find a solution to this issue. I'm in the process of writing an ajax script, however, I am struggling to retrieve the correct value from the POST request. Here is the code I have so far: <t ...

"Embrace the power of Ajax and JSON with no regrets

function register() { hideshow('loading', 1); //error(0); $.ajax({ type: 'POST', dataType: 'json', url: 'submit.php', data: $('#regForm').serialize(), su ...

When the open button is clicked, the Div will toggle between open and closed states

Recently, some of my questions have not been well-received, which makes me feel a bit disheartened. It's important to remember to be kind when providing feedback. I've noticed that some people downvote without offering constructive criticism, whi ...

Utilizing Nicknames in a JavaScript Function

I'm dealing with a function that is responsible for constructing URLs using relative paths like ../../assets/images/content/recipe/. My goal is to replace the ../../assets/images section with a Vite alias, but I'm facing some challenges. Let me ...

Struggling with JavaScript conditional statements

Currently, I am in the process of creating a login and registration panel using jQuery and PHP. Essentially, if there are any errors during registration, it sets certain form errors, redirects back to the registration page, the JavaScript identifies these ...

What is the process for reversing styles on the second click?

This is the script I've written: function displayPanel(index, colorCode) { buttons.forEach(function(button){ button.style.borderBottom=""; }); tabButtons[index].style.borderBottom="none"; panels.forEach(function(panel){ ...

Tips for refreshing a DOM element after inserting with jQuery

I'm trying to update the LI element after using the insertBefore function in jQuery. The issue arises after adding new elements to UL where I encounter difficulty deleting the same element (using emailTagRemove). Check out the demo to see the proble ...

Determine if offcanvas element is visible upon initialization in Bootstrap 5 Offcanvas

I have a search-filter offcanvas div for location and property type on this webpage: On larger screens (desktop), the offcanvas is always visible, but on smaller screens (mobile), it is hidden and can be toggled with a button. This functionality works per ...

Switch between showing or hiding at least three divs

I'm currently using a simple script that toggles the visibility of two div elements: <script type='text/javascript'> $(window).load(function(){ function toggle_contents() { $('#page1').toggle(); ...

Guide to attaching and displaying an image on a Three.js map

Currently, I have a 3D map loaded with three.js that includes mouse interaction. I've managed to place an image on the map using absolute positioning, but unfortunately, as I move the map around, the image stays stationary. Does anyone know how I can ...

When the `back` button is clicked in a browser from a different domain, does it trigger a page reload?

Imagine a scenario where a user accesses mydomain.com. At this point, the history stack contains only one entry. Then, the user clicks on a link within my website that leads to mydomain.com/cool, causing another state to be pushed onto the stack. Now, with ...

Issue: The GET request to a third-party API using Fetch API encountered a "TypeError: Failed to fetch" error

After conducting extensive research and investing hours into this issue, I am at the point where I need to seek assistance. I am attempting to make a GET call to a third-party Infutor API using the fetch API in my ReactJS Project. Initially, I encountered ...

add an svg string element to a pre-existing svg element

I already have an <svg></svg> element in my code and now I want to add another svg element to it as a string. For instance: var new_svg = '<g><text x="100" y="100">Hello</text></g>'; d3.select('svg' ...

What could be causing my res.statusCode to switch from 200 to 404 after using collection.replaceOne?

After executing the line of code collection.replaceOne({_id: newObj._id}, newObj), the response status code changed unexpectedly from 200 OK to 404 Not Found. What could be causing this issue? Take a look at the following snippet of code: const updatePost ...

Conceal the menu on jQuery click event anywhere on the page

There is a button on my interface that, when clicked, opens a menu. The button appears blue when selected and the menu opens, but when a menu item is chosen, the menu closes and the button returns to its original state. However, my problem arises when I ...

Discovering feedback from JavaScript

I have been attempting to call JavaScript from a Visualforce page. The code snippet below shows a sample of the Visualforce page where I am trying to call a get method and am curious to see the response. Once I click on preview in the developer console, th ...

When the value of a Formcontrol is changed using valueAccessor.writeValue(), it remains unchanged

Encountering a similar issue as seen in this stack overflow post, but the solution provided isn't resolving the issue. Perhaps you can offer assistance on that thread. In my scenario, I have created a directive for formatting phone numbers: import { ...

`Sending binary data to client through GraphQL: A comprehensive guide`

I have a GraphQL server running on express. I am looking for a way to send images back to the client using nodejs buffer objects instead of JSON. How can I configure my graphql server to return bytes directly, without encoding them in base64 due to large ...

An easy guide to sorting outcomes using JSON

I have JSONResults in my Controller that contains all the data from a table. On the client's HTML detail view page, I am using JavaScript to fetch this data. How do I extract data from JSON where the client name is equal to klID (this is a JSON string ...