| 
      1
     | 
    
      //////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      2
     | 
    
      // Copyright 2018 Leszek Koltunski                                                          //
 
     | 
  
  
    | 
      3
     | 
    
      //                                                                                          //
 
     | 
  
  
    | 
      4
     | 
    
      // This file is part of Distorted.                                                          //
 
     | 
  
  
    | 
      5
     | 
    
      //                                                                                          //
 
     | 
  
  
    | 
      6
     | 
    
      // Distorted is free software: you can redistribute it and/or modify                        //
 
     | 
  
  
    | 
      7
     | 
    
      // it under the terms of the GNU General Public License as published by                     //
 
     | 
  
  
    | 
      8
     | 
    
      // the Free Software Foundation, either version 2 of the License, or                        //
 
     | 
  
  
    | 
      9
     | 
    
      // (at your option) any later version.                                                      //
 
     | 
  
  
    | 
      10
     | 
    
      //                                                                                          //
 
     | 
  
  
    | 
      11
     | 
    
      // Distorted is distributed in the hope that it will be useful,                             //
 
     | 
  
  
    | 
      12
     | 
    
      // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 
     | 
  
  
    | 
      13
     | 
    
      // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 
     | 
  
  
    | 
      14
     | 
    
      // GNU General Public License for more details.                                             //
 
     | 
  
  
    | 
      15
     | 
    
      //                                                                                          //
 
     | 
  
  
    | 
      16
     | 
    
      // You should have received a copy of the GNU General Public License                        //
 
     | 
  
  
    | 
      17
     | 
    
      // along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
 
     | 
  
  
    | 
      18
     | 
    
      //////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      19
     | 
    
      
 
     | 
  
  
    | 
      20
     | 
    
      precision highp float;
 
     | 
  
  
    | 
      21
     | 
    
      precision highp uint;
 
     | 
  
  
    | 
      22
     | 
    
      
 
     | 
  
  
    | 
      23
     | 
    
      #if __VERSION__ != 100
 
     | 
  
  
    | 
      24
     | 
    
      out vec4 fragColor;           // The output color
 
     | 
  
  
    | 
      25
     | 
    
      in vec2 v_TexCoordinate;      // Interpolated texture coordinate per fragment.
 
     | 
  
  
    | 
      26
     | 
    
      in vec2 v_Pixel;              // location of the current fragment, in pixels
 
     | 
  
  
    | 
      27
     | 
    
      #define TEXTURE texture
 
     | 
  
  
    | 
      28
     | 
    
      #define FRAG_COLOR fragColor
 
     | 
  
  
    | 
      29
     | 
    
      #else
 
     | 
  
  
    | 
      30
     | 
    
      varying vec2 v_TexCoordinate; // Interpolated texture coordinate per fragment.
 
     | 
  
  
    | 
      31
     | 
    
      varying vec2 v_Pixel;         // location of the current fragment, in pixels
 
     | 
  
  
    | 
      32
     | 
    
      #define TEXTURE texture2D
 
     | 
  
  
    | 
      33
     | 
    
      #define FRAG_COLOR gl_FragColor
 
     | 
  
  
    | 
      34
     | 
    
      #endif
 
     | 
  
  
    | 
      35
     | 
    
      
 
     | 
  
  
    | 
      36
     | 
    
      uniform sampler2D u_Texture;
 
     | 
  
  
    | 
      37
     | 
    
      uniform sampler2D u_DepthTexture;
 
     | 
  
  
    | 
      38
     | 
    
      
 
     | 
  
  
    | 
      39
     | 
    
      //////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      40
     | 
    
      // per-pixel linked list. Order Independent Transparency.
 
     | 
  
  
    | 
      41
     | 
    
      
 
     | 
  
  
    | 
      42
     | 
    
      uniform ivec2 u_Size;
 
     | 
  
  
    | 
      43
     | 
    
      uniform uint u_numRecords;
 
     | 
  
  
    | 
      44
     | 
    
      
 
     | 
  
  
    | 
      45
     | 
    
      layout (binding=0, offset=0) uniform atomic_uint u_Counter;  // initialize to 0
 
     | 
  
  
    | 
      46
     | 
    
      
 
     | 
  
  
    | 
      47
     | 
    
      layout (std430,binding=1) buffer linkedlist  // first (u_Size.x*u_Size.y) uints - head pointers,
 
     | 
  
  
    | 
      48
     | 
    
        {                                          // one for each pixel in the Output rectangle.
     | 
  
  
    | 
      49
     | 
    
        uint u_Records[];                          //
 
     | 
  
  
    | 
      50
     | 
    
        };                                         // Next 3*u_numRecords uints - actual linked list, i.e.
 
     | 
  
  
    | 
      51
     | 
    
                                                   // triplets of (pointer,depth,rgba).
 
     | 
  
  
    | 
      52
     | 
    
      
 
     | 
  
  
    | 
      53
     | 
    
      //////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      54
     | 
    
      // Concurrent insert to a linked list. Tim Harris, 'pragmatic implementation of non-blocking
 
     | 
  
  
    | 
      55
     | 
    
      // linked-lists', 2001.
 
     | 
  
  
    | 
      56
     | 
    
      // This arranges fragments by decreasing 'depth', so one would think - from back to front, but
 
     | 
  
  
    | 
      57
     | 
    
      // in main() below the depth is mapped with S*(1-depth)/2, so it is really front to back.
 
     | 
  
  
    | 
      58
     | 
    
      
 
     | 
  
  
    | 
      59
     | 
    
      void insert( vec2 ij, uint depth, uint rgba )
 
     | 
  
  
    | 
      60
     | 
    
        {
     | 
  
  
    | 
      61
     | 
    
        uint ptr = atomicCounterIncrement(u_Counter)-1u;
 
     | 
  
  
    | 
      62
     | 
    
      
 
     | 
  
  
    | 
      63
     | 
    
        if( ptr<u_numRecords )
 
     | 
  
  
    | 
      64
     | 
    
          {/*
     | 
  
  
    | 
      65
     | 
    
          uint color;
 
     | 
  
  
    | 
      66
     | 
    
          vec2 c = vec2(0.0,1.0);
 
     | 
  
  
    | 
      67
     | 
    
      
 
     | 
  
  
    | 
      68
     | 
    
          uint rgb = ((uint(255.0*c.x))<<16u) + uint(255.0*c.y);
 
     | 
  
  
    | 
      69
     | 
    
      
 
     | 
  
  
    | 
      70
     | 
    
               if(  rgb       ==  0u ) color = (255u<<24u) + (255u<<16u) + 255u;
 
     | 
  
  
    | 
      71
     | 
    
          else if( (rgb&255u) ==  0u ) color = (255u<<24u) + 255u;
 
     | 
  
  
    | 
      72
     | 
    
          else if( (rgb&255u) <= 50u ) color = (255u<<16u) + 255u;
 
     | 
  
  
    | 
      73
     | 
    
          else if( (rgb&255u) == 255u) color = (255u<<16u) + (255u<< 8u) + 255u;
 
     | 
  
  
    | 
      74
     | 
    
          else                         color = (255u<< 8u) + 255u;
 
     | 
  
  
    | 
      75
     | 
    
      */
 
     | 
  
  
    | 
      76
     | 
    
      vec4 c= vec4(1.0,1.0,0.0,1.0);
 
     | 
  
  
    | 
      77
     | 
    
      uint color = ((uint(255.0*c.r))<<24u) + ((uint(255.0*c.g))<<16u) + ((uint(255.0*c.b))<<8u) + uint(255.0*c.a);
 
     | 
  
  
    | 
      78
     | 
    
      
 
     | 
  
  
    | 
      79
     | 
    
          ptr = 3u*ptr + uint(u_Size.x*u_Size.y);
 
     | 
  
  
    | 
      80
     | 
    
      
 
     | 
  
  
    | 
      81
     | 
    
          u_Records[ptr   ] = 0u;
 
     | 
  
  
    | 
      82
     | 
    
          u_Records[ptr+1u] = depth;
 
     | 
  
  
    | 
      83
     | 
    
          u_Records[ptr+2u] = rgba;
 
     | 
  
  
    | 
      84
     | 
    
      
 
     | 
  
  
    | 
      85
     | 
    
          uint index = uint(ij.x + ij.y * float(u_Size.x));
 
     | 
  
  
    | 
      86
     | 
    
      
 
     | 
  
  
    | 
      87
     | 
    
          u_Records[index] = ptr;
 
     | 
  
  
    | 
      88
     | 
    
          }
 
     | 
  
  
    | 
      89
     | 
    
      /*
 
     | 
  
  
    | 
      90
     | 
    
        uint ptr = atomicCounterIncrement(u_Counter)-1u;
 
     | 
  
  
    | 
      91
     | 
    
      
 
     | 
  
  
    | 
      92
     | 
    
        if( ptr<u_numRecords )
 
     | 
  
  
    | 
      93
     | 
    
          {
     | 
  
  
    | 
      94
     | 
    
          ptr = 3u*ptr + uint(u_Size.x*u_Size.y);
 
     | 
  
  
    | 
      95
     | 
    
      
 
     | 
  
  
    | 
      96
     | 
    
          u_Records[ptr+1u] = depth;
 
     | 
  
  
    | 
      97
     | 
    
          u_Records[ptr+2u] = rgba;
 
     | 
  
  
    | 
      98
     | 
    
      
 
     | 
  
  
    | 
      99
     | 
    
          memoryBarrier();
 
     | 
  
  
    | 
      100
     | 
    
      
 
     | 
  
  
    | 
      101
     | 
    
          uint prev = uint(ij.x + ij.y * float(u_Size.x));
 
     | 
  
  
    | 
      102
     | 
    
          uint curr = u_Records[prev];
 
     | 
  
  
    | 
      103
     | 
    
      /*
 
     | 
  
  
    | 
      104
     | 
    
          while (true)
 
     | 
  
  
    | 
      105
     | 
    
            {
     | 
  
  
    | 
      106
     | 
    
            if ( curr==0u || depth > u_Records[curr+1u] )  // need to insert here
 
     | 
  
  
    | 
      107
     | 
    
              {
     | 
  
  
    | 
      108
     | 
    
      
 
     | 
  
  
    | 
      109
     | 
    
              u_Records[ptr] = curr; // next of new record is curr
 
     | 
  
  
    | 
      110
     | 
    
              memoryBarrier();
 
     | 
  
  
    | 
      111
     | 
    
              uint res = atomicCompSwap( u_Records[prev], curr, ptr );
 
     | 
  
  
    | 
      112
     | 
    
      /*
 
     | 
  
  
    | 
      113
     | 
    
              if (res==curr) break;      // done!
 
     | 
  
  
    | 
      114
     | 
    
              else           curr = res; // could not insert! retry from same place in list
 
     | 
  
  
    | 
      115
     | 
    
              }
 
     | 
  
  
    | 
      116
     | 
    
            else // advance in list
 
     | 
  
  
    | 
      117
     | 
    
              {
     | 
  
  
    | 
      118
     | 
    
              prev = curr;
 
     | 
  
  
    | 
      119
     | 
    
              curr = u_Records[prev];
 
     | 
  
  
    | 
      120
     | 
    
              }
 
     | 
  
  
    | 
      121
     | 
    
            }
 
     | 
  
  
    | 
      122
     | 
    
      */
 
     | 
  
  
    | 
      123
     | 
    
      //    }
 
     | 
  
  
    | 
      124
     | 
    
      
 
     | 
  
  
    | 
      125
     | 
    
      
 
     | 
  
  
    | 
      126
     | 
    
        }
 
     | 
  
  
    | 
      127
     | 
    
      
 
     | 
  
  
    | 
      128
     | 
    
      //////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      129
     | 
    
      
 
     | 
  
  
    | 
      130
     | 
    
      uint convert(vec4 c)
 
     | 
  
  
    | 
      131
     | 
    
        {
     | 
  
  
    | 
      132
     | 
    
        return ((uint(255.0*c.r))<<24u) + ((uint(255.0*c.g))<<16u) + ((uint(255.0*c.b))<<8u) + uint(255.0*c.a);
 
     | 
  
  
    | 
      133
     | 
    
        }
 
     | 
  
  
    | 
      134
     | 
    
      
 
     | 
  
  
    | 
      135
     | 
    
      //////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      136
     | 
    
      
 
     | 
  
  
    | 
      137
     | 
    
      void main()                    		
 
     | 
  
  
    | 
      138
     | 
    
        {
     | 
  
  
    | 
      139
     | 
    
        vec4 frag  = TEXTURE(u_Texture     , v_TexCoordinate);
 
     | 
  
  
    | 
      140
     | 
    
        float depth= TEXTURE(u_DepthTexture, v_TexCoordinate).r;
 
     | 
  
  
    | 
      141
     | 
    
      
 
     | 
  
  
    | 
      142
     | 
    
        if( frag.a > 0.95 )
 
     | 
  
  
    | 
      143
     | 
    
          {
     | 
  
  
    | 
      144
     | 
    
          gl_FragDepth = depth;
 
     | 
  
  
    | 
      145
     | 
    
          FRAG_COLOR   = frag;
 
     | 
  
  
    | 
      146
     | 
    
          }
 
     | 
  
  
    | 
      147
     | 
    
        else if( frag.a > 0.0 )
 
     | 
  
  
    | 
      148
     | 
    
          {
     | 
  
  
    | 
      149
     | 
    
          const float S= 2147483647.0; // max signed int. Could probably be max unsigned int but this is enough.
 
     | 
  
  
    | 
      150
     | 
    
          insert(v_Pixel, uint(S*(1.0-depth)/2.0), convert(frag) );
 
     | 
  
  
    | 
      151
     | 
    
          discard;
 
     | 
  
  
    | 
      152
     | 
    
          }
 
     | 
  
  
    | 
      153
     | 
    
        }
 
     |