トップページ > 記事閲覧
3D大量描画対応の要望
名前:早苗明紗 日時: 2014/06/26 21:40

管理人様 いつもDXライブラリにお世話になっております。 今回、C言語なんでも質問掲示板にて 3D空間に大量に描画したいというタイトル dixq.net/forum/viewtopic.php?f=3&t=15269&p=121541#p121541 で質問させていただいたところ Geometry Instancingという方法を教えていただきました。 DXライブラリにこの機能が実装されているとありがたいです。 お手数のことと存じますが、ご一考のほどよろしくお願いいたします。
メンテ

Page: 1 |

Re: 3D大量描画対応の要望 ( No.1 )
名前:管理人 日時:2014/06/27 00:43

Geometry Instancing を実装する予定はありませんが、 とりあえず 100万個を描画するという目標が気になります 恐らく Geometry Instancing を使用しても早苗明紗さんの 目標とするスペックの低いPCでの 100万個の描画は厳しいと思いますが、 一つ辺りのポリゴン数とボーン数はどのくらいでしょうか?
メンテ
Re: 3D大量描画対応の要望 ( No.2 )
名前:早苗明紗 日時:2014/06/27 17:00

お返事ありがとうございます。 現在は、計算の容易な円錐 DrawCone3D で円錐を形成するポリゴンの細かさを3としています。 2以下にしてもあまり変わりがないようでした 円錐は塗りつぶしてあります。 この基本描画関数での円錐が100万個描画できれば問題ありません。 なお、 C言語なんでも質問掲示板のほうで提案された三角形での描画は、頂点座標の計算が必要になるため おそらく円錐のほうがスピードが速いだろうと考えています。
メンテ
Re: 3D大量描画対応の要望 ( No.3 )
名前:h2so5 日時:2014/06/27 22:19

>C言語なんでも質問掲示板のほうで提案された三角形での描画は、頂点座標の計算が必要になるため >おそらく円錐のほうがスピードが速いだろうと考えています。 すべての立体は三角形の集合なので、頂点座標の計算は必要です。 円錐のほうが速いということはありません。
メンテ
Re: 3D大量描画対応の要望 ( No.4 )
名前:早苗明紗 日時:2014/06/28 08:32

h2so5様 申し訳ありません。言葉が足りませんでした。 最適化された内部プログラムによって描画される円錐形と、冗長な可能性のある素人の作った計算プログラムでは、最適化されたプログラムのほうが描画が速いと考えました ということです 実際、あちらでも述べたとおり実際に計測はしていませんが体感はほとんど変わらなかったので、理由は上記の通りなのではないかと考えたのです。
メンテ
Re: 3D大量描画対応の要望 ( No.5 )
名前:管理人 日時:2014/06/28 09:45

