简体   繁体   English

Three.js - 给出圆形的粒子

[英]Three.js - give particles round form

I am currently experimenting with three.js . 我目前正在尝试使用three.js I would like to change the code in the example below so the dots are round, not square. 我想更改下面示例中的代码,因此圆点是圆的,而不是方形。

Codepen example Codepen示例

I found another example called canvas particle random , which has round particles, and basically, the only difference in the script is the following: 我找到了另一个叫做canvas粒子随机的例子,它有圆粒子,基本上,脚本的唯一区别如下:

var PI2 = Math.PI * 2;
var program = function ( context ) {

    context.beginPath();
    context.arc( 0, 0, 0.5, 0, PI2, true );
    context.fill();

};

I thought that if I add this to the other script, then the particles would become round. 我想如果我把它添加到另一个脚本中,那么粒子就会变成圆形。 However, when I added the above script to the first script, it doesn't work (I just get a blue screen). 但是,当我将上述脚本添加到第一个脚本时,它不起作用(我只是得到一个蓝屏)。

Anyone know what I am doing wrong? 谁知道我做错了什么?

As others have said, you can use a texture as the map in your PointsMaterial. 正如其他人所说,您可以在PointsMaterial中使用纹理作为地图。
But if you just want circles, an easier method may be to create the map dynamically with a canvas (which is what the code you posted seems to be trying to do). 但是如果你只是想要圆圈,一个更简单的方法可能是用画布动态创建地图(这就是你发布的代码似乎试图做的事情)。

HERE is a fiddle with your code updated to use a canvas as your texture map. HERE是您更新代码的小提琴 ,使用画布作为纹理贴图。
NOTE: I have changed the colors in your paramters object to make it more obvious that different colors are being used. 注意:我更改了参数对象中的颜色,以便更明显地使用不同的颜色。

The function that creates a circle on a canvas for use as a map. 在画布上创建圆圈以用作地图的功能。

function createCanvasMaterial(color, size) {
  var matCanvas = document.createElement('canvas');
  matCanvas.width = matCanvas.height = size;
  var matContext = matCanvas.getContext('2d');
  // create exture object from canvas.
  var texture = new THREE.Texture(matCanvas);
  // Draw a circle
  var center = size / 2;
  matContext.beginPath();
  matContext.arc(center, center, size/2, 0, 2 * Math.PI, false);
  matContext.closePath();
  matContext.fillStyle = color;
  matContext.fill();
  // need to set needsUpdate
  texture.needsUpdate = true;
  // return a texture made from the canvas
  return texture;
}

map canvas creation in the loop using the parameters object. 使用parameters对象在循环中创建画布创建。

  for (i = 0; i < parameters.length; i++) {

    color = parameters[i][0];
    size = parameters[i][1];

    var hexColor = new THREE.Color(color[0], color[1], color[2]).getHexString();

    materials[i] = new THREE.PointsMaterial({
        size: 20,
        map: createCanvasMaterial('#'+hexColor, 256),
        transparent: true,
        depthWrite: false
    });

    particles = new THREE.Points(geometry, materials[i]);

    particles.rotation.x = Math.random() * 6;
    particles.rotation.y = Math.random() * 6;
    particles.rotation.z = Math.random() * 6;

    scene.add(particles);

  }

Have to set depthWrite to false on the marterial. 必须在marterial上将depthWrite设置为false。 see THIS issue. 看到这个问题。

I have now created a blog post on Three.js canvas particles 我现在在Three.js画布上创建了一篇博客文章

Even though this question has been asked more than 2 years ago, I thought it would be useful to add that you could always write your own fragment shader using a three.js ShaderMaterial : 虽然这个问题已经在2年多前被问过,但我认为添加你总是可以使用three.js ShaderMaterial创建自己的片段着色器会很有用

let geom = new three.Geometry();
geom.vertices.push(new three.Vector3(0,0,0));
let material = new three.ShaderMaterial({
    transparent: true,
    uniforms: {
        size: {value: 10},
        scale: {value: 1},
        color: {value: new three.Color('maroon')}
    },
    vertexShader: three.ShaderLib.points.vertexShader,
    fragmentShader: `
    uniform vec3 color;
    void main() {
        vec2 xy = gl_PointCoord.xy - vec2(0.5);
        float ll = length(xy);
        gl_FragColor = vec4(color, step(ll, 0.5));
    }
    `
});
let points = new three.Points(geom, material);

You can use a texture to your sprites: 你可以为你的精灵使用纹理:

  var tex = new THREE.TextureLoader().load("https://threejs.org/examples/textures/sprites/disc.png");
  // load the texture

  for (i = 0; i < parameters.length; i++) {

    color = parameters[i][0];
    size = parameters[i][1];

    materials[i] = new THREE.PointsMaterial({
      size: size,
      map: tex // apply the texture in your material
    });

    particles = new THREE.Points(geometry, materials[i]);

    particles.rotation.x = Math.random() * 6;
    particles.rotation.y = Math.random() * 6;
    particles.rotation.z = Math.random() * 6;

    scene.add(particles);

  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM