55 Three.js using canvas styled particles

brief introduction

With canvas stylized particles, we first need to paint a canvas texture. For example:

This is a little monster in bean eater drawn by canvas in the tutorial, and what we want to achieve today is to use it to stylize particles.

process

  • Through the code in the previous section, we need to extend it again. First, we need to get the canvas object, and generate the THREE.Texture object that can be used by particles through the canvas object.
  • Then, assign the texture object to the map attribute of the THREE.PointsMaterial, and continue to write according to the code in the previous section. It is found that the current effect is achieved.

    Thousands of colorful little monsters, the sense of terror arises spontaneously!

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="https://johnson2heng.github.io/three.js-demo/lib/three.js"></script>
<script src="https://johnson2heng.github.io/three.js-demo/lib/js/controls/OrbitControls.js"></script>
<script src="https://johnson2heng.github.io/three.js-demo/lib/js/libs/stats.min.js"></script>
<script src="https://johnson2heng.github.io/three.js-demo/lib/js/libs/dat.gui.min.js"></script>
<script>
    var renderer;

    function initRender() {
        renderer = new THREE.WebGLRenderer({antialias: true});
        renderer.setClearColor(new THREE.Color(0xffffff)); //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, 1, 1000);
        camera.position.set(20, 0, 100);
    }

    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);

    }

    //Randomly generate color
    function randomColor() {
        var arrHex = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"],
            strHex = "0x",
            index;
        for (var i = 0; i < 6; i++) {
            index = Math.round(Math.random() * 15);
            strHex += arrHex[index];
        }
        return strHex;
    }

    //Initialize performance plug-ins
    var stats;

    function initStats() {
        stats = new Stats();
        document.body.appendChild(stats.dom);
    }

    //User interaction plug in left mouse button press and hold rotation, right mouse button press and hold translation, scroll wheel zoom
    var controls;

    function initControls() {

        controls = new THREE.OrbitControls(camera, renderer.domElement);

        // If you use the animate method, delete this function
        //controls.addEventListener( 'change', render );
        // Whether there is inertia in the meaning of damping or rotation when the animation is recycled
        controls.enableDamping = true;
        //Dynamic damping coefficient is the mouse drag rotation sensitivity
        //controls.dampingFactor = 0.25;
        //Can I zoom
        controls.enableZoom = true;
        //Auto rotate or not
        controls.autoRotate = false;
        //Set the maximum distance between the camera and the origin
        controls.minDistance = 20;
        //Set the maximum distance between the camera and the origin
        controls.maxDistance = 10000;
        //Enable right drag
        controls.enablePan = true;
    }

    //Generate gui settings configuration item
    var gui;

    //Generate texture graphics
    function getTexture() {
        var canvas = document.createElement('canvas');
        canvas.width = 32;
        canvas.height = 32;

        var ctx = canvas.getContext('2d');
        // Drawing the body
        ctx.translate(-81, -84);

        ctx.fillStyle = "orange";
        ctx.beginPath();
        ctx.moveTo(83, 116);
        ctx.lineTo(83, 102);
        ctx.bezierCurveTo(83, 94, 89, 88, 97, 88);
        ctx.bezierCurveTo(105, 88, 111, 94, 111, 102);
        ctx.lineTo(111, 116);
        ctx.lineTo(106.333, 111.333);
        ctx.lineTo(101.666, 116);
        ctx.lineTo(97, 111.333);
        ctx.lineTo(92.333, 116);
        ctx.lineTo(87.666, 111.333);
        ctx.lineTo(83, 116);
        ctx.fill();

        // Draw eyes
        ctx.fillStyle = "white";
        ctx.beginPath();
        ctx.moveTo(91, 96);
        ctx.bezierCurveTo(88, 96, 87, 99, 87, 101);
        ctx.bezierCurveTo(87, 103, 88, 106, 91, 106);
        ctx.bezierCurveTo(94, 106, 95, 103, 95, 101);
        ctx.bezierCurveTo(95, 99, 94, 96, 91, 96);
        ctx.moveTo(103, 96);
        ctx.bezierCurveTo(100, 96, 99, 99, 99, 101);
        ctx.bezierCurveTo(99, 103, 100, 106, 103, 106);
        ctx.bezierCurveTo(106, 106, 107, 103, 107, 101);
        ctx.bezierCurveTo(107, 99, 106, 96, 103, 96);
        ctx.fill();

        // Drawing eyeballs
        ctx.fillStyle = "blue";
        ctx.beginPath();
        ctx.arc(101, 102, 2, 0, Math.PI * 2, true);
        ctx.fill();
        ctx.beginPath();
        ctx.arc(89, 102, 2, 0, Math.PI * 2, true);
        ctx.fill();

        var texture = new THREE.Texture(canvas);
        texture.needsUpdate = true;
        return texture;
    }

    var cloud;
    function initGui() {
        //Declare an object to save the relevant data of the requirement modification
        gui = {
            "size": 4,
            "transparent": true,
            "opacity": 0.6,
            "vertexColors": true,
            "color": 0xffffff,
            "sizeAttenuation": true,
            "rotateSystem": true,
            redraw: function () {
                if (cloud) {
                    scene.remove(cloud);
                }
                createParticles(gui.size, gui.transparent, gui.opacity, gui.vertexColors, gui.sizeAttenuation, gui.color);
                //Set whether to rotate automatically
                controls.autoRotate = gui.rotateSystem;
            }
        };
        var datGui = new dat.GUI();
        //Add the setting attribute to GUI, gui.add(controls, 'size', 0, 10).onChange(controls.redraw);
        datGui.add(gui, 'transparent').onChange(gui.redraw);
        datGui.add(gui, 'opacity', 0, 1).onChange(gui.redraw);
        datGui.add(gui, 'vertexColors').onChange(gui.redraw);
        datGui.addColor(gui, 'color').onChange(gui.redraw);
        datGui.add(gui, 'sizeAttenuation').onChange(gui.redraw);
        datGui.add(gui, 'rotateSystem').onChange(gui.redraw);

        gui.redraw();
    }

    //How to generate particles
    function createParticles(size, transparent, opacity, vertexColors, sizeAttenuation, color) {

        //Grid for particle data
        var geom = new THREE.Geometry();
        //The.pointcloudmaterial material material for stylized particles
        var material = new THREE.PointsMaterial({
            size: size,
            transparent: transparent,
            opacity: opacity,
            vertexColors: vertexColors,
            sizeAttenuation: sizeAttenuation,
            color: color,
            map:getTexture(),
            depthTest: false  //Set to solve transparency problems
        });


        var range = 500;
        for (var i = 0; i < 15000; i++) {
            var particle = new THREE.Vector3(Math.random() * range - range / 2, Math.random() * range - range / 2, Math.random() * range - range / 2);
            geom.vertices.push(particle);
            var color = new THREE.Color(+randomColor());
            //. sethsl (h, s, l) H - hue value between 0.0 and 1.0 s - saturation value between 0.0 and 1.0 L - luminance value between 0.0 and 1.0. Use HSL to set the color.
            //Randomizes the current brightness of each particle
            //color.setHSL(color.getHSL().h, color.getHSL().s, Math.random() * color.getHSL().l);
            geom.colors.push(color);
        }

        //Generate model and add it to the scene
        cloud = new THREE.Points(geom, material);

        scene.add(cloud);
    }

    function render() {
        renderer.render(scene, camera);
    }

    //Function triggered by window change
    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        render();
        renderer.setSize(window.innerWidth, window.innerHeight);

    }

    function animate() {
        //Update controller
        controls.update();
        render();

        //Update performance plug-ins
        stats.update();
        requestAnimationFrame(animate);
    }

    function draw() {
        initRender();
        initScene();
        initCamera();
        initLight();
        initModel();
        initControls();
        initStats();
        initGui();

        animate();
        window.onresize = onWindowResize;
    }
</script>
</html>

Tags: github Attribute

Posted on Fri, 01 May 2020 13:24:21 -0700 by mdaoust