とりあえず高速に円錐を100万個描画するプログラムを組んでみましたので よろしければ実行して、画面左上に表示される FPS がどのくらいの値になるかを 確認してみてください( 30 に達していないとゲームとしては厳しいと思います ) #include "DxLib.h" #include <malloc.h> #define ONE_SPACE (15.0f) #define ONE_VERTEXNUM (21) #define ONE_INDEXNUM (36) #define ONESET_X_NUM (10) #define ONESET_Y_NUM (10) #define ONESET_Z_NUM (10) #define ONESET_TOTAL_NUM ( ONESET_X_NUM * ONESET_Y_NUM * ONESET_Z_NUM ) #define ONESET_TOTAL_VERTEXNUM ( ONESET_TOTAL_NUM * ONE_VERTEXNUM ) #define ONESET_TOTAL_INDEXNUM ( ONESET_TOTAL_NUM * ONE_INDEXNUM ) #define SET_X_NUM (10) #define SET_Y_NUM (10) #define SET_Z_NUM (10) #define SET_SPACE (150.0f) // 円錐の頂点データ VERTEX3D ConeVertex[ ONE_VERTEXNUM ] = { { { 0.000000f , 0.000000f, 5.000000f }, { 0.000000f, 0.447214f, 0.894427f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { -3.909158f, 0.000000f, 3.117449f }, { -0.699291f, 0.447214f, 0.557666f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { -4.874640f, 0.000000f, -1.112605f }, { -0.872002f, 0.447214f, -0.199029f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { -2.169418f, 0.000000f, -4.504845f }, { -0.388077f, 0.447214f, -0.805851f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { 2.169419f, 0.000000f, -4.504844f }, { 0.388077f, 0.447214f, -0.805851f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { 4.874640f, 0.000000f, -1.112605f }, { 0.872002f, 0.447214f, -0.199029f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { 3.909157f, 0.000000f, 3.117450f }, { 0.699291f, 0.447214f, 0.557666f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { 0.000000f, 10.000000f, 0.000000f }, { 0.000000f, 0.447214f, 0.894427f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { 0.000000f, 10.000000f, 0.000000f }, { -0.699291f, 0.447214f, 0.557666f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { 0.000000f, 10.000000f, 0.000000f }, { -0.872002f, 0.447214f, -0.199029f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { 0.000000f, 10.000000f, 0.000000f }, { -0.388077f, 0.447214f, -0.805851f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { 0.000000f, 10.000000f, 0.000000f }, { 0.388077f, 0.447214f, -0.805851f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { 0.000000f, 10.000000f, 0.000000f }, { 0.872002f, 0.447214f, -0.199029f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { 0.000000f, 10.000000f, 0.000000f }, { 0.699291f, 0.447214f, 0.557666f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { 0.000000f, 0.000000f, 5.000000f }, { 0.000000f, -1.000000f, 0.000000f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { -3.909158f, 0.000000f, 3.117449f }, { 0.000000f, -1.000000f, 0.000000f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { -4.874640f, 0.000000f, -1.112605f }, { 0.000000f, -1.000000f, 0.000000f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { -2.169418f, 0.000000f, -4.504845f }, { 0.000000f, -1.000000f, 0.000000f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { 2.169419f, 0.000000f, -4.504844f }, { 0.000000f, -1.000000f, 0.000000f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { 4.874640f, 0.000000f, -1.112605f }, { 0.000000f, -1.000000f, 0.000000f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, { { 3.909157f, 0.000000f, 3.117450f }, { 0.000000f, -1.000000f, 0.000000f }, { 255, 255, 0, 0 }, { 255, 255, 255, 0 }, 0.000000f, 0.000000f, 0.000000f, 0.000000f }, } ; // 円錐の頂点インデックス WORD ConeIndex[ ONE_INDEXNUM ] = { 0, 7, 1, 1, 8, 2, 2, 9, 3, 3, 10, 4, 4, 11, 5, 5, 12, 6, 6, 13, 0, 14, 15, 20, 20, 15, 16, 20, 16, 19, 19, 16, 17, 19, 17, 18, } ; // 頂点バッファハンドル int VertexBufferHandle ; // 頂点インデックスハンドル int IndexBufferHandle ; // 頂点バッファのセットアップ void SetupVertexBuffer( void ) { int i ; int j ; int k ; int l ; VERTEX3D *Vertex ; VERTEX3D *vert ; WORD *Index ; WORD *ind ; float TotalXDistance ; float TotalYDistance ; float TotalZDistance ; VECTOR AddPos ; WORD AddIndex ; // 1セットの描画範囲を計算 TotalXDistance = ONESET_X_NUM * ( ONE_SPACE - 1 ) ; TotalYDistance = ONESET_Y_NUM * ( ONE_SPACE - 1 ) ; TotalZDistance = ONESET_Z_NUM * ( ONE_SPACE - 1 ) ; // 1セット分の頂点データと頂点インデックスを格納するためのメモリを確保 Vertex = ( VERTEX3D * )malloc( sizeof( VERTEX3D ) * ONESET_TOTAL_VERTEXNUM ) ; Index = ( WORD * )malloc( sizeof( WORD ) * ONESET_TOTAL_INDEXNUM ) ; // 1セット分の円錐の頂点データと頂点インデックスデータを作成 vert = Vertex ; ind = Index ; AddIndex = 0 ; for( i = 0 ; i < ONESET_X_NUM; i++ ) { for( j = 0; j < ONESET_Y_NUM; j++ ) { for( k = 0; k < ONESET_Z_NUM; k++ ) { AddPos.x = i * ONE_SPACE - TotalXDistance / 2.0f ; AddPos.y = j * ONE_SPACE - TotalYDistance / 2.0f ; AddPos.z = k * ONE_SPACE - TotalZDistance / 2.0f ; for( l = 0; l < ONE_VERTEXNUM; l++ ) { *vert = ConeVertex[ l ] ; vert->pos = VAdd( vert->pos, AddPos ) ; vert++ ; } for( l = 0; l < ONE_INDEXNUM; l++ ) { *ind = ConeIndex[ l ] + AddIndex ; ind++ ; } AddIndex += ONE_VERTEXNUM ; } } } // 頂点バッファの作成 VertexBufferHandle = CreateVertexBuffer( ONESET_TOTAL_VERTEXNUM, DX_VERTEX_TYPE_NORMAL_3D ) ; // 頂点インデックスバッファの作成 IndexBufferHandle = CreateIndexBuffer( ONESET_TOTAL_INDEXNUM, DX_INDEX_TYPE_16BIT ) ; // 頂点バッファに頂点データを転送 SetVertexBufferData( 0, Vertex, ONESET_TOTAL_VERTEXNUM, VertexBufferHandle ) ; // 頂点インデックスバッファに頂点インデックスデータを転送 SetIndexBufferData( 0, Index, ONESET_TOTAL_INDEXNUM, IndexBufferHandle ) ; // 確保していたメモリを解放 free( Vertex ) ; free( Index ) ; } // WinMain関数 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int i ; int j ; int k ; int FPS ; int FrameCount ; LONGLONG BaseTime ; LONGLONG Time ; VECTOR CameraPos ; VECTOR CameraTargetPos ; MATRIX TranslateMatrix ; float TotalXDistance ; float TotalYDistance ; float TotalZDistance ; VECTOR TranslateVector ; int x ; int xadd ; // ウインドウモードで起動 ChangeWindowMode( TRUE ) ; // VSYNC待ちをしない SetWaitVSyncFlag( FALSE ) ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1 ; // 頂点バッファをセットアップ SetupVertexBuffer() ; // 描画先を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; // カメラの設定 CameraPos.x = 0.0f ; CameraPos.y = 0.0f ; CameraPos.z = -2500.0f ; SetCameraNearFar( 10.0f, 10000.0f ) ; CameraTargetPos = VAdd( CameraPos, VGet( 0.0f, 0.0f, 1.0f ) ) ; SetCameraPositionAndTarget_UpVecY( CameraPos, CameraTargetPos ) ; // FPSカウントの準備 BaseTime = GetNowHiPerformanceCount() ; FPS = 0 ; FrameCount = 0 ; // 描画範囲を予め計算しておく TotalXDistance = SET_SPACE * ( SET_X_NUM - 1 ) ; TotalYDistance = SET_SPACE * ( SET_Y_NUM - 1 ) ; TotalZDistance = SET_SPACE * ( SET_Z_NUM - 1 ) ; // 動きの滑らかさを確認するための四角形の位置を移動速度を初期化 x = 0 ; xadd = 8 ; // メインループ(何かキーが押されたらループを抜ける) while( ProcessMessage() == 0 ) { // 動きの滑らかさを確認するための四角形の位置の移動 x += xadd ; if( x <= 0 || x >= 640 ) { xadd = -xadd ; } // 画面のクリア ClearDrawScreen() ; // Zバッファを使用する設定 SetUseZBufferFlag( TRUE ) ; SetWriteZBufferFlag( TRUE ) ; // 円錐を描画 for( i = 0 ; i < SET_X_NUM ; i ++ ) { for( j = 0 ; j < SET_Y_NUM ; j ++ ) { for( k = 0 ; k < SET_Z_NUM ; k ++ ) { // 1セットを描画する位置を設定 TranslateVector.x = i * SET_SPACE - TotalXDistance / 2.0f ; TranslateVector.y = j * SET_SPACE - TotalYDistance / 2.0f ; TranslateVector.z = k * SET_SPACE - TotalZDistance / 2.0f ; TranslateMatrix = MGetTranslate( TranslateVector ) ; SetTransformToWorld( &TranslateMatrix ) ; // 1セット描画 DrawPolygonIndexed3D_UseVertexBuffer( VertexBufferHandle, IndexBufferHandle, DX_NONE_GRAPH, FALSE ) ; } } } // Zバッファを使用する設定を解除 SetWriteZBufferFlag( FALSE ) ; SetUseZBufferFlag( FALSE ) ; // 動きの滑らかさを確認するための四角形の描画 DrawBox( x, 448, x + 32, 480, GetColor( 255,255,255 ), TRUE ) ; // FPSの描画 DrawFormatString( 0, 0, GetColor( 255,255,255 ), "FPS:%d", FPS ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; // フレームカウンタをインクリメント FrameCount++ ; // 1秒経過していたら、1秒間の内にカウントしたフレーム数をFPSとしてセットする Time = GetNowHiPerformanceCount() ; if( Time - BaseTime > 1000000 ) { FPS = FrameCount ; FrameCount = 0 ; BaseTime = Time ; } } // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; } 因みにこのプログラムでは見た目が全部同じで全く動かない円錐を描画するということを前提に 高速に描画できるようにしていますので、描画するものの種類が複数あったり 一つ一つが動いたりするなど描画の自由度が増すに従って処理負荷はこのプログラムよりも 2倍、3倍と重くなっていきます 低いスペックとは言えない私が使用しているパソコンでもこのプログラムを実行したところ FPS が 70 程度でしたので、やはり低いスペックのパソコンで100万個を描画するのは難しいと思います
メンテ
Re: 3D大量描画対応の要望 ( No.6 )
名前:早苗明紗 日時:2014/06/28 21:03

