Project

General

Profile

« Previous | Next » 

Revision 33f59f22

Added by Leszek Koltunski almost 6 years ago

OIT: move towards 4 passes ( clear - build - collapse - render )

View differences:

src/main/java/org/distorted/library/main/DistortedEffects.java
68 68
    mQuadPositions.put(positionData).position(0);
69 69
    }
70 70

  
71
  /// OIT SSBO BUFFER ///
72
  private static int[] mLinkedListSSBO = new int[1];
73
  private static int[] mAtomicCounter = new int[1];
74

  
75
  static
76
    {
77
    mLinkedListSSBO[0]= -1;
78
    mAtomicCounter[0] = -1;
79
    }
80

  
81
  private static int mBufferSize=(0x1<<23);  // 8 million entries
82

  
71 83
  /// OIT CLEAR PROGRAM ///
72 84
  private static DistortedProgram mOITClearProgram;
73 85
  private static int mOITClearDepthH;
......
83 95
  private static int mOITBuildSizeH;
84 96
  private static int mOITBuildNumRecordsH;
85 97

  
86
  private static int[] mLinkedListSSBO = new int[1];
87
  private static int[] mAtomicCounter = new int[1];
88

  
89
  static
90
    {
91
    mLinkedListSSBO[0]= -1;
92
    mAtomicCounter[0] = -1;
93
    }
94

  
95
  private static int mBufferSize=(0x1<<23);  // 8 million entries
98
  /// OIT COLLAPSE PROGRAM ///
99
  private static DistortedProgram mOITCollapseProgram;
100
  private static int mOITCollapseDepthTextureH;
101
  private static int mOITCollapseDepthH;
102
  private static int mOITCollapseTexCorrH;
103
  private static int mOITCollapseSizeH;
96 104

  
97 105
  /// OIT RENDER PROGRAM ///
98 106
  private static DistortedProgram mOITRenderProgram;
99
  private static int mOITRenderTextureH;
100
  private static int mOITRenderDepthTextureH;
101 107
  private static int mOITRenderDepthH;
102 108
  private static int mOITRenderTexCorrH;
103 109
  private static int mOITRenderSizeH;
......
235 241
      GLES31.glBindBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER, 0);
236 242
      }
237 243

  
238
    // BLIT DEPTH RENDER PROGRAM ///////////////////////////
244
    // OIT COLLAPSE PROGRAM ///////////////////////////
245
    final InputStream oitCollapseVertStream = resources.openRawResource(R.raw.oit_vertex_shader);
246
    final InputStream oitCollapseFragStream = resources.openRawResource(R.raw.oit_collapse_fragment_shader);
247

  
248
    try
249
      {
250
      mOITCollapseProgram = new DistortedProgram(oitCollapseVertStream,oitCollapseFragStream,Distorted.GLSL_VERSION,Distorted.GLSL_VERSION, Distorted.GLSL);
251
      }
252
    catch(Exception e)
253
      {
254
      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile OIT COLLAPSE program: "+e.getMessage());
255
      throw new RuntimeException(e.getMessage());
256
      }
257

  
258
    int oitCollapseProgramH   = mOITCollapseProgram.getProgramHandle();
259
    mOITCollapseDepthTextureH = GLES31.glGetUniformLocation( oitCollapseProgramH, "u_DepthTexture");
260
    mOITCollapseDepthH        = GLES31.glGetUniformLocation( oitCollapseProgramH, "u_Depth");
261
    mOITCollapseTexCorrH      = GLES31.glGetUniformLocation( oitCollapseProgramH, "u_TexCorr");
262
    mOITCollapseSizeH         = GLES31.glGetUniformLocation( oitCollapseProgramH, "u_Size");
263

  
264
    // OIT RENDER PROGRAM ///////////////////////////
239 265
    final InputStream oitRenderVertStream = resources.openRawResource(R.raw.oit_vertex_shader);
240 266
    final InputStream oitRenderFragStream = resources.openRawResource(R.raw.oit_render_fragment_shader);
