Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Rendertexture is black sometimes when read from shader

Discussion in 'Shaders' started by cadynbombaci, Dec 30, 2020.

  1. cadynbombaci

    cadynbombaci

    Joined:
    Oct 10, 2017
    Posts:
    10
    I believe I've been working on this abomination of a shader for over a month, putting easily over a hundred hours just into solving the stupid problem of having a buffer for my shader without using custom scripts because VRChat. So, I've found a pretty reliable to way get data to a camera by adding a tiny plane of quads in front of a camera with a tiny size and clipping distance and on orthographic. Point is: Yes, the pixels are placed correctly and read correctly SOMETIMES. Other times, they all magically turn black. I have the camera set to don't clear, so it shouldn't be clearing pixels at all anyways, yet it does, unless it's an error with reading from it. Funny thing is I also a check which if it's reading zeros, tries to read it again up to 10 times again, and it still fails. Gonna post my relevant code below. Any help or ideas on how to do this better are appreciated. Thankyou.

    Quick edit: To be more specific, It seems to be relatively rare, as whenever I have it print all of the data for a few vertices, I can never find evidence of the data all getting set to 0, but if I have it only give me data for when it's 0 I can see that it happens at least once every 0.06 seconds (the time between frames at the moment because I'm also saving pictures of the renderTexture every frame. I can post these if needed.)

    Oh, also, yes _PosBuffer is an RWStructuredBuffer that I'm using for debugging, but it's gonna have to go for final production since again VRChat has no support.

    Helper functions used for encoding and reading data:

    Code (CSharp):
    1. float f2textp1(float inp) {
    2.             if (inp == 0) {
    3.                 return 0;
    4.             }
    5.             return (floor(log2(abs(inp))) + 127) / 512 + 0.25*(1 - sign(inp));
    6.         }
    7.         float f2textp2(float inp) {
    8.             if (inp == 0) {
    9.                 return 0;
    10.             }
    11.             return (abs(inp) / pow(2, floor(log2(abs(inp))))) - 1;
    12.         }
    13.  
    14.         float2 f2text(float inp) {
    15.             if (inp == 0) {
    16.                 return float2(0, 0);
    17.             }
    18.             float temp = floor(log2(abs(inp)));
    19.             return float2((temp + 127) / 512 + 0.25*(1 - sign(inp)), (abs(inp) / pow(2, temp)) - 1);
    20.         }
    21.         float text2f(float2 inp) {
    22.             float temp1 = floor(inp.x * 2);
    23.             float s = 1 - temp1 * 2;
    24.             float temp2 = round(512 * (inp.x - temp1 * 0.5) - 126);
    25.             float temp3 = (inp.y + 1) / 2;
    26.             return s * temp3 * pow(2, temp2);
    27.         }
    28.  
    29.         float3 f2text3p1(float3 inp) {
    30.             return float3(f2textp1(inp.x), f2textp1(inp.y), f2textp1(inp.z));
    31.         }
    32.         float3 f2text3p2(float3 inp) {
    33.             return float3(f2textp2(inp.x), f2textp2(inp.y), f2textp2(inp.z));
    34.         }
    35.      
    36.         float3 text2f3(float3 inp1, float3 inp2) {
    37.             return float3(text2f(float2(inp1.x, inp2.x)), text2f(float2(inp1.y, inp2.y)), text2f(float2(inp1.z, inp2.z)));
    38.         }
    39.         vertdata text2data(uint vid)
    40.         {
    41.             vertdata outp;
    42.  
    43.             float2 coords = float2((float)((vid * 5) % 512), (float)(int)(vid * 5 / 512.0f));
    44.             float2 coords2 = float2((float)((1 + vid * 5) % 512), (float)(int)((1 + vid * 5) / 512.0f));
    45.             float2 coords3 = float2((float)((2 + vid * 5) % 512), (float)(int)((2 + vid * 5) / 512.0f));
    46.             float2 coords4 = float2((float)((3 + vid * 5) % 512), (float)(int)((3 + vid * 5) / 512.0f));
    47.             float2 coords5 = float2((float)((4 + vid * 5) % 512), (float)(int)((4 + vid * 5) / 512.0f));
    48.  
    49.             coords = (coords + 0.5) * _PosMap_TexelSize.xy;
    50.             coords2 = (coords2 + 0.5) * _PosMap_TexelSize.xy;
    51.             coords3 = (coords3 + 0.5) * _PosMap_TexelSize.xy;
    52.             coords4 = (coords4 + 0.5) * _PosMap_TexelSize.xy;
    53.             coords5 = (coords5 + 0.5) * _PosMap_TexelSize.xy;
    54.  
    55.             vertdata pOutp;
    56.  
    57.             outp.position = text2f3(tex2Dlod(_PosMap, float4(coords, 0, 0)).xyz, tex2Dlod(_PosMap, float4(coords2, 0, 0)).xyz);
    58.             outp.computeTime = text2f(tex2Dlod(_PosMap, float4(coords5, 0, 0)).xy);
    59.             outp.force = text2f3(tex2Dlod(_PosMap, float4(coords3, 0, 0)).xyz, tex2Dlod(_PosMap, float4(coords4, 0, 0)).xyz);
    60.  
    61.             /*if ((outp.computeTime == 0 || all(outp.position == 0)) && _Time.y > 0.05 && _Time.y < 1) {
    62.                 pOutp = outp;
    63.                 pOutp.force = float3(tex2Dlod(_PosMap, float4(coords5, 0, 0)).xy,_Time.y);
    64.                 _PosBuffer[vid] = pOutp;
    65.             }*/
    66.          
    67.          
    68.             return outp;
    69.         }
    Main physics and geometry code, this is run after the main shader:
    Code (CSharp):
    1. struct a2v
    2.             {
    3.                 float4 vertex : POSITION;
    4.                 uint vid : SV_VertexID;
    5.                 float4 texcoord : TEXCOORD0;
    6.                 float4 texcoord1 : TEXCOORD1;
    7.                 float4 texcoord2 : TEXCOORD2;
    8.                 float3 normal : NORMAL;
    9.             };
    10.             struct v2g {
    11.                 float4 vertex : SV_POSITION;
    12.                 uint vid : BLENDINDICES;
    13.                 float4 pos : NORMAL;
    14.                 float4 force : BINORMAL;
    15.             };
    16.             struct g2f {
    17.                 float4 vertex : SV_POSITION;
    18.                 float4 pos : COLOR6;
    19.                 float4 force : COLOR7;
    20.                 float rtype : DEPTH1;
    21.                 float vid : DEPTH2;
    22.             };
    23.  
    24.             v2g vert(a2v v) {
    25.                 v2g o;
    26.                 float wDelta = _Time.y - _PrevTime;
    27.                 if (wDelta > 1 / _UpdateRate) {
    28.                     float windMagnitude = (_WindMax - _WindMin) * 2.0;
    29.                     float3 wind = float3(_WindMax, _WindMax, _WindMax) - hash33(_Time.yzw)*windMagnitude;
    30.                     _WindForce = lerp(_WindForce, wind, wDelta * _WindDamp);
    31.                     _PrevTime = _Time.y;
    32.                 }
    33.                 //v.pid = v.vid;
    34.                 vertdata inp = text2data(v.vid);
    35.                 float3 force = inp.force;
    36.                 float tDelta = _Time.y - inp.computeTime;
    37.                 float transp = 0;
    38.                 if(inp.computeTime == 0 || all(inp.position == 0)){
    39.                     uint attemptnum = 0;
    40.                     while ((inp.computeTime == 0 || all(inp.position == 0)) && attemptnum < 10) {
    41.                         inp = text2data(v.vid);
    42.                         attemptnum++;
    43.                     }
    44.                     if (attemptnum == 10 && _Time.y > 1) {
    45.                         transp = 1;
    46.                         tDelta = 0;
    47.                     }
    48.                 }
    49.  
    50.                 vertdata outp;
    51.                 if (tDelta > (1 / _UpdateRate)) {
    52.                     float4 pos = mul(unity_ObjectToWorld, v.vertex);
    53.                     outp.position = pos.xyz / pos.w;
    54.  
    55.                     float3 mforce = outp.position - inp.position;
    56.                     mforce /= tDelta;
    57.                     mforce *= _ForceMult;
    58.                     float mmult = min(1, MaxForce*MaxForce / (mforce.x*mforce.x + mforce.y*mforce.y + mforce.z*mforce.z));
    59.                     mforce *= mmult;
    60.  
    61.                     float3 totaldisp = mforce;
    62.                     float3 noisecoords = _Time.www / 4 + v.vertex.xyz;
    63.                     float3 noisecoords2 = _Time.www / 4 + v.vertex.xyz * 2;
    64.                     float3 randNums = hash33(_Time.www / 4 + v.vertex.xyz * 16) * 2 + float3(-1, -1, -1);
    65.                     randNums *= randFac;
    66.                     float3 finaldisp;
    67.                     finaldisp.x = totaldisp.x*(1 + NoiseFac * (snoise(noisecoords) + snoise(noisecoords2) * FractFac + randNums.x));
    68.                     finaldisp.y = totaldisp.y*(1 + NoiseFac * (snoise(noisecoords + float3(712, 712, 712)) + snoise(noisecoords2 + float3(712, 712, 712)) * FractFac + randNums.y));
    69.                     finaldisp.z = totaldisp.z*(1 + NoiseFac * (snoise(noisecoords + float3(1916, 1916, 1916)) + snoise(noisecoords2 + float3(1916, 1916, 1916)) * FractFac + randNums.z));
    70.  
    71.                     finaldisp += _Gravity;
    72.                     force = lerp(force, finaldisp, tDelta * _ForceDamp);
    73.                     force *= min(1, _MaxForceFinal*_MaxForceFinal / (force.x*force.x + force.y*force.y + force.z*force.z));
    74.                  
    75.                  
    76.                     outp.force = force;
    77.                     outp.computeTime = _Time.y;
    78.                 }
    79.                 else
    80.                 {
    81.                     outp = inp;
    82.                 }
    83.                 o.vertex = v.vertex;
    84.                 o.vid = v.vid;
    85.                 o.pos = float4(outp.position, outp.computeTime);
    86.                 o.force = float4(outp.force, transp);
    87.                 return o;
    88.             }
    89.             [maxvertexcount(63)]
    90.             void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream)
    91.             {
    92.                 g2f o;
    93.                 for (int i = 0; i < 3; i++) {
    94.                     o.vertex = UnityObjectToClipPos(IN[i].vertex);
    95.                     o.pos = IN[i].pos;
    96.                     o.force = IN[i].force;
    97.                     o.rtype = 0;
    98.                     o.vid = IN[i].vid;
    99.                     triStream.Append(o);
    100.                 }
    101.                 triStream.RestartStrip();
    102.                 float size = offScale * cPlaneSize / cImageSize;
    103.                 for (int h = 0; h < 5; h++) {
    104.                     for (int i = 0; i < 3; i++) {
    105.                         uint tId = h + (IN[i].vid * 5);
    106.                         int x = tId % 512;
    107.                         int y = (int)(tId / 512.0f);
    108.                         float ystart = 0 - (cPlaneSize*offScale / 2) + size * y;
    109.                         float xstart = 0 - (cPlaneSize*offScale / 2) + size * x;
    110.                         float zmult = 0;
    111.                         uint id = tId * 4 + 30000;
    112.                         float diff = size / 2.0f;
    113.                         float4 diffArrayV[4] = {
    114.                             float4(0,size,zmult*0.00390625f,id),
    115.                             float4(size,size,zmult*0.00390625f,id+1),
    116.                             float4(0,0,zmult*0.00390625f,id+2),
    117.                             float4(size,0,zmult*0.00390625f,id + 3)
    118.                         };
    119.                         float4 base = float4(xstart, ystart, 0, 1);
    120.                         o.pos = IN[i].pos;
    121.                         o.force = IN[i].force;
    122.                         o.rtype = h + 1;
    123.                         for (int q = 0; q < 4; q++) {
    124.                             o.vertex = UnityObjectToClipPos(base + float4(diffArrayV[q].xyz + _ToBottomCenter, 0));
    125.                             o.vid = IN[i].vid;
    126.                             triStream.Append(o);
    127.                         }
    128.                         triStream.RestartStrip();
    129.                     }
    130.                 }
    131.             }
    132.             float4 frag(g2f i) : SV_TARGET {
    133.                 float trans = 1 - i.force.w;
    134.                 float4 transm = float4(trans,trans,trans,trans);
    135.                 switch (i.rtype)
    136.                 {
    137.                     case 1:
    138.                         return float4(f2text3p1(i.pos.xyz), 1.0);
    139.                         break;
    140.                     case 2:
    141.                         return float4(f2text3p2(i.pos.xyz), 1.0);
    142.                         break;
    143.                     case 3:
    144.                         return float4(f2text3p1(i.force.xyz), 1.0);
    145.                         break;
    146.                     case 4:
    147.                         return float4(f2text3p2(i.force.xyz), 1.0);
    148.                         break;
    149.                     case 5:
    150.                         vertdata pOutp;
    151.                         pOutp.position = i.pos.xyz;
    152.                         pOutp.force = i.force.xyz;
    153.                         pOutp.computeTime = _Time.y;
    154.                         if (i.pos.w == 0 || all(pOutp.position == 0)) {
    155.                             _PosBuffer[(uint)i.vid] = pOutp;
    156.                         }
    157.                         return float4(f2text(i.pos.w), 0.0, 1.0);
    158.                         break;
    159.                     default:
    160.                         return float4(0.0, 0.0, 0.0, 0.0);
    161.                         break;
    162.                 }
    163.             }