Project

General

Profile

« Previous | Next » 

Revision 56c6ca24

Added by Leszek Koltunski almost 6 years ago

OIT: lots of progress on all fronts. Still a few bugs to solve though!

View differences:

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

  
71
  /// BLIT DEPTH PROGRAM ///
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;
77
  private static int mBlitDepthSizeH;
78
  private static int mBlitDepthNumRecordsH;
71
  /// OIT CLEAR PROGRAM ///
72
  private static DistortedProgram mOITClearProgram;
73
  private static int mOITClearDepthH;
74
  private static int mOITClearTexCorrH;
75
  private static int mOITClearSizeH;
76

  
77
  /// OIT BUILD PROGRAM ///
78
  private static DistortedProgram mOITBuildProgram;
79
  private static int mOITBuildTextureH;
80
  private static int mOITBuildDepthTextureH;
81
  private static int mOITBuildDepthH;
82
  private static int mOITBuildTexCorrH;
83
  private static int mOITBuildSizeH;
84
  private static int mOITBuildNumRecordsH;
79 85

  
80 86
  private static int[] mLinkedListSSBO = new int[1];
81 87
  private static int[] mAtomicCounter = new int[1];
......
88 94

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

  
91
  /// BLIT DEPTH RENDER PROGRAM ///
92
  private static DistortedProgram mBlitDepthRenderProgram;
93
  private static int mBlitDepthRenderDepthTextureH;
94
  private static int mBlitDepthRenderDepthH;
95
  private static int mBlitDepthRenderTexCorrH;
96
  private static int mBlitDepthRenderSizeH;
97
  /// OIT RENDER PROGRAM ///
98
  private static DistortedProgram mOITRenderProgram;
99
  private static int mOITRenderTextureH;
100
  private static int mOITRenderDepthTextureH;
101
  private static int mOITRenderDepthH;
102
  private static int mOITRenderTexCorrH;
103
  private static int mOITRenderSizeH;
97 104

  
98 105
  /// NORMAL PROGRAM /////
99 106
  private static DistortedProgram mNormalProgram;
......
155 162
    final InputStream blitVertStream = resources.openRawResource(R.raw.blit_vertex_shader);
156 163
    final InputStream blitFragStream = resources.openRawResource(R.raw.blit_fragment_shader);
157 164

  
158
    String blitVertHeader= (Distorted.GLSL_VERSION + "#define NUM_VERTEX 0\n"  );
159
    String blitFragHeader= (Distorted.GLSL_VERSION + "#define NUM_FRAGMENT 0\n");
160

  
161 165
    try
162 166
      {
163
      mBlitProgram = new DistortedProgram(blitVertStream,blitFragStream,blitVertHeader,blitFragHeader, Distorted.GLSL);
167
      mBlitProgram = new DistortedProgram(blitVertStream,blitFragStream,Distorted.GLSL_VERSION,Distorted.GLSL_VERSION, Distorted.GLSL);
164 168
      }
165 169
    catch(Exception e)
