(Intergrate P5.js and Three.js) — Create a ThreeJS scene with animations from P5.js library?

后端 未结 2 1932
南旧
南旧 2020-12-19 20:15

Before we begin, you may want to read my previous post which lead to the creation of this question:

Drawing/Rendering 3D objects with epicycles and fourier transfor

相关标签:
2条回答
  • 2020-12-19 20:35

    Use WEBGL mode in p5.js instead of using three.js. Example:

    let t
    function setup(){
      createCanvas(400,400,WEBGL)
    //w = width of plane
    //h = height of plane
      t = createGraphics(w,h)
    }
    
    function draw(){
      background(0)
     //To draw to the texture use t. before any drawing function
      texture(t)
      plane(w,h)
    }
    

    Watch the Coding Train's playlist about WEBGL in p5.js,

    link to the videos.

    If you really want to use THREE.js, IDK how to.

    0 讨论(0)
  • 2020-12-19 20:36

    Dabbled a bit more with what I think is your basic concept. Believe it or not, more than 50% of the effort involved working around dithering issues associated with overlapping transparent objects in motion, an area where three.js is a bit weak. But, after a bit of searching, one can mitigate the dithering issues with adjustments to the Z alignment of the objects and the renderOrder.

    In any event, take a look at the code below, which extends your effort, introducing 5 randomly sized and rotating transparent circles. For drawing lines, take a look at the following link https://threejs.org/docs/#manual/en/introduction/How-to-update-things .

    <html>
      <head>
        <title>Epicyclic Circles</title>
        <style>
          body { margin: 0; }
          canvas { width: 100%; height: 100% }
        </style>
      </head>
      <body>
    
        <script src="https://rawgit.com/mrdoob/three.js/dev/build/three.js"></script>
        <script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/controls/OrbitControls.js"></script>
    
        <script>
    
          // Set up the basic scene, camera, and lights.
    
          var scene = new THREE.Scene();
          scene.background = new THREE.Color( 0xf0f0f0 );
    
          var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
          scene.add(camera)
    
          var light = new THREE.PointLight( 0xffffff, 0.8 );
          camera.add( light );
    
          camera.position.z = 200;
    
          var renderer = new THREE.WebGLRenderer();
          renderer.setSize( window.innerWidth, window.innerHeight );
          document.body.appendChild( renderer.domElement );
    
          // Add the orbit controls to permit viewing the scene from different angles via the mouse.
    
          controls = new THREE.OrbitControls( camera, renderer.domElement );
          controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
          controls.dampingFactor = 0.25;
          controls.screenSpacePanning = false;
          controls.minDistance = 0;
          controls.maxDistance = 500;
    
          function createCircleMesh(plane, radius, depth, meshColor, meshOpacity) {
              let extrudeSettings = { depth: depth, bevelEnabled: true, bevelSegments: 2, steps: 2, bevelSize: .25, bevelThickness: .25 };
    
              let arcShape = new THREE.Shape();
              arcShape.moveTo( 0, 0 );
              arcShape.absarc( 0, 0, radius, 0, Math.PI * 2, false );
              let holePath = new THREE.Path();
              holePath.moveTo( 0, radius * 0.75 );
              holePath.absarc( 0, radius * 0.75, radius * 0.20, 0, Math.PI * 2, true );
              arcShape.holes.push( holePath );
                
              var geometry = new THREE.ExtrudeBufferGeometry( arcShape, extrudeSettings );
              var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial({color: meshColor, roughness: 1, metalness: 0, transparent: meshOpacity !== 1, opacity: meshOpacity}) );
              scene.add( mesh );
              
              if (plane === "XZ") {
                mesh.rotateX(Math.PI / 2);
              } else if (plane === "YZ") {
                mesh.rotateY(Math.PI / 2);
              }
              return mesh;
          }
          
          // Create an array of circles and their meshes.
          circle = [];
          for (let i = 0; i < 5; i++) {
          
              let r = 5 - i;
              
              circle[i] = {
                  radius: r*10 + Math.random() * r * 10,
                  rotationRate: (Math.random() * 2 * Math.PI - Math.PI) / 100
              };
    
              // RenderOrder is stepped to reduce dithering.
              circle[i].mesh = createCircleMesh("XY", circle[i].radius, 5, 0xff0000, 0.5);
              circle[i].mesh.renderOrder = i;
              
              circle[i].centerMesh = createCircleMesh("XY", 5, 2, 0xff0000, 1);
              if (i === 0) {
                  circle[i].centerX = circle[i].radius;
                  circle[i].centerY = circle[i].radius;
                  circle[i].centerZ = i;  // Offset the meshes to reduce dithering.
              } else {
                  circle[i].centerX = circle[i-1].centerX + circle[i-1].radius;
                  circle[i].centerY = circle[i-1].centerY;
                  circle[i].centerZ = i;  // Offset the meshes to reduce dithering.
              }
              circle[i].rotated = 0;
          }
    
          // Set up "viewing" planes.
          
          var plane = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
          var helper = new THREE.PlaneHelper( plane, 500, 0x696969 );
          scene.add( helper );
    
          var plane2 = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), 0 );
          var helper2 = new THREE.PlaneHelper( plane2, 500, 0xE06666 );
          scene.add( helper2 );
    
          var plane3 = new THREE.Plane( new THREE.Vector3( 0, 0, 1 ), 0 );
          var helper3 = new THREE.PlaneHelper( plane3, 500, 0xD85C6 );
          scene.add( helper3 );
    
          var size = 250;
          var divisions = 10;
    
          var gridHelper = new THREE.GridHelper( size, divisions );
          scene.add( gridHelper );
    
          var animate = function () {
            requestAnimationFrame( animate );
    
            // During each animation frame, let's rotate the objects.
            
            for (let i = 0; i < 5; i++) {
                let c = circle[i];
                
                c.rotated += c.rotationRate;
                if (0 < i) {
                    c.centerX = circle[i-1].centerX + circle[i-1].radius * Math.cos(circle[i-1].rotated);
                    c.centerY = circle[i-1].centerY + circle[i-1].radius * Math.sin(circle[i-1].rotated);
                }
                
                // Note that due to the stepping of the meshes to reduce dithering, it is necessary
                // to alter the step (via Math.sign(camera.position.z)) if we're looking via the backside.
                c.mesh.rotateZ(c.rotationRate);
                c.mesh.position.set(c.centerX, c.centerY, c.centerZ * Math.sign(camera.position.z));
                c.centerMesh.position.set(c.centerX, c.centerY, c.centerZ * Math.sign(camera.position.z));            
                
            }
    
            renderer.render( scene, camera );
          };
    
          animate();
        </script>
      </body>
    </html>

    This might look better full screen rather than in the small viewport within Stackoverflow.

    Hope this helps you along your way.

    0 讨论(0)
提交回复
热议问题