15
头图
Disclaimer: The graphic and model materials involved in this article are only for personal study, research and appreciation. Please do not re-modify, illegally spread, reprint, publish, commercialize, or conduct other profit-making activities.

background

"The Ring of Eldon" is a relatively popular game recently. It can be found that its Logo is composed of several arcs and line segments. This article uses the React + Three.js technology stack to realize the flame effect of Aerdon's ring Logo . The knowledge points involved in this article include: basic usage of Fire.js and other basic knowledge of Three.js .

Effect

The effect is shown in 👆 banner , the main page is composed of Logo graphics, Logo has a far-to-near loading effect, and after loading, it has an up and down easing animation effect.

Online preview :

Adapted:

  • 💻 PC end
  • 📱 Mobile terminal

accomplish

The flame effect of Logo is mainly realized by Fire.js . Before starting to realize it, let's understand its basic usage.

💡 Fire.js

Threejs provides an expansion pack that can achieve fire and smoke effects. By referencing and setting parameters, you can achieve very realistic fire and aversion effects. [However, this expansion pack has been removed from the new version]

flame sets optional property :

  • color1 : Inner flame color
  • color2 : Outer flame color
  • color3 : smoke color
  • colorBias : Color deviation
  • burnRate : Burn rate
  • diffuse : Diffusion
  • viscosity : Viscosity
  • expansion : Inflation
  • swirl : Rotation
  • drag : drag and drop
  • airSpeed : Air Velocity
  • windX : X Axial wind direction
  • windY : Y Axial wind direction
  • speed : Flame Speed
  • massConservation : Conservation of mass

Common method :

  • Added resource: addSource(u, v, radius, density, windX, windY)
  • Clear resources: clearSources()
  • Set Map: setSourceMap(texture)

Basic usage :

The fire effect can be achieved in a few simple steps: creating a carrier, initializing with the Fire constructor, adding a flame, adding to the scene, etc. Multiple fire sources can be created, and multiple flame effects can be superimposed on the same carrier.

const geometry = new THREE.PlaneBufferGeometry(10, 10);
const fire = new THREE.Fire(geometry,{
  textureWidth: 10,
  textureHeight: 10,
  debug:false
});
fire.addSource(0.5, 0.1, 0.1, 1.0, 0.0, 1.0);
scene.add(fire);

achieves the effect :

🔗 Try to adjust various parameters of the flame online: threejs/examples/webgl_fire.html

resource introduction

the module resources required for development, note that Three.js and Fire.js are from the Fire.js TWEEN is used to implement a simple lens tweening animation, and ringTexture is the texture that needs to show the outline of the flame effect.

import React from 'react';
import * as THREE from './libs/three.module.js';
import { Fire } from './libs/Fire.js';
import { TWEEN } from "three/examples/jsm/libs/tween.module.min.js";
import ringTexture from './images/ring.png';

The page DOM has a very simple structure, containing only a container #container WEBGL

<div className='ring_page' id="container"></div>

scene initialization

Initialize rendering scene, camera and light source. (If you need to learn more about this part of the knowledge, you can read my previous articles or read the official website documents, and I will not repeat them in this article)

const container = document.getElementById('container');
const renderer = new THREE.WebGLRenderer({ antialias: true,  alpha: true });
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
renderer.setClearAlpha(0);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 100);
camera.lookAt(new THREE.Vector3(0, 0, 0));
const ambientLight = new THREE.AmbientLight(0xffffff, 1);
scene.add(ambientLight);

💡 set render background transparency

  • alpha : Whether to enable transparency in canvas , the default is false .
  • renderer.setClearAlpha(alpha : Float) : Set the transparency value of alpha . The legal parameter is a floating point number between 0.0 and 1.0 .

In the above code, the background of canvas can be set to transparent by setting new THREE.WebGLRenderer({ antialias: true, alpha: true }) and renderer.setClearAlpha(0) , so that the background style can be set by CSS . The background image in this example is set via CSS , not Sence.background .

🌵 When alpha: true is enabled, the transparency defaults to 0 , and renderer.setClearAlpha(0) can be omitted.

Add Logo Body

Create a PlaneBufferGeometry plane as the flame Logo carrier, Logo shape is generated by calling setSourceMap using textures, then add various parameters of Fire.js , adjust the position of the plane, and finally add it to the scene.

const ring = new Fire(new THREE.PlaneBufferGeometry(20, 25), {
  textureWidth: 800,
  textureHeight: 1000,
  debug: false,
});
ring.setSourceMap(new THREE.TextureLoader().load(ringTexture));
ring.color1 = new THREE.Color(0xffffff);
ring.color2 = new THREE.Color(0xf59e00);
ring.color3 = new THREE.Color(0x08120a);
ring.colorBias = .6;
ring.burnRate = 10;
ring.diffuse = 1;
ring.viscosity = .5;
ring.expansion = -1.6;
ring.swirl = 10;
ring.drag = 0.4;
ring.airSpeed = 18;
ring.windX = 0.1;
ring.windY = 0.2;
ring.speed = 100;
ring.massConservation = false;
ring.position.y = 4;
ring.position.z = -6;
scene.add(ring)

The shape of 🌵 Logo can also be directly generated by splicing geometric objects such as rings. In this article, in order to save time and be more realistic, the textures drawn by myself in Photoshop are directly used. Note that the main part of the texture uses white in the actual application, and I changed it to black for the convenience of display.

page scaling

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}, false);

Shot tweening

Motion tweening by far and near shots when the page has just started to load.

const controls = new OrbitControls(camera, renderer.domElement);
Animations.animateCamera(camera, controls, { x: 0, y: 0, z: 22 }, { x: 0, y: 0, z: 0 }, 2400, () => {
  controls.enabled = false;
});

page redraw animation

Ease animation and rendering update for pattern line reciprocating motion.

let step = 0;
const animate = () => {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
  stats && stats.update();
  TWEEN && TWEEN.update();
  step += .03;
  ring && (ring.position.y = Math.abs(2.2 + Math.sin(step)));
}

At this point, all the effects of Ayrden's ring of a low-profile version of Logo have been realized 😂 . I hope that with the accumulation of my knowledge of graphics, I can use shader to achieve more cool effects 🔥 . The complete code can be viewed at the link below.

🔗 full code: https://github.com/dragonir/3d/tree/master/src/containers/Ring

Summarize

The new knowledge mainly included in the knowledge points of this article:

  • Fire.js Basic usage
  • Set render background transparency
If you want to know about scene initialization, lighting, shadows, basic geometry, meshes, materials, and other Three.js related knowledge, you can read my previous articles. reprint please indicate the original address and author . If you think the article is helpful to you, don't forget to one-click three links 👍 .

appendix


dragonir
1.8k 声望3.9k 粉丝

Accepted ✔