166 170
      {
......
172 176
    mBlitTextureH  = GLES31.glGetUniformLocation( blitProgramH, "u_Texture");
173 177
    mBlitDepthH    = GLES31.glGetUniformLocation( blitProgramH, "u_Depth");
174 178

  
175
    // BLIT DEPTH PROGRAM ////////////////////////////////////
176
    final InputStream blitDepthVertStream = resources.openRawResource(R.raw.blit_depth_vertex_shader);
177
    final InputStream blitDepthFragStream = resources.openRawResource(R.raw.blit_depth_fragment_shader);
179
    // OIT CLEAR PROGRAM ////////////////////////////////////
180
    final InputStream oitClearVertStream = resources.openRawResource(R.raw.oit_vertex_shader);
181
    final InputStream oitClearFragStream = resources.openRawResource(R.raw.oit_clear_fragment_shader);
178 182

  
179 183
    try
180 184
      {
181
      mBlitDepthProgram = new DistortedProgram(blitDepthVertStream,blitDepthFragStream,blitVertHeader,blitFragHeader, Distorted.GLSL);
185
      mOITClearProgram = new DistortedProgram(oitClearVertStream,oitClearFragStream,Distorted.GLSL_VERSION,Distorted.GLSL_VERSION, Distorted.GLSL);
182 186
      }
183 187
    catch(Exception e)
184 188
      {
185
      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile BLIT DEPTH program: "+e.getMessage());
189
      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile OIT CLEAR program: "+e.getMessage());
186 190
      throw new RuntimeException(e.getMessage());
187 191
      }
188 192

  
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");
194
    mBlitDepthSizeH         = GLES31.glGetUniformLocation( blitDepthProgramH, "u_Size");
195
    mBlitDepthNumRecordsH   = GLES31.glGetUniformLocation( blitDepthProgramH, "u_numRecords");
193
    int oitClearProgramH   = mOITClearProgram.getProgramHandle();
194
    mOITClearDepthH        = GLES31.glGetUniformLocation( oitClearProgramH, "u_Depth");
195
    mOITClearTexCorrH      = GLES31.glGetUniformLocation( oitClearProgramH, "u_TexCorr");
196
    mOITClearSizeH         = GLES31.glGetUniformLocation( oitClearProgramH, "u_Size");
197

  
198
    // OIT BUILD PROGRAM ////////////////////////////////////
199
    final InputStream oitBuildVertStream = resources.openRawResource(R.raw.oit_vertex_shader);
200
    final InputStream oitBuildFragStream = resources.openRawResource(R.raw.oit_build_fragment_shader);
201

  
202
    try
203
      {
204
      mOITBuildProgram = new DistortedProgram(oitBuildVertStream,oitBuildFragStream,Distorted.GLSL_VERSION,Distorted.GLSL_VERSION, Distorted.GLSL);
205
      }
206
    catch(Exception e)
207
      {
208
      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile OIT BUILD program: "+e.getMessage());
209
      throw new RuntimeException(e.getMessage());
210
      }
211

  
212
    int oitBuildProgramH   = mOITBuildProgram.getProgramHandle();
213
    mOITBuildTextureH      = GLES31.glGetUniformLocation( oitBuildProgramH, "u_Texture");
214
    mOITBuildDepthTextureH = GLES31.glGetUniformLocation( oitBuildProgramH, "u_DepthTexture");
215
    mOITBuildDepthH        = GLES31.glGetUniformLocation( oitBuildProgramH, "u_Depth");
216
    mOITBuildTexCorrH      = GLES31.glGetUniformLocation( oitBuildProgramH, "u_TexCorr");
217
    mOITBuildSizeH         = GLES31.glGetUniformLocation( oitBuildProgramH, "u_Size");
218
    mOITBuildNumRecordsH   = GLES31.glGetUniformLocation( oitBuildProgramH, "u_numRecords");
196 219

  
197 220
    if( mLinkedListSSBO[0]<0 )
198 221
      {
......
213 236
      }
214 237

  
215 238
    // BLIT DEPTH RENDER PROGRAM ///////////////////////////
216
    final InputStream blitDepthRenderVertStream = resources.openRawResource(R.raw.blit_depth_vertex_shader);
217
    final InputStream blitDepthRenderFragStream = resources.openRawResource(R.raw.blit_depth_render_fragment_shader);
239
    final InputStream oitRenderVertStream = resources.openRawResource(R.raw.oit_vertex_shader);
240
    final InputStream oitRenderFragStream = resources.openRawResource(R.raw.oit_render_fragment_shader);
218 241

  
219 242
    try
220 243
      {
221
      mBlitDepthRenderProgram = new DistortedProgram(blitDepthRenderVertStream,blitDepthRenderFragStream,blitVertHeader,blitFragHeader, Distorted.GLSL);
244
      mOITRenderProgram = new DistortedProgram(oitRenderVertStream,oitRenderFragStream,Distorted.GLSL_VERSION,Distorted.GLSL_VERSION, Distorted.GLSL);
222 245
      }
223 246
    catch(Exception e)
224 247
      {
225
      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile BLIT DEPTH RENDER program: "+e.getMessage());
248
      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile OIT RENDER program: "+e.getMessage());
226 249
      throw new RuntimeException(e.getMessage());
227 250
      }
228 251

  
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");
233
    mBlitDepthRenderSizeH         = GLES31.glGetUniformLocation( blitDepthRenderProgramH, "u_Size");
252
    int oitRenderProgramH   = mOITRenderProgram.getProgramHandle();
253
    mOITRenderTextureH      = GLES31.glGetUniformLocation( oitRenderProgramH, "u_Texture");
254
    mOITRenderDepthTextureH = GLES31.glGetUniformLocation( oitRenderProgramH, "u_DepthTexture");
255
    mOITRenderDepthH        = GLES31.glGetUniformLocation( oitRenderProgramH, "u_Depth");
256
    mOITRenderTexCorrH      = GLES31.glGetUniformLocation( oitRenderProgramH, "u_TexCorr");
257
    mOITRenderSizeH         = GLES31.glGetUniformLocation( oitRenderProgramH, "u_Size");
234 258

  
235 259
    // NORMAL PROGRAM //////////////////////////////////////
236 260
    final InputStream normalVertexStream   = resources.openRawResource(R.raw.normal_vertex_shader);
......
393 417
    GLES31.glBindBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER, mAtomicCounter[0] );
