The display of the expected outcome for the Three.js global heightmap is not appearing as intended

After discovering a global 4k height map online, I was eager to create a model of Earth using it. Fortunately, I stumbled upon an open-source script that promised to do just that.

function createGeometryFromMap() {
    var depth = 512;
    var width = 512;

    var spacingX = 3;
    var spacingZ = 3;
    var heightOffset = 2;

    var canvas = document.createElement('canvas');
    canvas.width = 512;
    canvas.height = 512;
    var ctx = canvas.getContext('2d');

    var img = new Image();
    img.src = "assets/earth.jpg";
    img.onload = function () {
        // draw on canvas
        ctx.drawImage(img, 0, 0);
        var pixel = ctx.getImageData(0, 0, width, depth);

        var geom = new THREE.Geometry;
        var output = [];
        for (var x = 0; x < depth; x++) {
            for (var z = 0; z < width; z++) {
                // get pixel
                // since we're grayscale, we only need one element

                var yValue = pixel.data[z * 4 + (depth * x * 4)] / heightOffset;
                var vertex = new THREE.Vector3(x * spacingX, yValue, z * spacingZ);
                geom.vertices.push(vertex);
            }
        }

        // creating triangles from vertices
        for (var z = 0; z < depth - 1; z++) {
            for (var x = 0; x < width - 1; x++) {
                var a = x + z * width;
                var b = (x + 1) + (z * width);
                var c = x + ((z + 1) * width);
                var d = (x + 1) + ((z + 1) * width);

                var face1 = new THREE.Face3(a, b, d);
                var face2 = new THREE.Face3(d, c, a);

                face1.color = new THREE.Color(scale(getHighPoint(geom, face1)).hex());
                face2.color = new THREE.Color(scale(getHighPoint(geom, face2)).hex())

                geom.faces.push(face1);
                geom.faces.push(face2);
            }
        }

        geom.computeVertexNormals(true);
        geom.computeFaceNormals();
        geom.computeBoundingBox();

        var zMax = geom.boundingBox.max.z;
        var xMax = geom.boundingBox.max.x;

        var mesh = new THREE.Mesh(geom, new THREE.MeshLambertMaterial({
            vertexColors: THREE.FaceColors,
            color: 0x666666,
            shading: THREE.NoShading
        }));
        mesh.translateX(-xMax / 2);
        mesh.translateZ(-zMax / 2);
        scene.add(mesh);
        mesh.name = 'valley';
    };

}

function getHighPoint(geometry, face) {

    var v1 = geometry.vertices[face.a].y;
    var v2 = geometry.vertices[face.b].y;
    var v3 = geometry.vertices[face.c].y;

    return Math.max(v1, v2, v3);
}

Despite successful attempts with the Grand Canyon and Hawaii heightmaps provided, my own global heightmap didn't yield desired results.

This is the terrain of Grand Canyon:

https://i.sstatic.net/9MOTO.jpg

This is the global heightmap that I am using:

https://i.sstatic.net/ZqZ6i.jpg

And this is the result I am getting for the 3D terrain of the world:

https://i.sstatic.net/kCPOg.jpg

It's clear that something is off, as the outcome doesn't resemble our planet at all.

Answer №1

When instructing your 2D canvas context to .drawImage(), it will render a 4000 pixels image on top of a 512 pixels canvas. According to the MDN documentation, this is the standard behavior when using only three arguments: as explained here.

You have two options:

  • Adjust the Earth image size to fit within your 512x512 pixels canvas by utilizing the 4th and 5th arguments for dWidth, dHeight.
  • Expand your canvas dimensions to align with the width and height of your Earth image.

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

What is the process for closing the side menu by clicking on the dark area?

I created a basic side navigation menu. When you resize the window to a smaller size, a red square will appear. If you click on this red square, the menu will open. The menu opens correctly, but I want it to close when I click on the dark area instead of ...

Discover the steps to download web page data using Objective-C while ensuring that JavaScript has finished executing

