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

magento2 - Magento 2 admin grid add filter to collection -

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

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