Using a 2D png image as a texture around a 3D sphere in Three.js results in a dark appearance

As I explore THREE.js to showcase a 3D rotating earth on the web, my goal is to also have an image surrounding the spinning globe.

Despite trying various methods, none seemed to work out for me. The image loader option I attempted failed to display anything at all.

var img = new THREE.ImageLoader();
img.load("texture/circle.png");

Essentially, I aimed for something similar to this reference: https://i.sstatic.net/2ZRZZ.jpg

The globe animation functions smoothly, yet incorporating the circular image overlay as depicted in the provided image remains my target.

Below is the script snippet:

<script>

    var container, stats, raycaster;
    var camera, scene, renderer;
    var group;
    var mouseX = 0, mouseY = 0;

    var windowHalfX = window.innerWidth / 2;
    var windowHalfY = window.innerHeight / 2;

    init();
    animate();

    function init() {

    container = document.getElementById( 'container' );

    camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 2000 );
    camera.position.z = 500;

    scene = new THREE.Scene();

    group = new THREE.Object3D();
    scene.add( group );

    // earth

    var loader = new THREE.TextureLoader();
    loader.load( 'textures/1.jpg', function ( texture ) {

    var geometry = new THREE.SphereGeometry( 200, 20, 20 );

    var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
    var mesh = new THREE.Mesh( geometry, material );
    group.add( mesh );
    raycaster = new THREE.Raycaster();


    } );


    // shadow

    var canvas = document.createElement( 'canvas' );
    canvas.width = 128;
    canvas.height = 128;

    var context = canvas.getContext( '2d' );
    var gradient = context.createRadialGradient(
    canvas.width / 2,
    canvas.height / 2,
    0,
    canvas.width / 2,
    canvas.height / 2,
    canvas.width / 2
    );
    
    context.fillStyle = gradient;
    context.fillRect( 0, 0, canvas.width, canvas.height );

    var texture = new THREE.Texture( canvas );
    texture.needsUpdate = true;

    var geometry = new THREE.PlaneGeometry( 300, 300, 3, 3 );
    var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );

    var mesh = new THREE.Mesh( geometry, material );
    mesh.position.y = - 250;
    group.add( mesh );

    renderer = new THREE.CanvasRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );

    container.appendChild( renderer.domElement );

    stats = new Stats();
    stats.domElement.style.position = 'absolute';
    stats.domElement.style.top = '0px';
    container.appendChild( stats.domElement       );

    document.addEventListener( 'mousemove', onDocumentMouseMove, false );

   
    window.addEventListener( 'resize', onWindowResize, false );

    }

    function onWindowResize() {

    windowHalfX = window.innerWidth / 2;
    windowHalfY = window.innerHeight / 2;

    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize( window.innerWidth, window.innerHeight );

    }

    function onDocumentMouseMove( event ) {

    mouseX = ( event.clientX - windowHalfX );
    mouseY = ( event.clientY - windowHalfY );

    }


    function animate() {

    requestAnimationFrame( animate );

    render();
    stats.update();

    }

    function render() {


    camera.lookAt( scene.position );

    group.rotation.y -= 0.001;

    renderer.render( scene, camera );

    }

</script>

Answer №1

For those seeking something similar, your code may require adjustments. Please review this link: http://jsfiddle.net/MP6BF/

var container, stats, raycaster;
var camera, scene, renderer;
var group;
var mouseX = 0, mouseY = 0;

var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;

init();
animate();

function init() {

container = document.createElement('div');
document.body.appendChild(container);

camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 500;

scene = new THREE.Scene();

group = new THREE.Object3D();
scene.add( group );

// earth



var loader = new THREE.TextureLoader();
//loader.load( 'http://i.imgur.com/AV28hq6.jpg', function ( texture ) {
    loader.load('http://www.joshcarllewis.com/static/articles/html5-3d-canvas-tutorial/earth.jpg',function(texture){
var geometry = new THREE.SphereGeometry( 200, 25, 200 );

var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
var mesh = new THREE.Mesh( geometry, material );
group.add( mesh );
raycaster = new THREE.Raycaster();


} );
    loader.load( 'http://i.imgur.com/AV28hq6.jpg', function ( texture ) {
var geometry = new THREE.PlaneGeometry( 600, 575, 30, 30 );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );

var mesh = new THREE.Mesh( geometry, material );
mesh.position.z =  100;
//mesh.rotation.x = - Math.PI / 2;
scene.add( mesh );
    });


// shadow

var canvas = document.createElement( 'canvas' );
canvas.width = 128;
canvas.height = 128;

var context = canvas.getContext( '2d' );
var gradient = context.createRadialGradient(
canvas.width / 2,
canvas.height / 2,
0,
canvas.width / 2,
canvas.height / 2,
canvas.width / 2
);
//gradient.addColorStop( 0.1, 'rgba(210,210,210,1)' );
//gradient.addColorStop( 1, 'rgba(255,255,255,1)' );

context.fillStyle = gradient;
context.fillRect( 0, 0, canvas.width, canvas.height );

var texture = new THREE.Texture( canvas );
texture.needsUpdate = true;

var geometry = new THREE.PlaneGeometry( 300, 300, 3, 3 );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );

var mesh = new THREE.Mesh( geometry, material );
mesh.position.y = - 250;
//mesh.rotation.x = - Math.PI / 2;
scene.add( mesh );

renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );

container.appendChild( renderer.domElement );


document.addEventListener( 'mousemove', onDocumentMouseMove, false );

//

window.addEventListener( 'resize', onWindowResize, false );

}

function onWindowResize() {

windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;

camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();

renderer.setSize( window.innerWidth, window.innerHeight );

}

