3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

3D空間に画像を設置したーい

3
Last updated at Posted at 2025-12-18

3D空間に画像を設置する関数をリファレンスページを探すとビルボードが出てきました。
しかし結果が地面に画像を平面に貼り付けようとするとカメラに画像が張り付いた感じになり、やりたいこととは異なりました。
理想とビルボード.png
別の方法を調べると板ポリゴンに画像を貼り付ける方法があったので、試していきたいと思います。

お品書き

1.各パラメータの解説
2.画像の描画
3.まとめ

1.各パラメータの解説

以下のコードは初期化処理です。

3DImage.cpp
#include <DxLib.h>

constexpr int IMAGE_RADIUS = (1024 / 2);

// 頂点番号
constexpr int LEFT_BACK     = 0;
constexpr int LEFT_FORWARD  = 1;
constexpr int RIGHT_BACK    = 2;
constexpr int RIGHT_FORWARD = 3;

// 頂点配列
VERTEX3D imageVertex_[4];

int imagePath_;
VECTOR imagePos_;

void Init(void)
{
	// 法線方向(上方向)
    const VECTOR INIT_NORM = VGet(0.0f, 1.0f, 0.0f);

    // 拡散光(青色)
    const COLOR_U8 INIT_DIFUSECOLOR = GetColorU8(0, 0, 255, 255);

    VECTOR imageOffset;

    // 位置割り当て
    imagePos_ = VGet(0.0f, 0.0f, 0.0f);

    // 画像割り当て
    imagePath_ = LoadGraph("画像のハンドル");

    // 左前
    imageOffset = VGet(-IMAGE_RADIUS, 0.0f, -IMAGE_RADIUS);
    imageVertex_[LEFT_BACK].pos  = VAdd(imagePos_, imageOffset);
    imageVertex_[LEFT_BACK].norm = INIT_NORM;
    imageVertex_[LEFT_BACK].dif  = INIT_DIFUSECOLOR;
    imageVertex_[LEFT_BACK].u = 0.0f;
    imageVertex_[LEFT_BACK].v = 1.0f;

    // 左奥
    imageOffset = VGet(-IMAGE_RADIUS, 0.0f, IMAGE_RADIUS);
    imageVertex_[LEFT_FORWARD].pos  = VAdd(imagePos_, imageOffset);
    imageVertex_[LEFT_FORWARD].norm = INIT_NORM;
    imageVertex_[LEFT_FORWARD].dif  = INIT_DIFUSECOLOR;
    imageVertex_[LEFT_FORWARD].u = 0.0f;
    imageVertex_[LEFT_FORWARD].v = 0.0f;

    // 右前
    imageOffset = VGet(IMAGE_RADIUS, 0.0f, -IMAGE_RADIUS);
    imageVertex_[RIGHT_BACK].pos  = VAdd(imagePos_, imageOffset);
    imageVertex_[RIGHT_BACK].norm = INIT_NORM;
    imageVertex_[RIGHT_BACK].dif  = INIT_DIFUSECOLOR;
    imageVertex_[RIGHT_BACK].u = 1.0f;
    imageVertex_[RIGHT_BACK].v = 1.0f;

    // 右奥
    imageOffset = VGet(IMAGE_RADIUS, 0.0f, IMAGE_RADIUS);
    imageVertex_[RIGHT_FORWARD].pos  = VAdd(imagePos_, imageOffset);
    imageVertex_[RIGHT_FORWARD].norm = INIT_NORM;
    imageVertex_[RIGHT_FORWARD].dif  = INIT_DIFUSECOLOR;
    imageVertex_[RIGHT_FORWARD].u = 1.0f;
    imageVertex_[RIGHT_FORWARD].v = 0.0f;
}

VERTEX3Dの初期化

[板ポリゴンのイメージ画像を貼り付け]
今回はシンプルに画像を貼り付けるので、頂点数を4つにします。
板ポリゴンイメージ.png

.pos

各頂点のグローバル座標の位置です。
今回は imagePos_ の値を板ポリゴンの中央にしたいので、
中央座標から画像の半径分調整します。

tips
頂点の数値を別々にすれば、画像を曲げたり斜めにすることができる!!

ゆがみ.png

.norm

頂点の法線方向で、ライティングの計算時にされます。
今回は平行な地面に設置させたいので、Y軸をプラス方向にします。

注意!!
法線の向きを誤ると、明るさ・陰影・光沢・テクスチャの方向に影響が出ます。画像が反映されない原因になるのでご注意を...

.dif

頂点のディフューズカラー(拡散光)です。
今回は元画像を青色にしたいので[青100%, 不透過度100%]にします。

tips
数値を別々にすると、線形グラデーションが再現できます

グラデーション.png

.u.v

UV座標はテクスチャ画像の位置から[0.0 ~ 1.0]の範囲で座標を指定します。
UとVがいまいちわからなかったのですが、
[ UX軸VY軸 ]と覚えれば大丈夫です。

UV座標の注意点

blender等はデカルト座標で初期座標は画像の左下ですが、
それとは異なりスクリーン座標なので初期座標は画像の左上です。

デカルトとスクリーン.png

.su.sv

頂点のサブテクスチャです。リファレンスによると今のバージョンで使用しないようです。今回は使用しません

2.画像の描画

3D頂点の準備が整いましたので描画を行います。

3DImage.cpp
#include <DxLib.h>

// 頂点番号
constexpr int LEFT_BACK     = 0;
constexpr int LEFT_FORWARD  = 1;
constexpr int RIGHT_BACK    = 2;
constexpr int RIGHT_FORWARD = 3;

void Draw(void)
{
    // 三角ポリゴンの頂点数
    const int POINT_CNT = 6;

    // 三角ポリゴンの数
    cosnt int TRIANGLE_CNT = 2;
    
    
    WORD index[POINT_CNT];

    // 三角ポリゴンA
    index[0] = LEFT_BACK;
    index[1] = LEFT_FORWARD;
    index[2] = RIGHT_BACK;

    // 三角ポリゴンB
    index[3] = RIGHT_FORWARD;
    index[4] = RIGHT_BACK;
    index[5] = LEFT_FORWARD;

    // 画像描画
	DrawPolygonIndexed3D(imageVertex_, 4, index, TRIANGLE_CNT, imagePath_, true);
}

私は、「WORD変数ってなんぞや?」と思いましたが、
どうやら、unsigned intのように符号なしの整数を扱うデータ型らしく、
unsigned intと違う点として、以下のようになります。

符号なし整数型の違い unsigned int WORD[unsigned short]
ビット幅 32 16
数値の範囲 0 ~ 4,294,967,295 0 ~ 65,535

これで完成ですお疲れ様でした。
完成.png

おわりに

私は個人制作で敵召喚の魔法陣エフェクト制作し導入したのですが、
「何もない空間から魔法陣が出てくるより、既にあったほうがカッコよくね?」
となり、これを制作することに至りました。
ですが、まだ頂点シェーダーなどの特殊効果を導入できていません!!
これからいろいろとシェーダーなどアレンジしてみたいと思います。

比較.gif

参考文献

リファレンスページ

3
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?