Project

General

Profile

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

library / src / main / res / raw / blit_depth_fragment_shader.glsl @ 78e89fb5

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 vec2 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 + uint(u_Size.x*u_Size.y);
57

    
58
	u_Records[ptr   ] = 0u;
59
    u_Records[ptr+1u] = depth;
60
    u_Records[ptr+2u] = rgba;//(255u<<16u) + (255u);//rgba;
61

    
62
    uint index = uint(ij.x + ij.y * u_Size.x);
63

    
64
    u_Records[index] = ptr;
65
    discard;
66
    }
67
*/
68
  if( ptr<u_numRecords )
69
    {
70
    ptr = 3u*ptr + uint(u_Size.x*u_Size.y);
71

    
72
    u_Records[ptr+1u] = depth;
73
    u_Records[ptr+2u] = rgba;
74

    
75
    memoryBarrier();
76

    
77
    uint prev = uint(ij.x + ij.y * u_Size.x);
78
    uint curr = u_Records[prev];
79

    
80
    while (true)
81
      {
82
      if ( curr==0u || depth > u_Records[curr+1u] )  // need to insert here
83
        {
84
        u_Records[ptr] = curr;     // next of new record is curr
85
        memoryBarrier();
86
        uint res = atomicCompSwap( u_Records[prev], curr, ptr );
87

    
88
        if (res==curr) break;      // done!
89
        else           curr = res; // could not insert! retry from same place in list
90
        }
91
      else                         // advance in list
92
        {
93
        prev = curr;
94
        curr = u_Records[prev];
95
        }
96
      }
97

    
98
    discard;
99
    }
100
  }
101

    
102
//////////////////////////////////////////////////////////////////////////////////////////////
103

    
104
uint convert(vec4 c)
105
  {
106
  return ((uint(255.0*c.r))<<24u) + ((uint(255.0*c.g))<<16u) + ((uint(255.0*c.b))<<8u) + uint(255.0*c.a);
107
  }
108

    
109
//////////////////////////////////////////////////////////////////////////////////////////////
110

    
111
void main()                    		
112
  {
113
  vec4 frag  = texture(u_Texture     , v_TexCoordinate);
114
  float depth= texture(u_DepthTexture, v_TexCoordinate).r;
115

    
116
  if( frag.a > 0.95 )
117
    {
118
    gl_FragDepth = depth;
119
    fragColor    = frag;
120
    }
121
  else if( frag.a > 0.0 )
122
    {
123
    const float S= 2147483647.0; // max signed int. Could probably be max unsigned int but this is enough.
124
    insert(v_Pixel, uint(S*(1.0-depth)/2.0), convert(frag) );
125
    }
126
  else discard;
127
  }
(1-1/9)