シャドウマップ関係関数

宣言int MakeShadowMap( int SizeX, int SizeY ) ;

概略シャドウマップを作成する

引数 SizeX , SizeY : 作成するシャドウマップのサイズ( 2のn乗である必要があります )
戻り値 -1   : エラー発生
-1以外 : シャドウマップのハンドル

解説  シャドウマップは3Dモデルの描画で影を表現する為のもので、この関数にシャドウマップの横解像度 SizeX、縦解像度 SizeY を引数として渡して作成します。

DXライブラリでシャドウマップを使用した影の表現する手順は以下のようになります。


<最初に行うこと>

1.MakeShadowMap を使用してシャドウマップを作成


<シャドウマップの準備>

2.SetShadowMapLightDirection を使用してシャドウマップへの描画で想定するライトの向きを設定

3.SetShadowMapDrawArea を使用してシャドウマップに描画する3D空間の範囲を設定

4.ShadowMap_DrawSetup を使用してシャドウマップへの描画の準備

5.シャドウマップへ描画したい全ての3Dモデルを MV1DrawModel で描画

6.ShadowMap_DrawEnd を使用してシャドウマップへの描画を終了


<シャドウマップによる影の表現を伴う3Dモデル描画>

7.SetUseShadowMap を使用して使用するシャドウマップを設定

8.シャドウマップによる影の表現を伴う描画を行いたい全ての3Dモデルを MV1DrawModel で描画

9.SetUseShadowMap のシャドウマップハンドルを指定する引数( 第二引数 )に -1 を渡して呼び出し、
  使用するシャドウマップの設定を解除


<最後に行うこと>

10.必要が無くなったシャドウマップを DeleteShadowMap を使用して削除


 尚、引数のコメントにもありますが SizeX、SizeY は2のn乗の数値( 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 ... )である必要があります。
 SizeX, SizeY で指定するサイズが大きければ大きいほど描画される影の粗さが軽減されますが、その分描画負荷や使用するVRAMのサイズも大きくなりますので注意してください。

 また、シャドウマップの機能はグラフィックスデバイスがシェーダーモデル2.0以降に対応している必要があり、 且つそれなりに処理負荷が高いので古いPCでも動作するソフトを作成する場合はシャドウマップの機能を使用しないか、 オプション等でシャドウマップの機能を使用するかどうかを選択できるようにする必要があります。

サンプル

  板ポリゴンにキャラクターモデルの影を描画します。
Windows用
#include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int StageModelHandle ; int CharaModelHandle ; int ShadowMapHandle ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) { // エラーが発生したら終了 return -1 ; } // 描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ) ; // キャラクターモデルの読み込み CharaModelHandle = MV1LoadModel( "DxChara.x" ) ; // ステージモデルの読み込み StageModelHandle = MV1LoadModel( "Plane.mqo" ) ; // シャドウマップハンドルの作成 ShadowMapHandle = MakeShadowMap( 1024, 1024 ) ; // カメラの位置と向きを設定 SetCameraPositionAndTarget_UpVecY( VGet( 0.0f, 800.0f, -800.0f ), VGet( 0.000f, 500.000f, 0.000f ) ); // 描画する奥行き方向の範囲を設定 SetCameraNearFar( 40.000f, 2000.000f ); // ライトの方向を設定 SetLightDirection( VGet( 0.5f, -0.5f, 0.5f ) ); // シャドウマップが想定するライトの方向もセット SetShadowMapLightDirection( ShadowMapHandle, VGet( 0.5f, -0.5f, 0.5f ) ) ; // シャドウマップに描画する範囲を設定 SetShadowMapDrawArea( ShadowMapHandle, VGet( -1000.0f, -1.0f, -1000.0f ), VGet( 1000.0f, 1000.0f, 1000.0f ) ) ; // メインループ while( ProcessMessage() == 0 ) { // 画面をクリア ClearDrawScreen() ; // シャドウマップへの描画の準備 ShadowMap_DrawSetup( ShadowMapHandle ) ; // シャドウマップへステージモデルの描画 MV1DrawModel( StageModelHandle ) ; // シャドウマップへキャラクターモデルの描画 MV1DrawModel( CharaModelHandle ) ; // シャドウマップへの描画を終了 ShadowMap_DrawEnd() ; // 描画に使用するシャドウマップを設定 SetUseShadowMap( 0, ShadowMapHandle ) ; // ステージモデルの描画 MV1DrawModel( StageModelHandle ) ; // キャラクターモデルの描画 MV1DrawModel( CharaModelHandle ) ; // 描画に使用するシャドウマップの設定を解除 SetUseShadowMap( 0, -1 ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } // シャドウマップの削除 DeleteShadowMap( ShadowMapHandle ) ; // ステージモデルの削除 MV1DeleteModel( StageModelHandle ) ; // キャラクターモデルの削除 MV1DeleteModel( CharaModelHandle ) ; // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }



