GteFluid2SolvePoisson.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 Fluid2SolvePoisson::Fluid2SolvePoisson(std::shared_ptr<ProgramFactory> const& factory,
15  int xSize, int ySize, int numXThreads, int numYThreads,
16  std::shared_ptr<ConstantBuffer> const& parameters, int numIterations)
17  :
18  mNumXGroups(xSize/numXThreads),
19  mNumYGroups(ySize/numYThreads),
20  mNumIterations(numIterations)
21 {
22  mPoisson0 = std::make_shared<Texture2>(DF_R32_FLOAT, xSize, ySize);
23  mPoisson0->SetUsage(Resource::SHADER_OUTPUT);
24  mPoisson1 = std::make_shared<Texture2>(DF_R32_FLOAT, xSize, ySize);
25  mPoisson1->SetUsage(Resource::SHADER_OUTPUT);
26 
27  int i = factory->GetAPI();
28  factory->PushDefines();
29  factory->defines.Set("NUM_X_THREADS", numXThreads);
30  factory->defines.Set("NUM_Y_THREADS", numYThreads);
31 
32  // For zeroing mPoisson0 on the GPU.
33  mZeroPoisson = factory->CreateFromSource(*msZeroSource[i]);
34  if (mZeroPoisson)
35  {
36  mZeroPoisson->GetCShader()->Set("poisson", mPoisson0);
37  }
38 
39  // Create the shader for generating velocity from vortices.
40  mSolvePoisson = factory->CreateFromSource(*msSolveSource[i]);
41  if (mSolvePoisson)
42  {
43  mSolvePoisson->GetCShader()->Set("Parameters", parameters);
44  }
45 
46  factory->defines.Clear();
47  factory->defines.Set("USE_ZERO_X_EDGE", 1);
48  factory->defines.Set("NUM_Y_THREADS", numYThreads);
49  mWriteXEdge = factory->CreateFromSource(*msEnforceSource[i]);
50 
51  factory->defines.Clear();
52  factory->defines.Set("USE_ZERO_Y_EDGE", 1);
53  factory->defines.Set("NUM_X_THREADS", numXThreads);
54  mWriteYEdge = factory->CreateFromSource(*msEnforceSource[i]);
55 
56  factory->PopDefines();
57 }
58 
59 void Fluid2SolvePoisson::Execute(std::shared_ptr<GraphicsEngine> const& engine,
60  std::shared_ptr<Texture2> const& divergence)
61 {
62  std::shared_ptr<ComputeShader> solve = mSolvePoisson->GetCShader();
63  std::shared_ptr<ComputeShader> xwrite = mWriteXEdge->GetCShader();
64  std::shared_ptr<ComputeShader> ywrite = mWriteYEdge->GetCShader();
65 
66  solve->Set("divergence", divergence);
67  engine->Execute(mZeroPoisson, mNumXGroups, mNumYGroups, 1);
68  for (int i = 0; i < mNumIterations; ++i)
69  {
70  // Take one step of the Poisson solver.
71  solve->Set("poisson", mPoisson0);
72  solve->Set("outPoisson", mPoisson1);
73  engine->Execute(mSolvePoisson, mNumXGroups, mNumYGroups, 1);
74 
75  // Set the boundary to zero.
76  xwrite->Set("image", mPoisson1);
77  engine->Execute(mWriteXEdge, 1, mNumYGroups, 1);
78  ywrite->Set("image", mPoisson1);
79  engine->Execute(mWriteYEdge, mNumXGroups, 1, 1);
80 
81  std::swap(mPoisson0, mPoisson1);
82  }
83 }
84 
85 
87 "layout(r32f) uniform writeonly image2D poisson;\n"
88 "\n"
89 "layout (local_size_x = NUM_X_THREADS, local_size_y = NUM_Y_THREADS, local_size_z = 1) in;\n"
90 "void main()\n"
91 "{\n"
92 " ivec2 c = ivec2(gl_GlobalInvocationID.xy);\n"
93 " imageStore(poisson, c, vec4(0.0f, 0.0f, 0.0f, 0.0f));\n"
94 "}\n";
95 
97 "uniform Parameters\n"
98 "{\n"
99 " vec4 spaceDelta; // (dx, dy, 0, 0)\n"
100 " vec4 halfDivDelta; // (0.5/dx, 0.5/dy, 0, 0)\n"
101 " vec4 timeDelta; // (dt/dx, dt/dy, 0, dt)\n"
102 " vec4 viscosityX; // (velVX, velVX, 0, denVX)\n"
103 " vec4 viscosityY; // (velVX, velVY, 0, denVY)\n"
104 " vec4 epsilon; // (epsilonX, epsilonY, 0, epsilon0)\n"
105 "};\n"
106 "\n"
107 "layout(r32f) uniform readonly image2D divergence;\n"
108 "layout(r32f) uniform readonly image2D poisson;\n"
109 "layout(r32f) uniform writeonly image2D outPoisson;\n"
110 "\n"
111 "layout (local_size_x = NUM_X_THREADS, local_size_y = NUM_Y_THREADS, local_size_z = 1) in;\n"
112 "void main()\n"
113 "{\n"
114 " ivec2 c = ivec2(gl_GlobalInvocationID.xy);\n"
115 " ivec2 dim = imageSize(divergence);\n"
116 "\n"
117 " int x = int(c.x);\n"
118 " int y = int(c.y);\n"
119 " int xm = max(x - 1, 0);\n"
120 " int xp = min(x + 1, dim.x - 1);\n"
121 " int ym = max(y - 1, 0);\n"
122 " int yp = min(y + 1, dim.y - 1);\n"
123 "\n"
124 " // Sample the divergence at (x,y).\n"
125 " float div = imageLoad(divergence, c).x;\n"
126 "\n"
127 " // Sample Poisson values at (x+dx,y), (x-dx,y), (x,y+dy), (x,y-dy).\n"
128 " float poisPZ = imageLoad(poisson, ivec2(xp, y)).x;\n"
129 " float poisMZ = imageLoad(poisson, ivec2(xm, y)).x;\n"
130 " float poisZP = imageLoad(poisson, ivec2(x, yp)).x;\n"
131 " float poisZM = imageLoad(poisson, ivec2(x, ym)).x;\n"
132 "\n"
133 " vec4 temp = vec4(poisPZ + poisMZ, poisZP + poisZM, 0.0f, div);\n"
134 " float outPoissonValue = dot(epsilon, temp);\n"
135 " imageStore(outPoisson, c, vec4(outPoissonValue, 0.0f, 0.0f, 0.0f));\n"
136 "}\n";
137 
139 "#if USE_ZERO_X_EDGE\n"
140 "layout(r32f) uniform writeonly image2D image;\n"
141 "\n"
142 "layout (local_size_x = 1, local_size_y = NUM_Y_THREADS, local_size_z = 1) in;\n"
143 "void main()\n"
144 "{\n"
145 " ivec2 c = ivec2(gl_GlobalInvocationID.xy);\n"
146 " ivec2 dim = imageSize(image);\n"
147 " imageStore(image, ivec2(0, c.y), vec4(0.0f, 0.0f, 0.0f, 0.0f));\n"
148 " imageStore(image, ivec2(dim.x - 1, c.y), vec4(0.0f, 0.0f, 0.0f, 0.0f));\n"
149 "}\n"
150 "#endif\n"
151 "\n"
152 "#if USE_ZERO_Y_EDGE\n"
153 "layout(r32f) uniform writeonly image2D image;\n"
154 "\n"
155 "layout (local_size_x = NUM_X_THREADS, local_size_y = 1, local_size_z = 1) in;\n"
156 "void main()\n"
157 "{\n"
158 " ivec2 c = ivec2(gl_GlobalInvocationID.xy);\n"
159 " ivec2 dim = imageSize(image);\n"
160 " imageStore(image, ivec2(c.x, 0), vec4(0.0f, 0.0f, 0.0f, 0.0f));\n"
161 " imageStore(image, ivec2(c.x, dim.y - 1), vec4(0.0f, 0.0f, 0.0f, 0.0f));\n"
162 "}\n"
163 "#endif\n";
164 
166 "RWTexture2D<float> poisson;\n"
167 "\n"
168 "[numthreads(NUM_X_THREADS, NUM_Y_THREADS, 1)]\n"
169 "void CSMain(uint2 c : SV_DispatchThreadID)\n"
170 "{\n"
171 " poisson[c] = 0.0f;\n"
172 "}\n";
173 
175 "cbuffer Parameters\n"
176 "{\n"
177 " float4 spaceDelta; // (dx, dy, 0, 0)\n"
178 " float4 halfDivDelta; // (0.5/dx, 0.5/dy, 0, 0)\n"
179 " float4 timeDelta; // (dt/dx, dt/dy, 0, dt)\n"
180 " float4 viscosityX; // (velVX, velVX, 0, denVX)\n"
181 " float4 viscosityY; // (velVX, velVY, 0, denVY)\n"
182 " float4 epsilon; // (epsilonX, epsilonY, 0, epsilon0)\n"
183 "};\n"
184 "\n"
185 "Texture2D<float> divergence;\n"
186 "Texture2D<float> poisson;\n"
187 "RWTexture2D<float> outPoisson;\n"
188 "\n"
189 "[numthreads(NUM_X_THREADS, NUM_Y_THREADS, 1)]\n"
190 "void CSMain(uint2 c : SV_DispatchThreadID)\n"
191 "{\n"
192 " uint2 dim;\n"
193 " divergence.GetDimensions(dim.x, dim.y);\n"
194 "\n"
195 " int x = int(c.x);\n"
196 " int y = int(c.y);\n"
197 " int xm = max(x - 1, 0);\n"
198 " int xp = min(x + 1, dim.x - 1);\n"
199 " int ym = max(y - 1, 0);\n"
200 " int yp = min(y + 1, dim.y - 1);\n"
201 "\n"
202 " // Sample the divergence at (x,y).\n"
203 " float div = divergence[int2(x, y)];\n"
204 "\n"
205 " // Sample Poisson values at (x+dx,y), (x-dx,y), (x,y+dy), (x,y-dy).\n"
206 " float poisPZ = poisson[int2(xp, y)];\n"
207 " float poisMZ = poisson[int2(xm, y)];\n"
208 " float poisZP = poisson[int2(x, yp)];\n"
209 " float poisZM = poisson[int2(x, ym)];\n"
210 "\n"
211 " float4 temp = float4(poisPZ + poisMZ, poisZP + poisZM, 0.0f, div);\n"
212 " outPoisson[c] = dot(epsilon, temp);\n"
213 "}\n";
214 
216 "#if USE_ZERO_X_EDGE\n"
217 "RWTexture2D<float> image;\n"
218 "\n"
219 "[numthreads(1, NUM_Y_THREADS, 1)]\n"
220 "void CSMain(uint2 c : SV_DispatchThreadID)\n"
221 "{\n"
222 " uint2 dim;\n"
223 " image.GetDimensions(dim.x, dim.y);\n"
224 " image[uint2(0, c.y)] = 0.0f;\n"
225 " image[uint2(dim.x - 1, c.y)] = 0.0f;\n"
226 "}\n"
227 "#endif\n"
228 "\n"
229 "#if USE_ZERO_Y_EDGE\n"
230 "RWTexture2D<float> image;\n"
231 "\n"
232 "[numthreads(NUM_X_THREADS, 1, 1)]\n"
233 "void CSMain(uint2 c : SV_DispatchThreadID)\n"
234 "{\n"
235 " uint2 dim;\n"
236 " image.GetDimensions(dim.x, dim.y);\n"
237 " image[uint2(c.x, 0)] = 0.0f;\n"
238 " image[uint2(c.x, dim.y - 1)] = 0.0f;\n"
239 "}\n"
240 "#endif\n";
241 
243 {
246 };
247 
249 {
252 };
253 
255 {
258 };
DF_R32_FLOAT
Definition: GteDataFormat.h:20
static std::string const msHLSLSolveSource
std::shared_ptr< ComputeProgram > mSolvePoisson
static std::string const * msSolveSource[ProgramFactory::PF_NUM_API]
static std::string const msHLSLZeroSource
void Execute(std::shared_ptr< GraphicsEngine > const &engine, std::shared_ptr< Texture2 > const &divergence)
static std::string const * msZeroSource[ProgramFactory::PF_NUM_API]
static std::string const msGLSLEnforceSource
std::shared_ptr< ComputeProgram > mWriteXEdge
static std::string const * msEnforceSource[ProgramFactory::PF_NUM_API]
GLsizei const GLchar *const * string
Definition: glcorearb.h:809
Fluid2SolvePoisson(std::shared_ptr< ProgramFactory > const &factory, int xSize, int ySize, int numXThreads, int numYThreads, std::shared_ptr< ConstantBuffer > const &parameters, int numIterations)
std::shared_ptr< ComputeProgram > mZeroPoisson
std::shared_ptr< Texture2 > mPoisson0
static std::string const msGLSLZeroSource
std::shared_ptr< Texture2 > mPoisson1
std::shared_ptr< ComputeProgram > mWriteYEdge
static std::string const msHLSLEnforceSource
static std::string const msGLSLSolveSource


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