blob: 2d61b895b6d1ed4019625fc3a4c909b1159e07c0 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
//--------------------------------------------------------------------------------------
// Order Independent Transparency with Dual Depth Peeling
//
// Author: Louis Bavoil
// Email: sdkfeedback@nvidia.com
//
// Copyright (c) NVIDIA Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#extension ARB_draw_buffers : require
uniform samplerRECT DepthBlenderTex;
uniform samplerRECT FrontBlenderTex;
#define MAX_DEPTH 1.0
vec4 ShadeFragment();
void main(void)
{
// window-space depth interpolated linearly in screen space
float fragDepth = gl_FragCoord.z;
vec2 depthBlender = textureRect(DepthBlenderTex, gl_FragCoord.xy).xy;
vec4 forwardTemp = textureRect(FrontBlenderTex, gl_FragCoord.xy);
// Depths and 1.0-alphaMult always increase
// so we can use pass-through by default with MAX blending
gl_FragData[0].xy = depthBlender;
// Front colors always increase (DST += SRC*ALPHA_MULT)
// so we can use pass-through by default with MAX blending
gl_FragData[1] = forwardTemp;
// Because over blending makes color increase or decrease,
// we cannot pass-through by default.
// Each pass, only one fragment writes a color greater than 0
gl_FragData[2] = vec4(0.0);
float nearestDepth = -depthBlender.x;
float farthestDepth = depthBlender.y;
float alphaMultiplier = 1.0 - forwardTemp.w;
if (fragDepth < nearestDepth || fragDepth > farthestDepth) {
// Skip this depth in the peeling algorithm
gl_FragData[0].xy = vec2(-MAX_DEPTH);
return;
}
if (fragDepth > nearestDepth && fragDepth < farthestDepth) {
// This fragment needs to be peeled again
gl_FragData[0].xy = vec2(-fragDepth, fragDepth);
return;
}
// If we made it here, this fragment is on the peeled layer from last pass
// therefore, we need to shade it, and make sure it is not peeled any farther
vec4 color = ShadeFragment();
gl_FragData[0].xy = vec2(-MAX_DEPTH);
if (fragDepth == nearestDepth) {
gl_FragData[1].xyz += color.rgb * color.a * alphaMultiplier;
gl_FragData[1].w = 1.0 - alphaMultiplier * (1.0 - color.a);
} else {
gl_FragData[2] += color;
}
}
|