見出し画像

Processingでグラデーションを表現する

こんにちは。

今回はグラデーションを使って質感を加えよう!ということで、

自分用のまとめも兼ねてグラデーションを作る方法をシェアしたいと思います。

ざっくりと3種類の方法を紹介します。

P2Dを使う

画像1

color col1, col2, col3;

void setup(){
 size(500, 500, P2D);
 colorMode(HSB, 360, 100, 100, 100);
 col1 = color(9, 85, 95);
 col2 = color(315, 85, 95);
 col3 = color(360);

 background(360);
 noStroke();
 grdRect1(width*0.25, height*0.25, 200, 200);
 grdRect2(width*0.75, height*0.25, 200, 200);
 grdRect3(width*0.25, height*0.75, 200, 200);
 grdRect4(width*0.75, height*0.75, 200, 200);

 saveFrame("gradation.png");
}

void grdRect1(float x, float y, float w, float h){
 float hw = w/2;
 float hh = h/2;
 
 fill(col1);
 beginShape();
 vertex(x-hw, y-hh);
 vertex(x+hw, y-hh);
 fill(col2);
 vertex(x+hw, y+hh);
 vertex(x-hw, y+hh);
 endShape();
}

void grdRect2(float x, float y, float w, float h){
 float hw = w/2;
 float hh = h/2;
 
 fill(col1);
 beginShape();
 vertex(x-hw, y-hh);
 fill(col2);
 vertex(x+hw, y-hh);
 vertex(x+hw, y+hh);
 vertex(x-hw, y+hh);
 endShape();
}

void grdRect3(float x, float y, float w, float h){
 float hw = w/2;
 float hh = h/2;
 
 fill(col1);
 beginShape();
 vertex(x-hw, y-hh);
 fill(col2);
 vertex(x+hw, y-hh);
 fill(col3);
 vertex(x+hw, y+hh);
 vertex(x-hw, y+hh);
 endShape();
}

void grdRect4(float x, float y, float w, float h){
 float hw = w/2;
 float hh = h/2;
 
 fill(col1);
 beginShape();
 vertex(x-hw, y-hh);
 vertex(x+hw, y-hh);
 fill(col2);
 vertex(x+hw, y+hh);
 fill(col3);
 vertex(x-hw, y+hh);
 endShape();
}

P2Dを使うと、beginShape()とendShape()の途中に入っているfill()やstroke()が適応されグラデーションを作ることができます。

fill()の位置でグラデーションをある程度調整することができます。

例えば中心から外側に向かってグラデーションにするなどの細かい調整はできませんが残りに2つの方法に比べて動作が軽くなります。
それと2色以上を使えるのもいいですね。

P3Dでも同じことができますよ。

lerpColor()関数を使う

画像3

color col1, col2;

void setup() {
 size(500, 500);
 rectMode(CENTER);
 colorMode(HSB, 360, 100, 100, 100);
 col1 = color(9, 85, 95);
 col2 = color(55, 85, 95);

 background(360);
 noStroke();
 grdRect1(width*0.25, height*0.25, 200, 200);
 grdRect2(width*0.75, height*0.25, 200, 200);
 grdCircle1(width*0.25, height*0.75, 200);
 grdCircle2(width*0.75, height*0.75, 200);

 saveFrame("gradation.png");
}

void grdRect1(float x, float y, float w, float h) {
 float c = 100;
 for (int i=0; i<c; i++) {
   color col = lerpColor(col1, col2, i/c);
   float ww = lerp(w, 0, i/c);
   float hh = lerp(h, 0, i/c);

   fill(col);
   rect(x, y, ww, hh);
 }
}

void grdRect2(float x, float y, float w, float h) {
 float c = 100;
 for (int i=0; i<c; i++) {
   color col = lerpColor(col1, col2, i/c);
   float ww = lerp(w, 0, i/c);
   float xx = lerp(x, x-(w/2), i/c);

   fill(col);
   rect(xx, y, ww, h);
 }
}

void grdCircle1(float x, float y, float d) {
 float c = 100;
 for (int i=0; i<c; i++) {
   color col = lerpColor(col1, col2, i/c);
   float dd = lerp(d, d*0.2, i/c);

   fill(col);
   ellipse(x, y, dd, dd);
 }
}