宣言int DeleteShadowMap( int SmHandle ) ;

概略シャドウマップを削除する

引数 SmHandle: 削除するシャドウマップのハンドル
戻り値 0:成功
 -1:エラー発生

解説  SmHandle で指定されたシャドウマップを削除します。
 保持しておけるシャドウマップの数や、シャドウマップの保持に必要な VRAM の容量には限りがありますので、 不要になったシャドウマップはこの関数を使用して削除するようにしてください。

サンプル

  MakeShadowMap のサンプルを参照してください。



宣言int SetShadowMapLightDirection( int SmHandle, VECTOR Direction ) ;

概略シャドウマップで想定するライトの方向を設定する

引数 SmHandle:ライトの方向を設定するシャドウマップのハンドル
Direction:シャドウマップに設定する「想定するライトの方向」
戻り値 0:成功
 -1:エラー発生

解説  MakeShadowMap で作成したシャドウマップへの描画の際に想定するライトの方向を設定します。

 この関数で設定したライトの方向を前提に、シャドウマップへの描画が行われます。

 因みに、ライトの方向は SetLightDirection 等の関数で設定しているのに何故この関数で別に設定しなければならないのかと言いますと、 今のところDXライブラリのシャドウマップ機能ではディレクショナルライト一つ分しか想定することができないからです。
( ディレクショナルライト以外や、複数のライトを使用された場合にシャドウマップでどのライトの情報を使用すればよいか判断できない )

 なので、全てのライトの情報をシャドウマップへ反映させられるようになった際にはこの関数は使用する必要がなくなると思います。

 尚、この関数は ShadowMap_DrawSetup を呼ぶ前( シャドウマップへの描画を開始する前 )に呼んでおく必要がありますので注意してください。

サンプル

  板ポリゴンにキャラクターモデルの影を描画して、その影の角度( とライトの方向 )を回転させます。
Windows用
#include "DxLib.h" #include <math.h> int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int StageModelHandle ; int CharaModelHandle ; int ShadowMapHandle ; float Angle ; VECTOR LightDirection ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) { // エラーが発生したら終了 return -1 ; } // 描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ) ; // キャラクターモデルの読み込み CharaModelHandle = MV1LoadModel( "DxChara.x" ) ; // ステージモデルの読み込み StageModelHandle = MV1LoadModel( "Plane.mqo" ) ; // シャドウマップハンドルの作成 ShadowMapHandle = MakeShadowMap( 1024, 1024 ) ; // カメラの位置と向きを設定 SetCameraPositionAndTarget_UpVecY( VGet( 0.0f, 800.0f, -800.0f ), VGet( 0.000f, 500.000f, 0.000f ) ); // 描画する奥行き方向の範囲を設定 SetCameraNearFar( 40.000f, 2000.000f ); // シャドウマップに描画する範囲を設定 SetShadowMapDrawArea( ShadowMapHandle, VGet( -1000.0f, -1.0f, -1000.0f ), VGet( 1000.0f, 1000.0f, 1000.0f ) ) ; // ライトの角度を初期化 Angle = 0.0f ; // メインループ while( ProcessMessage() == 0 ) { // 画面をクリア ClearDrawScreen() ; // ライトの角度を変更 Angle += 0.0125f ; if( Angle > DX_PI_F * 2.0f ) { Angle -= DX_PI_F * 2.0f ; } // ライトの方向ベクトルの算出 LightDirection.x = sin( Angle ) ; LightDirection.z = cos( Angle ) ; LightDirection.y = -1.0f ; // ライトの方向を設定 SetLightDirection( LightDirection ); // シャドウマップが想定するライトの方向もセット SetShadowMapLightDirection( ShadowMapHandle, LightDirection ) ; // シャドウマップへの描画の準備 ShadowMap_DrawSetup( ShadowMapHandle ) ; // シャドウマップへステージモデルの描画 MV1DrawModel( StageModelHandle ) ; // シャドウマップへキャラクターモデルの描画 MV1DrawModel( CharaModelHandle ) ; // シャドウマップへの描画を終了 ShadowMap_DrawEnd() ; // 描画に使用するシャドウマップを設定 SetUseShadowMap( 0, ShadowMapHandle ) ; // ステージモデルの描画 MV1DrawModel( StageModelHandle ) ; // キャラクターモデルの描画 MV1DrawModel( CharaModelHandle ) ; // 描画に使用するシャドウマップの設定を解除 SetUseShadowMap( 0, -1 ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } // シャドウマップの削除 DeleteShadowMap( ShadowMapHandle ) ; // ステージモデルの削除 MV1DeleteModel( StageModelHandle ) ; // キャラクターモデルの削除 MV1DeleteModel( CharaModelHandle ) ; // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }



宣言int ShadowMap_DrawSetup( int SmHandle ) ;

概略シャドウマップへの描画の準備を行う

引数 SmHandle:シャドウマップへの描画準備を行うシャドウマップのハンドル
戻り値 0:成功
 -1:エラー発生

解説  SmHandle で指定されたシャドウマップへの描画の準備を行います。

 この関数を実行すると SetDrawScreen の設定に関係なく、以降 ShadowMap_DrawEnd が呼ばれるまで描画先は SmHandle で指定したシャドウマップになります。

 なので、この関数を呼んだ後、シャドウマップに描画したい3Dモデルを MV1DrawModel で描画して、 その後 ShadowMap_DrawEnd でシャドウマップへの描画を終了する、という形になります。

 因みにシャドウマップに描画する3Dモデルとは「影を落としたい3Dモデル」ですので、おばけのような影を落としたくない3Dモデルはシャドウマップへの描画を行う必要はありません。

 尚、この関数を呼んだ後は ShadowMap_DrawEnd を呼んでシャドウマップへの描画を終了するまでは SetShadowMapDrawAreaSetShadowMapLightDirectionSetUseShadowMapTestDrawShadowMap などのシャドウマップの設定を変更したり、 現在の状態を確認したりする為の関数は使用できませんので注意してください。

サンプル

  MakeShadowMap のサンプルを参照してください。



宣言int ShadowMap_DrawEnd( void ) ;

概略シャドウマップへの描画を終了する

引数 なし
戻り値 0:成功
 -1:エラー発生

解説  ShadowMap_DrawSetup で開始したシャドウマップへの描画を終了します。
 ShadowMap_DrawEnd 単体で使用することは無く、ShadowMap_DrawSetup で開始したシャドウマップへの描画を終了するには必ずこの関数を使用するので、 ShadowMap_DrawSetup とは常に対で使用することになります。

 尚、ShadowMap_DrawSetup を呼んだ後はこの関数を呼んでシャドウマップへの描画を終了するまでは SetShadowMapDrawAreaSetShadowMapLightDirectionSetUseShadowMapTestDrawShadowMap などのシャドウマップの設定を変更したり、 現在の状態を確認したりする為の関数は使用できませんので注意してください。

サンプル

  MakeShadowMap のサンプルを参照してください。



宣言int SetUseShadowMap( int SmSlotIndex, int SmHandle ) ;

概略描画で使用するシャドウマップを変更する

引数 SmSlotIndex:描画で使用するシャドウマップをセットするスロット番号( 0~2 )
SmHandle:描画で使用するシャドウマップのハンドル
     ( -1を渡すと SmSlotIndex で指定したスロットのシャドウマップを解除 )
戻り値 0:成功
 -1:エラー発生

解説  3Dモデルを MV1DrawModel で描画する際の影表現に使用するシャドウマップを指定するための関数です。

 SmSlotIndex でシャドウマップをセットするスロットを0~2の3つから選択します、0~2全てにシャドウマップを設定することで、最大で同時に3つのシャドウマップを使用することができます。
 複数のシャドウマップを使用する例は以下の通りです。


