My three.js program isn't displaying anything on the screen, even though I'm confident that my

Currently, I am delving into the world of three.js with the aim of creating a 3D showroom showcasing a few planets. I have managed to create the moon, but alas, all that greets me upon running my code is a dismal black screen. Here's the code I have painstakingly put together so far (even in its updated version, it refuses to cooperate):

function main() {
    const canvas = document.querySelector('#c');
    const renderer = new THREE.WebGLRenderer({canvas});

    const fov = 35;
    const aspect = window.innerWidth / innerHeight;
    const near = 1;
    const far = 65536;
    const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
    camera.position.set(0, 0, 0);

    const controls = new THREE.OrbitControls(camera, renderer.domElement);
    controls.target.set(0, 0, 0);
    controls.update();

    const scene = new THREE.Scene();

    const light = new THREE.PointLight(0xffffff, 1, 100);
    light.position.set(50, 50, 50);
    scene.add(light);


     //moon
     const radius = 100;
     const xSegments = 50;
     const ySegments = 50;
     const geo = new THREE.SphereGeometry(radius, xSegments, ySegments);

     function makeInstance(geo, color, x) {
        const material = new THREE.MeshPhongMaterial();
        const moonMesh = new THREE.Mesh(geo, material);
        scene.add(moonMesh);

        moonMesh.position.x = x;

        return moonMesh
     }

     moon = makeInstance(geo, 0xffffff, 0);

     {
         const loader = new THREE.SphereTextureLoader();
         const texture = loader.load([
             'https://i.ibb.co/kgYT7L6/ea1d9797c9bf3dda7a23b238e5e4b364.jpg',
             'https://i.ibb.co/kgYT7L6/ea1d9797c9bf3dda7a23b238e5e4b364.jpg',
             'https://i.ibb.co/kgYT7L6/ea1d9797c9bf3dda7a23b238e5e4b364.jpg',
             'https://i.ibb.co/kgYT7L6/ea1d9797c9bf3dda7a23b238e5e4b364.jpg',
             'https://i.ibb.co/kgYT7L6/ea1d9797c9bf3dda7a23b238e5e4b364.jpg',
             'https://i.ibb.co/kgYT7L6/ea1d9797c9bf3dda7a23b238e5e4b364.jpg'
         ]);
         scene.background = texture;
     }

     function resizeRendererToDisplaySize(renderer) {
         const canvas = renderer.domElement;
         const width = canvas.clientWidth;
         const height = canvas.clientHeight;
         const needResize = canvas.width !== width || canvas.height !== height;
         if (needResize) {
             renderer.setSize(width, height, false);
         }
         return needResize;
     }

    /* ignore this for now was just testing something
 function render(time) {
         time *= 0.001;

         if (resizeRendererToDisplaySize(renderer)) {
             const canvas = renderer.domElement;
             camera.aspect = canvas.clientWidth / canvas.clientHeight;
             camera.updateProjectionMatrix();
         }

         moon.forEach((moonMesh, ndx) => {
             const speed = 0.5 + ndx * .1;
             const rot = time * speed;
             moonMesh.rotation.x = rot;
             moonMesh.rotation.y = rot;
         });*/
         renderer.render(scene, camera);

         requestAnimationFrame(render);
     }
     requestAnimationFrame(render);

     controls.addEventListener('change', render);
     window.addEventListener('resize', render);

     window.addEventListener('mousedown', (e) => {
         e.preventDefault();
         window.focus();
     });
     window.addEventListener('keydown', (e) => {
         e.preventDefault();
     });
}
main();

Despite my best efforts, I continue to be greeted by an unyielding dark void on my screen, devoid of errors or warnings. My ultimate goal is to display three planets side by side, starting off with one planet at a time. Unfortunately, I seem to be stuck at square one and can't seem to crack the code.

As an added reference, here's the HTML snippet accompanying my endeavor:

<html>

<head>
    <meta charset="utf8">
    <title> test2 </title>
    <link rel="stylesheet" href="test2.css">
</head>

<body>
    <script src="../lib/three.min.js"></script>
    <script src="../lib/OrbitControls.js"></script>
    <script src="../lib/webgl-utils.js"></script>
    <script src="../lib/webgl-debug.js"></script>

    <script src="test2.js"></script>
</body>


</html>

Answer №1

MeshPhongMaterial requires a light source to be visible. I'm not quite sure what your intentions are with the light = {} object, but it won't provide any illumination. If you want to create a star-like effect, consider adding a genuine THREE.PointLight object to your scene. It might also be helpful to begin by incorporating an AmbientLight to ensure your objects are properly positioned.

Regarding your star background, the stars appear as tiny 1px dots that dissolve into darkness when scaled down. They look like this in the demonstration provided here: https://i.sstatic.net/2qp3Q.png

I suggest opting for a more detailed starry background, such as the Milky Way, to enhance the overall aesthetic.

Answer №2

