5.2 3Dプログラミング2

Filed in processing , メディアプログラミング特論 0 comments

前節では基本的なオブジェクトの作成、座標系の移動、回転、拡大縮小を学びました。この節では、ライティングの演出やカメラの設定を体験します。

5.2.1 ライト

ここでは、processingの3D空間上でライトを使ってみます。ライトといっても、環境光、方向光、スポットライト、ハイライトなど様々な要素がありますが、まずは、一番基本的なライトです。

2016_09_28_19_59

図5.2-a

リスト5.2-a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
float theta = 0.0;    //角度
 
//1秒で1回転するように30で割る。度数法だと12°
//更に6で割ると1周期6秒
float rad = (TWO_PI/30.0)/6;
 
void setup() {
  size(400, 400, P3D);
  frameRate(30);  //1秒30フレーム
  noStroke();
}
 
void draw() {
  background(0);
  lights();    //基本ライトを設置
 
  //立体の中心を画面中央に移動
  translate(width/2, height/2); 
  rotateX(theta);  //X軸に対してtheta分だけ回転
  rotateY(theta);  //Y軸に対してtheta分だけ回転
  box(150, 150, 150);  //150x150x150pxの立方体を描画
 
  theta += rad;    //時間を進める
  if (theta > TWO_PI) theta = 0.0;    //1周期分終わったら原点に戻る
}

これで、陰影が付いたことが確認できました。

5.2.2 環境光

次に環境光(ambient light)を再現してみます。環境光は方向性を持たない光です。全体をまんべんなく照らしているので、オブジェクトに陰影は付きません。構文は次の形になります。

1
2
3
4
 
//ambientLight(赤, 緑, 青)
ambientLight(red, green, blue);
//

ambient_light

図5.2-b

2016_09_28_20_08

図5.2-c
リスト5.2-b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
float theta = 0.0;    //角度
 
//1秒で1回転するように30で割る。度数法だと12°
//更に6で割ると1周期6秒
float rad = (TWO_PI/30.0)/6;
 
void setup() {
  size(400, 400, P3D);
  frameRate(30);  //1秒30フレーム
  noStroke();
}
 
void draw() {
  background(0);
  ambientLight(127, 0, 0);  //赤の環境光
 
  //立体の中心を画面中央に移動
  translate(width/2, height/2); 
  rotateX(theta);  //X軸に対してtheta分だけ回転
  rotateY(theta);  //Y軸に対してtheta分だけ回転
  box(150, 150, 150);  //150x150x150pxの立方体を描画
 
  theta += rad;    //時間を進める
  if (theta > TWO_PI) theta = 0.0;    //1周期分終わったら原点に戻る
}

5.2.3 その他のタイプのライト

Processingが提供しているライトのタイプは方向光、点光源やスポットライトなどそれぞれ特色があり、それらを組み合わせて使うこともできます。

●方向光(directionalLight)

方向光(directional light)は一定の方向を持ったライトで、物体をまんべんなく照らします。nx, ny, nzでは、光が向かっている方向を-1.0 ~ 1.0の間で指定します。

1
2
3
4
 
//directionalLight(赤, 緑, 青, x方向, y方向, z方向)
directionalLight(red, green, blue, nx, ny, nz);
//

directional_light

図5.2-d

●点光源(pointLight)

pointLightは電球のように一箇所から拡散する光です。

1
2
3
4
 
//pointLight(赤, 緑, 青, x座標, y座標, z座標);
pointLight(red, green, blue, x, y, z);
//

point_light

図5.2-e

●スポットライト(spotLight)

spotLightはその名の通り、一定方向に強い光をあてるライトです。directionalLightやpointLightと比べると、細かい設定が可能です。

1
2
3
4
5
6
7
 
spotLight(red, green, bule, //赤, 緑, 青
          x, y, z,          //光源のx, y, z座標
          nx, ny, nz,       //光の方向
          angle,            //スポットの角度(ここでは20°)
          concentration);   //光の集まり度合い。数値が小さいと強く一点に集まる
//

spot_light

図5.2-f

次のサンプルでは、3種類のライトを切り替えることができます【リスト5.2-c】。

図5.2-g
リスト5.2-c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
int lightFlag = 1;
 
void setup() {
  size(400, 400, P3D);
  frameRate(30);  //1秒30フレーム
  noStroke();
}
 
