Processingによる3DCGグラフィック作品
CGプログラミング作品「星の最期」
2019.04〜2019.06
課題制作、コンペ応募
Processing
概要
この作品は全てがprocessing言語で描かれた3Dグラフィック作品です。超新星爆発の色彩やフォルムを元に線の重なりによる美しさをテーマに製作しました。炎や爆発特有の繊細に揺らぐ曲線の集合体のようなフォルム、それらが重なり合うことで引き立つそれぞれの色彩に魅力を感じ、これをプログラミングで表現しました。2本ずつ枝分かれしていく単純な再帰構造を元に、3本目を追加し元の2本と微妙に重ね合わせることで複雑な線にしています。
また、実行するごとに違ったテイストの爆発が起きるため、様々な色、形、雰囲気を楽しむことができます。
実行結果例
Processingコード
int a = 12; //線の透明度
int dd = 400; //最初の角度(初期値用)415
int d = dd; //最初の角度(動かす用)
int p = 5; //何度ずつ増やすか
int sen_step;
float sen_angle;
float sen_length;
float sen_start;
float sen_scale;
float x, y, z;
float hoshi;
PVector location;
int sss;
int step=sss;
float[] r = new float[4];
float[] g = new float[4];
float[] b = new float[4];
float ran;
void setup() {
size(1300, 800, P3D);
rectMode(CENTER);
colorMode(RGB, 255, 255, 255, 100);
background(0);
frameRate(1);
sen_step = 10; //再帰回数 10以上で動作重
sen_angle = radians(d); //分かれる角度 315
sen_length = 190; //最初の線の長さ
sen_start = 0; //スタート地点(中心)
newSen();
iro();
effect();
}
void draw() {
sen_angle=radians(d);
d += p; //pの値ごとに再帰時の角度を変える
println(d);
if (d>dd+p*3) {
save("bon" + 0 + ".png"); //画像を保存
noLoop(); //角度が規定値に達したら停止(4回描画したら)
}
translate(width/2, height/2, 0); //原点を画面の中心へ
rotateX(radians(random(240, 400))); //フレームごとに回転させてズレを作る
rotateZ(radians(random(320)));
if (d
450) {
b[i] = random(0, 100);
} else {
b[i] = random(255);
}
}
}
.mo{
void huyasu() {
pushMatrix();
blendMode(ADD); //色反映
strokeWeight(1);
noFill();
if (step>sen_step-1) { //再帰2回目まで描画しない
noStroke();
} else {
if (d>=dd+p*4) {
stroke( r[0], g[0], b[0], a );
} else if (d>=dd+p*3) {
stroke( r[1], g[1], b[1], a );
} else if (d>=dd+p*2) {
stroke( r[2], g[2], b[2], a );
} else if (d>=dd+p) {
stroke( r[3], g[3], b[3], a );
}
}
translate(0, -sen_length, 0); //中心を軸にランダムで回転し、増やす
for (int i=0; i<6; i++) {
translate(0, sen_length, 0);
rotateX(radians(random(360)));
newSen();
}
for (int i=1; i<=4; i++) {
translate(0, sen_length, 0);
rotateZ(radians(random(360)));
newSen();
}
popMatrix();
}
void newSen() {
sen(sen_start, sen_length, sen_step);
}
void sen(float start, float nagasa, int step) {
float angle; //再帰時の角度の設定用
sss=step;
line(0, 0, 0, -nagasa);
translate(0, -nagasa); //ずれを戻して中心に修正
nagasa *= sen_scale; //次の再帰の長さを計算
if (step > 0) {
angle = sen_angle;
//3方向に分かれる線を描画。
pushMatrix();
rotateX(angle);
rotateZ(angle);
sen(start, nagasa, step-1);
popMatrix();
pushMatrix();
rotateX(-angle);
rotateZ(-angle);
sen(start, nagasa, step-1);
popMatrix();
pushMatrix();
rotateX(0); //3本目は角度をずらす
rotateZ(angle/2);
sen(start, nagasa, step-1);
popMatrix();
}
}
void effect() {
blendMode(ADD);
for (int i=0; i<200; i++) { //星をちりばめる
pushMatrix();
x=random(-1000, width+1000);
y=random(height+1000);
z=random(-1200, -1000);
hoshi=random(3);
translate(0, -300, 0);
stroke(random(180, 255), random(180, 255), random(180, 255), 50); //星本体
strokeWeight(hoshi);
point(x, y, z);
stroke(random(180, 255), random(180, 255), random(180, 255), 10); //発光、ぼかし
strokeWeight(hoshi*2);
point(x, y, z);
strokeWeight(hoshi*3);
point(x, y, z);
strokeWeight(hoshi*4);
point(x, y, z);
popMatrix();
}
location = new PVector(0, 0); //背景モヤ
pushMatrix();
translate(width/2, height/2, 0);
scale(random(4, 8));
for (float i=0; i<400; i+=0.1) {
location.x = cos(radians(i)) * width/2.5;
location.y = sin(radians(i*3)) * height/2.5;
location.z = sin(radians(i*10)) * height/1.5;
strokeWeight(50);
stroke(r[3], g[3], b[3], 2);
point(location.x, location.y, location.z);
location.x = cos(radians(i)) * width/2.5;
location.y = sin(radians(i*3)) * height/2.5;
location.z = sin(radians(i*10)) * height/1.5;
strokeWeight(160);
stroke(r[1]-80, g[1]-80, b[1]-80, 1);
point(location.x, location.y, location.z);
}
popMatrix();
pushMatrix(); //点々演出
translate(width/2, height/1.4, 0);
for (float ii=0; ii<600; ii+=1) {
rotateY(radians(ii*random(1, 50)));
rotateX(radians(ii));
for (float i=0; i<40; i+=1) {
location.x = cos(radians(i*0.7)) * width/2.6;
location.y = sin(radians(i*0.2)) * height/2.6;
location.z = sin(radians(i*0.3)) * height/2.6;
strokeWeight(1);
stroke(r[2], g[2], b[2], 30);
point(location.x, location.y, location.z);
strokeWeight(1);
stroke(r[1], g[1], b[1], 15);
point(location.x+50, location.y+50, location.z+5);
}
}
popMatrix();
}