394 418

  
395 419
    ByteBuffer atomicBuf = (ByteBuffer)GLES31.glMapBufferRange( GLES31.GL_ATOMIC_COUNTER_BUFFER, 0, 4,
396
                                                                GLES31.GL_MAP_READ_BIT|GLES31.GL_MAP_WRITE_BIT);
420
                                                                GLES31.GL_MAP_WRITE_BIT|GLES31.GL_MAP_INVALIDATE_BUFFER_BIT);
397 421
    if( atomicBuf!=null )
398 422
      {
399 423
      IntBuffer atomicIntBuf = atomicBuf.order(ByteOrder.nativeOrder()).asIntBuffer();
......
413 437
    }
414 438

  
415 439
///////////////////////////////////////////////////////////////////////////////////////////////////
440
// Pass1 of the OIT algorithm. Clear per-pixel head-poiners.
441

  
442
  static void oitClear(DistortedOutputSurface surface)
443
    {
444
    mOITClearProgram.useProgram();
445

  
446
    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
447
    GLES31.glUniform2f(mOITClearTexCorrH, 1.0f, 1.0f );   // corrections do not really matter here - only present because of common vertex shader.
448
    GLES31.glUniform1f( mOITClearDepthH , 1.0f);          // likewise depth
449
    GLES31.glUniform2f(mOITClearSizeH, surface.mWidth, surface.mHeight);
450
    GLES31.glVertexAttribPointer(mOITClearProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
451
    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
452
    }
453

  
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455
// Pass2 of the OIT algorithm - build per-pixel linked lists.
416 456

  
417
  static void blitDepth(DistortedOutputSurface surface, float corrW, float corrH)
457
  static void oitBuild(DistortedOutputSurface surface, float corrW, float corrH)
418 458
    {
419
    mBlitDepthProgram.useProgram();
459
    mOITBuildProgram.useProgram();
420 460

  
421 461
    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
422
    GLES31.glUniform1i(mBlitDepthTextureH, 0);
423
    GLES31.glUniform1i(mBlitDepthDepthTextureH, 1);
424
    GLES31.glUniform2f(mBlitDepthTexCorrH, corrW, corrH );
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);
428
    GLES31.glVertexAttribPointer(mBlitDepthProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
462
    GLES31.glUniform1i(mOITBuildTextureH, 0);
463
    GLES31.glUniform1i(mOITBuildDepthTextureH, 1);
464
    GLES31.glUniform2f(mOITBuildTexCorrH, corrW, corrH );
465
    GLES31.glUniform2f(mOITBuildSizeH, surface.mWidth, surface.mHeight);
466
    GLES31.glUniform1ui(mOITBuildNumRecordsH, (mBufferSize-surface.mWidth*surface.mHeight)/3 );  // see the fragment shader
467
    GLES31.glUniform1f(mOITBuildDepthH , 1.0f-surface.mNear);
468
    GLES31.glVertexAttribPointer(mOITBuildProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
429 469
    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
430 470
    }
431 471

  
432 472
///////////////////////////////////////////////////////////////////////////////////////////////////
433
// render all the transparent pixels from the per-pixel linked lists. This is in the 'merge
434
// postprocessing buckets' stage.
473
// Pass3 of the OIT algorithm. Render all the transparent pixels from the per-pixel linked lists.
435 474

  
436
  static void mergeOIT(DistortedOutputSurface surface, float corrW, float corrH)
475
  static void oitRender(DistortedOutputSurface surface, float corrW, float corrH)
437 476
    {
438
    mBlitDepthRenderProgram.useProgram();
477
    mOITRenderProgram.useProgram();
439 478

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

  
442 481
    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
443
    GLES31.glUniform1i(mBlitDepthRenderDepthTextureH, 1);
444
    GLES31.glUniform2f(mBlitDepthRenderTexCorrH, corrW, corrH );
445
    GLES31.glUniform2f(mBlitDepthRenderSizeH, surface.mWidth, surface.mHeight);
446
    GLES31.glUniform1f( mBlitDepthRenderDepthH , 1.0f-surface.mNear);
447
    GLES31.glVertexAttribPointer(mBlitDepthRenderProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
482
    GLES31.glUniform1i(mOITRenderTextureH, 0);
483
    GLES31.glUniform1i(mOITRenderDepthTextureH, 1);
484
    GLES31.glUniform2f(mOITRenderTexCorrH, corrW, corrH );
485
    GLES31.glUniform2f(mOITRenderSizeH, surface.mWidth, surface.mHeight);
486
    GLES31.glUniform1f( mOITRenderDepthH , 1.0f-surface.mNear);
487
    GLES31.glVertexAttribPointer(mOITRenderProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
448 488
    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
449 489
    }
450 490

  
src/main/java/org/distorted/library/main/DistortedNode.java
283 283

  
284 284
    if( input.setAsInput() )
285 285
      {
286
      surface.setAsOutput(currTime);
287 286
      mState.apply();
288 287
      GLES31.glDisable(GLES31.GL_BLEND);
289 288
      mEffects.drawPriv(mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime, 0);
......
303 302

  
304 303
    if( input.setAsInput() )
305 304
      {
306
      surface.setAsOutput(currTime);
307 305
      mState.apply();
308 306
      mEffects.drawPriv(mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime, 0);
309 307
      return 1;
src/main/java/org/distorted/library/main/DistortedOutputSurface.java
78 78

  
79 79
  // Global buffers used for postprocessing.
80 80
  private static DistortedOutputSurface[] mBuffer = new DistortedOutputSurface[EffectQuality.LENGTH];
81
  private static DistortedOutputSurface   mBufferOIT;
81 82

  
82 83
  private long mTime;
83 84
  private float mFOV;
......
184 185

  
185 186
///////////////////////////////////////////////////////////////////////////////////////////////////
186 187

  
187
  private static void createBuffers(int width, int height, float near)
188
  private static void createPostprocessingBuffers(int width, int height, float near)
188 189
    {
189 190
    float mipmap=1.0f;
190 191

  
191
    for(int j=0; j<EffectQuality.LENGTH; j++)
192
    for (int j=0; j<EffectQuality.LENGTH; j++)
192 193
      {
193
      mBuffer[j] = new DistortedFramebuffer(2,BOTH_DEPTH_STENCIL,TYPE_SYST, (int)(width*mipmap), (int)(height*mipmap) );
194
      mBuffer[j] = new DistortedFramebuffer(2, BOTH_DEPTH_STENCIL, TYPE_SYST, (int) (width * mipmap), (int) (height * mipmap));
194 195
      mBuffer[j].mMipmap = mipmap;
195
      mBuffer[j].mNear   = near;  // copy mNear as well (for blitting- see PostprocessEffect.apply() )
196
      mBuffer[j].glClearColor(1.0f,1.0f,1.0f,0.0f);
196
      mBuffer[j].mNear = near;  // copy mNear as well (for blitting- see PostprocessEffect.apply() )
197
      mBuffer[j].glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
197 198

  
198 199
      mipmap *= EffectQuality.MULTIPLIER;
199 200
      }
......
202 203

  
203 204
    GLES31.glStencilMask(0xff);
204 205
    GLES31.glDepthMask(true);
205
    GLES31.glColorMask(true,true,true,true);
206
    GLES31.glClearColor(1.0f,1.0f,1.0f,0.0f);
206
    GLES31.glColorMask(true, true, true, true);
207
    GLES31.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
207 208
    GLES31.glClearDepthf(1.0f);
208 209
    GLES31.glClearStencil(0);
209 210

  
210
    for(int j=0; j<EffectQuality.LENGTH; j++)
211
    for (int j=0; j<EffectQuality.LENGTH; j++)
211 212
      {
212 213
      mBuffer[j].setAsOutput();
213 214
      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[1], 0);
214
      GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT|GLES31.GL_DEPTH_BUFFER_BIT|GLES31.GL_STENCIL_BUFFER_BIT);
215
      GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT | GLES31.GL_DEPTH_BUFFER_BIT | GLES31.GL_STENCIL_BUFFER_BIT);
215 216
      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[0], 0);
216 217
      GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
217 218
      }
218 219
    }
219 220

  
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222

  
223
  private static void initializeOIT(DistortedOutputSurface surface)
224
    {
225
    if( mBufferOIT==null )
226
      {
227
      mBufferOIT = new DistortedFramebuffer(1, BOTH_DEPTH_STENCIL, TYPE_SYST, surface.mWidth, surface.mHeight);
228
      mBufferOIT.mMipmap = 1.0f;
229
      mBufferOIT.mNear = surface.mNear;  // copy mNear as well (for blitting- see PostprocessEffect.apply() )
230
      mBufferOIT.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
231

  
232
      DistortedObject.toDo(); // create the FBOs immediately. This is safe as we must be holding the OpenGL context now.
233

  
234
      mBufferOIT.setAsOutput();
235
      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBufferOIT.mColorH[0], 0);
236
      GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT | GLES31.GL_DEPTH_BUFFER_BIT | GLES31.GL_STENCIL_BUFFER_BIT);
237
      }
238

  
239
    if( mBufferOIT.mWidth != surface.mWidth || mBufferOIT.mHeight != surface.mHeight )
240
      {
241
      mBufferOIT.mWidth  = (int)(surface.mWidth *mBufferOIT.mMipmap);
242
      mBufferOIT.mHeight = (int)(surface.mHeight*mBufferOIT.mMipmap);
243

  
244
      mBufferOIT.mNear   = surface.mNear;  // Near plane is independent of the mipmap level
245

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

  
248
      mBufferOIT.createProjection();
249

  
250
      int maxw = mBufferOIT.mWidth  > mBufferOIT.mRealWidth  ? mBufferOIT.mWidth  : mBufferOIT.mRealWidth;
251
      int maxh = mBufferOIT.mHeight > mBufferOIT.mRealHeight ? mBufferOIT.mHeight : mBufferOIT.mRealHeight;
252

  
253
      if (maxw > mBufferOIT.mRealWidth || maxh > mBufferOIT.mRealHeight)
254
        {
255
        mBufferOIT.mRealWidth = maxw;
256
        mBufferOIT.mRealHeight = maxh;
257

  
258
        mBufferOIT.recreate();
259
        mBufferOIT.create();
260
        }
261
      }
262

  
263
    if( mBufferOIT.mNear != surface.mNear || mBufferOIT.mFOV != surface.mFOV )
264
      {
265
      mBufferOIT.mNear = surface.mNear;
266
      mBufferOIT.mFOV  = surface.mFOV;
267
      mBufferOIT.createProjection();
268
      }
269

  
270
    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mBufferOIT.mFBOH[0]);
