-
Notifications
You must be signed in to change notification settings - Fork 0
/
VDIGenerator.comp
273 lines (222 loc) · 9.08 KB
/
VDIGenerator.comp
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
uniform vec2 viewportSize;
uniform vec2 dsp;
uniform float fwnw;
uniform float nw;
// -- comes from CacheSpec -----
uniform vec3 blockSize;
uniform vec3 paddedBlockSize;
uniform vec3 cachePadOffset;
// -- comes from TextureCache --
uniform vec3 cacheSize; // TODO: get from texture!?
uniform mat4 transform;
#pragma scenery verbatim
layout(set = 0, binding = 0) uniform VRParameters {
mat4 projectionMatrices[2];
mat4 inverseProjectionMatrices[2];
mat4 headShift;
float IPD;
int stereoEnabled;
} vrParameters;
const int MAX_NUM_LIGHTS = 1024;
layout(set = 1, binding = 0) uniform LightParameters {
mat4 ViewMatrices[2];
mat4 InverseViewMatrices[2];
mat4 ProjectionMatrix;
mat4 InverseProjectionMatrix;
vec3 CamPosition;
};
layout(push_constant) uniform currentEye_t {
int eye;
} currentEye;
#define SEPARATE_DEPTH 0
#define WORLD_ABS 0
layout(local_size_x = 15, local_size_y = 15) in;
layout(set = 2, binding = 0) uniform sampler3D volumeCache;
layout(set = 3, binding = 0, rgba8) uniform image3D OutputSubVDIColor;
#pragma scenery endverbatim
// intersect ray with a box
// http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm
void intersectBox( vec3 r_o, vec3 r_d, vec3 boxmin, vec3 boxmax, out float tnear, out float tfar )
{
// compute intersection of ray with all six bbox planes
vec3 invR = 1 / r_d;
vec3 tbot = invR * ( boxmin - r_o );
vec3 ttop = invR * ( boxmax - r_o );
// re-order intersections to find smallest and largest on each axis
vec3 tmin = min(ttop, tbot);
vec3 tmax = max(ttop, tbot);
// find the largest tmin and the smallest tmax
tnear = max( max( tmin.x, tmin.y ), max( tmin.x, tmin.z ) );
tfar = min( min( tmax.x, tmax.y ), min( tmax.x, tmax.z ) );
}
float adjustOpacity(float a, float modifiedStepLength) {
return 1.0 - pow((1.0 - a), modifiedStepLength);
}
float diffPremultiplied(vec4 a, vec4 b) {
a.rgb = a.rgb * a.a;
b.rgb = b.rgb * b.a;
return length(a.rgb-b.rgb);
}
const vec4 bitEnc = vec4(1.,255.,65025.,16581375.);
vec4 EncodeFloatRGBA (float v) {
vec4 enc = bitEnc * v;
enc = fract(enc);
enc -= enc.yzww * vec2(1./255., 0.).xxxy;
return enc;
}
vec4 encode(float x, float y){
vec4 rgba;
x += 128.;
y += 128.;
int ix = int( x * 256. ); // convert to int to split accurately
int v1x = ix / 256; // hi
int v1y = ix - v1x * 256; // lo
rgba.r = float( v1x + 1 ) / 255.; // normalize
rgba.g = float( v1y + 1 ) / 255.;
int iy = int( y * 256. );
int v2x = iy / 256; // hi
int v2y = iy - v2x * 256; // lo
rgba.b = float( v2x + 1 ) / 255.;
rgba.a = float( v2y + 1 ) / 255.;
return rgba - 1./256.;
}
// ---------------------
// $insert{Convert}
// $insert{SampleVolume}
// ---------------------
void main()
{
// imageStore(OutputSubVDIColor, ivec3(0, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(1, 0, 0, 1));
// imageStore(OutputSubVDIColor, ivec3(1, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0.5));
// imageStore(OutputSubVDIColor, ivec3(2, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(1));
//
// if(true && 1>0) {
// return;
//
// }
mat4 ipv = InverseViewMatrices[0] * InverseProjectionMatrix;
mat4 pv = ProjectionMatrix * ViewMatrices[0];
// frag coord in NDC
// TODO: Re-introduce dithering
// vec2 fragCoord = (vrParameters.stereoEnabled ^ 1) * gl_FragCoord.xy + vrParameters.stereoEnabled * vec2((gl_FragCoord.x/2.0 + currentEye.eye * gl_FragCoord.x/2.0), gl_FragCoord.y);
// vec2 viewportSizeActual = (vrParameters.stereoEnabled ^ 1) * viewportSize + vrParameters.stereoEnabled * vec2(viewportSize.x/2.0, viewportSize.y);
// vec2 uv = 2 * ( gl_FragCoord.xy + dsp ) / viewportSizeActual - 1;
ivec3 imageCoords = imageSize(OutputSubVDIColor);
float newSupSegThresh = 0.05;
vec2 texcoord = gl_GlobalInvocationID.xy/vec2(imageCoords.b, imageCoords.g);
vec2 uv = texcoord * 2.0 - vec2(1.0);
vec2 depthUV = (vrParameters.stereoEnabled ^ 1) * texcoord + vrParameters.stereoEnabled * vec2((texcoord.x/2.0 + currentEye.eye * 0.5), texcoord.y);
depthUV = depthUV * 2.0 - vec2(1.0);
vec4 FragColor = vec4(0.0);
// NDC of frag on near and far plane
vec4 front = vec4( uv, -1, 1 );
vec4 back = vec4( uv, 1, 1 );
// calculate eye ray in world space
vec4 wfront = ipv * front;
wfront *= 1 / wfront.w;
vec4 wback = ipv * back;
wback *= 1 / wback.w;
// -- bounding box intersection for all volumes ----------
float tnear = 1, tfar = 0, tmax = getMaxDepth( depthUV );
float n, f;
// $repeat:{vis,intersectBoundingBox|
bool vis = false;
intersectBoundingBox( wfront, wback, n, f );
f = min( tmax, f );
if ( n < f )
{
tnear = min( tnear, max( 0, n ) );
tfar = max( tfar, f );
vis = true;
}
// }$
// -------------------------------------------------------
#if SEPARATE_DEPTH
int maxSupersegments = imageCoords.r;
#else
int maxSupersegments = imageCoords.r/3;
#endif
float minOpacity = 0.001; //If alpha is less than this, the sample is considered transparent and not included in generated supersegments
int supersegmentNum = 0;
if ( tnear < tfar )
{
vec4 fb = wback - wfront;
int numSteps =
( fwnw > 0.00001 )
? int ( log( ( tfar * fwnw + nw ) / ( tnear * fwnw + nw ) ) / log ( 1 + fwnw ) )
: int ( trunc( ( tfar - tnear ) / nw + 1 ) );
// int cnt = 0;
bool supersegmentIsOpen = false;
float supSegStartPoint = 0.0;
float supSegEndPoint = 0.0;
bool lastSample = false;
bool transparentSample = false;
bool lastSupersegment = false;
float step = tnear;
vec4 v = vec4( 0 );
vec4 curV = vec4( 0 );
for ( int i = 0; i < numSteps; ++i, step += nw + step * fwnw )
{
transparentSample = false;
if(i==(numSteps-1)) {
lastSample = true;
}
if(supersegmentNum == maxSupersegments - 1) {
lastSupersegment = true;
}
vec4 wpos = mix( wfront, wback, step );
vec4 ro_world, rd_world;
#if WORLD_ABS
ro_world = InverseViewMatrices[0] * vec4(0, 0, 0, 1);
ro_world = ro_world / ro_world.w;
rd_world = wback - wfront;
rd_world = normalize(rd_world);
#endif
// $insert{Accumulate}
/*
inserts something like the following (keys: vis,blockTexture,convert)
if (vis)
{
float x = blockTexture(wpos, volumeCache, cacheSize, blockSize, paddedBlockSize, cachePadOffset);
v = max(v, convert(x));
}
*/
}
FragColor = v;
if(supersegmentNum < maxSupersegments) {
for(int i = supersegmentNum; i < maxSupersegments; i++) {
#if SEPARATE_DEPTH
imageStore(OutputSubVDIColor, ivec3(i, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0));
imageStore(OutputSubVDIDepth, ivec3(2 * i, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0));
imageStore(OutputSubVDIDepth, ivec3(2 * i + 1, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0));
#else
imageStore(OutputSubVDIColor, ivec3(3 * i, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0));
imageStore(OutputSubVDIColor, ivec3(3 * i + 1, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0));
imageStore(OutputSubVDIColor, ivec3(3 * i + 2, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0));
#endif
}
}
} else {
FragColor = vec4(0, 0, 0, 0);
if(supersegmentNum < maxSupersegments) {
for(int i = supersegmentNum; i < maxSupersegments; i++) {
#if SEPARATE_DEPTH
imageStore(OutputSubVDIColor, ivec3(i, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0));
imageStore(OutputSubVDIDepth, ivec3(2 * i, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0));
imageStore(OutputSubVDIDepth, ivec3(2 * i + 1, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0));
#else
imageStore(OutputSubVDIColor, ivec3(3 * i, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0));
imageStore(OutputSubVDIColor, ivec3(3 * i + 1, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0));
imageStore(OutputSubVDIColor, ivec3(3 * i + 2, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0));
#endif
}
}
}
// if(supersegmentNum < maxSupersegments - 1) {
// for(int i = supersegmentNum; i < maxSupersegments; i++) {
// imageStore(OutputSubVDIDepth, ivec3(i, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0));
// imageStore(OutputSubVDIColor, ivec3(i, gl_GlobalInvocationID.y, gl_GlobalInvocationID.x), vec4(0));
// }
// }
// imageStore(OutputRender, ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y), FragColor);
}