241 267

  
......
250 276
      }
251 277

  
252 278
    int oitRenderProgramH   = mOITRenderProgram.getProgramHandle();
253
    mOITRenderTextureH      = GLES31.glGetUniformLocation( oitRenderProgramH, "u_Texture");
254
    mOITRenderDepthTextureH = GLES31.glGetUniformLocation( oitRenderProgramH, "u_DepthTexture");
255 279
    mOITRenderDepthH        = GLES31.glGetUniformLocation( oitRenderProgramH, "u_Depth");
256 280
    mOITRenderTexCorrH      = GLES31.glGetUniformLocation( oitRenderProgramH, "u_TexCorr");
257 281
    mOITRenderSizeH         = GLES31.glGetUniformLocation( oitRenderProgramH, "u_Size");
......
470 494
    }
471 495

  
472 496
///////////////////////////////////////////////////////////////////////////////////////////////////
473
// Pass3 of the OIT algorithm. Render all the transparent pixels from the per-pixel linked lists.
497
// Pass3 of the OIT algorithm. Cut occluded parts of the linked list.
498

  
499
  static void oitCollapse(DistortedOutputSurface surface, float corrW, float corrH)
500
    {
501
    mOITCollapseProgram.useProgram();
502

  
503
    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
504
    GLES31.glUniform1i(mOITCollapseDepthTextureH, 1);
505
    GLES31.glUniform2f(mOITCollapseTexCorrH, corrW, corrH );
506
    GLES31.glUniform2f(mOITCollapseSizeH, surface.mWidth, surface.mHeight);
507
    GLES31.glUniform1f( mOITCollapseDepthH , 1.0f-surface.mNear);
508
    GLES31.glVertexAttribPointer(mOITCollapseProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
509
    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
510
    }
511

  
512
///////////////////////////////////////////////////////////////////////////////////////////////////
513
// Pass4 of the OIT algorithm. Render all the transparent pixels from the per-pixel linked lists.
474 514

  
475 515
  static void oitRender(DistortedOutputSurface surface, float corrW, float corrH)
476 516
    {
477 517
    mOITRenderProgram.useProgram();
478 518

  
479
    //analyzeBuffer(surface.mWidth, surface.mHeight);
480

  
481 519
    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
482
    GLES31.glUniform1i(mOITRenderTextureH, 0);
483
    GLES31.glUniform1i(mOITRenderDepthTextureH, 1);
484 520
    GLES31.glUniform2f(mOITRenderTexCorrH, corrW, corrH );
485 521
    GLES31.glUniform2f(mOITRenderSizeH, surface.mWidth, surface.mHeight);
486 522
    GLES31.glUniform1f( mOITRenderDepthH , 1.0f-surface.mNear);
src/main/java/org/distorted/library/main/DistortedOutputSurface.java
71 71

  
72 72
  // Global buffers used for postprocessing.
73 73
  private static DistortedOutputSurface[] mBuffer = new DistortedOutputSurface[EffectQuality.LENGTH];
74
  private static DistortedOutputSurface   mBufferOIT;
75 74

  
76 75
  private long mTime;
77 76
  private float mFOV;
......
211 210
      {
212 211
      mBuffer[j] = null;
213 212
      }
214

  
215
    mBufferOIT = null;
216 213
    }
217 214

  
218 215
///////////////////////////////////////////////////////////////////////////////////////////////////
......
259 256

  
260 257
  private static void oitClear(DistortedOutputSurface buffer)
261 258
    {
262
    if( mBufferOIT==null )
263
      {
264
      mBufferOIT = new DistortedFramebuffer(1, BOTH_DEPTH_STENCIL, TYPE_SYST, buffer.mWidth, buffer.mHeight);
265
      mBufferOIT.mMipmap = 1.0f;
266
      mBufferOIT.mNear = buffer.mNear;  // copy mNear as well (for blitting- see PostprocessEffect.apply() )
267
      mBufferOIT.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
268

  
269
      DistortedObject.toDo(); // create the FBOs immediately. This is safe as we must be holding the OpenGL context now.
270
      }
271

  
272
    if( mBufferOIT.mWidth != buffer.mWidth || mBufferOIT.mHeight != buffer.mHeight )
273
      {
274
      mBufferOIT.mWidth  = (int)(buffer.mWidth *mBufferOIT.mMipmap);
275
      mBufferOIT.mHeight = (int)(buffer.mHeight*mBufferOIT.mMipmap);
276

  
277
      mBufferOIT.mNear   = buffer.mNear;  // Near plane is independent of the mipmap level
278

  
279
      //android.util.Log.e("surface", "viewport "+i+" to ("+from.mWidth+"x"+from.mHeight+")");
280

  
281
      mBufferOIT.createProjection();
282

  
283
      int maxw = mBufferOIT.mWidth  > mBufferOIT.mRealWidth  ? mBufferOIT.mWidth  : mBufferOIT.mRealWidth;
284
      int maxh = mBufferOIT.mHeight > mBufferOIT.mRealHeight ? mBufferOIT.mHeight : mBufferOIT.mRealHeight;
285

  
286
      if (maxw > mBufferOIT.mRealWidth || maxh > mBufferOIT.mRealHeight)
287
        {
288
        mBufferOIT.mRealWidth = maxw;
289
        mBufferOIT.mRealHeight = maxh;
290

  
291
        mBufferOIT.recreate();
292
        mBufferOIT.create();
293
        }
294
      }
295

  
296
    if( mBufferOIT.mNear != buffer.mNear || mBufferOIT.mFOV != buffer.mFOV )
297
      {
298
      mBufferOIT.mNear = buffer.mNear;
299
      mBufferOIT.mFOV  = buffer.mFOV;
300
      mBufferOIT.createProjection();
301
      }
302

  
303
    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mBufferOIT.mFBOH[0]);
304
    DistortedRenderState.colorDepthStencilOn();
305
    GLES31.glClearColor(buffer.mClearR, buffer.mClearG, buffer.mClearB, buffer.mClearA);
306
    GLES31.glClearDepthf(buffer.mClearDepth);
307
    GLES31.glClearStencil(buffer.mClearStencil);
308
    GLES31.glClear(buffer.mClear);
309
    DistortedRenderState.colorDepthStencilRestore();
310

  
311 259
    DistortedEffects.zeroOutAtomic();
312 260
    DistortedEffects.oitClear(buffer);
313

  
314 261
    GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT|GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
315 262
    }