271

  
272
    DistortedRenderState.colorDepthStencilOn();
273
    GLES31.glClearColor(surface.mClearR, surface.mClearG, surface.mClearB, surface.mClearA);
274
    GLES31.glClearDepthf(surface.mClearDepth);
275
    GLES31.glClearStencil(surface.mClearStencil);
276
    GLES31.glClear(surface.mClear);
277
    DistortedRenderState.colorDepthStencilRestore();
278

  
279
    DistortedEffects.zeroOutAtomic();
280
    DistortedEffects.oitClear(surface);
281

  
282
    GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT|GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
283
    }
284

  
220 285
///////////////////////////////////////////////////////////////////////////////////////////////////
221 286

  
222 287
  static synchronized void onDestroy()
......
225 290
      {
226 291
      mBuffer[j] = null;
227 292
      }
293

  
294
    mBufferOIT = null;
228 295
    }
229 296

  
230 297
///////////////////////////////////////////////////////////////////////////////////////////////////
......
233 300
// smaller. That takes care of outputting pixels to them. When we use them as input, we have to
234 301
// adjust the texture coords - see the get{Width|Height}Correction functions.
235 302

  
236
  private static void cloneViewport(DistortedOutputSurface from)
303
  private static void clonePostprocessingViewport(DistortedOutputSurface from)
