Project

General

Profile

« Previous | Next » 

Revision 375b3950

Added by Leszek Koltunski over 6 years ago

OIT: something starts working ('Blur' and 'Multiblur' work, 'Triblur' and 'Transparency' do not)

View differences:

src/main/java/org/distorted/library/main/DistortedEffects.java
70 70

  
71 71
  /// BLIT DEPTH PROGRAM ///
72 72
  private static DistortedProgram mBlitDepthProgram;
73
  private static int mBlitDepthTextureH;
74
  private static int mBlitDepthDepthTextureH;
75
  private static int mBlitDepthDepthH;
76
  private static int mBlitDepthTexCorrH;
73 77
  private static int mBlitDepthSizeH;
78
  private static int mBlitDepthNumRecordsH;
74 79

  
75 80
  private static int[] mLinkedListSSBO = new int[1];
76 81
  private static int[] mAtomicCounter = new int[1];
......
83 88

  
84 89
  private static int mBufferSize=(0x1<<23);  // 8 million entries
85 90

  
86
  private static IntBuffer mIntBuffer;
87

  
88
private static ByteBuffer mBuf, mAtomicBuf;
89
private static IntBuffer mIntBuf, mAtomicIntBuf;
90

  
91 91
  /// BLIT DEPTH RENDER PROGRAM ///
92 92
  private static DistortedProgram mBlitDepthRenderProgram;
93
  private static int mBlitDepthRenderDepthTextureH;
94
  private static int mBlitDepthRenderDepthH;
95
  private static int mBlitDepthRenderTexCorrH;
93 96
  private static int mBlitDepthRenderSizeH;
94 97

  
95 98
  /// NORMAL PROGRAM /////
......
184 187
      }
185 188

  
186 189
    int blitDepthProgramH   = mBlitDepthProgram.getProgramHandle();
190
    mBlitDepthTextureH      = GLES31.glGetUniformLocation( blitDepthProgramH, "u_Texture");
191
    mBlitDepthDepthTextureH = GLES31.glGetUniformLocation( blitDepthProgramH, "u_DepthTexture");
192
    mBlitDepthDepthH        = GLES31.glGetUniformLocation( blitDepthProgramH, "u_Depth");
193
    mBlitDepthTexCorrH      = GLES31.glGetUniformLocation( blitDepthProgramH, "u_TexCorr");
187 194
    mBlitDepthSizeH         = GLES31.glGetUniformLocation( blitDepthProgramH, "u_Size");
188

  
189
    mIntBuffer = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
190
    mIntBuffer.put(0,0);
195
    mBlitDepthNumRecordsH   = GLES31.glGetUniformLocation( blitDepthProgramH, "u_numRecords");
191 196

  
192 197
    if( mLinkedListSSBO[0]<0 )
193 198
      {
......
203 208
      GLES31.glGenBuffers(1,mAtomicCounter,0);
204 209
      GLES31.glBindBufferBase(GLES31.GL_ATOMIC_COUNTER_BUFFER, 0, mAtomicCounter[0]);
205 210
      GLES31.glBindBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER, mAtomicCounter[0] );
206
      GLES31.glBufferData(GLES31.GL_ATOMIC_COUNTER_BUFFER, 4, mIntBuffer, GLES31.GL_DYNAMIC_DRAW);
211
      GLES31.glBufferData(GLES31.GL_ATOMIC_COUNTER_BUFFER, 4, null, GLES31.GL_DYNAMIC_DRAW);
207 212
      GLES31.glBindBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER, 0);
208 213
      }
209 214

  
......
222 227
      }
223 228

  
224 229
    int blitDepthRenderProgramH   = mBlitDepthRenderProgram.getProgramHandle();
230
    mBlitDepthRenderDepthTextureH = GLES31.glGetUniformLocation( blitDepthRenderProgramH, "u_DepthTexture");
231
    mBlitDepthRenderDepthH        = GLES31.glGetUniformLocation( blitDepthRenderProgramH, "u_Depth");
