読者です 読者をやめる 読者になる 読者になる

デジタル・デザイン・ラボラトリーな日々

アラフィフプログラマーが数学と物理を基礎からやり直す

3Dを基礎から勉強する テクスチャマッピング陰影付け

前回の「3Dを基礎から勉強する テクスチャマッピング」では、テスクチャを貼り付けたことにより陰影が消えてしまいました。
陰影(シェーディング)については、以前に「3Dを基礎から勉強する フラットシェーディング」をやりました。これを応用すれば、陰影はつけれそうです。
今のプログラムはもともと「3Dモデルを表示するJavaアプレットの作成」を参考にTypeScriptに移植したものです。この記事内の「【ステップ4】面の明るさを設定する」でもフラットシェーディングを行っていますので、この考え方で実現させます。

現在、面を塗る際に法線ベクトルのz成分を元に陰影の描画色を定めています。

var rgb = this.HSVtoRGB(0.4 * 360, 0.5 * 255, face.nz * 255);
g.fillStyle = 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';     // 面の塗りつぶし
g.fill();

face.nzには1.0~0.0の値が入っており、光源の角度(cos)が「0°」に近くなると値が1.0となり面の明るさが最大値となります。
f:id:Yaju3D:20130525230936j:plainf:id:Yaju3D:20130526212554j:plain

HTML5Canvasでは、ピクセルデータを読み込んで色を演算させることが出来るのですが、今回はもっと簡単な方法を用います。
Canvasに透明度(globalAlpha)のプロパティがあり、その値は0.0(完全に透明)から 1.0(透明度なし)となっています。
ポリゴン面を黒色で塗る時にglobalAlphaプロパティを使ってテクスチャに陰影を付けます。
この際に、face.nzとglobalAlphaプロパティの値は反対関係にありますから、g.globalAlpha = 1 - face.nzとしています。

if (this.isTexture) {
    // テクスチャの描画
    var vertex_list = [pt1.x, pt1.y, pt2.x, pt2.y, pt3.x, pt3.y];
    var uv_list = [face.coords[0].u, face.coords[0].v, face.coords[1].u, face.coords[1].v, face.coords[2].u, face.coords[2].v];
    this.drawTriangle(g, this.texture, vertex_list, uv_list, i);
    g.save();
    g.globalAlpha = 1 - face.nz;
    g.fillStyle = 'Black';
    g.fill();
    g.restore();
}

結果は下記の通りになります。
f:id:Yaju3D:20150712124232j:plain

参考:床井研究室 コンピュータグラフィックス
10.陰影付け、12.テクスチャマッピング