void draw() {
  background(0);
 
  //立体の中心をマウスの位置に移動
  translate(mouseX, mouseY);
 
  if (lightFlag == 1) {
 
    //directionalLight(赤, 緑, 青, x方向, y方向, z方向);
    //x, y, z方向は光源が照らす方向。-1.0 ~ 1.0
    directionalLight(0, 255, 0, 1.0, 1.0, 0.0);
 
  } else if (lightFlag == 2) {
 
    //pointLight(赤, 緑, 青, x座標, y座標, z座標);
    pointLight(255, 0, 0, -200, 0, 200);
 
  } else if (lightFlag == 3) {
 
    spotLight(0, 0, 255,   //赤, 緑, 青
              0, -200, 0,  //光源のx, y, z座標
              0, 1.0, 0,   //光源が照らす方向。-1.0 ~ 1.0
              PI/4,        //スポットの角度(ここでは45°)
              1);          //光が拡散する度合い
  }
 
  sphere(75);  //球を描画
}
 
void keyPressed() {
 
  switch(key) {
 
  case '1':  //1を押したら、directionalLight   
    lightFlag = 1;
    break;
  case '2':    //2を押したら、pointLight
    lightFlag = 2;
    break;    
  case '3':    //3を押したら、spotLight
    lightFlag = 3;
    break;
  }
}

5.2.4 ハイライトとオブジェクトの色

様々な種類のライトがありましたが、次は光源の鏡面反射色成分を指定するlightSpecular()と、オブジェクトの鏡面反射色を設定するspecular()を使います。似た名称で混同しやすいのですが、反射成分が光源とオブジェクトのどちらに属しているかの違いです。

1
2
3
4
5
6
7
 
//lightSpecular(赤, 緑, 青)
lightSpecular(red, green, blue);   //光源の鏡面反射色成分
 
//specular(赤, 緑, 青)
specular(red, green, blue);        //オブジェクトの鏡面反射色(オブジェクトの色)
//

10_6_15__1_35_AM

図5.2-h

次のコードを実行してみましょう【リスト5.2-d】。

リスト5.2-d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
boolean lightFlag = false;
 
void setup() {
  size(400, 400, P3D);
  background(0);
  noStroke();
}
 
void draw() {
  background(0);
 
  ambientLight(10, 10, 10);    //環境光
 
  pushMatrix();
  translate(width/2, height/2, 0);
 
  //強い光のハイライトを設定
  if (lightFlag)lightSpecular(255, 0, 0);
  else lightSpecular(50, 0, 0);    //弱い光のハイライトを設定
 
  //方向光を設定
  directionalLight(255, 255, 255, -1, 1, -1);
 
  specular(255, 255, 255);    //オブジェクトの色を設定
  sphere(100);
  popMatrix();
}
 
//lightSpecularの切り替え用フラッグ
void mousePressed() {
  if (lightFlag) lightFlag = false;
  else lightFlag = true;
}

クリックでlightSpecularの値が変わります。例えばlightSpecular(50, 0, 0)の場合、ハイライトは緩やかになり、lightSpecular(255, 0, 0)の場合はハイライトが強くなります。

次に、ふたつの球それぞれにspecular()を設定してみます。

2016_09_29_0_16

図5.2-i
リスト5.2-e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
float angle = 0.0;
 
void setup() {
  size(400, 400, P3D);
  background(0);
  noStroke();
}
 
void draw() {
  background(0);
 
  ambientLight(20, 20, 20);    //環境光を当てる
  //光の鏡面反射色(ハイライト)を設定
  lightSpecular(255, 255, 255);
  //方向光を設定
  directionalLight(100, 100, 100, 0, 1, -1);
 
  //左の球
  pushMatrix();
  translate(100, height/2, 0);
  specular(255, 0, 0);  //オブジェクトの色
  sphere(50);
  popMatrix();
 
  //右の球
  pushMatrix();
  translate(300, height/2, 0);
  specular(0, 0, 255);  //オブジェクトの色
  sphere(50);
  popMatrix();
}

5.2.5 光沢

光沢はshininess()で設定します。

2016_09_29_0_19

図5.2-j
リスト5.2-f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
float angle = 0.0;
 
void setup() {
  size(400, 400, P3D);
  background(0);
  noStroke();
}
 
 
void draw() {
  background(0);
 
  ambientLight(20, 20, 20);    //環境光を当てる
  //光の鏡面反射色(ハイライト)を設定
  lightSpecular(255, 255, 255);
  //方向光を設定
  directionalLight(100, 100, 100, 0, 1, -1);
 
  //左の球
  pushMatrix();
  translate(100, height/2, 0);
  specular(200, 200, 200);  //オブジェクトの色を設定
  shininess(5.0);    //オブジェクトの光沢を設定
  sphere(50);
  popMatrix();
 
  //右の球
  pushMatrix();
  translate(300, height/2, 0);
  specular(200, 200, 200);  //オブジェクトの色を設定
  shininess(1.0);    //オブジェクトの光沢を設定
  sphere(50);
  popMatrix();
}

