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
|
static const std::string EXTRA_SHADER_CODE = R"(
#version 430
layout (local_size_x = 1, local_size_y = 1) in;
layout (std430, binding=3) buffer bufferFluid { float fluidCells[]; };
layout (std430, binding=4) buffer bufferExtra { float extraCells[]; };
uniform uint nX;
uniform uint nY;
const float convLength = 1.0 / float(max(nX,nY));
/// Array indexing
uint indexOfDirection(int i, int j) {
return 3*(i+1) + (j+1);
}
uint indexOfFluidVertex(uint x, uint y) {
return 3*nX*y + 3*x;
}
/// Data access
vec2 getFluidVelocity(uint x, uint y) {
const uint idx = indexOfFluidVertex(x, y);
return vec2(
fluidCells[idx + 0],
fluidCells[idx + 1]
);
}
void setFluidExtra(uint x, uint y, float curl) {
const uint idx = indexOfFluidVertex(x, y);
extraCells[idx + 0] = curl;
}
void main() {
const uint x = gl_GlobalInvocationID.x;
const uint y = gl_GlobalInvocationID.y;
if ( !(x < nX && y < nY) ) {
return;
}
// simple central difference discretization of the 2d curl operator
const float dxvy = (getFluidVelocity(x+1,y).y - getFluidVelocity(x-1,y).y)
/ (2*convLength);
const float dyvx = (getFluidVelocity(x,y+1).x - getFluidVelocity(x,y-1).x)
/ (2*convLength);
setFluidExtra(x, y, dxvy - dyvx);
}
)";
|