232
    mBlitDepthRenderTexCorrH      = GLES31.glGetUniformLocation( blitDepthRenderProgramH, "u_TexCorr");
225 233
    mBlitDepthRenderSizeH         = GLES31.glGetUniformLocation( blitDepthRenderProgramH, "u_Size");
226 234

  
227 235
    // NORMAL PROGRAM //////////////////////////////////////
......
377 385
    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
378 386
    }
379 387

  
388
///////////////////////////////////////////////////////////////////////////////////////////////////
389
// reset atomic counter to 0
390

  
391
  static void zeroOutAtomic()
392
    {
393
    GLES31.glBindBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER, mAtomicCounter[0] );
394

  
395
    ByteBuffer atomicBuf = (ByteBuffer)GLES31.glMapBufferRange( GLES31.GL_ATOMIC_COUNTER_BUFFER, 0, 4,
396
                                                                GLES31.GL_MAP_READ_BIT|GLES31.GL_MAP_WRITE_BIT);
397
    if( atomicBuf!=null )
398
      {
399
      IntBuffer atomicIntBuf = atomicBuf.order(ByteOrder.nativeOrder()).asIntBuffer();
400

  
401
      int counter = atomicIntBuf.get(0);
402
      atomicIntBuf.put(0, 0);
403
      //android.util.Log.e("counter", "now = "+counter+" w="+surface.mWidth+" h="+surface.mHeight
404
      //                             +" diff="+(counter-surface.mWidth*surface.mHeight));
405
      }
406
    else
407
      {
408
      android.util.Log.e("counter", "failed to map buffer");
409
      }
410

  
411
    GLES31.glUnmapBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER);
412
    GLES31.glBindBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER, 0);
413
    }
414

  
380 415
///////////////////////////////////////////////////////////////////////////////////////////////////
381 416

  
382 417
  static void blitDepthPriv(DistortedOutputSurface surface, float corrW, float corrH)
......
384 419
    mBlitDepthProgram.useProgram();
385 420

  
386 421
    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
422
    GLES31.glUniform1i(mBlitDepthTextureH, 0);
423
    GLES31.glUniform1i(mBlitDepthDepthTextureH, 1);
424
    GLES31.glUniform2f(mBlitDepthTexCorrH, corrW, corrH );
387 425
    GLES31.glUniform2f(mBlitDepthSizeH, surface.mWidth, surface.mHeight);
426
    GLES31.glUniform1ui(mBlitDepthNumRecordsH, (mBufferSize-surface.mWidth*surface.mHeight)/3 );  // see the fragment shader
427
    GLES31.glUniform1f(mBlitDepthDepthH , 1.0f-surface.mNear);
388 428
    GLES31.glVertexAttribPointer(mBlitDepthProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
389 429
    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
390 430
    }
......
400 440
    //analyzeBuffer(surface.mWidth, surface.mHeight);
401 441

  
402 442
    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
443
    GLES31.glUniform1i(mBlitDepthRenderDepthTextureH, 1);
444
    GLES31.glUniform2f(mBlitDepthRenderTexCorrH, corrW, corrH );
403 445
    GLES31.glUniform2f(mBlitDepthRenderSizeH, surface.mWidth, surface.mHeight);
446
    GLES31.glUniform1f( mBlitDepthRenderDepthH , 1.0f-surface.mNear);
404 447
    GLES31.glVertexAttribPointer(mBlitDepthRenderProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
405 448
    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
406

  
407
    // reset atomic counter to 0
408
    GLES31.glBindBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER, mAtomicCounter[0] );
409

  
410
    mAtomicBuf = (ByteBuffer)GLES31.glMapBufferRange( GLES31.GL_ATOMIC_COUNTER_BUFFER, 0, 4,
411
                                                      GLES31.GL_MAP_READ_BIT|GLES31.GL_MAP_WRITE_BIT);
412
    if( mAtomicBuf!=null )