例1:
 スロット0:動かない3Dモデルを一度だけ描画したシャドウマップ
 スロット1:動く3Dモデルを毎フレーム描画したシャドウマップ
 スロット2:使用しない

 動かない3Dモデルのシャドウマップへの描画が一度だけで済むので、その分の負荷が軽減できます。


例2:
 スロット0:プレイヤーキャラとその周辺の狭い範囲にある3Dモデルだけを描画したシャドウマップ
 スロット1:広範囲の3Dモデルを描画したシャドウマップ
 スロット2:使用しない

 シャドウマップは描画する範囲が広くなればなるほど影が粗くなるので、 プレイヤーの周りは高精度の影を描画、プレイヤーから離れた箇所は低精度の影を描画とすることができます。


例3:
 スロット0:動かない3Dモデルを一度だけ描画したシャドウマップ
 スロット1:プレイヤーキャラとその周辺の狭い範囲にある動く3Dモデルだけを描画したシャドウマップ
 スロット2:広範囲の動く3Dモデルを描画したシャドウマップ

 例1と例2を合わせた使い方です。



 SmHandle に指定するシャドウマップは、ShadowMap_DrawSetupShadowMap_DrawEnd を使用してシャドウマップへの3Dモデルの描画が行われた後のものである必要があります。

 尚、シャドウマップによる影の描画が必要なくなった後は、SmHandle に -1 を渡して関数を呼び、設定したシャドウマップを解除する必要があります。

サンプル

  解説の例1のサンプルです。ステージモデル用のシャドウマップとキャラクターモデル用のシャドウマップを別々に用意して、
 ステージモデル用のシャドウマップにはメインループに入る前に一度だけステージモデルを描画して、メインループ中では
 キャラクターモデル用のシャドウマップに対してのみ毎フレームキャラクターモデルを描画するようにしています。
Windows用
#include "DxLib.h" #include <math.h> int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int StageModelHandle ; int CharaModelHandle ; int StageShadowMapHandle ; int CharaShadowMapHandle ; float Angle ; VECTOR CharaPosition ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) { // エラーが発生したら終了 return -1 ; } // 描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ) ; // キャラクターモデルの読み込み CharaModelHandle = MV1LoadModel( "DxChara.x" ) ; // ステージモデルの読み込み StageModelHandle = MV1LoadModel( "SimplePillarStage.mqo" ) ; // ステージモデル用のシャドウマップハンドルの作成 StageShadowMapHandle = MakeShadowMap( 2048, 2048 ) ; // キャラクターモデル用のシャドウマップハンドルの作成 CharaShadowMapHandle = MakeShadowMap( 2048, 2048 ) ; // カメラの位置と向きを設定 SetCameraPositionAndTarget_UpVecY( VGet( 0.0f, 1500.0f, -1500.0f ), VGet( 0.0f, 800.0f, -800.0f ) ); // 描画する奥行き方向の範囲を設定 SetCameraNearFar( 160.000f, 80000.000f ); // シャドウマップに描画する範囲を設定 SetShadowMapDrawArea( StageShadowMapHandle, VGet( -4000.0f, -1.0f, -4000.0f ), VGet( 4000.0f, 4000.0f, 4000.0f ) ) ; SetShadowMapDrawArea( CharaShadowMapHandle, VGet( -4000.0f, -1.0f, -4000.0f ), VGet( 4000.0f, 4000.0f, 4000.0f ) ) ; // ライトの方向を設定 SetLightDirection( VGet( 0.5f, -0.5f, 0.5f ) ); // シャドウマップが想定するライトの方向もセット SetShadowMapLightDirection( StageShadowMapHandle, VGet( 0.5f, -0.5f, 0.5f ) ) ; SetShadowMapLightDirection( CharaShadowMapHandle, VGet( 0.5f, -0.5f, 0.5f ) ) ; // ステージモデル用のシャドウマップへの描画の準備 ShadowMap_DrawSetup( StageShadowMapHandle ) ; // ステージモデル用のシャドウマップへステージモデルの描画 MV1DrawModel( StageModelHandle ) ; // ステージモデル用のシャドウマップへの描画を終了 ShadowMap_DrawEnd() ; // キャラクターの位置となる角度を初期化 Angle = 0.0f ; // メインループ while( ProcessMessage() == 0 ) { // 画面をクリア ClearDrawScreen() ; // キャラクターの位置となる角度を変更 Angle += 0.0125f ; if( Angle > DX_PI_F * 2.0f ) { Angle -= DX_PI_F * 2.0f ; } // キャラクターの座標を算出 CharaPosition.x = sin( Angle ) * 1000.0f ; CharaPosition.z = cos( Angle ) * 1000.0f ; CharaPosition.y = 0.0f ; // キャラクターモデルの座標を変更 MV1SetPosition( CharaModelHandle, CharaPosition ) ; // キャラクターモデル用のシャドウマップへの描画の準備 ShadowMap_DrawSetup( CharaShadowMapHandle ) ; // キャラクターモデル用のシャドウマップへキャラクターモデルの描画 MV1DrawModel( CharaModelHandle ) ; // キャラクターモデル用のシャドウマップへの描画を終了 ShadowMap_DrawEnd() ; // 描画にキャラクターモデル用のシャドウマップと // ステージモデル用のシャドウマップのどちらも使用する SetUseShadowMap( 0, StageShadowMapHandle ) ; SetUseShadowMap( 1, CharaShadowMapHandle ) ; // ステージモデルの描画 MV1DrawModel( StageModelHandle ) ; // キャラクターモデルの描画 MV1DrawModel( CharaModelHandle ) ; // 描画に使用するシャドウマップの設定を解除 SetUseShadowMap( 0, -1 ) ; SetUseShadowMap( 1, -1 ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } // シャドウマップの削除 DeleteShadowMap( StageShadowMapHandle ) ; DeleteShadowMap( CharaShadowMapHandle ) ; // ステージモデルの削除 MV1DeleteModel( StageModelHandle ) ; // キャラクターモデルの削除 MV1DeleteModel( CharaModelHandle ) ; // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }



