主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ
書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。
2020/05/23
そんなことをする必要があるかどうかはさておき、やりたくなったのでメモしておきます。
前提環境は以下の通り :
Vertex Shader は頂点をそのまま渡すだけのものを、 Hull Shader は下のような感じ。
// #define TESSELLATION 16
h2d_const hs_const()
{
h2d_const o = (h2d_const) 0;
const float tess = TESSELLATION;
o.edges[0] = tess;
o.edges[1] = tess;
o.edges[2] = tess;
o.edges[3] = tess;
o.inside[0] = tess;
o.inside[1] = tess;
return o;
}
[domain("quad")]
[partitioning("pow2")]
[outputtopology("point")]
[outputcontrolpoints(4)]
[patchconstantfunc("hs_const")]
h2d hs(const InputPatch<v2h, 4> input, const uint id : SV_OUTPUTCONTROLPOINTID)
{
h2d o = (h2d) 0;
o.position = input[id].position.xyz;
return o;
}
この状態で、 Domain Shader で一意な ID を割り振っていきたい。
ただ、参考にした Qiita 記事の割り振り方だと、 ID の重複がいくつか見られました。
ID: 15 までの描画
ID: 16 までの描画、見ての通り若干描画されている数が多い
そこで、改良したのがこちらです。
[domain("quad")]
d2g ds(const h2d_const data, const OutputPatch<h2d, 4> i, const float2 uv : SV_DOMAINLOCATION)
{
d2g o = (d2g) 0;
// position 計算はなくても良いよ!
const float3 x = lerp(i[0].position, i[1].position, uv.x);
const float3 y = lerp(i[3].position, i[2].position, uv.x);
const float3 z = lerp(x, y, uv.y);
o.position = float4(z, 1.0f);
o.id = (uint) (uv.x * TESSELLATION) + ((uint) ((uv.y * TESSELLATION) * TESSELLATION)) + (uint) (uv.y * TESSELLATION);
return o;
}
全ての値を Geometry Shader から出力して、 Analyzer でダンプした感じだと、
ID: 0 から連番で出力されていました。
ということで、 ID の生成方法でした。