ターン制オンラインゲーム(カタン)の作り方:RPC
今回はターン制オンラインゲームの作り方について、カタン(ボードゲーム)を例に紹介していきます。

カタン(ボードゲーム)の特徴
カタンのようなボードゲームの場合、アクションゲームのような高速同期システムは不要なので、ある程度はシステムをシンプルに作れます。だたし、ボードゲームでは1試合が長く多人数でプレイするため、プレイヤーのネットワーク切断を考慮に入れた設計をしなければゲームが成立しにくくなります。切断後に再接続を行っても、不整合が発生しないように注意する必要があります。
ターン制オンラインゲームに必要な2つの仕組み
実は、ターン制オンラインゲームで必要なシステムを最もシンプルに考えると、シングルプレイヤーゲームに追加するべきものは以下の2点のみです。
1.ルームシステム
2.RPCシステム
ルームシステム
まずは、ルームシステムです。マッチングシステムと言ってもいいです。ボードゲームなので、ルーム作成が基準になるでしょう。二人プレイならランダムマッチでもいいでしょうね。役割としては、連絡先の交換と通信の中継です。ルームシステムには、基本的にどこぞのサーバーを利用することになります。Unityで有名なPUNでは、最大人数に制限はありますが無料でサーバーを利用できますし、後述のRPCシステムも一緒に付いてきます。(ただPUNはもうレガシーでFusionが後継のようです。)システム作れるならもちろんマイサーバーでもいいですし、どこかのクラウドサーバーを使ってもいいですね。

RPCシステム
RPCとは、Remote Procedure Callの略で、遠隔コード実行です。簡単に言うと、相手クライアントに所定のコードを(引数指定して)実行させるということです。セキュリティの文脈でもたまに出てきますね。もし所定コードのではなくて、任意コードを実行できる状態になってたら脆弱性なので注意しましょう。
基本的に、ターン制オンラインゲームではほぼ全ての関数コールをRPCを通して行うことになるでしょう。カタンを例に紹介します。
- ルーム作成(一人目・マスター)
- 二人目以降入場(全プレイヤーが自己情報をRPCで通達)
- ゲーム開始・地形生成(マスターがRPCで通達)
- ダイスロール(RPC)
- アクション(RPC)
- …
こんな具合に、全プレイヤーで共有しておくべき情報は全てRPCで行います。ここで、RPCは遠隔コード実行ですが、自分に対しても発動させることでコードを省略できます。
ダイスロールでいうと、プレイヤーがダイスロールボタンを押すと、RPCのDiceRoll関数にダイス結果の引数が与えられて実行されます。自分を含む全プレイヤーが同じダイス値のDiceRoll関数を実行するので、その通りに各自アニメーションなどで演出しましょう。
地形生成では、RPCでMapGenerate関数に乱数シードを与えて実行します。全プレイヤーで共通の乱数シードを使えば、乱数を使う場面でも全プレイヤーに同一の結果がでます。全プレイヤーが共通の回数で乱数を使うようにすればかなりの通信を節約できます。
ゲーム進行など、一人が代表して行うべき処理もあります、RPC関数内にてif (MasterClient) {} で分岐して処理しましょう。
自分のカタンでは、以下図のようにRPCとゲームフローを作成しています。

上記のコントロールフローに載っている事柄はRPCで実行しています(他にもある)。ひとつひとつの操作で、割と細かくRPCを実行しています。他プレイヤーへの通達のためと、自分の切断・復帰時の行動ログとしての役割もあります。
回線切断・復帰対策
回線切断で落ちた後、同一ルームに帰ってきたときに必要な処理は同期です。ここで、全プレイヤー分の行動ログの保存は、全てのRPCコールを保存しておくことで実現できます。復帰してきたプレイヤーは、RPCコールを古いものから全て順番に実行すると、切断前とほぼ同じ状態に復元できます。
ここで、復元の注意点について紹介します。
UI操作であってもRPCで実行する
相手プレイヤーにYes/Noダイアログを出すRPCがあることはわかると思います。そして、その返答もRPCで行われることもわかると思いますが、ここで、ダイアログの消去も返答のRPC上で行いましょう。もしダイアログ消去をRPC上で行わなかった場合、復帰してきたときに返答済みのダイアログが残ってしまいます。カタンではコントロールフロー上の「パネル消し」が相当します。