宣言int SetShadowMapDrawArea( int SmHandle, VECTOR MinPosition, VECTOR MaxPosition ) ;

概略シャドウマップに描画する範囲を設定する

引数 SmHandle:描画する範囲を設定するシャドウマップのハンドル
MinPosition:描画する範囲の座標値の小さいほうの頂点の座標
MaxPosition:描画する範囲の座標値の大きいほうの頂点の座標
戻り値 0:成功
 -1:エラー発生

解説  SmHandle が示すシャドウマップに対して、ShadowMap_DrawSetupShadowMap_DrawEnd を使用してシャドウマップに描画する範囲を設定します。

 シャドウマップによる影の表現では『シャドウマップによる影の表現を行いたい3Dモデル』をシャドウマップに描画する必要があります。
 シャドウマップに対して3Dモデルを描画する手順は、


1.SetShadowMapDrawArea を使用して『シャドウマップによる影の表現を行いたい全ての3Dモデル』が
  存在する範囲を設定

2.ShadowMap_DrawSetup を呼び出してシャドウマップへの描画の準備

3.『シャドウマップによる影の表現を行いたい全ての3Dモデル』を MV1DrawModel で描画

4.ShadowMap_DrawEnd でシャドウマップへの描画を終了


 となります。

 尚、SetShadowMapDrawArea は ShadowMap_DrawSetup を使用する前に呼んでおく必要がありますので注意してください。

 また、描画範囲は必要最小限の大きさにする必要があります。
何故かと言いますと、描画範囲が広くなれば広くなるほど実際にシャドウマップを使用して影を描画した際の影が粗くなるからです。
( シャドウマップの解像度は変化せずに、シャドウマップに描画する範囲が広くなるため、単位距離辺りに割かれるピクセル数が少なくなるからです )

 この関数を使用して描画範囲を明示的に指定しない場合はカメラの設定から自動的に描画範囲を決定しますが、 大抵の場合カメラはかなり広い範囲を描画範囲としているので、影が凄く粗くなります。なので、必要な範囲をこの関数で設定することをお勧めします。

サンプル

  シャドウマップに描画する範囲を変更した結果を確認するためのサンプルです。上下キーで描画の範囲を変更できます。
