1+ #version 430 compatibility
2+
3+ layout (location = 0 ) out vec4 EyeBuffer;
4+ layout (location = 1 ) out vec4 OcclusionBuffer;
5+
6+ in vec3 world_pos;
7+ in vec2 CVector;
8+ in vec4 pos_clip_space;
9+
10+ uniform sampler3D TexVolume;
11+ uniform sampler1D TexTransferFunc;
12+
13+ uniform vec3 VolumeScaledSizes;
14+
15+ uniform float StepSize;
16+
17+ uniform vec2 ScreenSize;
18+
19+ uniform sampler2D EyeBufferPrev;
20+ uniform sampler2D OcclusionBufferPrev;
21+
22+ uniform float OcclusionExtent;
23+ uniform vec2 GridSize;
24+
25+ uniform float VolumeDiagonal;
26+
27+ uniform float UITransparencyScale;
28+
29+ vec4 GetFromTransferFunction (vec3 in_pos)
30+ {
31+ float vol_density = texture(TexVolume, in_pos / VolumeScaledSizes).r;
32+ return texture(TexTransferFunc, vol_density);
33+ }
34+
35+ float Algorithm3 (float st, float slice_distance)
36+ {
37+ // ////////////////////////////
38+ // Equation 13
39+ vec2 xy_d = pos_clip_space.xy / pos_clip_space.w;
40+
41+ float s_occlusion = 0.0 ;
42+
43+ // x of y, they're equal
44+ float x_grid_pos = 0.5 ;
45+ int xpos_sample = 0 ;
46+ while (xpos_sample < GridSize.x)
47+ {
48+ float y_grid_pos = 0.5 ;
49+ int ypos_sample = 0 ;
50+ while (ypos_sample < GridSize.y)
51+ {
52+ // ////////////////////////////
53+ // Generate each sample on an uniform grid an multiply by the current radius to evaluate occlusion
54+ // . center ir 0.0
55+ // ***********
56+ // * X X X *
57+ // * X X X *
58+ // * X X X *
59+ // ***********
60+ vec2 p = ((vec2 (x_grid_pos, y_grid_pos) - (GridSize / 2 .0f)) / (GridSize / 2 .0f)) * OcclusionExtent;
61+
62+ // ////////////////////////////
63+ // Equation 14
64+ // must normalize the grid pos to multiply by the radius of the occlusion extent
65+ vec2 p_d = xy_d + CVector * p;
66+
67+ // ///////////////////////////////
68+ // Equation 15
69+ vec2 p_t = 0.5 * p_d + vec2 (0.5 );
70+
71+ float occ_sample = texture(OcclusionBufferPrev, p_t).r;
72+ s_occlusion += occ_sample;
73+
74+ y_grid_pos += 1 .0f;
75+ ypos_sample = ypos_sample + 1 ;
76+ }
77+ x_grid_pos += 1 .0f;
78+ xpos_sample = xpos_sample + 1 ;
79+ }
80+ s_occlusion = (s_occlusion / (GridSize.x * GridSize.y)) * exp (- st * slice_distance * UITransparencyScale);
81+
82+ return s_occlusion;
83+ }
84+
85+ // http://developer.download.nvidia.com/books/HTML/gpugems/gpugems_ch39.html
86+ void main(void )
87+ {
88+ vec3 aabb = VolumeScaledSizes * 0.5 ;
89+ if (world_pos.x > aabb.x || world_pos.x < - aabb.x ||
90+ world_pos.y > aabb.y || world_pos.y < - aabb.y ||
91+ world_pos.z > aabb.z || world_pos.z < - aabb.z )
92+ discard ;
93+ else
94+ {
95+ vec3 pos_from_zero = world_pos + aabb;
96+ vec4 src = GetFromTransferFunction(pos_from_zero);
97+
98+ float st = src.a;
99+
100+ vec4 dst = texelFetch(EyeBufferPrev, ivec2 (gl_FragCoord .st), 0 );
101+
102+ float occlusion;
103+ // if (!(dst.a > 0.99))
104+ {
105+ occlusion = texture(OcclusionBufferPrev, (gl_FragCoord .st) / ScreenSize).r;
106+
107+ // Evaluate the current opacity
108+ src.a = 1.0 - exp (- src.a * StepSize);
109+
110+ // Front-to-back composition
111+ src.rgb = src.rgb * occlusion * src.a;
112+
113+ dst = dst + (1.0 - dst.a) * src;
114+ }
115+ occlusion = Algorithm3(st, StepSize);
116+ OcclusionBuffer = vec4 (occlusion, 0 , 0 , 0 );
117+
118+ EyeBuffer = dst;
119+ }
120+ }
0 commit comments