316 263

  
......
344 291
    }
345 292

  
346 293
///////////////////////////////////////////////////////////////////////////////////////////////////
294
// two phases: 1. collapse the SSBO 2. blend the ssbo's color
347 295

  
348 296
  private int oitRender(long currTime, DistortedOutputSurface buffer)
349 297
    {
350
    if( buffer==this )
351
      {
352
      android.util.Log.e("surface", "feedback loop in oitRender!");
353
      return 0;
354
      }
298
    float corrW = buffer.getWidthCorrection();
299
    float corrH = buffer.getHeightCorrection();
355 300

  
356 301
    GLES31.glViewport(0, 0, mWidth, mHeight);
357 302
    setAsOutput(currTime);
358
    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
359
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[0]);
360 303
    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
361 304
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mDepthStencilH[0]);
362 305

  
363
    DistortedRenderState.disableStencil();
364
    DistortedEffects.oitRender(this, buffer.getWidthCorrection(), buffer.getHeightCorrection() );
365
    DistortedRenderState.restoreStencil();
306
    DistortedRenderState.switchOffColorDepthStencil();
307
    DistortedEffects.oitCollapse(this, corrW, corrH );
366 308

  
367 309
    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
368 310
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
369 311

  
312
    DistortedRenderState.switchColorDepthOnStencilOff();
313
    DistortedEffects.oitRender(this, corrW, corrH);
314
    DistortedRenderState.restoreColorDepthStencil();
315

  
370 316
    return 1;
371 317
    }
