rendering

  • Updated Demo 2 (final version) : Changed the shape of particles

  • Upgrade version demo 1: change particle size, color

  • ThreeJS official example: threejs.org/examples/#c…

The JS part of the original particle animation is more than 100 lines of code, it is not difficult to see. However, in the process of achieving the desired effect, especially in Demo 2, I still encountered many problems and even thought that it could not be achieved. Fortunately, a solution was found and the requirements were perfectly fulfilled.

This document will cover some of the key points to be aware of when implementing the two demos, some of the problems encountered, and some of the solutions.

Three. Js version: R90

Upgraded Version Demo 1

The idea for creating a particle is to define a Material and pass it as a parameter to the particle constructor.

new THREE.Sprite( material )
Copy the code

Change particle color/size

What is Material? It describes the appearance of an object.

So, to change the color or size of the particle, start with Material. The Material category has also changed during the update to the three.js version. Material supported by older versions may not be available in newer versions, as detailed later in the documentation.

The particle Wave example uses the SpriteCanvasMaterial to create the particle material, whose API is defined as follows:

Create a material that can draw custom sprites using a 2d canvas.

The constructor takes two arguments. How to modify the particle color size is clear.

var material = new THREE.SpriteCanvasMaterial( {
    color: 0xffffff.// Particle color
	program: function ( context ) {	// The method used to draw particles
		context.beginPath();
		context.arc( 0.0.0.5.0, PI2, true );	// Draw a circle. You can change the size here.context.fill(); }});Copy the code

You only change some particles

for ( var ix = 0; ix < AMOUNTX; ix ++ ) {
	for ( var iy = 0; iy < AMOUNTY; iy ++ ) {
		particle = particles[ i ++ ] = new THREE.Sprite( material ); // Change the material parameter here
		particle.position.x = ix * SEPARATION - ( ( AMOUNTX * SEPARATION ) / 2 );
		particle.position.z = iy * SEPARATION - ( ( AMOUNTY * SEPARATION ) / 2); scene.add( particle ); }}Copy the code

Upgraded Demo 2

Change the shape of the particle

Based on a demo, we can bold ideas, to change the particle shape, only need to modify. THREE SpriteCanvasMaterial method of program parameters. Yes, that’s right.

Let’s say we draw a square particle:

var material = new THREE.SpriteCanvasMaterial ({
    color: "orange".// Particle color
    program: function(context) {    // The method used to draw particles
        context.fillRect(0.0.2.2);   // Draw a square}});Copy the code

The effect is as follows:

However, when we move the mouse around and the camera Angle changes, we find a very serious problem:

Residual shadows will appear on the canvas.

It was very tragic.

I’ve been stuck with this question for a long time. I initially thought it was ThreeJS, but it turned out to be me using it incorrectly. Refer to this problem three.js canvas wont clear/Sprite trai… As well as issue# 4418. In particular, these two passages:

That is, the particle must be drawn in the region of 1×1. Beyond this area, the above residual shadow problem occurs because the excess cannot be removed in time. For example, the orange square above, with sides set to 2px, is problematic.

What if I wanted to draw bigger particles? The idea is that the program method draws particles in the region of 1 x 1, and then scales up the particles. That is, it modifies the three variables particle.scale. X, particle.scale.

The corresponding code in Demo 2:

  • Draw particle shape:

    var material2 = new THREE.SpriteCanvasMaterial ({
    
        color: '#F28321'.// Particle color
        program: function(context) {    // The method used to draw particles
            context.beginPath();
            // Draw a gradient rectangle
            var lGrd = context.createLinearGradient(0.008.0.25.0.016.0.25); 
            lGrd.addColorStop(0.'#F28321');  
            lGrd.addColorStop(1.'transparent');  
            context.fillStyle = lGrd;  
            context.fillRect(0.008.0.25.0.016.0.25);  // Note the size of the coordinates here
            // Draw bottom and top circles
            context.fillStyle = "#F28321";
            context.arc(0.0.0.008.0, PI2, true);    // Draw the bottom circle
            context.arc(0.0.25.0.008.0, PI2, true);    // Draw the top circle
            context.fill();                  
            context.closePath();
    
            // Draw the top gradient color circle
            var rGrd = context.createRadialGradient(0.0.25.0.0.0.25.0.025);
            rGrd.addColorStop(0.'transparent');  
            rGrd.addColorStop(1.'rgba(242,131,33,0.28)');  
            context.fillStyle = rGrd; 
            context.arc(0.0.25.0.025.0, PI2, true);    // Draw a circlecontext.fill(); }});Copy the code

  • Magnifying particles:

    // Update particle position and size
    for (var ix = 0; ix < AMOUNTX; ix++) {
        for (var iy = 0; iy < AMOUNTY; iy++) {
            particle = particles[i++];
            // Update particle position
            particle.position.y = (Math.sin((ix + count) * 0.3) * 50) + (Math.sin((iy + count) * 0.5) * 50);
            // Update particle size
            particle.scale.x =  particle.scale.y = particle.scale.z  = ( (Math.sin((ix + count) * 0.3) + 1) * 4 + (Math.sin((iy + count) * 0.5) + 1) * 4) *100;	// Under normal conditions, zoom in 100 times}}Copy the code

ThreeJS version

The version of ThreeJS is important in this demo. At first I use is not an example of website (www.css88.com/archives/59… The version is R56.

However, ParticleCanvasMaterial and Particle used in this code have been removed in ThreeJS R62 and later. The following problems may occur:

Uncaught TypeError: THREE.ParticleCanvasMaterial is not a constructor
Copy the code
THREE.Particle has been renamed to THREE.Sprite.
Copy the code

So keep an eye out for ThreeJS’s version and its upgrade guide.

Use ThreeJS in React

In normal cases, you can import the ThreeJS module as follows: threejs.org/docs/index….

But, in the particle wave instance, want to use js/renderers/Projector. Js and js/renderers/CanvasRenderer. Js. Import the ThreeJS module and use require to load the first two files. It still doesn’t work.

The final solution is to reference ThreeJS ‘.min.js file in HTML. Then use require in the corresponding component to load the two JS files.

Maybe there’s a better way. It needs research. Reference topic:

  • Can’t use CanvasRenderer or Projector when I’m using Three from NPM: github.com/mrdoob/thre…

  • Transform examples/js to support modules: github.com/mrdoob/thre…