5.2.6 カメラ

ここではカメラを設置して、空間の見え方を設定します。
標準のカメラはcamera()を使います。視点と中心点、天地がどの方向か(通常はYが天)を指定します。

1
2
3
4
 
//camera(視点X, 視点Y, 視点Z, 中心点X, 中心点Y, 中心点Z, 天地X, 天地Y, 天地Z)
camera(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
//

2016_09_29_3_09

図5.2-k

コードは【リスト5.2-g】になります。camera関数の中の値を変えてどのように見え方が変化するか確認しましょう。

リスト5.2-g
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void setup() {
  size(400, 400, P3D);
  noFill();
  stroke(0);
}
 
void draw() { 
  background(255);
 
  //基準点を画面中央
  translate(width/2, height/2, 0);
 
  camera(90.0, -100.0, 300.0, // 視点X, 視点Y, 視点Z
         0.0, 0.0, 0.0, // 中心点X, 中心点Y, 中心点Z
         0.0, 1.0, 0.0); // 天地X, 天地Y, 天地Z
 
  box(150);
}

5.2.7 ortho()

パースペクティブ(遠近)がつかない立体です。

1
2
3
4
5
6
7
 
//ortho(左, 右, 下, 上);
ortho(left, right, bottom, top);
 
//ortho(左, 右, 下, 上, 近い面までの距離、遠い面までの距離);
ortho(left, right, bottom, top, near, far);
//

2016_09_29_3_16

図5.2-l
リスト5.2-h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void setup() { 
  size(400, 400, P3D);
  noFill();
  stroke(0);
 
  //ortho(左、右、下、上)
  ortho(-width/2, width/2, -height/2, height/2);
}
 
void draw() {  
  background(255);
 
  //基準点を画面中央
  translate(width/2, height/2, 0);
  rotateX(-PI/9.0);
  rotateY(-PI/9.0);
  box(150);
}

5.2.8 frustum()

パースペクティブが付いた空間になります。次の形で使います。

1
2
3
4
 
frustum(左、右、下、上、近い面までの距離、遠い面までの距離)
frustum(left, right, bottom, top, near, far);
//

【図5.2-m】はその構造を図解したものです。

image61

図5.2-m

2016_09_29_3_51

図5.2-n
リスト5.2-i
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
float scale = 5;  //視点の範囲の拡大率
float aspect;  //画面の縦横比
 
void setup() {
  size(400, 400, P3D);
  noFill();
  stroke(0);
 
  //画面の縦横比が変わってもオブジェクトが歪まないように比率を計算
  aspect = float(width)/float(height);
 
  //frustum(左、右、下、上、近い面までの距離、遠い面までの距離)
  frustum(-scale*aspect, scale*aspect, -scale, scale, 10, 500);
}
 
void draw() {
  background(255);
 
  //基準点を画面中央。z軸方向には-100
  translate(width/2, height/2, 0);
  rotateX(-PI/9.0);  //-20°回転
  box(150);
}

5.2.9 perspective()

perspective()はfrustum()とほぼ同じ機能ですが、x座標の視野角(fov)を設定できるのが特徴で、fovの設定を変えると遠近感のつき方が変化します。次の形で使います。

1
2
3
4
 
//perspective(視野角、縦横の比率、近い面までの距離、遠い面までの距離) 
perspective(foxy, aspect, zNear, zFar);
//

【図5.2-o】はその構造を図解したものです。

image62

図5.2-o

サンプルは、視野角を非常に広い90度にしているために、遠近感が強くなっています。一般的には、30度から60度ぐらいまでが適切かもしれません。

2016_09_29_4_02

図5.2-p
リスト5.2-j
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void setup() {
  size(400, 400, P3D);
  noFill();
  stroke(0);
 
  float fov = PI/2.0;  //視野角90°
 
  //perspective(視野角、縦横の比率、近い面までの距離、遠い面までの距離) 
  perspective(fov, float(width)/float(height), 100.0, 800.0);
}
 
void draw() {
  background(255);
 
  translate(width/2, height/2, 100);  //基準点を画面中央
  rotateX(-PI/9.0);  //-20°回転
  box(150);
}
Posted by noguchi   @   29 9月 2016 0 comments

0 Comments

Sorry, comments are closed.

Previous Post
«
Next Post
»
Stroom designed by Credit Cards In conjunction with Web Hosting Reseller , Dream Interpretation Guide , Best Website Hosting.