372 318

  
......
414 360
    int quality=0, internalQuality = 0, numRenders = 0, bucketChange = 0;
415 361
    DistortedNode child1, child2;
416 362
    EffectQueuePostprocess lastQueue=null, currQueue;
417
    long lastBucket=0, currBucket=0;
363
    long lastBucket=0, currBucket;
418 364

  
419 365
    oitClear(this);
420 366

  
......
426 372

  
427 373
      if( currBucket==0 )
428 374
        {
429
        GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mBufferOIT.mFBOH[0]);
430
        numRenders += child1.draw(time, mBufferOIT);
375
        GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
376
        numRenders += child1.draw(time, this);
431 377

  
432 378
        //setAsOutput(time);
433 379
        //numRenders += child1.draw(time,this);
......
451 397
              }
452 398

  
453 399
            numRenders += lastQueue.postprocess(mBuffer);
454
            numRenders += mBufferOIT.oitBuild(mBuffer[quality]);
400
            numRenders += oitBuild(mBuffer[quality]);
455 401
            clearBuffer(mBuffer[quality]);
456 402
            }
457 403

  
......
472 418
            }
473 419

  
474 420
          numRenders += currQueue.postprocess(mBuffer);
475
          numRenders += mBufferOIT.oitBuild(mBuffer[quality]);
421
          numRenders += oitBuild(mBuffer[quality]);
476 422
          GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT);
477
          numRenders += oitRender(time,mBufferOIT);  // merge the OIT linked list
423
          numRenders += oitRender(time,this);  // merge the OIT linked list
478 424
          clearBuffer(mBuffer[quality]);
479 425
          }
480 426
        } // end else (postprocessed child)
......
483 429
      lastBucket= currBucket;
484 430
      } // end main for loop
485 431

  
486
    if( currBucket==0 ) // there was no postprocessing - we need to merge the main buffer
487
      {
488
      numRenders += oitRender(time,mBufferOIT);
489
      }
490

  
491 432
    return numRenders;
492 433
    }
493 434

  
src/main/java/org/distorted/library/main/DistortedRenderState.java
231 231
    GLES31.glDisable(GLES31.GL_SCISSOR_TEST);
232 232
    }
233 233

  
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235

  
236
  static void switchOffColorDepthStencil()
237
    {
238
    sState.stencilTest = cState.stencilTest;
239

  
240
    if( cState.stencilTest!=0 )
241
      {
242
      cState.stencilTest = 0;
243
      //android.util.Log.d("State", "stencil test off");
244
      GLES31.glDisable(GLES31.GL_STENCIL_TEST);
245
      }
246

  
247
    sState.depthTest = cState.depthTest;
248

  
249
    if( cState.depthTest!=0 )
250
      {
251
      cState.depthTest = 0;
252
      //android.util.Log.d("State", "depth test off");
253
      GLES31.glDisable(GLES31.GL_DEPTH_TEST);
254
      }
255

  
256
    sState.colorMaskR = cState.colorMaskR;
257
    sState.colorMaskG = cState.colorMaskG;
258
    sState.colorMaskB = cState.colorMaskB;
259
    sState.colorMaskA = cState.colorMaskA;
260

  
261
    if( cState.colorMaskR!=0 || cState.colorMaskG!=0 || cState.colorMaskB!=0 || cState.colorMaskA!=0 )
262
      {
263
      cState.colorMaskR = 0;
264
      cState.colorMaskG = 0;
265
      cState.colorMaskB = 0;
266
      cState.colorMaskA = 0;
267
      //android.util.Log.d("State", "switch off color writing");
268
      GLES31.glColorMask(false,false,false,false);
269
      }
270

  
271
    sState.depthMask = cState.depthMask;
272

  
273
    if( cState.depthMask!=0 )
274
      {
275
      cState.depthMask = 0;
276
      //android.util.Log.d("State", "switch off depth writing");
277
      GLES31.glDepthMask(false);
278
      }
279

  
280
    sState.stencilMask = cState.stencilMask;
281

  
282
    if( cState.stencilMask!= 0x00 )
283
      {
284
      cState.stencilMask = 0x00;
285
      //android.util.Log.d("State", "stencil mask off");
286
      GLES31.glStencilMask(cState.stencilMask);
287
      }
288
    }
