preface
The previous section implemented the color gradient effect and diffusion sweep effect, this section to add the background sky box, diffusion wall, diffusion circle.
Added skybox idea
There are two formats for adding sky box. One is to form sky box with six pictures, one is to create a big enough ball and paste a picture scene on the surface of the ball to form sky ball.
- Six pictures: This way is clearance
three
theTHREE.CubeTextureLoader().load
Method, add six map addresses to this object and set the scene background to this object. The schematic diagram is shown below - A picture: Because
three
There is no loadhdr
The way of sky box can imitate the way of loading six pictures, because loading six pictures is equivalent to creating a cube, each face is pasted with a picture material, and the camera forms a sky box in the cube. thenhdr
A single image can be achieved by creating a sphere with a surface map and the camera inside the sphere (this approach is suggested by my colleague’s imagination 😂). Here is a recommended website where you can download the HDR material (this material can be used as an empty box or as an environment map)polyhaven.com/hdris 。
Skybox implementation
I chose the first method for skybox implementation here (because the data is six images), the code is as follows
const textureCube = new THREE.CubeTextureLoader().load(['1.jpg'.'2.jpg'.'3.jpg'.'4.jpg'.'5.jpg'.'6.jpg']); scene.background = textureCube;// as a background map
Copy the code
The following data
The effect
Diffusion circle realization idea
Create a circle by using three. RingGeometry, then add the desired texture to the circle, and then change the size of the circle for each frame of the Render loop.
Diffusion circle realization
Create the THREE.RingGeometry model by creating three.textureLoader (), where this.img is the image address, and assign the read texture to THREE.MeshBasicMaterial. Then change the scale of the model in the Render loop to simulate the diffusion effect. The following code
/* eslint-disable */
import * as THREE from 'three';
/** * ripple scattering layer *@param Options. img Photo address *@param Options. speed Flow speed *@param Options. Scene three *@param Options. radius Radius of the circle *@param Options. thing Position of the circle *@param Options. meshrings store circular data *@example* /
class RunRing {
constructor(option) {
this.img = option.img || ' ';
this.speed = option.speed / 100 || 0.01;
this.scene = option.scene;
this.radius = option.radius || 100;
this.position = option.position || [0.0.0];
this.meshrings = [];
this.CreatRing();
}
CreatRing() {
// Create an object to read the photo texture
const textureLoader = new THREE.TextureLoader();
textureLoader.load(this.img, (texture) = > {
// Create a circle structure
const geometry = new THREE.RingGeometry(0.this.radius, 500);
// Create a material and assign the read image to the material
const material2 = new THREE.MeshBasicMaterial({
color: 0xffffff.side: THREE.DoubleSide,
depthTest: true.blending: THREE.AdditiveBlending,
map: texture,
});
// Multiple models are generated when multiple points are passed in
for (let i = 0; i < this.position.length; i += 1) {
// Combine to generate model
this.meshring = new THREE.Mesh(geometry, material2);
// Set the X-axis offset of the model so that the model is tiled on the x-plane
this.meshring.rotateX(Math.PI / 2);
// Set the initial state model scale
this.meshring.scale.set(0.1.0.1.0.1);
// Set the model position
this.meshring.position.set(this.position[i][0].this.position[i][1].this.position[i][2]);
// Store model objects for render to change properties and destroy objects
this.meshrings.push(this.meshring)
// Add it to the scene
this.scene.add(this.meshrings[i]); }});// Create render with model changes per frame
this.thing = setInterval(() = > {
// Loop through all created models to make changes
for (let i = 0; i < this.position.length; i += 1) {
// If the model is already created
if (this.meshrings[i]) {
// When the scale of the model is less than 1, the model is enlarged
if (this.meshrings[i].scale.x < 1) {
this.meshrings[i].scale.set(
this.meshrings[i].scale.x + 0.01.this.meshrings[i].scale.x + 0.01.this.meshrings[i].scale.x + 0.01,); }else {
// When the model ratio is greater than 1, the model is reset
this.meshrings[i].scale.set(0.1.0.1.0.1); }}}},50);
}
delete() {
// Delete the corresponding model in scene
for (let i = 0; i < this.position.length; i += 1) {
if (this.meshrings[i]) {
this.scene.remove(this.meshrings[i]); }}if (this.thing) {
// Clear the render event
clearInterval(this.thing); }}}export default RunRing;
Copy the code
The data format
{
img: "clice.png".scene: scene,
speed: 1.radius: 400.position: [[400.30.400],
[100.30.1200]],}Copy the code
rendering
Diffusion wall implementation ideas
As in the previous section, the diffusion wall is achieved through ShaderMaterial. The effect to be achieved is that the transparency of the wall increases with the height, so the transparency of the model point is inversely proportional to the height. The diffusion effect of the model is to mod the position of the model point by mod function to carry out the mod operation (%), the calculation result is limited to 0-1.
Diffusion wall implementation
/* eslint-disable */
import * as THREE from "three";
/** * wave wall *@param Options. Scene three *@param * the options. The radius center@param Options. Height Wall height *@param Opacity *@param Options. color Wall color *@example* /
class Wall {
constructor(option) {
this.scene = option.scene;
this.radius = option.radius || 420;
this.height = option.height || 120;
this.opacity = option.opacity || 0.5;
this.color = option.color || "#efad35";
this.speed = option.speed || 0.5;
this.mesh = ""; // Generated model data
this.CreatRing();
}
CreatRing() {
const vertexShader = ` uniform vec3 u_color; uniform float time; uniform float u_height; varying float v_opacity; Void main() {// Multiply the model point position by a coefficient of 0.0-1.0 to simulate the diffusion effect. Vec3 vPosition = position * mod(time/20.0, 1.0); // Opacity of the model is inversely proportional to the height of the model v_opacity = 1.0-position. y/u_height; Gl_Position = projectionMatrix * modelViewMatrix * vec4(vPosition, 1.0); } `;
const fragmentShader = ` uniform vec3 u_color; uniform float u_opacity; varying float v_opacity; V_opacity * u_opacity is the product of the opacity effect generated by the height and passed in by the model. gl_FragColor = vec4(u_color, v_opacity * u_opacity); } `;
// Get parameters
const { radius, height, opacity, color, speed, renderOrder } = this;
// Generate the model structure
const geometry = new THREE.CylinderGeometry(
radius,
radius,
height,
32.1.true
);
// Set the model position
geometry.translate(0, height / 2.0);
// Customize the model material
const material = new THREE.ShaderMaterial({
uniforms: {
u_height: {
value: height,
},
u_opacity: {
value: opacity,
},
u_color: {
value: new THREE.Color(color),
},
time: {
value: 0,}},transparent: true.depthWrite: false.depthTest: false.side: THREE.DoubleSide,
vertexShader: vertexShader,
fragmentShader: fragmentShader,
});
// Combine materials and structures to generate objects
const mesh = new THREE.Mesh(geometry, material);
// Set model occlusion, put the model first to prevent occlusion
mesh.renderOrder = renderOrder || 1;
this.mesh = mesh; }}export default Wall;
Copy the code
rendering
Project address: github.com/lixiaochjaj…