xxxxxxxxxx
// TransformFeedbackによる動的更新のテスト。
// https://wgld.org/d/webgl2/w015.html
// 3つの頂点を動かす
// 動かすと同時に描画する感じでよろしく
// つまり今回shaderは1個だけ
// transform feedback
// 「attrがundefined」という条件を追加しました
// これがないと描画と同時に更新することができないんですよね
// attributeの入れ替えの際に入れ替えたattributeがoutIndexをもって
// いない、また入れ替えでinされるattributeがoutIndexを持っている
// ことにより不具合が生じるわけ
// 同じIndexを指定しておくことで、これを回避できる。
// そういうことです
// TFでoutIndex>=0であってもattrがundefinedでないならば
// つまりinで宣言されているならば
// 通常の処理をしないといけないし
// 逆に通常の処理をしていたattributeにTF処理をさせたかったら
// あらかじめoutIndexを設定しておかないといけないのだよ
// 以上だよ。
// ...ということです。できましたね。おめでとう🎉
// 2023-09-27
// Locater導入
const ex = p5wgex;
let _node;
let LC;
// vec3
// 重心と方向
// 重心をマウスで動かし
// 方向は速度を随時足す感じで
// 速度は重心位置とマウス位置で計算
const vs =
`#version 300 es
in vec3 aPosition;
in vec4 aColor;
out vec3 aNextPosition;
out vec4 vColor;
uniform vec2 uMouse;
uniform bool uMoveFlag;
void main(){
vColor = aColor;
vec2 pos = aPosition.xy;
float angle = aPosition.z;
// マウスにより速度を計算
vec2 v = 0.1 * (uMouse - pos);
if (!uMoveFlag) v = vec2(0.0);
// 重心移動
pos += v;
// 重心の周りに回転
angle += 0.1 + length(v)*5.0;
aNextPosition = vec3(pos, angle);
// 領域制限
pos.x = clamp(pos.x, -1.0, 1.0);
pos.y = clamp(pos.y, -1.0, 1.0);
gl_Position = vec4(pos + 0.2 * vec2(cos(angle), sin(angle)), 0.0, 1.0);
}
`;
const fs =
`#version 300 es
precision highp float;
in vec4 vColor;
out vec4 col;
void main(){
col = vColor;
}
`;
function setup() {
createCanvas(600, 600, WEBGL);
pixelDensity(1);
_node = new ex.RenderNode(this._renderer.GL);
_node.registPainter("transform", vs, fs, ["aNextPosition"]);
// 入れ替えることを想定している場合は同じoutIndexを事前に指定しておく
// swapした場合aNextPositionでaPositionのattrが参照されるがこのとき
// これがTFbindされるためにはoutIndexが設定されていないといけない
// これは同じ番号でOKです
_node.registFigure("TF", [
{name:"aPosition", size:3,
data:[0,0,0, 0,0,PI*2/3, 0,0,PI*4/3],
usage:"dynamic_copy", outIndex:0},
{name:"aColor", size:4, data:[1,0,0,1,0,1,0,1,0,0,1,1]},
{name:"aNextPosition", size:3,
data:[0,0,0,0,0,0,0,0,0],
usage:"dynamic_copy", outIndex:0}
]);
// おわりです。
LC = new foxIA.Locater(this.canvas);
}
function draw() {
_node.clear(0.5, 0.7, 0.8);
LC.update();
const p = LC.getPos({normalize:true});
_node.use("transform", "TF", "triangles")
.setUniform("uMouse", [p.x*2-1, 1-p.y*2])
.setUniform("uMoveFlag", LC.isActive())
.drawArrays("triangles")
.swapAttribute("aPosition", "aNextPosition")
.unbind();
_node.flush();
}