我遇到了一些问题(我认为)在C#中打包我的结构并将它们传递给我在HLSL中注册的cbuffers。当我以一种方式打包我的结构时,信息似乎能够传递到着色器:
[StructLayout(LayoutKind.Explicit, Size = 16)]
internal struct TestStruct
{
[FieldOffset(0)]
public Vector3 mEyePosition;
[FieldOffset(12)]
public int type;
}
当我创建这个结构并将其设置为C#中的常量缓冲区时,它似乎工作得很好。我得到了我期望的颜色:
cbuffer PerFrame : register(b0)
{
Vector3 eyePos;
int type;
}
float3 GetColour()
{
float3 returnColour = float(0.0f, 0.0f, 0.0f);
switch(type)
{
case 0:
returnColour = float3(1.0f, 0.0f, 0.0f);
break;
case 1:
returnColour = float3(0.0f, 1.0f, 0.0f);
break;
case 2:
returnColour = float3(0.0f, 0.0f, 1.0f);
break;
}
return returnColour;
}
但是当我使用另一个结构将结构更改为结构时,它似乎确实设置正确。请注意,内部结构将包含其中的额外信息,但我现在试图尽可能地简化它:
[StructLayout(Layout.Explicit, Size = 16)] //Note this is 16 because HLSL packs in 4 float 'chunks'
internal struct InternalTestStruct
{
[FieldOffset(0)]
public int type;
}
[StructLayout(LayoutKind.Explicit, Size = 32)]
internal struct TestStruct
{
[FieldOffset(0)]
public Vector3 mEyePosition;
//Missing 4 bytes here for correct packing.
[FieldOffset(16)]
public InternalTestStruct internal;
}
在HLSL中
struct InternalType
{
int type;
}
cbuffer PerFrame : register(b0)
{
Vector3 eyePos;
InternalType internalStruct;
}
float3 GetColour()
{
float3 returnColour = float(0.0f, 0.0f, 0.0f);
switch(internaltype.type)
{
case 0:
returnColour = float3(1.0f, 0.0f, 0.0f);
break;
case 1:
returnColour = float3(0.0f, 1.0f, 0.0f);
break;
case 2:
returnColour = float3(0.0f, 0.0f, 1.0f);
break;
}
return returnColour;
}
你认为我收拾结构的方式有问题吗? 或者问题可能在其他地方,我只认为这是我的包装,因为我可以得到第一个例子,当我用TestStruct设置常量缓冲区时,但只要我扩展它以包含InternalTestStruct它似乎不工作
任何帮助都会很棒。
提前致谢。
答案 0 :(得分:0)
使用时:
struct InternalType
{
int type;
}
cbuffer PerFrame : register(b0)
{
float3 eyePos;
InternalType internalStruct;
}
因为InternalType的大小为4,所以它将打包成16的布局,所以它与你刚刚使用int的方式完全相同。
要使用InternalTestStruct匹配第二个c#结构,您需要执行以下操作:
cbuffer PerFrame : register(b0)
{
float3 eyePos;
int dummy; //Here you need to force the padding
InternalType internalStruct;
}
如果将internaltype更改为大于1的大小,则填充将变为自动(但保持显式是很好的。)