Windows用
#include "DxLib.h" #define CHARA_POS_SPACE (1500.0f) #define CHARA_NUM (4) #define CHARA_POS_DISTANCE ( ( CHARA_NUM - 1 ) * CHARA_POS_SPACE ) int StageModelHandle ; int CharaModelHandle ; int ShadowMapHandle ; // キャラクターを描画する void CharaDraw( void ) { int i ; int j ; VECTOR Position ; // キャラクターを16体描画 for( i = 0 ; i < CHARA_NUM ; i ++ ) { for( j = 0 ; j < CHARA_NUM ; j ++ ) { // 描画位置を設定 Position.x = -CHARA_POS_DISTANCE / 2.0f + CHARA_POS_SPACE * j ; Position.y = 0.0f ; Position.z = -CHARA_POS_DISTANCE / 2.0f + CHARA_POS_SPACE * i ; MV1SetPosition( CharaModelHandle, Position ) ; // 3Dモデルを描画 MV1DrawModel( CharaModelHandle ) ; } } } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { float DrawAreaSize ; VECTOR DrawAreaMinPos ; VECTOR DrawAreaMaxPos ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) { // エラーが発生したら終了 return -1 ; } // 描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ) ; // キャラクターモデルの読み込み CharaModelHandle = MV1LoadModel( "DxChara.x" ) ; // ステージモデルの読み込み StageModelHandle = MV1LoadModel( "Plane.mqo" ) ; // シャドウマップハンドルの作成 ShadowMapHandle = MakeShadowMap( 1024, 1024 ) ; // カメラの位置と向きを設定 SetCameraPositionAndTarget_UpVecY( VGet( 0.0f, 3600.0f, -3400.0f ), VGet( 0.000f, 500.000f, -500.000f ) ); // 描画する奥行き方向の範囲を設定 SetCameraNearFar( 200.000f, 10000.000f ); // ライトの方向を設定 SetLightDirection( VGet( 0.5f, -0.5f, 0.5f ) ); // シャドウマップが想定するライトの方向もセット SetShadowMapLightDirection( ShadowMapHandle, VGet( 0.5f, -0.5f, 0.5f ) ) ; // 描画するサイズを初期化 DrawAreaSize = 1000.0f ; // メインループ while( ProcessMessage() == 0 ) { // 画面をクリア ClearDrawScreen() ; // 上下キーで描画するサイズを変更 if( CheckHitKey( KEY_INPUT_UP ) == 1 ) { DrawAreaSize += 10.0f ; } if( CheckHitKey( KEY_INPUT_DOWN ) == 1 ) { DrawAreaSize -= 10.0f ; if( DrawAreaSize < 1.0f ) { DrawAreaSize = 1.0f ; } } // シャドウマップに描画する範囲を設定 DrawAreaMinPos = VGet( -DrawAreaSize, -1.0f, -DrawAreaSize ) ; DrawAreaMaxPos = VGet( DrawAreaSize, 1000.0f, DrawAreaSize ) ; SetShadowMapDrawArea( ShadowMapHandle, DrawAreaMinPos, DrawAreaMaxPos ) ; // シャドウマップへの描画の準備 ShadowMap_DrawSetup( ShadowMapHandle ) ; // シャドウマップへステージモデルの描画 MV1DrawModel( StageModelHandle ) ; // シャドウマップへキャラクターモデルの描画 CharaDraw() ; // シャドウマップへの描画を終了 ShadowMap_DrawEnd() ; // 描画に使用するシャドウマップを設定 SetUseShadowMap( 0, ShadowMapHandle ) ; // ステージモデルの描画 MV1DrawModel( StageModelHandle ) ; // キャラクターモデルの描画 CharaDraw() ; // 描画に使用するシャドウマップの設定を解除 SetUseShadowMap( 0, -1 ) ; // 画面に現在のサイズと範囲を描画 DrawFormatString( 0, 0, GetColor( 255,255,255 ), "AreaSize:%.1f", DrawAreaSize ) ; DrawFormatString( 0, 16, GetColor( 255,255,255 ), "MinPos( %.1f, %.1f, %.1f )", DrawAreaMinPos.x, DrawAreaMinPos.y, DrawAreaMinPos.z ) ; DrawFormatString( 0, 32, GetColor( 255,255,255 ), "MaxPos( %.1f, %.1f, %.1f )", DrawAreaMaxPos.x, DrawAreaMaxPos.y, DrawAreaMaxPos.z ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } // シャドウマップの削除 DeleteShadowMap( ShadowMapHandle ) ; // ステージモデルの削除 MV1DeleteModel( StageModelHandle ) ; // キャラクターモデルの削除 MV1DeleteModel( CharaModelHandle ) ; // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }



宣言int SetShadowMapAdjustDepth( int SmHandle, float Depth ) ;

概略シャドウマップを使用した3Dモデル描画時の深度判定の補正値を設定する

引数 SmHandle:深度判定の補正値を変更するシャドウマップのハンドル
Depth:深度判定の補正値( デフォルト:0.002f )
戻り値 0:成功
 -1:エラー発生

解説  SmHandle が示すシャドウマップを使用して影の表現をする際に行われる

『シャドウマップに記録されている深度値と影判定用の深度値との比較』

で使用される深度値の補正値を設定します。

 補正値の詳しい説明をしようとするとシャドウマップによる影表現の仕組みを1から説明しなければならないので、 この補正値を変更するとどのようなことになるかをサンプルプログラムで確認してみてください。

 因みに、概ね問題の無い補正値( 0.002f )をデフォルト値として設定していますので、変更しなければ正常な描画結果を得られない場合のみこの関数を使用するようにしてください。

サンプル

  シャドウマップを使用して影を表現するサンプルに、上下キーで深度判定の補正値を変更できるようにしたもの。
Windows用
#include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int StageModelHandle ; int CharaModelHandle ; int ShadowMapHandle ; float Adjust ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) { // エラーが発生したら終了 return -1 ; } // 描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ) ; // キャラクターモデルの読み込み CharaModelHandle = MV1LoadModel( "DxChara.x" ) ; // ステージモデルの読み込み StageModelHandle = MV1LoadModel( "Plane.mqo" ) ; // シャドウマップハンドルの作成 ShadowMapHandle = MakeShadowMap( 1024, 1024 ) ; // カメラの位置と向きを設定 SetCameraPositionAndTarget_UpVecY( VGet( 0.0f, 800.0f, -800.0f ), VGet( 0.000f, 500.000f, 0.000f ) ); // 描画する奥行き方向の範囲を設定 SetCameraNearFar( 40.000f, 2000.000f ); // ライトの方向を設定 SetLightDirection( VGet( 0.5f, -0.5f, 0.5f ) ); // シャドウマップが想定するライトの方向もセット SetShadowMapLightDirection( ShadowMapHandle, VGet( 0.5f, -0.5f, 0.5f ) ) ; // シャドウマップに描画する範囲を設定 SetShadowMapDrawArea( ShadowMapHandle, VGet( -1000.0f, -1.0f, -1000.0f ), VGet( 1000.0f, 1000.0f, 1000.0f ) ) ; // 補正値を初期化 Adjust = 0.002f ; // メインループ while( ProcessMessage() == 0 ) { // 画面をクリア ClearDrawScreen() ; // 上下キーで補正値を変更 if( CheckHitKey( KEY_INPUT_UP ) == 1 ) { Adjust += 0.001f ; } if( CheckHitKey( KEY_INPUT_DOWN ) == 1 ) { Adjust -= 0.001f ; } SetShadowMapAdjustDepth( ShadowMapHandle, Adjust ) ; // シャドウマップへの描画の準備 ShadowMap_DrawSetup( ShadowMapHandle ) ; // シャドウマップへステージモデルの描画 MV1DrawModel( StageModelHandle ) ; // シャドウマップへキャラクターモデルの描画 MV1DrawModel( CharaModelHandle ) ; // シャドウマップへの描画を終了 ShadowMap_DrawEnd() ; // 描画に使用するシャドウマップを設定 SetUseShadowMap( 0, ShadowMapHandle ) ; // ステージモデルの描画 MV1DrawModel( StageModelHandle ) ; // キャラクターモデルの描画 MV1DrawModel( CharaModelHandle ) ; // 描画に使用するシャドウマップの設定を解除 SetUseShadowMap( 0, -1 ) ; // 現在の補正値を画面に描画 DrawFormatString( 0, 0, GetColor( 255,255,255 ), "Adjust Depth:%f", Adjust ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } // シャドウマップの削除 DeleteShadowMap( ShadowMapHandle ) ; // ステージモデルの削除 MV1DeleteModel( StageModelHandle ) ; // キャラクターモデルの削除 MV1DeleteModel( CharaModelHandle ) ; // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }



