Project

General

Profile

Download (4.87 KB) Statistics
| Branch: | Revision:

library / src / main / res / raw / oit_build_fragment_shader.glsl @ 3f12341d

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2018 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

    
21
precision highp float;
22
precision highp int;
23

    
24
out vec4 fragColor;
25
in vec2 v_TexCoordinate;
26
in vec2 v_Pixel;              // location of the current fragment, in pixels
27

    
28
uniform sampler2D u_Texture;
29
uniform sampler2D u_DepthTexture;
30

    
31
//////////////////////////////////////////////////////////////////////////////////////////////
32
// per-pixel linked list. Order Independent Transparency.
33

    
34
uniform uvec2 u_Size;
35
uniform uint u_numRecords;
36

    
37
layout (binding=0, offset=0) uniform atomic_uint u_Counter;
38

    
39
layout (std430,binding=1) buffer linkedlist  // first (u_Size.x*u_Size.y) uints - head pointers,
40
  {                                          // one for each pixel in the Output rectangle.
41
  uint u_Records[];                          //
42
  };                                         // Next 3*u_numRecords uints - actual linked list, i.e.
43
                                             // triplets of (pointer,depth,rgba).
44

    
45
//////////////////////////////////////////////////////////////////////////////////////////////
46
// Concurrent insert to a linked list. Tim Harris, 'pragmatic implementation of non-blocking
47
// linked-lists', 2001.
48
// This arranges fragments by decreasing 'depth', so one would think - from back to front, but
49
// in main() below the depth is mapped with S*(1-depth)/2, so it is really front to back.
50

    
51
void insert( vec2 ij, uint depth, uint rgba )
52
  {
53
  uint ptr = atomicCounterIncrement(u_Counter);
54

    
55
  if( ptr<u_numRecords )
56
    {
57
    ptr = 3u*ptr + u_Size.x*u_Size.y;
58

    
59
    u_Records[ptr+1u] = depth;
60
    u_Records[ptr+2u] = rgba;
61

    
62
    memoryBarrier();
63

    
64
    uint prev = uint(ij.x) + uint(ij.y) * u_Size.x;
65
    uint curr = u_Records[prev];
66

    
67
    while (true)
68
      {
69
      if ( curr==0u || depth > u_Records[curr+1u] )  // need to insert here
70
        {
71
        u_Records[ptr] = curr;     // next of new record is curr
72
        memoryBarrier();
73
        uint res = atomicCompSwap( u_Records[prev], curr, ptr );
74

    
75
        if (res==curr) break;      // done!
76
        else           curr = res; // could not insert! retry from same place in list
77
        }
78
      else                         // advance in list
79
        {
80
        prev = curr;
81
        curr = u_Records[prev];
82
        }
83
      }
84
    }
85
  }
86

    
87
//////////////////////////////////////////////////////////////////////////////////////////////
88

    
89
uint convert(vec4 c)
90
  {
91
  return ((uint(255.0*c.r))<<24u) + ((uint(255.0*c.g))<<16u) + ((uint(255.0*c.b))<<8u) + uint(255.0*c.a);
92
  }
93

    
94
//////////////////////////////////////////////////////////////////////////////////////////////
95
// Pass2 of the OIT algorithm - build the LinkedList phase.
96

    
97
void main()                    		
98
  {
99
  vec4  color= texture(u_Texture     , v_TexCoordinate);
100
  float depth= texture(u_DepthTexture, v_TexCoordinate).r;
101

    
102
  if( color.a > 0.97 )
103
    {
104
    gl_FragDepth = depth;
105
    fragColor    = color;
106
    }
107
  else
108
    {
109
    if( color.a > 0.0 )
110
      {
111
      const float S= 2147483647.0; // max signed int. Could probably be max unsigned int but this is enough.
112
      insert(v_Pixel, uint(S*(1.0-depth)/2.0), convert(color) );
113
      }
114
    discard;
115
    }
116
  }
(9-9/14)