289

  
290
///////////////////////////////////////////////////////////////////////////////////////////////////
291

  
292
  static void switchColorDepthOnStencilOff()
293
    {
294
    sState.stencilTest = cState.stencilTest;
295

  
296
    if( cState.stencilTest!=0 )
297
      {
298
      cState.stencilTest = 0;
299
      //android.util.Log.d("State", "stencil test off");
300
      GLES31.glDisable(GLES31.GL_STENCIL_TEST);
301
      }
302

  
303
    sState.depthTest = cState.depthTest;
304

  
305
    if( cState.depthTest!=0 )
306
      {
307
      cState.depthTest = 0;
308
      //android.util.Log.d("State", "depth test off");
309
      GLES31.glDisable(GLES31.GL_DEPTH_TEST);
310
      }
311

  
312
    sState.colorMaskR = cState.colorMaskR;
313
    sState.colorMaskG = cState.colorMaskG;
314
    sState.colorMaskB = cState.colorMaskB;
315
    sState.colorMaskA = cState.colorMaskA;
316

  
317
    if( cState.colorMaskR!=1 || cState.colorMaskG!=1 || cState.colorMaskB!=1 || cState.colorMaskA!=1 )
318
      {
319
      cState.colorMaskR = 1;
320
      cState.colorMaskG = 1;
321
      cState.colorMaskB = 1;
322
      cState.colorMaskA = 1;
323
      //android.util.Log.d("State", "switch on color writing");
324
      GLES31.glColorMask(true,true,true,true);
325
      }
326

  
327
    sState.depthMask = cState.depthMask;
328

  
329
    if( cState.depthMask!=1 )
330
      {
331
      cState.depthMask = 1;
332
      //android.util.Log.d("State", "switch on depth writing");
333
      GLES31.glDepthMask(true);
334
      }
335

  
336
    sState.stencilMask = cState.stencilMask;
337

  
338
    if( cState.stencilMask!= 0x00 )
339
      {
340
      cState.stencilMask = 0x00;
341
      //android.util.Log.d("State", "stencil mask off");
342
      GLES31.glStencilMask(cState.stencilMask);
343
      }
344
    }
345

  
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347

  
348
  static void restoreColorDepthStencil()
349
    {
350
    if( sState.stencilTest!=cState.stencilTest )
351
      {
352
      cState.stencilTest = sState.stencilTest;
353

  
354
      if (cState.stencilTest == 0)
355
        {
356
        GLES31.glDisable(GLES31.GL_STENCIL_TEST);
357
        }
358
      else
359
        {
360
        GLES31.glEnable(GLES31.GL_STENCIL_TEST);
361
        }
362
      }
363
    if( sState.depthTest!=cState.depthTest )
364
      {
365
      cState.depthTest = sState.depthTest;
366

  
367
      if (cState.depthTest == 0)
368
        {
369
        GLES31.glDisable(GLES31.GL_DEPTH_TEST);
370
        }
371
      else
372
        {
373
        GLES31.glEnable(GLES31.GL_DEPTH_TEST);
374
        }
375
      }
376
    if( sState.colorMaskR!=cState.colorMaskR || sState.colorMaskG!=cState.colorMaskG || sState.colorMaskB!=cState.colorMaskB || sState.colorMaskA!=cState.colorMaskA)
377
      {
378
      cState.colorMaskR = sState.colorMaskR;
379
      cState.colorMaskG = sState.colorMaskG;
380
      cState.colorMaskB = sState.colorMaskB;
381
      cState.colorMaskA = sState.colorMaskA;
382
      GLES31.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
383
      }
384
    if( sState.depthMask!=cState.depthMask )
385
      {
386
      cState.depthMask = sState.depthMask;
387
      GLES31.glDepthMask(cState.depthMask==1);
388
      }
389
    if( sState.stencilMask!=cState.stencilMask )
390
      {
391
      cState.stencilMask = sState.stencilMask;
392
      GLES31.glStencilMask(cState.stencilMask);
393
      }
394
    }