413
      {
414
      mAtomicIntBuf = mAtomicBuf.order(ByteOrder.nativeOrder()).asIntBuffer();
415

  
416
      int counter = mAtomicIntBuf.get(0);
417
      mAtomicIntBuf.put(0, 0);
418
      //android.util.Log.e("counter", "now = "+counter+" w="+surface.mWidth+" h="+surface.mHeight
419
      //                             +" diff="+(counter-surface.mWidth*surface.mHeight));
420
      }
421
    else
422
      {
423
      android.util.Log.e("counter", "failed to map buffer");
424
      }
425

  
426
    GLES31.glUnmapBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER);
427
    GLES31.glBindBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER, 0);
428 449
    }
429 450

  
430 451
///////////////////////////////////////////////////////////////////////////////////////////////////
......
435 456
    int errors = 0;
436 457

  
437 458
    GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, mLinkedListSSBO[0]);
438
    mBuf = (ByteBuffer)GLES31.glMapBufferRange(GLES31.GL_SHADER_STORAGE_BUFFER, 0, mBufferSize*4, GLES31.GL_MAP_READ_BIT);
439
    mIntBuf = mBuf.order(ByteOrder.nativeOrder()).asIntBuffer();
459
    ByteBuffer buf = (ByteBuffer)GLES31.glMapBufferRange(GLES31.GL_SHADER_STORAGE_BUFFER, 0, mBufferSize*4, GLES31.GL_MAP_READ_BIT);
460
    IntBuffer intBuf = buf.order(ByteOrder.nativeOrder()).asIntBuffer();
440 461

  
441 462
    for(int col=0; col<w; col++)
442 463
      for(int row=0; row<h; row++)
