Disclaimer: This article is only used for personal study, research and appreciation, please do not modify, illegally spread, reprint, publish, commercial use, and other profit behavior.

background

Elden Circle is one of the most popular games of late, and its Logo is made up of several arcs and line segments. This article uses React + three. js technology stack to implement the Elden Ring Logo with flame effect. This article covers basic usage methods of fire. js and other basic knowledge of three. js.

The effect

The realization effect is shown in the 👆 banner picture. The main body of the page is composed of Logo graphics. Logo has loading effects from far to near, and after loading, it has a slow animation effect up and down.

Online preview:

  • 👀Address 1:3d-dragonir.vercel.app/#/ring
  • 👀Address 2:dragonir.github.io/3d/#/ring

Adaptation:

  • 💻 PC
  • 📱The mobile terminal

implementation

The Fire effect of the Logo is mainly implemented through fire.js. Before we start to implement it, let’s take a look at its basic usage.

💡 Fire. Js

Threejs provides an extension pack that can implement fire and smoke effects by referencing and setting parameters to achieve very realistic fire and disgust effects. [However, this expansion pack has been removed from the new version]

Flame Settings Optional properties:

  • color1: Internal flame color
  • color2: Color of external flame
  • color3: Smoke color
  • colorBias: Color deviation
  • burnRate: the burning rate
  • diffuseSpread:
  • viscosityViscosity:
  • expansion: inflation
  • swirlRotation:
  • drag: drag and drop
  • airSpeed: Air speed
  • windX:XAxis direction of the wind
  • windY:YAxis direction of the wind
  • speed: Flame speed
  • massConservation: Conservation of mass

Common methods:

  • Adding a resource:addSource(u, v, radius, density, windX, windY)
  • Clear resources:clearSources()
  • Setting texture:setSourceMap(texture)

Basic usage:

The flame effect can be achieved by simple steps: creating a carrier, initializing with the Fire constructor, adding a flame, adding to the scene, and so on. 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);
Copy the code

Effect:

🔗 online try to adjust various flame parameters: threejs/examples/webgl_fire.html

Resources to introduce

Import the module resources required for development. Note that three.js and fire.js are older versions imported from the current directory, with fire.js removed from the new version. The TWEEN is used for simple shot TWEEN animations and the ringTexture is the texture that needs to show the flame effect profile.

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';
Copy the code

The page DOM structure is very simple and contains only a container for rendering WEBGL, # Container.

<div className='ring_page' id="container"></div>
Copy the code

Scene initialization

Initialize render scene, camera, and light source. (If you need to know more about this part of knowledge, you can refer to my previous articles or read the official website documents, this article will not be repeated)

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);
Copy the code

💡Set render background transparency

  • alpha:canvasWhether to enable transparency. Default valuefalse.
  • renderer.setClearAlpha(alpha : Float)Set:alphaThe transparency value, the legal parameter is one0.01.0Floating point number between.

Renderer({antiAlias: true, alpha: True}) and renderer.setClearAlpha(0) can set the Canvas background to transparent so that the background style can be set with CSS. The background image in this example is set using CSS, not sene.background.

🌵 When alpha: true is enabled, transparency defaults to 0 and renderer.setclearalpha (0) is not required.

Add a Logo body

Create a PlaneBufferGeometry plane as the flame Logo carrier. The Logo shape is generated using a map by calling setSourceMap, 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)
Copy the code

🌵 Logo shape can also be directly generated by using rings and other geometers. In order to save time and make it more realistic, I directly used my own maps drawn in Photoshop. Note that the main part of the texture will be white in practice, I changed it to black for ease of display.

Page scaling adaptation

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

Camera tween animation

Close and far shot tween animation as the page starts 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;
});
Copy the code

Page redraw animation

Pattern line reciprocating slow motion animation and rendering update.

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)));
}
Copy the code

Here, a low version of the Alden Ring Logo all effects are fully realized 😂, I hope that with the accumulation of graphics knowledge, the follow-up can achieve more cool effect 🔥 through shader. The full code can be viewed at the link below.

🔗 Full code: github.com/dragonir/3d…

conclusion

This article mainly contains new knowledge:

  • Fire.jsThe basic use
  • Set render background transparency

To learn more about scene initialization, lighting, shadows, base geometry, meshes, materials, and more about three.js, read my previous articles. Please indicate the original address and author. If you think the article is helpful to you, don’t forget a key three link oh 👍.

The appendix

  • [1].three.js to achieve magical 3D text suspension effect
  • [2].three.js implementation makes 2d images have 3D effect
  • [3].three.js to achieve the 2022 Winter Olympics theme 3D interesting page, Bing Dwen Dwen 🐼
  • [4].three.js to create an exclusive 3D medal
  • [5].three.js to achieve the Year of the Tiger Spring Festival 3D creative page
  • [6].three.js to implement the 3D dynamic Logo of facebook metasomes
  • [7].three.js to implement 3D panoramic detective game
  • [8].three.js to achieve cool acid style 3D pages