Unity计算着色器自定义结构体大小获取问题(替代sizeof)
解决Unity中计算着色器结构体大小获取的CS0233错误
首先,咱们得搞清楚为啥sizeof(VertexData)会报错——在C#的安全代码上下文里,sizeof只能用于预定义的值类型或者标记为unsafe的自定义结构体,哪怕你加了StructLayout属性也不行。不过别担心,有几个不用硬编码的靠谱方法:
方法1:使用Marshal.SizeOf(推荐,安全无需unsafe)
这是最常用的安全方式,只要你的结构体是blittable(能直接在托管和非托管内存间无缝转换)的就没问题。你的VertexData已经加了[StructLayout(LayoutKind.Sequential, Pack = 0)]属性,而且里面的Vector3、Vector2都是Unity原生的 blittable 类型,完全符合要求。代码这么写:
using System.Runtime.InteropServices; // 在创建ComputeBuffer前获取大小 int vertexDataStride = Marshal.SizeOf(typeof(VertexData)); ComputeBuffer vertexBuffer = new ComputeBuffer(totalVertexCount, vertexDataStride);
方法2:启用unsafe代码使用Unsafe.SizeOf
如果你项目允许启用unsafe代码(在Unity编辑器的PlayerSettings > Other Settings里勾选"Allow unsafe code"),可以用Unsafe.SizeOf<T>来获取大小,它的性能略优于Marshal.SizeOf,因为直接操作内存布局:
using System.Runtime.CompilerServices; unsafe { int vertexDataStride = Unsafe.SizeOf<VertexData>(); }
关键注意事项
- 必须保证C#端的
VertexData和计算着色器里的对应结构体内存布局完全一致。比如计算着色器里要写成:
struct VertexData { float3 position; float3 normal; float2 uv; };
你设置的Pack=0(自然对齐)和HLSL的默认内存对齐规则完全匹配,不会出现字段偏移错误。
- 绝对不要硬编码结构体大小!一旦你后续修改结构体(比如新增
float4 color字段),硬编码的数值会直接导致内存错乱,用上面的方法能自动适配结构体的变化。
内容的提问来源于stack exchange,提问作者Virus721
相关产品推荐
相关产品推荐