395

  
234 396
///////////////////////////////////////////////////////////////////////////////////////////////////
235 397

  
236 398
  static void disableStencil()
src/main/res/raw/oit_collapse_fragment_shader.glsl
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;           // 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.
31

  
32
uniform vec2 u_Size;
33

  
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
// Pass3 of the OIT algorithm - traverse the per-pixel LinkedList and cut occluded fragments.
42

  
43
void main()                    		
44
  {
45
  uint prev = uint(v_Pixel.x + v_Pixel.y * u_Size.x);
46
  uint curr = u_Records[prev];
47

  
48
  if (curr != 0u)
49
    {
50
    const float S= 2147483647.0;
51
    float depth = texture(u_DepthTexture, v_TexCoordinate).r;
52
    uint texdepth = uint(S*(1.0-depth)/2.0);
53
    uint linkedlistdepth = u_Records[curr+1u];
54

  
55
    while( curr != 0u && linkedlistdepth > texdepth )
56
      {
57
      prev = curr;
58
      curr = u_Records[curr];
59
      linkedlistdepth = u_Records[curr+1u];
60
      }
61

  
62
    if( curr != 0u )
63
      {
64
      u_Records[prev] = 0u;
65
      }
66
    }
67
  else discard;
68
  }
src/main/res/raw/oit_render_fragment_shader.glsl
24 24
in vec2 v_TexCoordinate;      // Interpolated texture coordinate per fragment.
25 25
in vec2 v_Pixel;              // location of the current fragment, in pixels
26 26

  
27
uniform sampler2D u_Texture;
28
uniform sampler2D u_DepthTexture;
29

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

  
......
54 51
  }
55 52

  
56 53
//////////////////////////////////////////////////////////////////////////////////////////////
57
// Pass3 of the OIT algorithm - traverse the per-pixel LinkedList and build the final color.
54
// Pass4 of the OIT algorithm - keep traversing the linked list, build the final color and blend it.
58 55

  
59 56
void main()                    		
60 57
  {
61
  float texdepth = texture(u_DepthTexture, v_TexCoordinate).r;
62
  vec4  color    = texture(u_Texture     , v_TexCoordinate);
63
  uint  index    = uint(v_Pixel.x + v_Pixel.y * u_Size.x);
64
  uint  curr     = u_Records[index];
58
  uint prev = uint(v_Pixel.x + v_Pixel.y * u_Size.x);
59
  uint curr = u_Records[prev];
65 60

  
66 61
  if (curr != 0u)
67 62
    {
68 63
    const float S= 2147483647.0;
69
    uint depth = u_Records[curr+1u];
70
    uint texdepthuint = uint(S*(1.0-texdepth)/2.0);
71
    texdepth = 1.0 -2.0*float(depth)/S;
64
    gl_FragDepth = 1.0 - 2.0*float(u_Records[curr+1u])/S;
65
    vec4 color   = convert(u_Records[curr+2u]);
72 66

  
73
    if( depth >= texdepthuint )
67
    while (curr != 0u)
74 68
      {
75
      vec4 clr= convert(u_Records[curr+2u]);
76 69
      curr = u_Records[curr];
77

  
78
      while (curr > 0u)
79
        {
80
        depth= u_Records[curr+1u];                       // keep walking the linked list
81
        if( depth < texdepthuint ) break;                // until we reach scene depth
82
        clr= blend( clr, convert(u_Records[curr+2u]) );  // and blending the colors in
83
        curr = u_Records[curr];
84
        }
85

  
86
      color = blend( clr, color);
70
      color = blend( color , convert(u_Records[curr+2u]) );
87 71
      }
88
    }
89 72

  
90
  gl_FragDepth = texdepth;
91
  fragColor    = color;
73
    fragColor = color;
74
    }
75
  else discard;
92 76
  }

Also available in: Unified diff