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…