Project

General

Profile

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

library / src / main / res / raw / oit_build_fragment_shader.glsl @ 9a3607b3

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 int;
22

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

    
27
uniform sampler2D u_Texture;
28
uniform sampler2D u_DepthTexture;
29

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

    
33
uniform uvec2 u_Size;
34
uniform uint u_numRecords;
35

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

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

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

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

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

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

    
61
    memoryBarrier();
62

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

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

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

    
86
//////////////////////////////////////////////////////////////////////////////////////////////
87

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

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

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

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