hlsl - Get the MSAA sample number inside pixelshader for OIT -
i try implement order independent transparency on own. finished without 1 thing... can see in picture below, oit msaa kind of wrong. think because of samples. because @ each triangle edge there 4 samples (and @ triangle edges).
alphablending , oit , without msaa
here shader code in hlsl:
create lists
rwbyteaddressbuffer trwfragmentlist : register(u1); void main(ps_input input) { float2 position = (input.pos.xy - float2(0.5,0.5)) / input.pos.w; uint nxposition = position.x; uint nyposition = position.y; uint vscreenaddress = nscreenwidth * nyposition + nxposition; float3 normal = normalize((float3)input.normal); float3 position = (float3)input.pos; float4 color = createphong(input); //float4 color = (float4)input.diffuse; // counter value , increment uint nnewfragmentaddress = 0; trwfragmentlist.interlockedadd(0, 44, nnewfragmentaddress); if (nnewfragmentaddress < 1000*1000*500) { uint pixel = 4 + nscreenwidth * nscreenheight * 4 + nnewfragmentaddress; trwfragmentlist.store(pixel + 4, asuint(position.x)); trwfragmentlist.store(pixel + 8, asuint(position.y)); trwfragmentlist.store(pixel + 12, asuint(position.z)); trwfragmentlist.store(pixel + 16, asuint(normal.x)); trwfragmentlist.store(pixel + 20, asuint(normal.y)); trwfragmentlist.store(pixel + 24, asuint(normal.z)); trwfragmentlist.store(pixel + 28, asuint(color.r)); trwfragmentlist.store(pixel + 32, asuint(color.g)); trwfragmentlist.store(pixel + 36, asuint(color.b)); trwfragmentlist.store(pixel + 40, asuint(color.a)); uint output = 0; trwfragmentlist.interlockedexchange(vscreenaddress * 4 + 4, pixel, output); trwfragmentlist.store(pixel, output); } }
sort lists
rwbyteaddressbuffer trwfragmentlist : register(u1); float4 main(ps_input input) : sv_target { float2 position = (input.pos.xy - float2(0.5,0.5)) / input.pos.w; uint nxposition = position.x; uint nyposition = position.y; uint vscreenaddress = 4+(nscreenwidth * nyposition + nxposition) * 4; if (trwfragmentlist.load(vscreenaddress) != 0) { uint = vscreenaddress; uint j = vscreenaddress; float zmin = 0; uint zminprev = i; { = j; zmin = asfloat(trwfragmentlist.load(trwfragmentlist.load(i) + 12)); zminprev = i; { if (asfloat(trwfragmentlist.load(trwfragmentlist.load(i) + 12)) > zmin) { zmin = asfloat(trwfragmentlist.load(trwfragmentlist.load(i) + 12)); zminprev = i; } = trwfragmentlist.load(i); } while (trwfragmentlist.load(i) > 0); //check swap if (zminprev != j) { uint trwj = trwfragmentlist.load(j); uint trwtrwmin = trwfragmentlist.load(trwfragmentlist.load(zminprev)); uint trwmin = trwfragmentlist.load(zminprev); trwfragmentlist.store(j,trwmin); trwfragmentlist.store(zminprev,trwtrwmin); trwfragmentlist.store(trwmin,trwj); } j = trwfragmentlist.load(j); } while (trwfragmentlist.load(j) > 0); } return float4(1, 0, 1, 1); }
render finished picture
rwbyteaddressbuffer trwfragmentlist : register(u1); float4 main(ps_input input) : sv_target { float2 position = (input.pos.xy - float2(0.5,0.5)) / input.pos.w; uint nxposition = position.x; uint nyposition = position.y; uint vscreenaddress = nscreenwidth * nyposition + nxposition; float3 color = float3(0.5, 0.5, 0.5); uint nscreenadress = vscreenaddress*4+4; while (trwfragmentlist.load(nscreenadress) != 0) { nscreenadress = trwfragmentlist.load(nscreenadress); float4 newcolor = float4(asfloat(trwfragmentlist.load(nscreenadress + 28)), asfloat(trwfragmentlist.load(nscreenadress + 32)), asfloat(trwfragmentlist.load(nscreenadress + 36)), asfloat(trwfragmentlist.load(nscreenadress + 40))); float fzvalue = asfloat(trwfragmentlist.load(nscreenadress + 12)); color = newcolor.a * newcolor.rgb + (1 - newcolor.a) * color.rgb; } trwfragmentlist.store(vscreenaddress * 4 + 4, 0); if (nxposition == 0 && nyposition) { trwfragmentlist.store(0, 0); } return float4(color.r, color.g, color.b, 1); }
my idea write sample number inside list, , @ end when render endpicture, compare list nodes , if close want check sample number , calculate average color. don't know how aktual sample number...
btw: 1 have better idear fix bug? not need fast calculation, don't render in realtime.
you have use sv_coverage
read mask in pixel shader of touched fragments.
with resolve transparency (and msaa in 1 go) accumulating n values ( n msaa nx ) according coverage, average , output.
if want output in msaa surface instead prior resolve, have use compute shader able accumulation once write n values separately.
i go compute actual mesh render, more convenient pixel shader kind of processing
Comments
Post a Comment