遅くなってしまい、申し訳ありません。 確認プログラムありがとうございます 現在利用できるもっとも高性能のPC Windows7 32bit Intel Corei5 M480 2.67GHz (モバイル用i5第一世代) RAM 4.00GB(2.93GB使用可能) グラボ:なし(あえて言うならIntelHDGraphics) でFPSは3でした
メンテ
Re: 3D大量描画対応の要望 ( No.7 )
名前:管理人 日時:2014/06/28 21:48

FPS が 3 ですか・・・ 書き込みNo.4 のテストプログラムはほぼ最高速の描画処理となっていますので、 残念ですが100万個を描画するというのは諦めて頂くしかありません
メンテ
Re: 3D大量描画対応の要望 ( No.8 )
名前:早苗明紗(解決) 日時:2014/06/28 23:32

非常に残念です。 ただ、現在作成中のシミュレーターは研究用プログラムですので、 スパコンが自由に使えるお金持ちの研究者には、より性能の高い100万個を 数年ごとにPCを買い換えることの出来る先進国の研究者には現在の1万個を さらにスペックの低いPCの方用には近似できるようなプログラムを検討することにします。 ありがとうございました
メンテ
Re: 3D大量描画対応の要望 ( No.9 )
名前:早苗明紗 日時:2014/06/28 23:34

管理人様 もし、よろしければ参考のためにPCスペックを教えていただくことは出来ますでしょうか?
メンテ
Re: 3D大量描画対応の要望 ( No.10 )
名前:管理人 日時:2014/06/28 23:50

はい OS : Windows7 Ultimate 64bit CPU : Intel(R) Core(TM) i7-3770K CPU @ 3.50GHz MEMORY : 32GB GPU : NVIDIA GeForce GTX 660 Ti VRAM 2GB 2年ほど前に購入したショップブランドのパソコンです
メンテ
Re: 3D大量描画対応の要望 ( No.11 )
名前:早苗明紗(解決) 日時:2014/06/29 07:29

ありがとうございます
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存