Creating a spherical shape for particles using Three.js

Currently delving into the world of three.js and seeking to morph the example code below to render circular dots instead of square ones.

Check out the Codepen example here.

A different demonstration named canvas particle random showcases round particles, with a script snippet that sets them in motion:

var PI2 = Math.PI * 2;
var program = function ( context ) {

    context.beginPath();
    context.arc( 0, 0, 0.5, 0, PI2, true );
    context.fill();

};

The solution seemed clear-cut—just merge this snippet into the original script to achieve spherical particles. However, upon implementation, all I got was a blank blue screen.

Any ideas on where I might be faltering?

Answer №1

Despite the fact that this inquiry was posted over 2 years ago, it may still be beneficial to mention that one can create a custom fragment shader using a three.js ShaderMaterial:

let geometry = new three.Geometry();
geometry.vertices.push(new three.Vector3(0,0,0));
let material = new three.ShaderMaterial({
    transparent: true,
    uniforms: {
        size: {value: 10},
        scale: {value: 1},
        color: {value: new three.Color('maroon')}
    },
    vertexShader: three.ShaderLib.points.vertexShader,
    fragmentShader: `
    uniform vec3 color;
    void main() {
        vec2 xy = gl_PointCoord.xy - vec2(0.5);
        float ll = length(xy);
        gl_FragColor = vec4(color, step(ll, 0.5));
    }
    `
});
let points = new three.Points(geometry, material);

Answer №2

If you're looking to create circles using PointsMaterial, one method is to use a texture as the map. However, another approach is to dynamically generate the map with a canvas, which seems to be what the provided code is attempting to do.

Check out this fiddle where I updated your code to utilize a canvas for the texture map. Please note that I modified the colors in the parameters object to showcase different color variations.

The function below demonstrates how to create a circle on a canvas that can be used as a map:


function createCanvasMaterial(color, size) {
  var matCanvas = document.createElement('canvas');
  matCanvas.width = matCanvas.height = size;
  var matContext = matCanvas.getContext('2d');
  
  var texture = new THREE.Texture(matCanvas);
  var center = size / 2;
  
  matContext.beginPath();
  matContext.arc(center, center, size/2, 0, 2 * Math.PI, false);
  // Additional code for filling and updating texture
  
  return texture;
}

The loop initializes the materials array based on the parameters object:


for (i = 0; i < parameters.length; i++) {
    // Code to extract color and size values from parameters
    
    materials[i] = new THREE.PointsMaterial({
        size: 20,
        map: createCanvasMaterial('#'+hexColor, 256),
        transparent: true,
        depthWrite: false
    });

    // Additional code for creating particles and adding them to the scene
}

Remember to set depthWrite to false in the material settings. For more insights, refer to this thread.

For further details on creating circular particles with Three.js using canvas, check out my blog post here.

Answer №3

Enhance your sprites with textures:

  var texture = new THREE.TextureLoader().load("https://example.com/textures/sprites/texture.png");
  // load the texture

  for (index = 0; index < parameters.length; index++) {

    color = parameters[index][0];
    size = parameters[index][1];

    materials[index] = new THREE.PointsMaterial({
      size: size,
      map: texture // apply the texture in your material
    });

    particles = new THREE.Points(geometry, materials[index]);

    particles.rotation.x = Math.random() * 6;
    particles.rotation.y = Math.random() * 6;
    particles.rotation.z = Math.random() * 6;

    scene.add(particles);

  }

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

Tips on decorating multi-chain selection buttons

Our latest project involved implementing multi-select buttons. Due to the complexities of styling select and option tags, we decided to utilize chosen.js for this purpose. <link rel="stylesheet" href="$url_link/css/user_css/chosen.css"> <script t ...

Tips for properly formatting Sequelize association fetching in your application

I am dealing with an association many-to-many between two tables, products and orders. In the pivot table, I store the product's id, quantity, and price. However, when fetching the product, I also require the product name which can only be retrieved f ...

What are the steps to delete data in angularjs?

I attempted to eliminate the data utilizing indexOf in AngularJS. Unfortunately, the remove function isn't functioning properly. Please guide me on identifying the mistake I may be making. JavaScript: var app = angular.module('myApp', []); ...

When using Vuejs + Laravel to make an Ajax request, only the most recent information entered into the view is submitted

