我正在尝试编写一个hlsl计算着色器,该hlsl compute着色器在rwtexture2中写入红色频道2,但我看到不一致时,当我尝试读取该值时,所有这些都取决于我是否放置了任意命令之前或之后的分配:
具体示例。我只派遣一个线程shader.Dispatch(1, 1, 1)
从附录结构缓冲程序读取后,派遣以下代码返回一个值为255的条目。
RWTexture2D<float4> gridModel;
AppendStructuredBuffer<float> outlierIndeces;
[numthreads(1, 1, 1)]
void IdentifyBorderPoints(uint3 id : SV_DispatchThreadID)
{
if (id.x == 0)
{
gridModel[id.xy] = float4(255, 0, 0, 0);
outlierIndeces.Append(gridModel[id.xy].r);
}
}
但是将分配移动在if-Statement之外使其返回1。但是,从我所看到的,这仍然应该只有255:
RWTexture2D<float4> gridModel;
AppendStructuredBuffer<float> outlierIndeces;
[numthreads(1, 1, 1)]
void IdentifyBorderPoints(uint3 id : SV_DispatchThreadID)
{
gridModel[id.xy] = float4(255, 0, 0, 0);
if (id.x == 0)
{
outlierIndeces.Append(gridModel[id.xy].r);
}
}
作为理智检查,评论作业使其返回0:
RWTexture2D<float4> gridModel;
AppendStructuredBuffer<float> outlierIndeces;
[numthreads(1, 1, 1)]
void IdentifyBorderPoints(uint3 id : SV_DispatchThreadID)
{
//gridModel[id.xy] = float4(255, 0, 0, 0);
if (id.x == 0)
{
outlierIndeces.Append(gridModel[id.xy].r);
}
}
我对编译的代码进行了更深入的了解,在那里我也看到了一个区别:以下编译的代码来自示例,该示例发生在if-Statement之前:
// Input signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// no Input
//
// Output signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// no Output
cs_5_0
dcl_globalFlags refactoringAllowed
dcl_uav_structured u0, 4
dcl_uav_typed_texture2d (float,float,float,float) u1
dcl_input vThreadID.xy
dcl_temps 2
dcl_thread_group 1, 1, 1
0: store_uav_typed u1.xyzw, vThreadID.xyyy, l(255.000000,0,0,0)
1: if_z vThreadID.x
2: mov r0.x, l(0)
3: mov r0.yzw, vThreadID.yyyy
4: ld_uav_typed_indexable(texture2d)(float,float,float,float) r0.x, r0.xyzw, u1.xyzw
5: imm_atomic_alloc r1.x, u0
6: store_structured u0.x, r1.x, l(0), r0.x
7: endif
8: ret
// Approximately 0 instruction slots used
这是在if statement之后发生分配的示例中的编译代码:
// Input signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// no Input
//
// Output signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// no Output
cs_5_0
dcl_globalFlags refactoringAllowed
dcl_uav_structured u0, 4
dcl_uav_typed_texture2d (float,float,float,float) u1
dcl_input vThreadID.xy
dcl_temps 1
dcl_thread_group 1, 1, 1
0: if_z vThreadID.x
1: mov r0.x, l(0)
2: mov r0.yzw, vThreadID.yyyy
3: store_uav_typed u1.xyzw, r0.xyzw, l(255.000000,0,0,0)
4: imm_atomic_alloc r0.x, u0
5: store_structured u0.x, r0.x, l(0), l(255.000000)
6: endif
7: ret
// Approximately 0 instruction slots used
我不完全理解编译代码,但似乎只有在if-statement之后发生分配的情况下,值255才分配给结构化Buffy。
附加信息:我正在使用Unity的着色器编译器来编译代码。我使用的Unity的版本是2018.3.14f1。
我得到了一些帮助,我们发现了问题。在Unity中,我使用以下设置的重新文字初始化了网格模型:
texture = new RenderTexture(512, 512, 1, RenderTextureFormat.ARGB32);
texture.depth = 0;
texture.enableRandomWrite = true;
texture.Create();
我将其发送给着色器:
int identifyBorderPointsKernel = cShader.FindKernel("IdentifyBorderPoints");
cShader.SetTexture(identifyBorderPointsKernel, "gridModel", texture);
但是出现问题是因为RenderTextureFormat.argb32中的每个通道都是8位Float Chhanel,因此将我的INT夹至1。通过用float值代替255,而不是float值代替0.4,无论我在哪里完成分配,我都得到了平等。
我在if-statement的任一侧都会收到差异的原因是因为在if-statement内部发生分配的情况下,编译器将值直接分配给附录案件,并且不费心从纹理首先因此,该值永远不会被夹紧。