Encountering at least 4 issues:

  1. The existence of a SphereTextureLoader is questionable, as it's not recognized in three.js. Did you intend to use CubeTextureLoader instead?

  2. If using CubeTextureLoader, ensure that your textures are square. Cubemap textures necessitate square dimensions. Rectified by substituting with square cubemap textures.

  3. Given the camera's position at 0,0,0 and the sphere's center also being at 0,0,0, the camera resides within the sphere. I've adjusted the camera position accordingly.

  4. The light situated at 50, 50, 50 intersects with a sphere radius of 100, placing the light inside the sphere. Relocated the light outside the sphere for correct illumination.

After rectifying these discrepancies, the functionality appears to be restored.

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({
    canvas
  });

  const fov = 35;
  const aspect = window.innerWidth / innerHeight;
  const near = 1;
  const far = 65536;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
// adjusting the camera position away from the center
  camera.position.set(0, 0, 1000);

  const controls = new THREE.OrbitControls(camera, renderer.domElement);
  controls.target.set(0, 0, 0);
  controls.update();

  const scene = new THREE.Scene();

  const light = new THREE.PointLight(0xffffff, 1, 100);
// relocating the light external to the moon
  light.position.set(50, 50, 150);
  scene.add(light);


  //moon
  const radius = 100;
  const xSegments = 50;
  const ySegments = 50;
  const geo = new THREE.SphereGeometry(radius, xSegments, ySegments);

  function makeInstance(geo, color, x) {
    const material = new THREE.MeshPhongMaterial();
    const moonMesh = new THREE.Mesh(geo, material);
    scene.add(moonMesh);

    moonMesh.position.x = x;

    return moonMesh
  }

  const moon = makeInstance(geo, 0xffffff, 0);

  {
// utilize CubeTextureLoader instead of SphereTextureLoader (existence unknown)
    const loader = new THREE.CubeTextureLoader();
    const texture = loader.load([
// opt for square textures required for a cubemap
        'https://webglsamples.org/spacerocks/assets/space_rt.jpg',
        'https://webglsamples.org/spacerocks/assets/space_lf.jpg',
        'https://webglsamples.org/spacerocks/assets/space_up.jpg',
        'https://webglsamples.org/spacerocks/assets/space_dn.jpg',
        'https://webglsamples.org/spacerocks/assets/space_fr.jpg',
        'https://webglsamples.org/spacerocks/assets/space_bk.jpg',
   /*
      'https://i.ibb.co/kgYT7L6/ea1d9797c9bf3dda7a23b238e5e4b364.jpg',
      'https://i.ibb.co/kgYT7L6/ea1d9797c9bf3dda7a23b238e5e4b364.jpg',
      'https://i.ibb.co/kgYT7L6/ea1d9797c9bf3dda7a23b238e5e4b364.jpg',
      'https://i.ibb.co/kgYT7L6/ea1d9797c9bf3dda7a23b238e5e4b364.jpg',
      'https://i.ibb.co/kgYT7L6/ea1d9797c9bf3dda7a23b238e5e4b364.jpg',
      'https://i.ibb.co/kgYT7L6/ea1d9797c9bf3dda7a23b238e5e4b364.jpg'
   */
    ]);
    scene.background = texture;
  }

  function resizeRendererToDisplaySize(renderer) {
    const canvas = renderer.domElement;
    const width = canvas.clientWidth;
    const height = canvas.clientHeight;
    const needResize = canvas.width !== width || canvas.height !== height;
    if (needResize) {
      renderer.setSize(width, height, false);
    }
    return needResize;
  }

  function render(time) {
    time *= 0.001;

    if (resizeRendererToDisplaySize(renderer)) {
      const canvas = renderer.domElement;
      camera.aspect = canvas.clientWidth / canvas.clientHeight;
      camera.updateProjectionMatrix();
    }

    /* disregard this section momentarily, utilized for testing purposes
    moon.forEach((moonMesh, ndx) => {
      const speed = 0.5 + ndx * .1;
      const rot = time * speed;
      moonMesh.rotation.x = rot;
      moonMesh.rotation.y = rot;
    });
    */
    
    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);

  controls.addEventListener('change', render);
  window.addEventListener('resize', render);

  window.addEventListener('mousedown', (e) => {
    e.preventDefault();
    window.focus();
  });
  window.addEventListener('keydown', (e) => {
    e.preventDefault();
  });
}
main();
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r122/build/three.min.js"></script>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r122/examples/js/controls/OrbitControls.js"></script>
<canvas id="c"></canvas>

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

Modifying the page's left attribute dynamically with jQuery based on window resize

I am currently facing a small issue with my code. My goal is to update the 'left' CSS property of certain elements based on the difference between their current left value and the page resize amount. This way, when the background moves with a pag ...

Is there a way to use JavaScript or jQuery to automatically convert HTML/CSS files into PDF documents?