アニメーションは全て投げっぱなしで
もしアニメーション終了を起点に関数を実行しようとしているのならそれはやめておきましょう。復帰時にRPCコールとアニメーション時間の整合性が取れなくなるためです。アニメーションは時間指定で実行しておき、次のアニメーションが来た場合は即座に終了状態までアニメーション遷移してから次のアニメーションにとりかかるようにしましょう。
カタンでは、ダイス値を決めてダイスが動き始めるRPCの後、アニメーションと同じ時間が経った後ダイス値に応じたアクションを行うRPCが送られます。それでもアニメーション中にダイスを回したプレイヤーが落ちると破綻するので、もうひと工夫必要です。
全プレイヤーで情報共有する
もしマスタークライアントのみが知っている情報などがある場合、マスタークライアントが落ちると情報が消えてしまいます。また、マスタークライアントが落ちるとマスターが移譲されるシステムが多いでしょう。マスター以外必要ないようなゲーム進行情報だとしてもできるだけ共有しておきましょう。

StableDiffusionの歴史
StableDiffusionの初版は、2022年8月22日に公開されました。
まずは基礎として、Latent space、VAE、ノイズ除去、U-Net、CLIPなどキーワードの解説です。
Latent space
StableDiffusionでは、画像をピクセル基準ではなく、主に潜在ベクトルとして扱います。大体768次元くらいの大きさです。768個の値が、1枚の画像全てを表現することになります。
VAE
VAEは、Value Auto Encoderの略です。値を変換するということで、Latent spaceの潜在空間ベクトルとピクセル空間画像を変換する役割があります。Encoderがピクセル→ベクトル、Decoderがベクトル→ピクセルです。txt2imgの場合は最終段階でVAEの出番となっています。
ノイズ除去
StableDiffusionは、ノイズ除去拡散モデルが元になっています。ノイズ除去拡散モデルというのは画像にノイズを徐々に加えていき完全なノイズになるまでの過程を学習し、ノイズから画像への復元を実現するものです。
これを潜在空間ベクトルで行い、なおかつノイズ除去時にcross attentionとしてノイズ除去の方向性を指定する仕組みを追加したものがStableDiffusionです。
U-Net
ノイズ除去に使うモデル構造が、U-Netです。これは、扱うデータの抽象度を段階的に落としながら処理を行い、次に段階的に抽象度を上げながら処理することで、抽象度の高い情報から詳細な情報まで考慮に入れることができます。StableDiffusionでも層によって大まかに構図の層から指・塗り方の層まで抽象度の違う情報を処理しているそうです。
CLIP
CLIPは、画像とテキストを変換するためのモデルで、画像のテキスト説明、テキストの潜在ベクトル化を行えます。StableDiffusionでは最初のプロンプト入力段階でテキストの潜在ベクトル化を利用しています。
StableDiffusion v1.4 2022年8月22日
最初に公開されたモデルがv1.4です。実写風の画像生成が主で、イラスト風画像は非常に困難でした。かなり頑張ってCG風画像や、名画風、もしくは超デフォルメ風画像が限界でした。
手足の破綻率はかなりのもので、指が正確に生成されることはほぼありません。顔もかなりの確率で破綻するので、顔修復専用の機械学習モデルが追加で使われていました。




WaifuDiffusion v1.2 2022年9月8日
有志による追加学習により、イラスト風画像の生成を目指したモデルです。今ではもう公開されていませんが、様々な品質のイラストと実写画像が融合したような画像が生成されるようになりました。




NovelAI 2022年10月3日
NovelAI社が公開したStableDiffusionをベースに多少カスタマイズ、追加学習を行い、オンラインで上で利用できる有料画像生成機能です。非常に優れた品質のアニメイラスト画像を生成できました。Danbooruというイラスト転載・タグ付けサイトのデータが利用され、プロンプトがタグベースで記述できるようになっています。
当時の学習
ところで、このころは特定のキャラクターなどを追加学習するためにはモデル全体に対して学習するのが一般的でした。つまり、1キャラクターごとに4~8GBのモデルが必要になります。
そこで、簡易的な方法が出てきます。
Textual Inversion
Textual Inversion (TI)は、画像の生成方法をモデル側で学習するのではなく、Text側、つまりプロンプトとして表現される、意味のベクトルを学習するものです。例えば白髪ツインテエルフを「フリーレン」という単語に覚えさせることができます。しかし、モデルが表現できる範囲の画像しか生成されませんので、細かい特徴は一切学習できません。
WaifuDiffusion v1.3 2022年10月7日
さらなる追加学習により、v1.2よりイラスト品質の向上と実写感の減少が達成されました。破綻率も多少改善されました。




