As you can remember, the. Points renders each particle based on the vertices of the geometry. That is to say, we provide a complex geometry (such as a torus or a tube), and we can create a THREE.Points object based on the vertices of the geometry.
As shown in the figure above, each vertex used to generate the torus is a particle. This glowing particle is drawn with canvas. See the code method generateSprite in the case.
Then we wrote two more methods, one is the createMesh method to generate the normal model.
The other is to generate the createPointCloud of the particle model, which can generate different content through different configurations in the gui.
Case view address:
Case code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
html, body {
margin: 0;
height: 100%;
}
canvas {
display: block;
}
</style>
</head>
<body onload="draw();">
</body>
<script src="/lib/three.js"></script>
<script src="/lib/js/libs/stats.min.js"></script>
<script src="/lib/js/libs/dat.gui.min.js"></script>
<script>
var renderer;
function initRender() {
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setClearColor(new THREE.Color(0x000000)); //Set background color
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
var camera;
function initCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200);
camera.position.set(0, 0, 50);
}
var scene;
function initScene() {
scene = new THREE.Scene();
}
var light;
function initLight() {
scene.add(new THREE.AmbientLight(0x404040));
light = new THREE.DirectionalLight(0xffffff);
light.position.set(1, 1, 1);
scene.add(light);
}
function initModel() {
//Shaft assist (length of each shaft)
var object = new THREE.AxesHelper(500);
//scene.add(object);
}
//Initialize performance plug-ins
var stats;
function initStats() {
stats = new Stats();
document.body.appendChild(stats.dom);
}
//Generate gui settings configuration item
var controls,knot;
function initGui() {
//Declare an object to save the relevant data of the requirement modification
controls = {
"radius": 13,
"tube": 1.7,
"radialSegments": 156,
"tubularSegments": 12,
"p": 3,
"q": 4,
"heightScale": 3.5,
"asParticles": false,
"rotate": false,
redraw: function () {
// Delete the original model
if (knot) scene.remove(knot);
// Create a circular structure
///< param name = "radius" type = "float" > radius of ring junction < / param >
///< param name = "tube" type = "float" > radius of Circular Bend < / param >
///< param name = "radialsegments" type = "int" > number of segments on the circumference of the circular knot < / param >
///< param name = "tubularsegments" type = "int" > number of segments on the circumference of the ring bend < / param >
///< param name = "P" type = "float" > P \ Q: it is effective for the knot mode. It controls the number of turns of the curve path winding, and P determines the parameter of the vertical direction. < param >
///< param name = "Q" type = "float" > P \ Q: it is effective for the knot like mode. It controls the number of loops winding the curve path. Q determines the parameter of the horizontal direction. < param >
///< param name = "Highscale" type = "float" > scale in the height direction of the circular knot. The default value is 1 < / param >
var geom = new THREE.TorusKnotGeometry(controls.radius, controls.tube, Math.round(controls.radialSegments), Math.round(controls.tubularSegments), Math.round(controls.p), Math.round(controls.q), controls.heightScale);
//Judgment drawing model
if (controls.asParticles) {
knot = createPointCloud(geom);
} else {
knot = createMesh(geom);
}
// Add the newly created model
scene.add(knot);
}
};
var gui = new dat.GUI();
//Add the setting attribute to GUI, gui.add(controls, 'size', 0, 10).onChange(controls.redraw);
gui.add(controls, 'radius', 0, 40).onChange(controls.redraw);
gui.add(controls, 'tube', 0, 40).onChange(controls.redraw);
gui.add(controls, 'radialSegments', 0, 400).step(1).onChange(controls.redraw);
gui.add(controls, 'tubularSegments', 1, 20).step(1).onChange(controls.redraw);
gui.add(controls, 'p', 1, 10).step(1).onChange(controls.redraw);
gui.add(controls, 'q', 1, 15).step(1).onChange(controls.redraw);
gui.add(controls, 'heightScale', 0, 5).onChange(controls.redraw);
gui.add(controls, 'asParticles').onChange(controls.redraw);
gui.add(controls, 'rotate').onChange(controls.redraw);
controls.redraw();
}
var step = 0;
function render() {
stats.update();
if (controls.rotate) {
knot.rotation.y = step += 0.01;
}
renderer.render(scene, camera);
}
// Creating textures with canvas
function generateSprite() {
var canvas = document.createElement('canvas');
canvas.width = 16;
canvas.height = 16;
var context = canvas.getContext('2d');
var gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
gradient.addColorStop(0, 'rgba(255,255,255,1)');
gradient.addColorStop(0.2, 'rgba(0,255,255,1)');
gradient.addColorStop(0.4, 'rgba(0,0,64,1)');
gradient.addColorStop(1, 'rgba(0,0,0,1)');
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
return texture;
}
// Create a particle system
function createPointCloud(geom) {
var material = new THREE.PointCloudMaterial({
color: 0xffffff,
size: 3,
transparent: true,
blending: THREE.AdditiveBlending,
map: generateSprite(),
depthTest: false
});
var cloud = new THREE.Points(geom, material);
cloud.sortParticles = true;
return cloud;
}
//Create model
function createMesh(geom) {
// Create a texture that appears on both sides
var meshMaterial = new THREE.MeshNormalMaterial({});
meshMaterial.side = THREE.DoubleSide;
// Generating model
var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial]);
return mesh;
}
//Function triggered by window change
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
render();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
render();
//Update performance plug-ins
stats.update();
requestAnimationFrame(animate);
}
function draw() {
initRender();
initScene();
initCamera();
initLight();
initModel();
initStats();
initGui();
animate();
window.onresize = onWindowResize;
}
</script>
</html>