443 464
        {
444 465
        index = col+row*w;
445
        ptr = mIntBuf.get(index);
466
        ptr = intBuf.get(index);
446 467

  
447 468
        if( ptr!=0 )
448 469
          {
449 470
          if( ptr>0 && ptr<mBufferSize )
450 471
            {
451
            ptr = mIntBuf.get(ptr);
472
            ptr = intBuf.get(ptr);
452 473
            if( ptr != index )
453 474
              {
454 475
              android.util.Log.d("surface", "col="+col+" row="+row+" val="+ptr+" expected: "+index);
src/main/java/org/distorted/library/main/DistortedOutputSurface.java
353 353

  
354 354
        if( lastBucket!=currBucket )
355 355
          {
356
          if( lastBucket!=0 )
356
          if( lastBucket==0 )
357
            {
358
            DistortedEffects.zeroOutAtomic();
359
            }
360
          else
357 361
            {
358 362
            for(int j=bucketChange; j<i; j++)
359 363
              {
......
386 390
          numRenders += currQueue.postprocess(mBuffer);
387 391
          numRenders += blitWithDepth(time, mBuffer[quality]);
388 392
          GLES31.glMemoryBarrier(GLES31.GL_ALL_BARRIER_BITS);
389
          //GLES31.glFinish();
390 393
          numRenders += blitWithDepthRender(time,mBuffer[quality]);  // merge the OIT linked list
391 394
          clearBuffer(mBuffer[quality]);
392
          //GLES31.glFinish();
393 395
          }
394 396
        }
395 397

  
src/main/res/raw/blit_depth_fragment_shader.glsl
22 22

  
23 23
out vec4 fragColor;
24 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.
25 32

  
26 33
uniform vec2 u_Size;
34
uniform uint u_numRecords;
27 35

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

  
30
layout (std430,binding=1) buffer linkedlist
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)
31 105
  {
32
  uint u_Records[];
33
  };
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
  }
34 108

  
35 109
//////////////////////////////////////////////////////////////////////////////////////////////
36 110

  
37 111
void main()                    		
38 112
  {
39
  uint pixelX = uint(v_TexCoordinate.x * u_Size.x);
40
  uint pixelY = uint(v_TexCoordinate.y * u_Size.y);
41
  uint index  = pixelX + pixelY * uint(u_Size.x);
42

  
43
  uint ptr = uint(u_Size.x*u_Size.y) + atomicCounterIncrement(u_Counter);
44
  u_Records[ptr  ] = index;
45
  u_Records[index] = ptr;
46
  discard;
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
    }
47 126
  }
src/main/res/raw/blit_depth_render_fragment_shader.glsl
20 20
precision highp float;
21 21
precision highp int;
22 22

  
23
out vec4 fragColor;
24
in vec2 v_TexCoordinate;
23
out vec4 fragColor;           // The output color
24
in vec2 v_TexCoordinate;      // Interpolated texture coordinate per fragment.
25
in vec2 v_Pixel;              // location of the current fragment, in pixels
26

  
27
uniform sampler2D u_DepthTexture;
28

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

  
26 32
uniform vec2 u_Size;
27 33

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

  
40
//////////////////////////////////////////////////////////////////////////////////////////////
41

  
42
vec4 convert(uint rgba)
29 43
  {
30
  uint u_Records[];
31
  };
44
  return vec4( float((rgba>>24u)&255u),float((rgba>>16u)&255u),float((rgba>>8u)&255u),float(rgba&255u) ) / 255.0;
45
  }
46

  
47
//////////////////////////////////////////////////////////////////////////////////////////////
48
// https://en.wikipedia.org/wiki/Alpha_compositing (premultiplied)
49

  
50
vec4 blend(vec4 clr,vec4 srf)
51
  {
52
  return clr + (1.0 - clr.a) * vec4(srf.rgb * srf.a , srf.a);
53
  }
32 54

  
33 55
//////////////////////////////////////////////////////////////////////////////////////////////
34 56

  
35 57
void main()                    		
36 58
  {
37
  uint pixelX = uint(v_TexCoordinate.x * u_Size.x);
38
  uint pixelY = uint(v_TexCoordinate.y * u_Size.y);
39
  uint index  = pixelX + pixelY * uint(u_Size.x);
59
  uint index = uint(v_Pixel.x + v_Pixel.y * u_Size.x);
60
  uint curr = u_Records[index];
61

  
62
  if (curr == 0u) discard;
63

  
64
  vec4 color= vec4(0.0,0.0,0.0,0.0);
65
  u_Records[index] = 0u;
40 66

  
41
  uint ptr = u_Records[index];
42
  uint color = u_Records[ptr];
43
  //u_Records[ptr] = 0u;
67
  while (curr > 0u)
68
    {
69
    color= blend( color, convert(u_Records[curr+2u]) );  // keep walking the linked list
70
    curr = u_Records[curr];                              // and blending the colors in
71
    }
44 72

  
45
  if( color==index ) fragColor = vec4(0.0,1.0,0.0,1.0);
46
  else               fragColor = vec4(1.0,0.0,0.0,1.0);
73
  gl_FragDepth = texture(u_DepthTexture, v_TexCoordinate).r;
74
  fragColor    = color;
47 75
  }
src/main/res/raw/blit_depth_vertex_shader.glsl
20 20
precision highp float;
21 21
precision highp int;
22 22

  
23
in vec2 a_Position;
24
out vec2 v_TexCoordinate;
23
in vec2 a_Position;           // Per-vertex position.
24
out vec2 v_TexCoordinate;     //
25
out vec2 v_Pixel;             //
26

  
27
uniform float u_Depth;        // distance from the near plane to render plane, in clip coords
28
uniform vec2  u_TexCorr;      // when we blit from postprocessing buffers, the buffers can be
29
                              // larger than necessary (there is just one static set being
30
                              // reused!) so we need to compensate here by adjusting the texture
31
                              // coords.
32

  
33
uniform vec2 u_Size;         // size of the output surface, in pixels.
25 34

  
26 35
//////////////////////////////////////////////////////////////////////////////////////////////
27 36

  
28 37
void main()
29 38
  {
30
  v_TexCoordinate = a_Position + 0.5;
31
  gl_Position     = vec4(2.0*a_Position,1.0,1.0);
39
  v_TexCoordinate = (a_Position + 0.5) * u_TexCorr;
40
  v_Pixel         = v_TexCoordinate * u_Size;
41
  gl_Position     = vec4(2.0*a_Position,u_Depth,1.0);
32 42
  }

Also available in: Unified diff