void grdCircle2(float x, float y, float d) {
 float c = 100;
 for (int i=0; i<c; i++) {
   color col = lerpColor(col1, col2, i/c);
   float a = lerp(PI, 0, i/c);
   
   fill(col);
   arc(x, y, d, d, -a, a, CHORD);
 }
}

lerpColor()でグラデーションをしながら図形を重ねて描画しています。

先ほどの方法と比べてこちらはグラデーションの方向などを調整することができます。

lerpColor()がnoise()と相性良さそうなのもいいです。
lerpColor(col1, col2, noise())とこんな感じにできるので。

arc()を重ねて円を作る綺麗なグラデーションを作ることができます。

何度も重ねて描画しているので図形の数が増えると重くなります。

半透明の図形を重ねる

画像3

color col1, col2, col3;

void setup() {
 size(500, 500);
 rectMode(CENTER);
 colorMode(HSB, 360, 100, 100, 100);
 col1 = color(255, 85, 95);
 col2 = color(167, 85, 95);
 col3 = color(360);

 background(360);
 noStroke();
 grdRect1(width*0.25, height*0.25, 200, 200);
 grdRect2(width*0.75, height*0.25, 200, 200);
 grdCircle1(width*0.25, height*0.75, 200);
 grdCircle2(width*0.75, height*0.75, 200);

 saveFrame("gradation.png");
}

void grdRect1(float x, float y, float w, float h) {
 float c = 100;
 fill(col1);
 rect(x, y, w, h);
 for (int i=0; i<c; i++) {
   float ww = lerp(0, w, i/c);
   float hh = lerp(0, h, i/c);

   fill(col2, 2);
   rect(x, y, ww, hh);
 }
}

void grdRect2(float x, float y, float w, float h) {
 float c = 100;
 fill(col1);
 rect(x, y, w, h);
 
 for (int i=0; i<c; i++) {
   float ww = lerp(0, w, i/c);
   float hh = lerp(0, h, i/c);

   fill(col2, 4);
   rect(x, y, ww, hh);
 }
 
 for (int i=0; i<c; i++) {
   float hh = lerp(0, h, i/c);
   float yy = lerp(y+(h/2), y, i/c);

   fill(col3, 1);
   rect(x, yy, w, hh);
 }
}

void grdCircle1(float x, float y, float d) {
 float c = 100;
 fill(col1);
 ellipse(x, y, d, d);

 for (int i=0; i<c; i++) {
   float a = lerp(0, PI, i/c);

   fill(col2, 2);
   arc(x, y, d, d, -a, a, CHORD);
 }
}


void grdCircle2(float x, float y, float d) {
 float c = 100;

 pushMatrix();
 translate(x, y);
 fill(col1);
 ellipse(0, 0, d, d);

 for (int i=0; i<c; i++) {
   float dd = lerp(0, d, i/c);

   fill(col2, 2);
   ellipse(0, 0, dd, dd);
 }

 c = 50;
 rotate(PI*1.25);
 for (int i=0; i<c; i++) {
   float a = lerp(0, PI*0.75, i/c);

   fill(col3, 3);
   arc(0, 0, d, d, -a, a, CHORD);
 }
 popMatrix();
}

最初に図形を描きその上から半透明の図形を重ねて描きグラデーションを表現しています。
lerpColor()と似たようなやり方ですけど微妙な色の差が出ます。

うまく調整すれば何色も重ねることができそうです。

こちらもlerpColorを使う方法同様、動作が重くなります。

以上。

Processingクンフー奥義書『大鹿の舞 その一』でした。

おわりに

 今回紹介したこれらを組み合わせたり、改変したりすればもっと様々な表現ができると思うので、色々試してみると面白いと思います。

アイデアとしては
・stroke()にグラデーションを加えて何か面白い表現はできないか。
・グラデーションをアニメーションさせる。徐々に赤に染まっていくとか。
・プリミティブな図形ではなく、もっと複雑な形にグラデーションを加える。
・グラデーションを沢山の点で表現して、粒子とグラデーションの質感のバケモノにする。

とパッと思いついたものを書いてみました。

ありがとうございました。

応援してくださる方は購入&サポートをお願いします!

Happy coding!

ここから先は

0字

¥ 100

応援してくださる方!いつでもサポート受け付けてます!