「SPIR-VからHLSLを生成する」の版間の差分
ナビゲーションに移動
検索に移動
imported>Administrator |
Administrator (トーク | 投稿記録) |
||
135行目: | 135行目: | ||
* [[MacにMoltenVKを入れてVulkanを使ってみる]] | * [[MacにMoltenVKを入れてVulkanを使ってみる]] | ||
+ | [[category: 3DCG]] | ||
+ | [[category: シェーディング言語]] | ||
[[category: SPIR-V]] | [[category: SPIR-V]] | ||
[[category: HLSL]] | [[category: HLSL]] | ||
[[category: Vulkan]] | [[category: Vulkan]] |
2020年5月19日 (火) 02:11時点における最新版
SPIR-Vから様々なシェーディング言語に逆コンパイルできると色々捗ると思われる。 SPIR-VはHLSLとGLSLから生成できるので相互変換もできることになる。 夢が広がりんぐ。
準備[編集 | ソースを編集]
Vulkan SDKにSPIR-VからGLSLを生成する逆コンパイラが含まれている。 まずはダウンロードだ。今回はmacOS版をダウンロードしてきた。
Vulkan SDKを展開すると以下に逆コンパイラがある(mac版の場合)。
./macOS/bin/spirv-cross
SPIR-Vファイルは「DirectX Shader CompilerでSPIR-Vを出力する」で生成したものを使った。GLSLではなくHLSLから生成したSPIR-Vファイルだ。
spirv-crossのHLSL変換は「シェーダーモデル3.0以降」をサポートしている。
SM 6.0[編集 | ソースを編集]
実行
./spirv-cross --hlsl --shader-model 60 light_vs.spv
結果。出力用の変数にgl_PositionなどのGLSLのシステム変数名が使われている。なかなか衝撃的なソースコードだ。
cbuffer type_Globals : register(b0, space0)
{
column_major float4x4 _Globals_WorldViewProjection : packoffset(c0);
};
static float4 gl_Position;
static float4 in_var_POSITION0;
static float4 in_var_COLOR0;
static float4 out_var_COLOR0;
struct SPIRV_Cross_Input
{
float4 in_var_POSITION0 : TEXCOORD0;
float4 in_var_COLOR0 : TEXCOORD1;
};
struct SPIRV_Cross_Output
{
float4 out_var_COLOR0 : TEXCOORD0;
float4 gl_Position : SV_Position;
};
void vert_main()
{
gl_Position = mul(in_var_POSITION0, _Globals_WorldViewProjection);
out_var_COLOR0 = in_var_COLOR0;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
in_var_POSITION0 = stage_input.in_var_POSITION0;
in_var_COLOR0 = stage_input.in_var_COLOR0;
vert_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_Position = gl_Position;
stage_output.out_var_COLOR0 = out_var_COLOR0;
return stage_output;
}
SM 3.0[編集 | ソースを編集]
実行
./spirv-cross --hlsl --shader-model 30 light_vs.spv
結果。
cbuffer type_Globals : register(b0)
{
column_major float4x4 _Globals_WorldViewProjection : packoffset(c0);
};
uniform float4 gl_HalfPixel;
static float4 gl_Position;
static float4 in_var_POSITION0;
static float4 in_var_COLOR0;
static float4 out_var_COLOR0;
struct SPIRV_Cross_Input
{
float4 in_var_POSITION0 : TEXCOORD0;
float4 in_var_COLOR0 : TEXCOORD1;
};
struct SPIRV_Cross_Output
{
float4 out_var_COLOR0 : TEXCOORD0;
float4 gl_Position : POSITION;
};
void vert_main()
{
gl_Position = mul(in_var_POSITION0, _Globals_WorldViewProjection);
out_var_COLOR0 = in_var_COLOR0;
gl_Position.x = gl_Position.x - gl_HalfPixel.x * gl_Position.w;
gl_Position.y = gl_Position.y + gl_HalfPixel.y * gl_Position.w;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
in_var_POSITION0 = stage_input.in_var_POSITION0;
in_var_COLOR0 = stage_input.in_var_COLOR0;
vert_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_Position = gl_Position;
stage_output.out_var_COLOR0 = out_var_COLOR0;
return stage_output;
}
備考[編集 | ソースを編集]
SPIR-V経由で出力したコードを比較した限りでは以下のような結論に達した。
- HLSLで書く
- HLSLはHLSLのまま使う
- HLSLからGLSLを生成する
比較量は少ないでまだ正確なことは言えないが、 GLSLで書いてHLSLへ変換という逆パターンは危険そうな雰囲気がある。