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

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

Popular posts from this blog

Combining PHP Registration and Login into one class with multiple functions in one PHP file -

Android volley - avoid multiple requests of the same kind to the server? -

magento2 - Magento 2 admin grid add filter to collection -