GteFluid3SolvePoisson.cpp
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #include <GTEnginePCH.h>
12 using namespace gte;
13 
14 Fluid3SolvePoisson::Fluid3SolvePoisson(std::shared_ptr<ProgramFactory> const& factory,
15  int xSize, int ySize, int zSize, int numXThreads, int numYThreads, int numZThreads,
16  std::shared_ptr<ConstantBuffer> const& parameters, int numIterations)
17  :
18  mNumXGroups(xSize/numXThreads),
19  mNumYGroups(ySize/numYThreads),
20  mNumZGroups(zSize/numZThreads),
21  mNumIterations(numIterations)
22 {
23  mPoisson0 = std::make_shared<Texture3>(DF_R32_FLOAT, xSize, ySize, zSize);
24  mPoisson0->SetUsage(Resource::SHADER_OUTPUT);
25  mPoisson1 = std::make_shared<Texture3>(DF_R32_FLOAT, xSize, ySize, zSize);
26  mPoisson1->SetUsage(Resource::SHADER_OUTPUT);
27 
28  int i = factory->GetAPI();
29  factory->PushDefines();
30  factory->defines.Set("NUM_X_THREADS", numXThreads);
31  factory->defines.Set("NUM_Y_THREADS", numYThreads);
32  factory->defines.Set("NUM_Z_THREADS", numZThreads);
33 
34  // For zeroing mPoisson0 on the GPU.
35  mZeroPoisson = factory->CreateFromSource(*msZeroSource[i]);
36  if (mZeroPoisson)
37  {
38  mZeroPoisson->GetCShader()->Set("poisson", mPoisson0);
39  }
40 
41  // Create the shader for generating velocity from vortices.
42  mSolvePoisson = factory->CreateFromSource(*msSolveSource[i]);
43  if (mSolvePoisson)
44  {
45  mSolvePoisson->GetCShader()->Set("Parameters", parameters);
46  }
47 
48  factory->defines.Clear();
49  factory->defines.Set("USE_ZERO_X_FACE", 1);
50  factory->defines.Set("NUM_Y_THREADS", numYThreads);
51  factory->defines.Set("NUM_Z_THREADS", numZThreads);
52  mWriteXFace = factory->CreateFromSource(*msEnforceSource[i]);
53 
54  factory->defines.Clear();
55  factory->defines.Set("USE_ZERO_Y_FACE", 1);
56  factory->defines.Set("NUM_X_THREADS", numXThreads);
57  factory->defines.Set("NUM_Z_THREADS", numZThreads);
58  mWriteYFace = factory->CreateFromSource(*msEnforceSource[i]);
59 
60  factory->defines.Clear();
61  factory->defines.Set("USE_ZERO_Z_FACE", 1);
62  factory->defines.Set("NUM_X_THREADS", numXThreads);
63  factory->defines.Set("NUM_Y_THREADS", numYThreads);
64  mWriteZFace = factory->CreateFromSource(*msEnforceSource[i]);
65 
66  factory->PopDefines();
67 }
68 
69 void Fluid3SolvePoisson::Execute(std::shared_ptr<GraphicsEngine> const& engine,
70  std::shared_ptr<Texture3> const& divergence)
71 {
72  std::shared_ptr<ComputeShader> solve = mSolvePoisson->GetCShader();
73  std::shared_ptr<ComputeShader> xwrite = mWriteXFace->GetCShader();
74  std::shared_ptr<ComputeShader> ywrite = mWriteYFace->GetCShader();
75  std::shared_ptr<ComputeShader> zwrite = mWriteZFace->GetCShader();
76 
77  solve->Set("divergence", divergence);
78  engine->Execute(mZeroPoisson, mNumXGroups, mNumYGroups, mNumZGroups);
79  for (int i = 0; i < mNumIterations; ++i)
80  {
81  // Take one step of the Poisson solver.
82  solve->Set("poisson", mPoisson0);
83  solve->Set("outPoisson", mPoisson1);
85 
86  // Set the boundary to zero.
87  xwrite->Set("image", mPoisson1);
88  engine->Execute(mWriteXFace, 1, mNumYGroups, mNumZGroups);
89  ywrite->Set("image", mPoisson1);
90  engine->Execute(mWriteYFace, mNumXGroups, 1, mNumZGroups);
91  zwrite->Set("image", mPoisson1);
92  engine->Execute(mWriteZFace, mNumXGroups, mNumYGroups, 1);
93 
94  std::swap(mPoisson0, mPoisson1);
95  }
96 }
97 
98 
100 "layout(r32f) uniform writeonly image3D poisson;\n"
101 "\n"
102 "layout (local_size_x = NUM_X_THREADS, local_size_y = NUM_Y_THREADS, local_size_z = NUM_Z_THREADS) in;\n"
103 "void main()\n"
104 "{\n"
105 " ivec3 c = ivec3(gl_GlobalInvocationID.xyz);\n"
106 " imageStore(poisson, c, vec4(0.0f, 0.0f, 0.0f, 0.0f));\n"
107 "}\n";
108 
110 "uniform Parameters\n"
111 "{\n"
112 " vec4 spaceDelta; // (dx, dy, dz, 0)\n"
113 " vec4 halfDivDelta; // (0.5/dx, 0.5/dy, 0.5/dz, 0)\n"
114 " vec4 timeDelta; // (dt/dx, dt/dy, dt/dz, dt)\n"
115 " vec4 viscosityX; // (velVX, velVX, velVX, denVX)\n"
116 " vec4 viscosityY; // (velVX, velVY, velVY, denVY)\n"
117 " vec4 viscosityZ; // (velVZ, velVZ, velVZ, denVZ)\n"
118 " vec4 epsilon; // (epsilonX, epsilonY, epsilonZ, epsilon0)\n"
119 "};\n"
120 "\n"
121 "layout(r32f) uniform readonly image3D divergence;\n"
122 "layout(r32f) uniform readonly image3D poisson;\n"
123 "layout(r32f) uniform writeonly image3D outPoisson;\n"
124 "\n"
125 "layout (local_size_x = NUM_X_THREADS, local_size_y = NUM_Y_THREADS, local_size_z = NUM_Z_THREADS) in;\n"
126 "void main()\n"
127 "{\n"
128 " ivec3 c = ivec3(gl_GlobalInvocationID.xyz);\n"
129 " ivec3 dim = imageSize(divergence);\n"
130 "\n"
131 " int x = int(c.x);\n"
132 " int y = int(c.y);\n"
133 " int z = int(c.z);\n"
134 " int xm = max(x - 1, 0);\n"
135 " int xp = min(x + 1, dim.x - 1);\n"
136 " int ym = max(y - 1, 0);\n"
137 " int yp = min(y + 1, dim.y - 1);\n"
138 " int zm = max(z - 1, 0);\n"
139 " int zp = min(z + 1, dim.z - 1);\n"
140 "\n"
141 " // Sample the divergence at (x,y,z).\n"
142 " float div = imageLoad(divergence, c).x;\n"
143 "\n"
144 " // Sample Poisson values at immediate neighbors of (x,y,z).\n"
145 " float poisPZZ = imageLoad(poisson, ivec3(xp, y, z)).x;\n"
146 " float poisMZZ = imageLoad(poisson, ivec3(xm, y, z)).x;\n"
147 " float poisZPZ = imageLoad(poisson, ivec3(x, yp, z)).x;\n"
148 " float poisZMZ = imageLoad(poisson, ivec3(x, ym, z)).x;\n"
149 " float poisZZP = imageLoad(poisson, ivec3(x, y, zp)).x;\n"
150 " float poisZZM = imageLoad(poisson, ivec3(x, y, zm)).x;\n"
151 "\n"
152 " vec4 temp = vec4(poisPZZ + poisMZZ, poisZPZ + poisZMZ, poisZZP + poisZZM, div);\n"
153 " float outPoissonValue = dot(epsilon, temp);\n"
154 " imageStore(outPoisson, c, vec4(outPoissonValue, 0.0f, 0.0f, 0.0f));\n"
155 "}\n";
156 
158 "#if USE_ZERO_X_FACE\n"
159 "layout(r32f) uniform writeonly image3D image;\n"
160 "\n"
161 "layout (local_size_x = 1, local_size_y = NUM_Y_THREADS, local_size_z = NUM_Z_THREADS) in;\n"
162 "void main()\n"
163 "{\n"
164 " ivec3 c = ivec3(gl_GlobalInvocationID.xyz);\n"
165 " ivec3 dim = imageSize(image);\n"
166 " imageStore(image, ivec3(0, c.y, c.z), vec4(0.0f));\n"
167 " imageStore(image, ivec3(dim.x - 1, c.y, c.z), vec4(0.0f));\n"
168 "}\n"
169 "#endif\n"
170 "\n"
171 "#if USE_ZERO_Y_FACE\n"
172 "layout(r32f) uniform writeonly image3D image;\n"
173 "\n"
174 "layout (local_size_x = NUM_X_THREADS, local_size_y = 1, local_size_z = NUM_Z_THREADS) in;\n"
175 "void main()\n"
176 "{\n"
177 " ivec3 c = ivec3(gl_GlobalInvocationID.xyz);\n"
178 " ivec3 dim = imageSize(image);\n"
179 " imageStore(image, ivec3(c.x, 0, c.z), vec4(0.0f));\n"
180 " imageStore(image, ivec3(c.x, dim.y - 1, c.z), vec4(0.0f));\n"
181 "}\n"
182 "#endif\n"
183 "\n"
184 "#if USE_ZERO_Z_FACE\n"
185 "layout(r32f) uniform writeonly image3D image;\n"
186 "\n"
187 "layout (local_size_x = NUM_X_THREADS, local_size_y = NUM_Y_THREADS, local_size_z = 1) in;\n"
188 "void main()\n"
189 "{\n"
190 " ivec3 c = ivec3(gl_GlobalInvocationID.xyz);\n"
191 " ivec3 dim = imageSize(image);\n"
192 " imageStore(image, ivec3(c.x, c.y, 0), vec4(0.0f));\n"
193 " imageStore(image, ivec3(c.x, c.y, dim.z - 1), vec4(0.0f));\n"
194 "}\n"
195 "#endif\n";
196 
198 "RWTexture3D<float> poisson;\n"
199 "\n"
200 "[numthreads(NUM_X_THREADS, NUM_Y_THREADS, NUM_Z_THREADS)]\n"
201 "void CSMain(uint3 c : SV_DispatchThreadID)\n"
202 "{\n"
203 " poisson[c.xyz] = 0.0f;\n"
204 "}\n";
205 
207 "cbuffer Parameters\n"
208 "{\n"
209 " float4 spaceDelta; // (dx, dy, dz, 0)\n"
210 " float4 halfDivDelta; // (0.5/dx, 0.5/dy, 0.5/dz, 0)\n"
211 " float4 timeDelta; // (dt/dx, dt/dy, dt/dz, dt)\n"
212 " float4 viscosityX; // (velVX, velVX, velVX, denVX)\n"
213 " float4 viscosityY; // (velVX, velVY, velVY, denVY)\n"
214 " float4 viscosityZ; // (velVZ, velVZ, velVZ, denVZ)\n"
215 " float4 epsilon; // (epsilonX, epsilonY, epsilonZ, epsilon0)\n"
216 "};\n"
217 "\n"
218 "Texture3D<float> divergence;\n"
219 "Texture3D<float> poisson;\n"
220 "RWTexture3D<float> outPoisson;\n"
221 "\n"
222 "[numthreads(NUM_X_THREADS, NUM_Y_THREADS, NUM_Z_THREADS)]\n"
223 "void CSMain(uint3 c : SV_DispatchThreadID)\n"
224 "{\n"
225 " uint3 dim;\n"
226 " divergence.GetDimensions(dim.x, dim.y, dim.z);\n"
227 "\n"
228 " int x = int(c.x);\n"
229 " int y = int(c.y);\n"
230 " int z = int(c.z);\n"
231 " int xm = max(x - 1, 0);\n"
232 " int xp = min(x + 1, dim.x - 1);\n"
233 " int ym = max(y - 1, 0);\n"
234 " int yp = min(y + 1, dim.y - 1);\n"
235 " int zm = max(z - 1, 0);\n"
236 " int zp = min(z + 1, dim.z - 1);\n"
237 "\n"
238 " // Sample the divergence at (x,y,z).\n"
239 " float div = divergence[c];\n"
240 "\n"
241 " // Sample Poisson values at immediate neighbors of (x,y,z).\n"
242 " float poisPZZ = poisson[int3(xp, y, z)];\n"
243 " float poisMZZ = poisson[int3(xm, y, z)];\n"
244 " float poisZPZ = poisson[int3(x, yp, z)];\n"
245 " float poisZMZ = poisson[int3(x, ym, z)];\n"
246 " float poisZZP = poisson[int3(x, y, zp)];\n"
247 " float poisZZM = poisson[int3(x, y, zm)];\n"
248 "\n"
249 " float4 temp = float4(poisPZZ + poisMZZ, poisZPZ + poisZMZ, poisZZP + poisZZM, div);\n"
250 " outPoisson[c] = dot(epsilon, temp);\n"
251 "}\n";
252 
254 "#if USE_ZERO_X_FACE\n"
255 "RWTexture3D<float> image;\n"
256 "\n"
257 "[numthreads(1, NUM_Y_THREADS, NUM_Z_THREADS)]\n"
258 "void CSMain(uint3 c : SV_DispatchThreadID)\n"
259 "{\n"
260 " uint3 dim;\n"
261 " image.GetDimensions(dim.x, dim.y, dim.z);\n"
262 " image[uint3(0, c.y, c.z)] = 0.0f;\n"
263 " image[uint3(dim.x - 1, c.y, c.z)] = 0.0f;\n"
264 "}\n"
265 "#endif\n"
266 "\n"
267 "#if USE_ZERO_Y_FACE\n"
268 "RWTexture3D<float> image;\n"
269 "\n"
270 "[numthreads(NUM_X_THREADS, 1, NUM_Z_THREADS)]\n"
271 "void CSMain(uint3 c : SV_DispatchThreadID)\n"
272 "{\n"
273 " uint3 dim;\n"
274 " image.GetDimensions(dim.x, dim.y, dim.z);\n"
275 " image[uint3(c.x, 0, c.z)] = 0.0f;\n"
276 " image[uint3(c.x, dim.y - 1, c.z)] = 0.0f;\n"
277 "}\n"
278 "#endif\n"
279 "\n"
280 "#if USE_ZERO_Z_FACE\n"
281 "RWTexture3D<float> image;\n"
282 "\n"
283 "[numthreads(NUM_X_THREADS, NUM_Y_THREADS, 1)]\n"
284 "void CSMain(uint3 c : SV_DispatchThreadID)\n"
285 "{\n"
286 " uint3 dim;\n"
287 " image.GetDimensions(dim.x, dim.y, dim.z);\n"
288 " image[uint3(c.x, c.y, 0)] = 0.0f;\n"
289 " image[uint3(c.x, c.y, dim.z - 1)] = 0.0f;\n"
290 "}\n"
291 "#endif\n";
292 
294 {
297 };
298 
300 {
303 };
304 
306 {
309 };
std::shared_ptr< Texture3 > mPoisson1
DF_R32_FLOAT
Definition: GteDataFormat.h:20
static std::string const msGLSLEnforceSource
static std::string const msHLSLEnforceSource
void Execute(std::shared_ptr< GraphicsEngine > const &engine, std::shared_ptr< Texture3 > const &divergence)
static std::string const msGLSLSolveSource
std::shared_ptr< ComputeProgram > mWriteYFace
static std::string const * msEnforceSource[ProgramFactory::PF_NUM_API]
static std::string const * msSolveSource[ProgramFactory::PF_NUM_API]
std::shared_ptr< ComputeProgram > mZeroPoisson
Fluid3SolvePoisson(std::shared_ptr< ProgramFactory > const &factory, int xSize, int ySize, int zSize, int numXThreads, int numYThreads, int numZThreads, std::shared_ptr< ConstantBuffer > const &parameters, int numIterations)
GLsizei const GLchar *const * string
Definition: glcorearb.h:809
static std::string const msHLSLZeroSource
std::shared_ptr< ComputeProgram > mWriteXFace
static std::string const msGLSLZeroSource
std::shared_ptr< ComputeProgram > mWriteZFace
static std::string const msHLSLSolveSource
std::shared_ptr< ComputeProgram > mSolvePoisson
std::shared_ptr< Texture3 > mPoisson0
static std::string const * msZeroSource[ProgramFactory::PF_NUM_API]


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:59