237 304
    {
238
    if( mBuffer[0].mWidth != from.mWidth )
305
    if( mBuffer[0].mWidth != from.mWidth || mBuffer[0].mHeight != from.mHeight )
239 306
      {
240 307
      DistortedOutputSurface surface;
241 308

  
......
269 336

  
270 337
///////////////////////////////////////////////////////////////////////////////////////////////////
271 338

  
272
  private int blitWithDepth(long currTime, DistortedOutputSurface buffer)
339
  private int oitBuild(long currTime, DistortedOutputSurface buffer)
273 340
    {
274 341
    GLES31.glViewport(0, 0, mWidth, mHeight);
275 342
    setAsOutput(currTime);
......
278 345
    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
279 346
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mDepthStencilH[0]);
280 347

  
281
    GLES31.glDisable(GLES31.GL_STENCIL_TEST);
282
    GLES31.glStencilMask(0x00);
348
    //GLES31.glDisable(GLES31.GL_STENCIL_TEST);
349
    //GLES31.glStencilMask(0x00);
350

  
351
    DistortedRenderState.colorDepthStencilOn();
352
    DistortedRenderState.enableDepthTest();
283 353

  
284
    DistortedEffects.blitDepth(this, buffer.getWidthCorrection(), buffer.getHeightCorrection() );
354
    DistortedEffects.oitBuild(this, buffer.getWidthCorrection(), buffer.getHeightCorrection() );
285 355
    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
286 356
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
287 357
    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
288 358
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
289 359

  
360
    DistortedRenderState.colorDepthStencilRestore();
361
    DistortedRenderState.restoreDepthTest();
362

  
290 363
    return 1;
291 364
    }
292 365

  
293 366
///////////////////////////////////////////////////////////////////////////////////////////////////
294 367

  
295
  private int mergeOIT(long currTime, DistortedOutputSurface buffer)
368
  private int oitRender(long currTime, DistortedOutputSurface buffer)
296 369
    {
297 370
    GLES31.glViewport(0, 0, mWidth, mHeight);
298 371
    setAsOutput(currTime);
372
    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
373
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[0]);
299 374
    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
300 375
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mDepthStencilH[0]);
301 376

  
302 377
    DistortedRenderState.enableStencil();
