问题描述
我在与(我认为)的一些问题,我的结构的C#包装和传递他们通过cbuffers我已经注册的HLSL。当我在一个地收拾结构的信息似乎可以传递给着色器:
I'm having some issues with (i think) the packing of my structure in C# and passing them through to cbuffers i have registered in HLSL. When i pack my struct in one manner the information seems to be able to pass to the shader:
[StructLayout(LayoutKind.Explicit, Size = 16)]
internal struct TestStruct
{
[FieldOffset(0)]
public Vector3 mEyePosition;
[FieldOffset(12)]
public int type;
}
当我创建这个结构并将它设置为在C#中我不断的缓冲似乎工作得很好。我得到什么颜色返回我期望:
When i create this struct and set it as my constant buffer in C# it seems to work just fine. I get what colours returned that i expect:
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;
}
但是,当我改变结构要使用另一个结构它似乎一个结构正确设置。需要注意的是内部结构将被包含在里面的额外信息,但我试图尽可能简化它现在:
But when i change the structure to be a struct using another struct it does seem to set properly. Note that internal struct is going to be containing extra information in it, but i was trying to simplify it as much as possible for now:
[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 '吨似乎工作。
Do you think there is a problem in the way i am packing my structs?Or could the issue be elsewhere, i only think it is my packing because i can get the first example to work when i set the constant buffer with a TestStruct, but as soon as i expand it to include the InternalTestStruct it doesn't seem to work.
任何帮助将是巨大的。
先谢谢了。
推荐答案
当你使用:
struct InternalType
{
int type;
}
cbuffer PerFrame : register(b0)
{
float3 eyePos;
InternalType internalStruct;
}
自InternalType是大小为4的它将装入16的布局,所以。这是完全一样的,如果你只是用一个int
since InternalType is of size 4 it will pack into the layout of 16, so it's exactly the same as if you were just using an int.
要符合使用InternalTestStruct第二个C#结构,你需要做的:
To match the second c# structure using InternalTestStruct, you'd need to do:
cbuffer PerFrame : register(b0)
{
float3 eyePos;
int dummy; //Here you need to force the padding
InternalType internalStruct;
}
如果你改变internaltype的大小大于一填充随后将成为自动(但它总是很高兴保持明确的)。
If you change internaltype to a size larger than one the padding will then become automatic (but it's always nice to keep it explicit).
这篇关于编组C#结构体进入DX11 cbuffers的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!