NovelAIモデル流出 2022年10月6日
NovelAIが追加学習し、有料画像生成のために利用されていたモデルが流出しました。多少カスタムされているとはいえStableDiffusionのモデルなので、少しの手間でローカル利用のモデルとして利用できたそうです。
StableDiffusionのモデルは、ミックス・マージすることが可能です。単純に値を2つのモデルの中間にしてもよいし、EMAと呼ばれる学習度合いのような値を使って2つのモデルのいいとこ取りをすることも可能です。多くの追加学習モデルをマージしていくと、多くのモデルの特徴を持ったモデルを作ることも可能です。
Anything v3.0 2022年11月13日
出自不明のモデルですが、NovelAIモデルと同等か上回るような性能を持ったイラストモデルです。NovelAIと同じくDanbooruタグが有効な他、生成される画像にもNovelAIと似た傾向があるため流出モデルがマージ成分として含まれていると考えられます。手足の破綻はかなり少なく、顔修復は不要になりました。




StableDiffusion v2.0 2022年11月24日
StableDiffusionの次世代モデルで、より大きな画像解像度で学習されたモデルで、CLIPモデルも変更されているなど、v1.4とは異なるモデル構造のため旧モデルとは非互換の新しいものでした。しかし、手足の破綻問題はあまり改善されていなかったり、要求スペックが高い他、非互換のために旧モデルの学習結果を利用できなかったためあまり普及しませんでした。
WaifuDiffusion v1.4 2023年01月01日
StableDiffusion v2.0 をベースモデルとして学習されたイラストモデルで、NovelAI流出モデルを使用していないクリーンなモデルと言えます。しかし、そこまで品質は高くありません。




少し停滞と洗練
ここから、しばらくStableDiffusionモデルの進化はゆっくりになります。他社のMidjourneyやDallといったStableDiffusionより優れた品質のものが出てきますが、いずれも非ローカルの有料サービスです。
StableDiffusionでは、マージをU-Netの層別化によるイラストモデルと実写モデルのいいとこ取りが流行ったり、追加学習の効率化や、生成の高速・省メモリ化が行われていました。
追加学習法
Hyper Network
Textual Inversionの学習ではモデルが表現できないものは学習できず、モデル学習では学習結果が数GBにもなりました。100MB程度でモデル追加学習を保存できるのがHyperNetworkです。キャラクター再現や、画風再現も可能だそうです。ただし、学習に必要なGPUスペックは多いのでそこまで流行っていません。
Dream Booth
こちらもHyper Networkと似たような追加学習方法の1つです。HyperNetworkよりも学習再現率が高いですが、モデルは数GBにもなるのでこれも流行っていません。
LoRA
Low-Rank Adaptation of LLMの略です。Hyper NetworkやDream Boothよりも低VRAMで高速に学習でき、学習結果も数十MB程度で収まります。かなり手軽なので多くのキャラクターLoRAやポーズ、顔表情のLoRAが作られています。
ControlNet 2023年02月16日
プロンプトもしくはimg2imgの利用でしか生成結果をコントロールできなかったStableDiffusionですが、ControlNetにより詳細なimg2imgコントロールを行えるようになりました。棒人間によってポーズを決めたり、線画に色付けしてもらったり、写真をイラスト化してもらったり、落書きから完成まで持っていってもらったりできます。
ただしモデルが表現できないものは描けません。
たくさんのモデル
これまでのモデルは、huggingfaceという機械学習版のgithub風サイトで公開されたものがほとんどでしたが、CivitAIというStableDiffusion特化の共有サイトの利用が増えていきます。
モデルも、イラストからCG,実写まで非常に多種多様な専用モデルが作られました。




StableDiffusion XL (SDXL) 2023年07月27日
StabilityAIより公開された、StableDiffusion v2.0の次世代モデルです。学習解像度が1024x1024基準となっており、v1.4の512x512と比べると4倍の画素数になっています。
かなり広範囲の学習をされているようで、少しの追加学習で効果がでる柔軟さをもったモデルになっているそうです。手足の破綻が少ない上に、v1.4系列では困難だった指の生成もかなり破綻率が少なく生成できます。v2.0と同様に前モデルとの互換性はありませんが、互換性がないのでNovelAI流出問題もありません。SDXLの利用者は増えているようです。