303 378

  
304
    DistortedEffects.mergeOIT(this, buffer.getWidthCorrection(), buffer.getHeightCorrection() );
379
    DistortedEffects.oitRender(this, buffer.getWidthCorrection(), buffer.getHeightCorrection() );
305 380
    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
306 381
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
307 382

  
......
331 406
///////////////////////////////////////////////////////////////////////////////////////////////////
332 407
// Render all children, one by one. If there are no postprocessing effects, just render to THIS.
333 408
// Otherwise, render to a buffer and on each change of Postprocessing Bucket, apply the postprocessing
334
// to a whole buffer (lastQueue.postprocess) and merge it (this.blitWithDepth).
409
// to a whole buffer (lastQueue.postprocess) and merge it (this.oitBuild).
335 410

  
336 411
  int renderChildren(long time, int numChildren, ArrayList<DistortedNode> children)
337 412
    {
338 413
    int quality=0, internalQuality = 0, numRenders = 0, bucketChange = 0;
339 414
    DistortedNode child1, child2;
340 415
    EffectQueuePostprocess lastQueue=null, currQueue;
341
    long lastBucket=0, currBucket;
416
    long lastBucket=0, currBucket=0;
417

  
418
    initializeOIT(this);
342 419

  
343 420
    for(int i=0; i<numChildren; i++)
344 421
      {
......
346 423
      currQueue = child1.getPostprocessQueue();
347 424
      currBucket= currQueue.getID();
348 425

  
349
      if( currBucket==0 ) numRenders += child1.draw(time,this);
426
      if( currBucket==0 )
427
        {
428
        GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mBufferOIT.mFBOH[0]);
429
        numRenders += child1.draw(time, mBufferOIT);
430

  
431
        //setAsOutput(time);
432
        //numRenders += child1.draw(time,this);
433
        }
350 434
      else
351 435
        {
352
        if( mBuffer[0]==null ) createBuffers(mWidth,mHeight,mNear);
436
        if( mBuffer[0]==null ) createPostprocessingBuffers(mWidth,mHeight,mNear);
353 437

  
354 438
        if( lastBucket!=currBucket )
355 439
          {
356 440
          if( lastBucket==0 )
357 441
            {
358
            DistortedEffects.zeroOutAtomic();
442
            clonePostprocessingViewport(this);
359 443
            }
360 444
          else
361 445
            {
......
366 450
              }
367 451

  
368 452
            numRenders += lastQueue.postprocess(mBuffer);
369
            numRenders += blitWithDepth(time, mBuffer[quality]);
453
            numRenders += mBufferOIT.oitBuild(time, mBuffer[quality]);
370 454
            clearBuffer(mBuffer[quality]);
371 455
            }
372 456

  
373 457
          internalQuality = currQueue.getInternalQuality();
374 458
          quality         = currQueue.getQuality();
375 459
          bucketChange    = i;
376

  
377
          cloneViewport(this);
378 460
          }
379 461

  
462
        mBuffer[quality].setAsOutput(time);
380 463
        child1.drawNoBlend(time,mBuffer[quality]);
381 464

  
382 465
        if( i==numChildren-1 )
......
388 471
            }