While using OS X, I noticed that in Chrome I have the option to Save as PDF in the print window by setting the destination to "Save as PDF". Is this feature available on Windows? Is there a way to easily save to PDF with just one click? How can I access t ...

What methods can be used to eliminate superfluous `require(...)` or `import "...` statements while working with Rollup?

Currently, I am in the process of developing a library named share which will be utilized in various other services. To bundle this library, I have opted for Rollup.js. share serves as a common library accessed by multiple services, therefore it is essent ...

`Downloading npm package while on vpn is proving difficult`

Whenever I attempt to download a package from npm (or yarn) while connected to a VPN (I use Psiphon) in either VScode or my Command Prompt (I'm on Windows 10), it never seems to work. Instead, after some time, I receive an error message like the follo ...

JavaScript array manipulation

I am working with an array of objects that have a year and count property like this: [{year: "1920", count: 0}, {year: "1921", count: 2}, {year: "1925", count: 0}, {year: "1930", count: 21}, ....] My goal is to popu ...

Is it possible for Masonry to incorporate RTL (Right-To-Left) direction?

Before, Masonry worked perfectly with the Left-To-Right text direction. Now, I need to adjust it for use with Right-To-Left (RTL) languages like Hebrew and Arabic. When I try running Masonry with RTL text direction, the plugin still lays out the grid in a ...

What is preventing me from adding a borderRadius to this particular React bootstrap tab?

I have been working on tabbed content and encountered an issue with applying border radius. Despite adding style={{borderRadius: "10px"}}, it seems to have no effect. This styling works perfectly everywhere else in my project, so I am puzzled as ...

Vertical scrollbar in iframe unexpectedly appears immediately after the submit button is pressed

I have designed a contact form that is displayed in an iframe within an overlay div. I have carefully adjusted the dimensions of this div to ensure that there are no scrollbars visible when the form initially appears. However, after filling out the form an ...

How can I adjust the top margin of a legend that is placed at the bottom of a Doughnut chartjs graph?

I've been working on customizing doughnut graphs with ChartJS and I'm struggling to create space between the graph and the legend. Here's my legend configuration: plugins: { legend: { display: true, align: 'start', p ...

Ensure Angular JS includes a space or special character after applying a currency filter

Is there a way to include a space or special character after the "₹" symbol? Desired output: ₹ 49 Current output: ₹49 HTML - {{cart.getTotalPrice() | currency:"₹"}} ...

Storing Json data in a variable within Angular 2: a step-by-step guide

https://i.sstatic.net/2QjkJ.png Within the params.value object, there are 3 arrays containing names that I need to extract and store in a variable. I attempted to use a ForEach loop for this purpose, but encountered an issue. Can you spot what's wron ...

In JavaScript, you can use the document.cookie property to delete specific cookie values identified by their names and values

Within my JavaScript code, I am working with a cookie that contains multiple names and values: "Token=23432112233299; sessionuid=abce32343234" When I download a file from the server, a new cookie is added to the document, resulting in the following cooki ...

Unable to connect to Alpine store from an external source due to a typescript error

Here is how I have configured my Alpine store: Alpine.store( 'state', ({ qr: '' })) Now, I am attempting to update it from an external source as follows: Alpine.store( 'state' ).qr = 'test' However, I am encounte ...

Loop through object in React

I have what seems to be a beginner question with potentially many answers available. The object named Country.js is defined as follows: const Country = { albania: { 'countryNo': 70, 'name': { ...

Incorporating MongoDB collection elements into a Discord embed display

I am trying to include my collection of documents in an embed using MongoDB's ForEach function. However, I have noticed that when attempting to add a field to the embed within the forEach loop, it appears that the code sends the message first and the ...

It is impossible to alter the data contained within the input box

Objective: Upon clicking a button to display the modal, the selected data (first and last name) should be inserted into an input box and editable. The user should be able to modify the data. Issue: The data entered into the input box cannot be edited ...

"Adding an Image within a Textbox Using Ext JS: A Step-by-Step

How can I add a search image inside a textbox created with the following code? I have created a table with a footer, and within one of the textboxes in the table, I want to include a search button that will call another function when clicked. However, desp ...

using a practical example of CORS in JavaScript

I attempted a cross-origin AJAX request (CORS) and stumbled upon this helpful example by MJHALL to get me started. Executing the example on our internal networks (2 separate domains) resulted in success, returning the desired outcome. However, when I inte ...

Executing functions with directive controllers

Is there a simple way to call a function on a directive controller by accessing the instance using its id from the parent controller? <my-directive id="id1" /> var dirController = getDirectiveByID("id1"); dirController.someFunc(); If you have any ...

Differences in HTML animations can be seen when comparing Google Chrome to Microsoft Edge. Looking for a workaround for autoplay to ensure

My intro video animation is facing recording difficulties due to the autoplay policy in Google Chrome. It seems nearly impossible to capture it accurately. If only autoplay could function for an offline HTML file, my issue would be resolved. Unfortunately ...