擬似乱数関数を使用して、パーティクルを球面上に分散させる方法を学びます。
p5.js 2.0 WebGL p5.strands Shader GLSL
Learning Tutorial
パーティクルを球面上に配置する
先ほどは X 軸に沿って並べましたが、今度はパーティクルを球面上にランダムに配置して、より興味深いパターンを作ってみましょう。
スケッチのソースコードを見てみましょう:
let instancingShader;
let instancingStrokeShader;
let particleModel;
function instancingCallback() {
// 擬似乱数関数 (出典: https://stackoverflow.com/questions/4200224/random-noise-functions-for-glsl)
function rand(seed) {
return fract(sin(dot(seed, [12.9898, 78.233])) * 43758.5453123);
}
function randomPositionOnSphere() {
let id = instanceID();
let theta = rand([id, 0.1234]) * TWO_PI;
let phi = rand([id, 3.321]) * PI;
let r = 180;
let x = r * sin(phi) * cos(theta);
let y = r * cos(phi);
let z = r * sin(phi) * sin(theta);
return [x, y, z];
}
getWorldInputs((inputs) => {
inputs.position += randomPositionOnSphere();
return inputs;
});
}
async function setup() {
createCanvas(400, 400, WEBGL);
pixelDensity(1);
particleModel = buildGeometry(() => sphere(10, 4, 2));
instancingShader = baseColorShader().modify(instancingCallback);
instancingStrokeShader = baseStrokeShader().modify(instancingCallback);
}
function draw() {
background(0);
orbitControl();
shader(instancingShader);
fill(255, 100, 150);
strokeShader(instancingStrokeShader);
model(particleModel, 1000);
}ここで使用している rand() ヘルパー関数は、p5.strands に移植された 3 つの GLSL 関数を使用しています:
function rand(seed) {
return fract(sin(dot(seed, [12.9898, 78.233])) * 43758.5453123);
}fract(): 数値の小数部分を取り出します(例:3.42→0.42)sin(): 角度のサイン(正弦)を返しますdot(): 2 つのベクトルのドット積(内積)を返します。これはベクトルの類似度を測るものです。
これらの関数は、本来の数学的な意味を持ちつつ、ここではインスタンス ID に基づいて擬似乱数(決まった入力に対してランダムに見える値を返す)を生成するために組み合わされています。
シェーダー内でランダム性が必要な場合、通常の random() 関数は使えないため、このような数学的な手法が一般的に使われます。
License
Original URL: https://beta.p5js.org/tutorials/intro-to-p5-strands/
License: MIT License
Copyright (c) 2015-present p5.js contributors & The Processing Foundation