Project

General

Profile

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

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

1 7f1735dc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 7170e4eb leszek
21 f89a986e Leszek Koltunski
precision highp float;
22 47511918 Leszek Koltunski
precision highp int;
23 7170e4eb leszek
24 e029600f Leszek Koltunski
out vec4 fragColor;
25
in vec2 v_TexCoordinate;
26 375b3950 Leszek Koltunski
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 7170e4eb leszek
34 344ac0e4 Leszek Koltunski
uniform uvec2 u_Size;
35 375b3950 Leszek Koltunski
uniform uint u_numRecords;
36 7170e4eb leszek
37 e029600f Leszek Koltunski
layout (binding=0, offset=0) uniform atomic_uint u_Counter;
38 f89a986e Leszek Koltunski
39 375b3950 Leszek Koltunski
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 344ac0e4 Leszek Koltunski
    ptr = 3u*ptr + u_Size.x*u_Size.y;
58 375b3950 Leszek Koltunski
59
    u_Records[ptr+1u] = depth;
60
    u_Records[ptr+2u] = rgba;
61
62
    memoryBarrier();
63
64 344ac0e4 Leszek Koltunski
    uint prev = uint(ij.x) + uint(ij.y) * u_Size.x;
65 375b3950 Leszek Koltunski
    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 8777ce17 Leszek Koltunski
  {
91 375b3950 Leszek Koltunski
  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 8777ce17 Leszek Koltunski
94 7170e4eb leszek
//////////////////////////////////////////////////////////////////////////////////////////////
95 56c6ca24 Leszek Koltunski
// Pass2 of the OIT algorithm - build the LinkedList phase.
96 7170e4eb leszek
97
void main()                    		
98
  {
99 c1a38ba3 Leszek Koltunski
  vec4  color= texture(u_Texture     , v_TexCoordinate);
100 375b3950 Leszek Koltunski
  float depth= texture(u_DepthTexture, v_TexCoordinate).r;
101
102 6544040f Leszek Koltunski
  if( color.a > 0.97 )
103 375b3950 Leszek Koltunski
    {
104
    gl_FragDepth = depth;
105 c1a38ba3 Leszek Koltunski
    fragColor    = color;
106 375b3950 Leszek Koltunski
    }
107 56c6ca24 Leszek Koltunski
  else
108 375b3950 Leszek Koltunski
    {
109 c1a38ba3 Leszek Koltunski
    if( color.a > 0.0 )
110 56c6ca24 Leszek Koltunski
      {
111
      const float S= 2147483647.0; // max signed int. Could probably be max unsigned int but this is enough.
112 c1a38ba3 Leszek Koltunski
      insert(v_Pixel, uint(S*(1.0-depth)/2.0), convert(color) );
113 56c6ca24 Leszek Koltunski
      }
114
    discard;
115 375b3950 Leszek Koltunski
    }
116 7170e4eb leszek
  }