高速化
最近は、生成の高速化が流行っている印象です。NvidiaGPUのTensorCoreを利用したTensorRTや、高速生成に最適化されたLCM SamplingとLCMモデルなどがあります。
高速化を利用して、今後は動画生成も増えていくことでしょう。
Unityでボリュームレンダリング ~CTデータビジュアライゼーション~
Unityでボリュームレンダリングをするのに必要な実装について簡易的に解説してみます。方式としてはダイレクトボリュームレンダリング・レイキャスティングです。
今回は以下2編です。
データ入力編
カスタムシェーダー編
コンピュートシェーダー編
データ入力編
ボリュームデータは、3次元画像の形で表せます。Unityでは、Texture3Dとして3次元画像がサポートされていますので、そちらを使います。
CTデータは、3次元×CT値です。CTの値域は-1000 ~ 1000といった値をとりますので、通常の8bitカラーでは不足します。16bit浮動小数点のTextureFormat.RHalfあたりが適当でしょう。こちらはスカラー3次元画像用フォーマットです。
入力するボリュームデータは16bit整数(short)のraw形式であるとします。dicomを使いたかったらライブラリを探してきましょう。

入力の擬似コード
バイナリリーダーを用意し、ファイルを読み込みます。
BinaryReader reader = new BinaryReader(new FileStream(filePath, FileMode.Open));
3DTextureを作る前に、ボリュームデータを配列(1次元)に入れます。
float[] data = new float[dimX * dimY * dimZ];
ここで、ボリュームデータのエンディアン(バイトオーダー)に注意!データとOSの組み合わせによっては変換が必要です。
ushort dataval = reader.ReadUInt16();
リトルエンディアンからビッグエンディアンへの変換はこんな感じ
dataval = (ushort)(((dataval >> 8) | (dataval << 8)) & 0xFFFF);
データ値は、0~1の範囲の値に変換するとテクスチャアクセスの都合上扱いやすいです。シェーダーでは、テクスチャに0~1でアクセスします。
dataval = (dataval - min) / range;
forでもなんでもいいので回して配列に入れられたら実際にTexture3Dを作ります。
Texture3D texture3d = new Texture3D(dimX, dimY, dimZ, TextureFormat.RHalf, false);
texture3d.filterMode = FilterMode.Bilinear;
texture3d.wrapModeW = TextureWrapMode.Clamp;
作ったTexture3Dにデータを流し込みます。
texture3d.SetPixelData<float>(data, 0);
texture3d.Apply();
meshRenderer.sharedMaterial.SetTexture("_DataTex", 3dtexture);
これでボリュームデータの入力は完成です。
※発展
色設定はTexture2D(RGBA)で表現します。テクスチャの左端が0~1に変換したデータの0、右端がデータの1に対応する色に塗ります。
カスタムシェーダー編
Unityで3Dレンダリングするためには、基本的にMeshRendererが必要です。
また、ボリュームは3Dオブジェクトで、データの形も立方体(直方体は一旦無視)なので、プリミティブのキューブ立方体を用意しましょう。
Unityでボリュームレンダリングする際は、キューブのメッシュレンダリングを、ボリュームレンダリングに書き換えます。
カスタムシェーダー
では、カスタムシェーダーを作成します。かなり難しいのでUnityドキュメントをよく読む必要があります。
Unlit Shaderを改変していきます。
まず、Properties。マテリアルの項目設定にあたります。この場合3Dテクスチャを1つと、0~1の値を2つ設定できるマテリアルになります。
次はシェーダー設定。透過シェーダーであることを設定しています。途中のブロックコメントはコードのフォーマッタで壊されないためにあります。


参考
(これの簡易化版だよ!)
コンピュートシェーダー編
ボリュームはデータ量が大きいので、全体処理するときはコンピュートシェーダーを使うと高速化できます。法線計算だったり0~1化だったり。ただしメインメモリとGPUメモリの複雑な操作が必要になります。
AIイラスト 呪術師 vs 調整職人 vs 絵師 【Stable-Diffusion-WebUI】
この記事はStableDiffusion-webuiを触った個人的感触を書いたものです。

