発光体を作りたいのですが?生徒からの質問

サイエンス記事

Processingで3Dグラフィックスを使って太陽系を描いているときに、太陽を発光させたいとの要望が出て来ました。もう10回近く3Dグラフィックスの授業をやっているのですが、意外と初めての質問でした。

Processingではemissive()という関数で材質に発光する成分を持たせることができます。
この効果を見るために球体が発光する度合いを変えて動画にしてみました。小さい球は3次元極座標で球面上に配置し以下の式で3次元直交座標に変換しています。

x = rsinθcosφ
y = rsinθsinφ
z = rcosθ

 

ちょっとインパクトがないですね。太陽のようにギラギラ光る表現は難しいようです。

Processingのプログラムは以下のようになります。

float rotx = 0;
float roty = 0;
float emi = 0;
int delta = 1;

void setup() {
  size(640, 480, P3D);
  noStroke();
}

void draw() {
  background(0);
  emi += delta;
  if (emi>180 || emi<0) {
    delta *= -1;
  }
  fill(0, 50, 100);
  ambientLight(255, 255, 255);
  lightSpecular(55, 55, 55);
  directionalLight(255, 255, 255, 0, 0, -1);
  specular(255, 255, 255);
  emissive(emi, emi, emi);
  shininess(3.0);   
  translate(width/2, height/2, -500);
  rotateX(rotx);
  rotateY(roty);
  rotateZ(rotx/2);
  float x, y, z;
  float r, theta, phi;
  rotx += 0.01;
  roty += 0.01;
  r = 400;
  for (int j=0; j<12; j++) {
    for (int i=0; i<6; i++) {
      theta = radians(i*30);
      phi = radians(j*30);
      x=r*sin(theta)*cos(phi); 
      y=r*sin(theta)*sin(phi);
      z=r*cos(theta);
      pushMatrix();
      translate(x, y, z);
      sphere(50);
      popMatrix();
    }
  }
}

 

よりインパクトのある表現は2Dで行うことがよくあります。
それっぽく見えるように円の中央では明るく、周辺に行くに従い暗くします。
例えば以下の画像は暗くて大きい円を描き、少し明るくて小さい円を重ねて描き、さらに明るくて小さい円を描くということを繰り返して得られたものです。

Processingのプログラムは以下のようになります。

int r, g, b;

void setup() {
  size(640, 480);
  blendMode(ADD);  
  noStroke();
  imageMode(CENTER);
}

void draw() {
  background(0, 0, 0);
  for (int x = 25; x > 0; x--) {
    float dist = sq(x);
    dist /= 25.0;
    r = constrain(int(80/dist), 0, 255);
    g = constrain(int(80/dist), 0, 255);
    b = constrain(int(200/dist), 0, 255);
    fill(r, g, b);
    ellipse(width/2, height/2, x*25, x*25);
  }
  filter(BLUR, 5);
}

このような画像をたくさん作ってアレイリストに入れて表示すれば以下の炎のような表現も可能になります。