宣言int TestDrawShadowMap( int SmHandle, int x1, int y1, int x2, int y2 ) ;

概略シャドウマップを画面にテスト描画する

引数 SmHandle:テスト描画するシャドウマップのハンドル
x1, y1:テスト描画をする画面の左上座標
x2, y2:テスト描画をする画面の右下座標
戻り値 0:成功
 -1:エラー発生

解説  SmHandle が示すシャドウマップを画面に描画します。
 主に『意図通りにシャドウマップに対して描画ができているのか』を確認するために使用するデバッグ用の関数です。

サンプル

  SetShadowMapLightDirection のサンプルに TestDrawShadowMap を使用して画面左上にシャドウマップのテスト描画を加えたもの。
Windows用
#include "DxLib.h" #include <math.h> int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int StageModelHandle ; int CharaModelHandle ; int ShadowMapHandle ; float Angle ; VECTOR LightDirection ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) { // エラーが発生したら終了 return -1 ; } // 描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ) ; // キャラクターモデルの読み込み CharaModelHandle = MV1LoadModel( "DxChara.x" ) ; // ステージモデルの読み込み StageModelHandle = MV1LoadModel( "Plane.mqo" ) ; // シャドウマップハンドルの作成 ShadowMapHandle = MakeShadowMap( 1024, 1024 ) ; // カメラの位置と向きを設定 SetCameraPositionAndTarget_UpVecY( VGet( 0.0f, 800.0f, -800.0f ), VGet( 0.000f, 500.000f, 0.000f ) ); // 描画する奥行き方向の範囲を設定 SetCameraNearFar( 40.000f, 2000.000f ); // シャドウマップに描画する範囲を設定 SetShadowMapDrawArea( ShadowMapHandle, VGet( -1000.0f, -1.0f, -1000.0f ), VGet( 1000.0f, 1000.0f, 1000.0f ) ) ; // ライトの角度を初期化 Angle = 0.0f ; // メインループ while( ProcessMessage() == 0 ) { // 画面をクリア ClearDrawScreen() ; // ライトの角度を変更 Angle += 0.0125f ; if( Angle > DX_PI_F * 2.0f ) { Angle -= DX_PI_F * 2.0f ; } // ライトの方向ベクトルの算出 LightDirection.x = sin( Angle ) ; LightDirection.z = cos( Angle ) ; LightDirection.y = -1.0f ; // ライトの方向を設定 SetLightDirection( LightDirection ); // シャドウマップが想定するライトの方向もセット SetShadowMapLightDirection( ShadowMapHandle, LightDirection ) ; // シャドウマップへの描画の準備 ShadowMap_DrawSetup( ShadowMapHandle ) ; // シャドウマップへステージモデルの描画 MV1DrawModel( StageModelHandle ) ; // シャドウマップへキャラクターモデルの描画 MV1DrawModel( CharaModelHandle ) ; // シャドウマップへの描画を終了 ShadowMap_DrawEnd() ; // 描画に使用するシャドウマップを設定 SetUseShadowMap( 0, ShadowMapHandle ) ; // ステージモデルの描画 MV1DrawModel( StageModelHandle ) ; // キャラクターモデルの描画 MV1DrawModel( CharaModelHandle ) ; // 描画に使用するシャドウマップの設定を解除 SetUseShadowMap( 0, -1 ) ; // 画面左上にシャドウマップをテスト描画 TestDrawShadowMap( ShadowMapHandle, 0, 0, 320, 240 ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } // シャドウマップの削除 DeleteShadowMap( ShadowMapHandle ) ; // ステージモデルの削除 MV1DeleteModel( StageModelHandle ) ; // キャラクターモデルの削除 MV1DeleteModel( CharaModelHandle ) ; // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }




戻る