はじめに
なにもStableDiffusionに望みの絵を描いてもらう方法は1つではない。
一発で至高の1枚を描けるプロンプトを探す呪術師、ガチャとパラメータ修正を繰り返して理想に近づけていく調整職人、自ら描く絵の補佐を頼む絵師。
これらの3種類の描き方を紹介していく。
呪術師
StableDiffusion-webuiでは、正の意味をもつプロンプトと、負の意味をもつネガティブプロンプトをそれぞれ75トークンほど指示することができる。(トークンは単語とほぼ同じ)
そして、プロンプトは意味ベクトルとなり、描くものを決めていく。ここで大事なのはベクトルであるということだ。つまり、意味上の加算・減算ができる。例えば"花" - ”赤" = "赤以外の花"だ。
次に大事なのは、トークン(単語)の意味は辞書的で単一なものではないということだ。辞書でなければ何なのかというと、その単語が(学習時に)よく用いられる状況的な意味を指している。簡単に言うと、AIは偏見がすごく、単語に多くの意味を持っている。例えば"日本"→"和装・神社仏閣"、"テロリスト"→"中東人"、"水着"→”プール”, といったようにステレオタイプと拡大解釈に溢れている。
そして、プロンプトが呪文と呼ばれる由縁になっているのは、トークン(単語)に人間が知らない意味を見出していることがあるからだ。呪術師の間では、"high detailed"や、"4k 8k"、"masterpiece" などといった極めて主観的なプロンプトが使われている。AIは、人間が高精細と判断したり、傑作と呼ぶ作品に画像的な共通点を見出している。
これらのプロンプトに関する特徴を組み合わせ、長大なプロンプトを書き上げていくのが呪術師のやり方だ。
簡単な例はこんな感じ
プロンプト:「傑作、水着少女」
ネガティブ:「低クオリティ、プール」
プロンプト以外にも重要な項目が2つあるので記しておきたい。
縦横比と、CFG Scaleだ。
縦横比は、文字通り生成画像のアスペクト比である。正方形のままだと、頭部が見切れてしまうことがよくある。この場合、縦長にすると改善することが多い。重要なのは、縦横比が異なれば生成する画像の趣向も変わるということだ。縦長だと立ち絵で、横長だと複数人出たり、足を伸ばした構図になったりする。
CFG Scale(classifier-free guidance scale)は画像生成でどれだけプロンプトに従うかという説明がなされるが、基本的には5~15の範囲内で動かす必要はない。感覚的にはプロンプトが短いならばCFGも小さめのほうが柔軟で、長いプロンプトならCFGを高めにしないと言うことを聞いてくれない。逆に、CFGが低すぎるとカオスで印象派の絵画っぽくなり、CFGが高すぎると極彩色でAI特有の色収差風なものが現れる。
調整職人
StableDiffusion-webuiではテキストから画像を生成するだけでも様々なパラメータを調整できるし、それ以外にも、様々な機能が備わっている。プロンプトはほどほどに、パラメータ調整とランダム性を活用することで、より多彩で意外性のある生成をすることができる。
img2imgでは、画像とプロンプトから画像を生成することができる。この機能の主な使い方は、バリエーション生成か構図指定だ。
バリエーション生成は、txt2imgかimg2imgで生成した画像を入力画像とすることで、微妙な変化をもたらす使い方だ。この際重要なのは、入力画像を生成するのに使った設定を引き継ぐことと、Denoising strengthの値だ。プロンプトや設定が大きく異なると、色彩と形が似ていても全く別のものが生成されたりする。プロンプトに数トークン追加する程度なら大丈夫。そして、Denoising strengthは入力画像にどれだけ近づけないかを指定できる。0.5でほとんど同じ、1で全く別物なので、0.65~0.8ほどでガチャを繰り返すことになる。生成された画像を、さらに入力画像とするといったことを繰り返していく。
構図指定は、バリエーション生成の逆で、プロンプトを一致させない使い方だ。構図の入力は落書きレベルでよい。重要なのは、なにを描いているのか上手くプロンプトでAIに説明することだ。Denoising strengthは高めにする。背景が単色になりがちなのが難しい。
inpaint/outpaintingは、それぞれ細部調整と画角調整に使われる。ただし、こちらを使った結果は不自然なものになりやすく、結果をimg2imgで再描画するとよい。
inpaintは、指定箇所のみを再描画する。設定は元画像と同じでよい。主な用途としては余計なものを消すか、別のものに変えてもらうことだ。手指の修正をこれでやるのは難しい。
outpaintingは、主に見切れてしまった頭部の補完に使う。基本的にわかりやすい境界が拡張部にできてしまうので、inpaintで消してimg2imgで再描画するといった流れになる。
以上のように、調整職人は数多くのガチャを回し続けることになる。重要なのは、プロンプトで伝わりきらない意味を、入力画像とシード値で伝えるということだ。(プロンプトが少々異なっても、同じシード値であればAIの魂が似ていることに気づくだろう)
絵師
これまで紹介してきた呪術師や調整職人は、基本的に自ら線を描かない。呪術師や調整職人が行う方法と、自らが描く絵を組み合わせるのが絵師のやり方だ。
絵師は、主にimg2imgを使う。ラフ画を読み込ませ、塗りを担当してもらうケースが多い。AIの一番の得意分野が、実写レベルまで可能な塗りだからだ。塗ってもらった絵に絵師が更に線を加え、さらに再描画してもらうといったように、AIとの対話作業を行うことになる。
逆に、AIにラフだけ描いてもらったり、背景だけ用意してもらうといったことも可能だ。
StableDiffusionWebUIをローカル環境で動かす
はじめに
StableDiffusionをローカル環境で動かすには4GB以上のグラフィックメモリを積んだGPUが必要です。初心者の方には環境構築の簡単なNMKD StableDiffusion GUIの方をオススメします。(機能が少なくロードが長いですが)
NMKD Stable Diffusion GUI - AI Image Generator by N00MKRAD
導入
StableDiffusionWebUIはGitHubで公開されてます。
前提にインストールが必要なのは以下の通り
StableDiffusionのモデルデータ(学習済み)も用意する必要があります。有名なのは以下の3つ。好みでどうぞ
- 本家StableDiffusion
- WaifuDiffusion
hakurei/waifu-diffusion-v1-3 · Hugging Face - Trinart
あとはReadmeに従えばOKです
親切丁寧な導入記事
StableDiffusionWebUIの主な機能
- テキスト→画像 (txt2img)
- 画像+テキスト→画像 (img2img)
- 画像+テキスト+領域選択→画像 (Inpaint)
- 画像+テキスト→拡張画像 (Outpainting)
- 画像→超解像画像 (Extras)
- 追加学習機能
公式説明はこちら
Home · AUTOMATIC1111/stable-diffusion-webui Wiki · GitHub
続きは次の記事…
JavaからCUDAを触る GPUプログラミング
GPUをGPGPU(汎用計算)目的で操作する方法は、CUDAとOpenCLが有名です。
ただし、CUDAはNvidiaのGPUでしか使えませんし、OpenCLはGPU専用ではないのでとっつきにくいです。というわけでNvidiaのGPUがあるなら最初はCUDAをオススメします。どちらも、C言語をベースにした言語でプログラミングします。
CUDA
CUDA言語は、C言語の拡張で、CUDA ToolKitに含まれるnvccコンパイラを用いてコンパイルします。
__device__ や __host__ を記述することで、関数がGPUで使えるのか、CPUで使えるのか定義できます。
GPU処理の起点
CPU側のコードからCUDAランタイムAPIを呼び出して、__global__が記された関数をGPUで実行させることができます。上記の例だと、tidは何番目の処理かに相当する。
JavaからGPUを動かす
Javaコードを直接GPUで動かせるライブラリはAparapiくらいしかありません。Aparapiはビルドが少々難しいうえ、GPUの限られた機能しか使えません。
そこで、JavaコードからCUDAランタイムAPIを呼び出すことを考えます。JavaコードでCPU処理部分を記述し、GPU処理部分はCUDA言語で記述します。
JavaコードからCUDAランタイムを呼び出せるライブラリ
JCuda
おそらく最もライブラリとして完全です。今回はスルー
lwjgl.Cuda
LWJGLはゲームライブラリですが、GLからCUDA、ほかにも沢山組み合わせることができ、Minecraftでも利用されています。Maven一発で入れられるのもいい点です。
LWJGLからCUDAを呼び出すサンプルはこちらが参考になります。
内容はこんな感じです。
注意点
- 最初のCUDAファイルは文字列で渡してコンパイルしてもらう
- Java側でデータはスタック領域に配置しなければGPUメモリにコピーできない
- スタック領域では明示的なメモリ開放が必要
- 一次元配列以外のデータを渡すのはけっこう面倒
CUDAでのベクトル関数はこちらが便利