I attempted something similar: NSString *url = @"http://www.example.com"; NSURL *urlRequest = [NSURL URLWithString:url]; NSError *error = nil; NSString *htmlContent = [NSString stringWithContentsOfURL:urlrequest encoding:NSUTF8StringEncoding error:&e ...

Interested in building an album app using Django Tastypie and Backbone?

I'm currently working on developing a new album application using django, with two essential django models: class Album(models.Model): name = models.CharField(max_length=100) family = models.ForeignKey(FamilyProfile) created_by = models.F ...

Cannot find property in type, and the parameter is implicitly of an unspecified type

I've been encountering this issue where I keep getting an error message. I attempted to resolve it by setting "noImplicitAny": false in tsconfig.json, but unfortunately that did not work. As for the 'Property does not exist on type' error, I ...

Adaptable Image Functionality in Jquery Carousel

I've encountered an issue with my images within a jquery slider. While the slider itself is functioning properly, I am facing a couple of challenges. Initially, I aimed to make the images responsive, but upon removing the height property, the content ...

Guide on displaying an X mark on a checkbox in AngularJS when the ng-disabled value is set to true

Is there a way to display an X mark in red on checkboxes when the ng-disabled condition is evaluated as true? I am a beginner in Angular.js and would appreciate any assistance. Here is what I have attempted so far: if (module.Name === 'val1' || ...

Extract latitude and longitude coordinates from a dataset by applying a rectangular filter

I have developed a program that extracts information from a JSON object and showcases it on a webpage, specifically focusing on Public Bike Stations. The JSON object includes the latitude and longitude of each station, making it easy to locate them. My cu ...

Issue with Vue Loading Overlay Component functionality in nuxt2 .0

I've integrated the vue-loading-overlay plugin into my project. plugins/vueloadingoverlaylibrary.js import Vue from 'vue'; import Loading from 'vue-loading-overlay'; // import 'vue-loading-overlay/dist/vue-loading.css'; ...

Setting the button value to a textbox and refreshing the status information (Codeigniter)

How do I pass the value of my "ACTIVE" status attribute to my textbox? I want to update the user's status by clicking the ACTIVE button. The user's status is currently pending. While I can easily pass the userID, I'm facing an issu ...

Steps for placing a second pie chart alongside the initial one within a Bootstrap card

Is it possible to have two pie charts with different values using chart.js? I attempted to duplicate the script for the first chart to create a second one, but it did not display correctly. Why is the second pie chart not showing up? $(document).ready(fu ...

Tips for updating a URL using data obtained from a JSON response

As I loop through an array from JSON, I extract all the necessary information. For example, if I have cards for blog posts that include the title, short description, published date, and URL. When clicking on a card, it redirects to a corresponding page ba ...

Transformation from a graphql query to a json query

In exploring the GraphQL example, I am wondering how to make a similar request with JSON in Javascript. The GraphQL query in the example is: { trip( from: {place: "NSR:StopPlace:5533" }, to: {place:"NSR:StopPlace:5532"} ) { tripPatte ...

Problem encountered with modal and JavaScript: Uncaught TypeError: Unable to retrieve the property 'classList' of null

Trying to implement a modal feature for the first time but encountering an error when clicking the button. Unsure if I'm following the correct procedure as a JS beginner. Any assistance would be appreciated. ERROR { "message": "Uncaugh ...

The Next.js build version encounters an issue with 'auth' property being undefined and causes a failure

Our team has been happily working on a Next.js based website for the past few months. Everything was running smoothly without any major issues until yesterday when we encountered an error on the production version while using router.push: Cannot read prope ...

Mastering the utilization of API routes within the Next JS 13 App Router framework

As a newcomer to React JS and Next.js, I recently made the switch from using the Page Router API in Next.js to utilizing the new App Router introduced in Next.js 13. Previously, with the Page Router, creating a single GET request involved nesting your "JS ...

Turn off javascript on a website that you are embedding into another site

Is it feasible to deactivate JavaScript on a website you are attempting to embed? If the website is working against your embedding efforts, could you effectively neutralize all their JavaScript, even if it requires users to engage with the site without J ...

Problem with Raphael Sketch and Request to Ajax

Utilizing Raphael.js and jQuery Ajax, I am attempting to display some dots (circles) on the map in this [Demo][1]. I have a PHP file called econo.php which looks like this: <?PHP include 'conconfig.php'; $con = new mysqli(DB_HOST,DB_USER,DB_P ...

Monitor the number of clicks (conversions) on Google Adwords

On my website, I have a contact form and I would like to keep track of how many people click on it and gather information similar to what Google analytics provides. Here is what I want the form to do: When the button is clicked Ensure that all fields are ...

React function failing to utilize the latest state

I'm facing an issue with my handleKeyUp function where it doesn't seem to recognize the updated state value for playingTrackInd. Even though I update the state using setPlayingTrackInd, the function always reads playingTrackInd as -1. It's p ...

Utilizing the power of functional programming with Javascript to perform mapping

In order to address a fundamental issue involving list indexes, I am seeking a functional solution. To illustrate this problem in the context of React and ramda, consider the following example. const R = require('ramda'); const array = ["foo", ...