389 472

  
390 473
          numRenders += currQueue.postprocess(mBuffer);
391
          numRenders += blitWithDepth(time, mBuffer[quality]);
392
          GLES31.glMemoryBarrier(GLES31.GL_ALL_BARRIER_BITS);
393
          numRenders += mergeOIT(time,mBuffer[quality]);  // merge the OIT linked list
474
          numRenders += mBufferOIT.oitBuild(time, mBuffer[quality]);
475
          GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT);
476
          numRenders += oitRender(time,mBufferOIT);  // merge the OIT linked list
394 477
          clearBuffer(mBuffer[quality]);
395 478
          }
396
        }
479
        } // end else (postprocessed child)
397 480

  
398 481
      lastQueue = currQueue;
399 482
      lastBucket= currBucket;
483
      } // end main for loop
484

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

  
402 490
    return numRenders;
......
669 757
      mNear=0.99f;
670 758
      }
671 759

  
672
    if( mBuffer[0]!=null )
673
      {
674
      for(int j=0; j<EffectQuality.LENGTH; j++) mBuffer[j].mNear = mNear;
675
      }
676

  
677 760
    createProjection();
678 761
    }
679 762

  
src/main/java/org/distorted/library/main/DistortedRenderState.java
184 184
      }
185 185
    }
186 186

  
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

  
189
  static void enableDepthTest()
190
    {
191
    sState.depthTest = cState.depthTest;
192

  
193
    if (cState.depthTest != 1)
194
      {
195
      cState.depthTest = 1;
196
      GLES31.glEnable(GLES31.GL_DEPTH_TEST);
197
      }
198
    }
199

  
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201

  
202
  static void restoreDepthTest()
203
    {
204
    if (sState.depthTest != cState.depthTest)
205
      {
206
      cState.depthTest = sState.depthTest;
207

  
208
      if (cState.depthTest == 0)
209
        {
210
        GLES31.glDisable(GLES31.GL_DEPTH_TEST);
211
        }
212
      else
213
        {
214
        GLES31.glEnable(GLES31.GL_DEPTH_TEST);
215
        }
216
      }
217
    }
218

  
187 219
///////////////////////////////////////////////////////////////////////////////////////////////////
188 220

  
189 221
  static void switchOffDrawing()
src/main/res/raw/blit_depth_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;
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
  }
src/main/res/raw/blit_depth_render_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

  
42
vec4 convert(uint rgba)
43
  {
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
  }
54

  
55
//////////////////////////////////////////////////////////////////////////////////////////////
56

  
57
void main()                    		
58
  {
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
  else
64
    {
65
    u_Records[index] = 0u;
66

  
67
    vec4 color= convert(u_Records[curr+2u]);
68
    curr = u_Records[curr];
69

  
70
    while (curr > 0u)
71
      {
72
      color= blend( color, convert(u_Records[curr+2u]) );  // keep walking the linked list
73
      curr = u_Records[curr];                              // and blending the colors in
74
      }
75

  
76
    gl_FragDepth = texture(u_DepthTexture, v_TexCoordinate).r;
77
    fragColor    = color;
78
    }
79
  }
src/main/res/raw/blit_depth_vertex_shader.glsl
1
//////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 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
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.
34

  
35
//////////////////////////////////////////////////////////////////////////////////////////////
36

  
37
void main()
38
  {
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);
42
  }
src/main/res/raw/blit_fragment_shader.glsl
19 19

  
20 20
precision lowp float;
21 21

  
22
#if __VERSION__ != 100
23 22
out vec4 fragColor;           // The output color
24 23
in vec2 v_TexCoordinate;      // Interpolated texture coordinate per fragment.
25
#define TEXTURE texture
26
#define FRAG_COLOR fragColor
27
#else
28
varying vec2 v_TexCoordinate; // Interpolated texture coordinate per fragment.
29
#define TEXTURE texture2D
30
#define FRAG_COLOR gl_FragColor
31
#endif
32

  
33 24
uniform sampler2D u_Texture;  // The input texture.
34 25

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

  
37 28
void main()                    		
38 29
  {
39
  FRAG_COLOR = TEXTURE(u_Texture,v_TexCoordinate);
30
  fragColor = texture(u_Texture,v_TexCoordinate);
40 31
  }