Can someone guide me on implementing a basic ajax request using Vue with my Laravel backend? I have a boolean field called completed in a table named courses. In the view, users can see all assigned courses and toggle their completion status by pressing a ...

What should be placed in the form action field if the router.post() method includes a parameter such as :id?

I'm struggling with how to properly submit data to my update form and what needs to be entered in the action field, especially considering the router.post includes an :id parameter. Below is the relevant code snippet: router.post('/gymupdate/:id& ...

AngularJS traditional navigation rather than using $location.path

While working in controller A, I used $location.path('/home') for redirection. However, I realized that I needed a normal redirect as $location.path does not reload the page. I am aware that in ui-route, we have $state.go({reload:true}) for this ...

What is the reason behind the escape key not functioning in the Ace editor?

While using the Ace JavaScript editor with vim keybindings, I encountered an issue. Whenever I press the escape key to exit insert mode, the editor loses focus instead of exiting the mode. How can I capture this keypress in all modern browsers so that Ace ...

Display HTML content retrieved from a string saved in a React database

I am currently in the process of creating a React page and facing a challenge with incorporating HTML content from a RTDB that has been styled using "use styles". Here is an example of the styling: import { makeStyles } from '@material-ui/core/style ...

Troubleshooting: Angular Custom Elements malfunction on Firefox, Microsoft Edge, and Internet Explorer

Experimented with the Angular Elements Demo After downloading, installing, and building the demo locally. Implemented the following code: <!doctype html> <html lang="en> <head> <meta charset="utf-8> <title>Angular Eleme ...

Issues arising from the JSON responses within the Angular application

**JS Code** Currently facing an issue with retrieving JSON object values from PHP and displaying them in the console. I have set up a post method with the user value containing email and password. In my PHP file, I am validating it and returning the value ...

Editing a video directly within the browser prior to uploading it

For my new video upload platform, I am looking to give users the ability to trim their videos directly in their browser before uploading to the cloud storage. Can anyone suggest a Javascript solution for this feature? ...

Gradually enlarging the size of the font as time progresses

$( "h1" ).hover( function(){ for(var i=0;i<255;i++){ setTimeout(function(){$("#fat").css("font-size", (i + 12) + "pt")},200); } }, function(){$("#fat").delay(200).css("font-size","12pt")} ); My goal is to gradua ...

Tips for making multiple views function with angularjs' ui-router

I attempted to follow the instructions provided here but I am unable to make it work. https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views I made sure that my bootstrap grid divs were functioning correctly by placing them all in index.html an ...

Converting javascript html object lowercase

Is there a way to dynamically adjust the height of specific letters in my label? Right now, I am overriding the text for the elements: let element = document.getElementById('xxx') element.textContent = 'Label' I attempted using <sup ...

Leveraging jquery version 2.2.2 within a grails application

In an effort to ensure compatibility in a Grails project, we are looking to change the JavaScript library versions. We recently added AngularJS 1.5.2, which requires jQuery 2.1+ (source: https://docs.angularjs.org/misc/faq). Our current version of jQuery i ...

Notify users of any unsave changes before allowing them to navigate to a different page in ReactJS

I have a unique challenge with a dynamic form in which it automatically submits when all required fields are filled out, without a submit button. Imagine a user fills out some fields and then tries to leave the form by clicking a navigation link on the app ...

ParsleyJS always seems to miss the mark when it comes to

I had previously sought advice on a different JavaScript/jQuery form validation library but was told it was outdated, so I switched to Parsley. While Parsley allowed me to make some progress, I still encountered issues with its functionality. Specifically, ...

The type 'IProduct' cannot be assigned to type '[]'

Looking for help with dispatching events between parent and child components. Interfaces: export interface IProduct { id: string; name: string; price: string; image: string; inStock: number; fastDelivery: bo ...

What is the best way to remove top divs without causing the bottom divs to shift upwards?

I am faced with a scenario where I must remove the topmost divs in a document without altering the user's view. Essentially, I need to transition from: ---------start of document div1 div2 div3 ---------start of window div4 div5 ------- ...

Passing data through events from a parent component to a child component in Vue.js using the $emit method

Having trouble making this work! I have included the $emit code in my click event to trigger a custom event. <h2 class="form_section--header">Business Hours - <a href="javascript:void(0)" v-on:click="$emit('addBusinessHours', null)"> ...