3D空間での透明度のある画像描画とZソートなど
Posted: 2014年1月05日(日) 04:04
現在、DXライブラリを使用して3DのSTGを作っています。
DrawBillboard3Dを使用して弾の描画を行っているのですが、透明度がある場合や加算ブレンドを使うときは、
Zバッファと別にZソートを用いて奥から順に描画しなければならないと聞きました。
そこで以下のようなプログラムを作ってみました。
使用した画像はこちらです。
実行した結果、それなりには改善されてはいるのですが、画像のように少なからず背景が写ってしまいます。
これを改善する方法があれば教えていただけないでしょうか。
他にも、実際にゲーム化するときは1万以上の弾を同時に処理することになるので、
その時に出来るだけ軽くする方法などあれば教えて欲しいです。
DrawBillboard3Dを使用して弾の描画を行っているのですが、透明度がある場合や加算ブレンドを使うときは、
Zバッファと別にZソートを用いて奥から順に描画しなければならないと聞きました。
そこで以下のようなプログラムを作ってみました。
#include "DxLib.h"
//最大数
const int MAX_NUM = 10;
//弾の情報
struct SHOT{
VECTOR pos; //座標
float range; //カメラからの距離
}shot[MAX_NUM];
//ベクトル間の距離
float RangeV(VECTOR v1,VECTOR v2){
return (v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y) + (v1.z - v2.z) * (v1.z - v2.z);
}
//カメラから遠い順にソートする
int comp(const void * a,const void * b){
SHOT * c = (SHOT *)a;
SHOT * d = (SHOT *)b;
//qsortはint型しか扱えない?
return (unsigned int)(d->range * 10) - (unsigned int)(c->range * 10);
}
/*__________________________________________________*/
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(true);
DxLib_Init();
SetDrawScreen(DX_SCREEN_BACK);
SetCameraNearFar(100,10000);
SetUseZBuffer3D(true);
SetWriteZBuffer3D(true);
SetDrawMode(DX_DRAWMODE_BILINEAR);
//メインループ
while(!ProcessMessage() && !ScreenFlip() && !ClearDrawScreen()){
//カメラの座標
const VECTOR cameraPos = VGet(0,100,-1000);
SetCameraPositionAndTarget_UpVecY(cameraPos,VGet(0,0,0));
//位置と距離の設定
for(int i = 0;i < MAX_NUM;i ++){
//位置をランダムに設定
shot[i].pos = VGet(GetRand(500)-150.f,GetRand(500)-150.f,GetRand(500)-150.f);
//距離を取得する
shot[i].range = RangeV(cameraPos,shot[i].pos);
}
//Zソート
qsort(shot,MAX_NUM,sizeof(SHOT),comp);
//描画
const int IMG = LoadGraph("../image/shot.png");
for(int i = 0;i < MAX_NUM;i ++) DrawBillboard3D(shot[i].pos,0.5,0.5,500,0,IMG,true);
}
DxLib_End();
return 0;
}

実行した結果、それなりには改善されてはいるのですが、画像のように少なからず背景が写ってしまいます。
これを改善する方法があれば教えていただけないでしょうか。
他にも、実際にゲーム化するときは1万以上の弾を同時に処理することになるので、
その時に出来るだけ軽くする方法などあれば教えて欲しいです。