src/main/res/raw/blit_vertex_shader.glsl
19 19

  
20 20
precision lowp float;
21 21

  
22
#if __VERSION__ != 100
23 22
in vec2 a_Position;           // Per-vertex position.
24 23
out vec2 v_TexCoordinate;     //
25
#else
26
attribute vec2 a_Position;    // Per-vertex position.
27
varying vec2 v_TexCoordinate; //
28
#endif
29

  
30 24
uniform float u_Depth;        // distance from the near plane to render plane, in clip coords
31 25

  
32 26
//////////////////////////////////////////////////////////////////////////////////////////////
src/main/res/raw/oit_build_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;
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+1u] = depth;
59
    u_Records[ptr+2u] = rgba;
60

  
61
    memoryBarrier();
62

  
63
    uint prev = uint(ij.x + 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
    discard;
85
    }
86
  }
87

  
88
//////////////////////////////////////////////////////////////////////////////////////////////
89

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

  
95
//////////////////////////////////////////////////////////////////////////////////////////////
96
// Pass2 of the OIT algorithm - build the LinkedList phase.
97

  
98
void main()                    		
99
  {
100
  vec4 frag  = texture(u_Texture     , v_TexCoordinate);
101
  float depth= texture(u_DepthTexture, v_TexCoordinate).r;
102

  
103
  if( frag.a > 0.95 )
104
    {
105
    gl_FragDepth = depth;
106
    fragColor    = frag;
107
    }
108
  else
109
    {
110
    if( frag.a > 0.0 )
111
      {
112
      const float S= 2147483647.0; // max signed int. Could probably be max unsigned int but this is enough.
113
      insert(v_Pixel, uint(S*(1.0-depth)/2.0), convert(frag) );
114
      }
115
    discard;
116
    }
117
  }
src/main/res/raw/oit_clear_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
in vec2 v_TexCoordinate;
24
in vec2 v_Pixel;              // location of the current fragment, in pixels
25

  
26
//////////////////////////////////////////////////////////////////////////////////////////////
27
// per-pixel linked list. Order Independent Transparency.
28

  
29
uniform vec2 u_Size;
30

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

  
37
//////////////////////////////////////////////////////////////////////////////////////////////
38
// Pass1 of the OIT algorithm - 'clear the head pointers' phase.
39
// No we cannot optimize this out by moving the 'u_Records[index]=0u' to the end of the Pass3,
40
// because between passes the size of the surface we render to might change.
41

  
42
void main()                    		
43
  {
44
  uint index= uint(v_Pixel.x + v_Pixel.y * u_Size.x);
45
  u_Records[index] = 0u;
46
  discard;
47
  }
src/main/res/raw/oit_render_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_Texture;
28
uniform sampler2D u_DepthTexture;
29

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

  
33
uniform vec2 u_Size;
34

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

  
41
//////////////////////////////////////////////////////////////////////////////////////////////
42

  
43
vec4 convert(uint rgba)
44
  {
45
  return vec4( float((rgba>>24u)&255u),float((rgba>>16u)&255u),float((rgba>>8u)&255u),float(rgba&255u) ) / 255.0;
46
  }
47

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

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

  
56
//////////////////////////////////////////////////////////////////////////////////////////////
57
// Pass3 of the OIT algorithm - traverse the per-pixel LinkedList and build the final color.
58

  
59
void main()                    		
60
  {
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];
65

  
66
  if (curr != 0u)
67
    {
68
    const float S= 2147483647.0;
69
    uint depth = u_Records[curr+1u];
70
    uint texdepthuint = uint(S*(1.0-texdepth)/2.0);
71

  
72
    if( depth >= texdepthuint )
73
      {
74
      vec4 clr= convert(u_Records[curr+2u]);
75
      curr = u_Records[curr];
76

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

  
85
      color = blend( clr, color);
86
      }
87
    }
88

  
89
  gl_FragDepth = texdepth;
90
  fragColor    = color;
91
  }
src/main/res/raw/oit_vertex_shader.glsl
1
//////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 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
in vec2 a_Position;           // Per-vertex position.
24
out vec2 v_TexCoordinate;     //
25
out vec2 v_Pixel;             // 2D pixel coords in window space
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.
34

  
35
//////////////////////////////////////////////////////////////////////////////////////////////
36

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

Also available in: Unified diff