function onDocumentMouseMove( event ) {

mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );

}



function animate() {

requestAnimationFrame( animate );

render();

}

function render() {

//camera.position.x += ( mouseX - camera.position.x ) * 0.05;
//camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
camera.lookAt( scene.position );

group.rotation.y -= 0.001;







renderer.render( scene, camera );

}

Answer №2

Did you possibly forget to include some lighting in your scene?

// Adding subtle ambient lighting
var ambientLight = new THREE.AmbientLight(0x555555);
scene.add(ambientLight);

// Adding a directional light source
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);

I hope this information proves helpful!

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

Harvesting the local image file

Currently, I have implemented a form that allows users to upload images and crop them. The process flow has been established as follows: 1. User uploads the image 2. Server processes the image and sends it back to the browser 3. User crops the image a ...

Guide to configuring a background image from the public folder in a React application using Create React App

How do I properly set a background image in a .css file located in the src folder? src/Components/Component/Comp.css .services { background-image : url("./images/img-2.jpg"); background-position: center; background-size : cover; b ...

JavaScript Instant Validation: Ensuring Accuracy in Real-Time

I am trying to create a JavaScript code that validates user input based on certain rules. If the input does not meet the criteria, I want an error message to appear next to the text field. For instance, if the rule is that the first character must be a cap ...

Using Javascript to dynamically enable or disable an input field depending on the choice made in another field

I attempted to implement the solution provided in this answer for my code: How do I disable input field when certain select list value is picked but unfortunately, it is not working as expected. The scenario involves an HTML select field with the ID &apos ...

Transforming JSON format to another JSON format using AngularJS

I am in the process of setting up a questionnaire using angularjs. I have an array of responses that looks like the following, and I need to convert this object array into JSON format. How do I go about converting an object array into JSON format? ...

What is a more effective method for linking values with variables in an object?

Can you suggest a more efficient way to write this in JavaScript? let foo; if(bar) { foo = bar.value; } I am attempting to prevent a react error from occurring when `bar` is null if I were to use const foo = bar.value. ...

Using jQuery to fetch and display content only when the user hovers over

Looking to optimize page loading speed by minimizing the loading time of social icons such as Facebook Like and Twitter follow buttons. Considering displaying a static image of the like buttons initially, with the actual buttons appearing on mouse hover. ...

Creating rows dynamically in an HTML table using JavaScript

Seeking assistance with creating a dynamic html table that can add a new row each time a user clicks on a specific link. The table is meant for filling in job details for different positions. Any help with the HTML code implementation would be greatly appr ...

Exploring Angular testing by using mock services to simulate the behavior of other services

I am familiar with how to mock a function call to a service. However, I am facing a scenario where my MainService acts as a wrapper for multiple other services. export class MainService { constructor( public service1: Service1, public service2 ...

How to verify if an object in JavaScript includes a specific value?

Obtaining an array of nested objects from a database is my current task. Each object in the array includes a "metadataIdStrings" member that functions like a dictionary. For instance: [{ "customerId": 48, "uploaderId": "markdolenc", "filename": ...

Guide to dynamically adding a class in VueJS based on a certain condition

I'm in the process of transitioning a project to Vue, and I'm curious about how I can dynamically assign classes to specific elements based on database values rendered with Vue. Previously, I had this code set up without Vue: $(document).ready(f ...

Move the cursor to the start of a textarea with the power of jQuery

MyEvent.prototype.sendMessage_ = function(input) { //input is this.find('#mytextarea'); if (input.val().trim() != '') { input.val(''); $('#mytextarea').focus(); } }; //...within the html....// <text ...

Tips on using Ajax to post in HTML

Here is the code I have been working on: <script type="text/javascript"> var xmlDoc; var xmlhttp; function loadRates() { xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = readRates; xmlhttp.open("GE ...

What could be the reason for the malfunction of my error handler in ExpressJS?

Currently, I am in the process of constructing an API using ExpressJS for one of my projects and am keen on incorporating error handling. Despite consulting various online resources for guidance, I have experimented with different approaches to implement e ...

Validate User Input Using jQuery to Check if Empty or Deleted

Users can enter text into an input field, and an image will be displayed if the input is valid or invalid. I want to remove or change the image when the input field is empty. Despite writing the following code, it doesn't seem to work: $('#inpu ...

Using Jquery to toggle the visibility of divs based on radio button selections

I am struggling to hide the divs with the radio buttons until their title is clicked on. However, I am facing issues as they are not showing up when their title is clicked on. Any assistance would be greatly appreciated. SPIKE <!DOCTYPE html> &l ...

Guide to handling multiple forms within a single template using Express

If I have an index.html file containing two tables - "Customers" and "Items", along with two forms labeled "Add customer" and "Add item", how can I ensure that submitting these forms results in a new entry being added to the respective table as well as t ...

Autocomplete feature in Material-UI does not trigger the onChange event when a chip

I've encountered a quirk with the Material UI Autocomplete component. It seems that when I delete a tag directly from the chip using the (x) button, the onchange function of the autocomplete isn't triggered. Does anyone know how I can ensure that ...

Dealing with callback errors: error handling is anticipated

In my Vue web application, I have enabled ESLint and encountered an issue with the following code: myApi.get('products/12').then((prodResponse) => { state.commit('ADD_PRODUCT', {product: prodResponse.data}) }, error => { cons ...

Storing the information filled out in the form and utilizing it to navigate to the correct destination URL

With the generous assistance and insightful advice from members of Stack Overflow, I am nearing completion of my quiz project. However, I do have a few lingering questions regarding some final touches needed for the project. Before delving into those quest ...