В настоящее время я экспериментирую с three.js. Я хотел бы изменить код в примере ниже, чтобы точки были круглыми, а не квадратными.

Пример Codepen

Я нашел еще один пример под названием холст частиц случайный , который имеет круглые частицы, и в основном единственное отличие в сценарии заключается в следующем:

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

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

};

Я думал, что если я добавлю это к другому сценарию, то частицы станут круглыми. Однако, когда я добавил вышеуказанный скрипт в первый скрипт, он не работает (у меня просто синий экран).

Кто-нибудь знает, что я делаю не так?

4
Lavonen 6 Янв 2017 в 18:46

3 ответа

Лучший ответ

Как уже говорили другие, вы можете использовать текстуру в качестве карты в своем PointsMaterial.
Но если вам просто нужны круги, более простым способом может быть динамическое создание карты с помощью canvas (именно это, похоже, пытается сделать код, который вы опубликовали).

HERE - это скрипка с обновленным кодом, позволяющим использовать холст в качестве карты текстуры.
ПРИМЕЧАНИЕ. Я изменил цвета в вашем объекте параметров, чтобы было более очевидно, что используются разные цвета.

Функция, которая создает круг на холсте для использования в качестве карты.

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

Создание холста карты в цикле с использованием объекта параметров.

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

  }

Придется установить для параметра bottomWrite значение false на сайте. см. ЭТУ проблему.

Теперь я создал пост в блоге на частиц холста Three.js

5
2pha 26 Окт 2017 в 06:48

Вы можете использовать текстуру для ваших спрайтов:

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

  }
1
prisoner849 6 Янв 2017 в 16:18

Хотя этот вопрос задавался более 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);
3
Sebastiaan Marynissen 25 Янв 2019 в 08:17