GteFluid2InitializeSource.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 #include <random>
13 using namespace gte;
14 
15 Fluid2InitializeSource::Fluid2InitializeSource(std::shared_ptr<ProgramFactory> const& factory,
16  int xSize, int ySize, int numXThreads, int numYThreads,
17  std::shared_ptr<ConstantBuffer> const& parameters)
18  :
19  mNumXGroups(xSize/numXThreads),
20  mNumYGroups(ySize/numYThreads)
21 {
22  // Create the resources for generating velocity from vortices.
23  mVortex = std::make_shared<ConstantBuffer>(sizeof(Vortex), true);
24  mVelocity0 = std::make_shared<Texture2>(DF_R32G32_FLOAT, xSize, ySize);
25  mVelocity0->SetUsage(Resource::SHADER_OUTPUT);
26  mVelocity1 = std::make_shared<Texture2>(DF_R32G32_FLOAT, xSize, ySize);
27  mVelocity1->SetUsage(Resource::SHADER_OUTPUT);
28 
29  // Create the resources for generating velocity from wind and gravity.
30  mExternal = std::make_shared<ConstantBuffer>(sizeof(External), false);
31  External& e = *mExternal->Get<External>();
32  e.densityProducer = { 0.25f, 0.75f, 0.01f, 2.0f };
33  e.densityConsumer = { 0.75f, 0.25f, 0.01f, 2.0f };
34  e.gravity = { 0.0f, 0.0f, 0.0f, 0.0f };
35  e.wind = { 0.0f, 0.5f, 0.001f, 32.0f };
36  mSource = std::make_shared<Texture2>(DF_R32G32B32A32_FLOAT, xSize, ySize);
37  mSource->SetUsage(Resource::SHADER_OUTPUT);
38 
39  // Create the shader for generating velocity from vortices.
40  int i = factory->GetAPI();
41  factory->PushDefines();
42  factory->defines.Set("NUM_X_THREADS", numXThreads);
43  factory->defines.Set("NUM_Y_THREADS", numYThreads);
44  std::shared_ptr<ComputeShader> cshader;
45 
46  mGenerateVortex = factory->CreateFromSource(*msGenerateSource[i]);
47  if (mGenerateVortex)
48  {
49  cshader = mGenerateVortex->GetCShader();
50  cshader->Set("Parameters", parameters);
51  cshader->Set("Vortex", mVortex);
52  cshader->Set("inVelocity", mVelocity0);
53  cshader->Set("outVelocity", mVelocity1);
54  }
55 
56  // Create the shader for generating the sources to the fluid simulation.
57  mInitializeSource = factory->CreateFromSource(*msInitializeSource[i]);
59  {
60  cshader = mInitializeSource->GetCShader();
61  cshader->Set("Parameters", parameters);
62  cshader->Set("External", mExternal);
63  cshader->Set("source", mSource);
64  }
65 
66  factory->PopDefines();
67 }
68 
69 void Fluid2InitializeSource::Execute(std::shared_ptr<GraphicsEngine> const& engine)
70 {
71  // Use a Mersenne twister engine for random numbers.
72  std::mt19937 mte;
73  std::uniform_real_distribution<float> unirnd(0.0f, 1.0f);
74  std::uniform_real_distribution<float> symrnd(-1.0f, 1.0f);
75  std::uniform_real_distribution<float> posrnd0(0.001f, 0.01f);
76  std::uniform_real_distribution<float> posrnd1(128.0f, 256.0f);
77 
78  // Compute the velocity one vortex at a time. After the loop terminates,
79  // the final velocity is stored in mVelocity0.
80  std::shared_ptr<ComputeShader> cshader = mGenerateVortex->GetCShader();
81  memset(mVelocity0->GetData(), 0, mVelocity0->GetNumBytes());
82  Vortex& v = *mVortex->Get<Vortex>();
83  for (int i = 0; i < NUM_VORTICES; ++i)
84  {
85  v.data[0] = unirnd(mte);
86  v.data[1] = unirnd(mte);
87  v.data[2] = posrnd0(mte);
88  v.data[3] = posrnd1(mte);
89  if (symrnd(mte) < 0.0f)
90  {
91  v.data[3] = -v.data[3];
92  }
93  engine->Update(mVortex);
94 
95  engine->Execute(mGenerateVortex, mNumXGroups, mNumYGroups, 1);
96 
97  std::swap(mVelocity0, mVelocity1);
98  cshader->Set("inVelocity", mVelocity0);
99  cshader->Set("outVelocity", mVelocity1);
100  }
101 
102  // Compute the sources for the fluid simulation.
103  cshader = mInitializeSource->GetCShader();
104  cshader->Set("vortexVelocity", mVelocity0);
105  engine->Execute(mInitializeSource, mNumXGroups, mNumYGroups, 1);
106 }
107 
108 
109 // TODO: Write these shaders.
111 "uniform Parameters\n"
112 "{\n"
113 " vec4 spaceDelta; // (dx, dy, 0, 0)\n"
114 " vec4 halfDivDelta; // (0.5/dx, 0.5/dy, 0, 0)\n"
115 " vec4 timeDelta; // (dt/dx, dt/dy, 0, dt)\n"
116 " vec4 viscosityX; // (velVX, velVX, 0, denVX)\n"
117 " vec4 viscosityY; // (velVX, velVY, 0, denVY)\n"
118 " vec4 epsilon; // (epsilonX, epsilonY, 0, epsilon0)\n"
119 "};\n"
120 "\n"
121 "uniform Vortex\n"
122 "{\n"
123 " vec4 data; // (x, y, variance, amplitude)\n"
124 "};\n"
125 "\n"
126 "layout(rg32f) uniform readonly image2D inVelocity;\n"
127 "layout(rg32f) uniform writeonly image2D outVelocity;\n"
128 "\n"
129 "layout (local_size_x = NUM_X_THREADS, local_size_y = NUM_Y_THREADS, local_size_z = 1) in;\n"
130 "void main()\n"
131 "{\n"
132 " ivec2 c = ivec2(gl_GlobalInvocationID.xy);\n"
133 " vec2 location = spaceDelta.xy*(c + 0.5f);\n"
134 " vec2 diff = location - data.xy;\n"
135 " float arg = -dot(diff, diff) / data.z;\n"
136 " float magnitude = data.w*exp(arg);\n"
137 " vec2 vortexVelocity = magnitude*vec2(diff.y, -diff.x);\n"
138 " imageStore(outVelocity, c, vec4(imageLoad(inVelocity, c).xy + vortexVelocity, 0.0f, 0.0f));\n"
139 "}\n";
140 
142 "uniform Parameters\n"
143 "{\n"
144 " vec4 spaceDelta; // (dx, dy, 0, 0)\n"
145 " vec4 halfDivDelta; // (0.5/dx, 0.5/dy, 0, 0)\n"
146 " vec4 timeDelta; // (dt/dx, dt/dy, 0, dt)\n"
147 " vec4 viscosityX; // (velVX, velVX, 0, denVX)\n"
148 " vec4 viscosityY; // (velVX, velVY, 0, denVY)\n"
149 " vec4 epsilon; // (epsilonX, epsilonY, 0, epsilon0)\n"
150 "};\n"
151 "\n"
152 "uniform External\n"
153 "{\n"
154 " vec4 densityProducer; // (x, y, variance, amplitude)\n"
155 " vec4 densityConsumer; // (x, y, variance, amplitude)\n"
156 " vec4 gravity; // (x, y, *, *)\n"
157 " vec4 wind; // (x, y, variance, amplitude)\n"
158 "};\n"
159 "\n"
160 "layout(rg32f) uniform readonly image2D vortexVelocity;\n"
161 "layout(rgba32f) uniform writeonly image2D source;\n"
162 "\n"
163 "layout (local_size_x = NUM_X_THREADS, local_size_y = NUM_Y_THREADS, local_size_z = 1) in;\n"
164 "void main()\n"
165 "{\n"
166 " ivec2 c = ivec2(gl_GlobalInvocationID.xy);\n"
167 "\n"
168 " // Compute the location of the pixel (x,y) in normalized [0,1]^2.\n"
169 " vec2 location = spaceDelta.xy*(c + 0.5f);\n"
170 "\n"
171 " // Compute an input to the fluid simulation consisting of a producer of\n"
172 " // density and a consumer of density.\n"
173 " vec2 diff = location - densityProducer.xy;\n"
174 " float arg = -dot(diff, diff) / densityProducer.z;\n"
175 " float density = densityProducer.w*exp(arg);\n"
176 " diff = location - densityConsumer.xy;\n"
177 " arg = -dot(diff, diff) / densityConsumer.z;\n"
178 " density -= densityConsumer.w*exp(arg);\n"
179 "\n"
180 " // Compute an input to the fluid simulation consisting of gravity,\n"
181 " // a single wind source, and vortex impulses.\n"
182 " float windDiff = location.y - wind.y;\n"
183 " float windArg = -windDiff*windDiff / wind.z;\n"
184 " vec2 windVelocity = vec2(wind.w*exp(windArg), 0.0f);\n"
185 " vec2 velocity = gravity.xy + windVelocity + imageLoad(vortexVelocity, c).xy;\n"
186 "\n"
187 " imageStore(source, c, vec4(velocity, 0.0f, density));\n"
188 "}\n";
189 
191 "cbuffer Parameters\n"
192 "{\n"
193 " float4 spaceDelta; // (dx, dy, 0, 0)\n"
194 " float4 halfDivDelta; // (0.5/dx, 0.5/dy, 0, 0)\n"
195 " float4 timeDelta; // (dt/dx, dt/dy, 0, dt)\n"
196 " float4 viscosityX; // (velVX, velVX, 0, denVX)\n"
197 " float4 viscosityY; // (velVX, velVY, 0, denVY)\n"
198 " float4 epsilon; // (epsilonX, epsilonY, 0, epsilon0)\n"
199 "};\n"
200 "\n"
201 "cbuffer Vortex\n"
202 "{\n"
203 " float4 data; // (x, y, variance, amplitude)\n"
204 "};\n"
205 "\n"
206 "Texture2D<float2> inVelocity;\n"
207 "RWTexture2D<float2> outVelocity;\n"
208 "\n"
209 "[numthreads(NUM_X_THREADS, NUM_Y_THREADS, 1)]\n"
210 "void CSMain(uint3 c : SV_DispatchThreadID)\n"
211 "{\n"
212 " float2 location = spaceDelta.xy*(c.xy + 0.5f);\n"
213 " float2 diff = location - data.xy;\n"
214 " float arg = -dot(diff, diff) / data.z;\n"
215 " float magnitude = data.w*exp(arg);\n"
216 " float2 vortexVelocity = magnitude*float2(diff.y, -diff.x);\n"
217 " outVelocity[c.xy] = inVelocity[c.xy] + vortexVelocity;\n"
218 "}\n";
219 
221 "cbuffer Parameters\n"
222 "{\n"
223 " float4 spaceDelta; // (dx, dy, 0, 0)\n"
224 " float4 halfDivDelta; // (0.5/dx, 0.5/dy, 0, 0)\n"
225 " float4 timeDelta; // (dt/dx, dt/dy, 0, dt)\n"
226 " float4 viscosityX; // (velVX, velVX, 0, denVX)\n"
227 " float4 viscosityY; // (velVX, velVY, 0, denVY)\n"
228 " float4 epsilon; // (epsilonX, epsilonY, 0, epsilon0)\n"
229 "};\n"
230 "\n"
231 "cbuffer External\n"
232 "{\n"
233 " float4 densityProducer; // (x, y, variance, amplitude)\n"
234 " float4 densityConsumer; // (x, y, variance, amplitude)\n"
235 " float4 gravity; // (x, y, *, *)\n"
236 " float4 wind; // (x, y, variance, amplitude)\n"
237 "};\n"
238 "\n"
239 "Texture2D<float2> vortexVelocity;\n"
240 "RWTexture2D<float4> source;\n"
241 "\n"
242 "[numthreads(NUM_X_THREADS, NUM_Y_THREADS, 1)]\n"
243 "void CSMain(uint2 c : SV_DispatchThreadID)\n"
244 "{\n"
245 " // Compute the location of the pixel (x,y) in normalized [0,1]^2.\n"
246 " float2 location = spaceDelta.xy*(c + 0.5f);\n"
247 "\n"
248 " // Compute an input to the fluid simulation consisting of a producer of\n"
249 " // density and a consumer of density.\n"
250 " float2 diff = location - densityProducer.xy;\n"
251 " float arg = -dot(diff, diff) / densityProducer.z;\n"
252 " float density = densityProducer.w*exp(arg);\n"
253 " diff = location - densityConsumer.xy;\n"
254 " arg = -dot(diff, diff) / densityConsumer.z;\n"
255 " density -= densityConsumer.w*exp(arg);\n"
256 "\n"
257 " // Compute an input to the fluid simulation consisting of gravity,\n"
258 " // a single wind source, and vortex impulses.\n"
259 " float windDiff = location.y - wind.y;\n"
260 " float windArg = -windDiff*windDiff / wind.z;\n"
261 " float2 windVelocity = float2(wind.w*exp(windArg), 0.0f);\n"
262 " float2 velocity = gravity.xy + windVelocity + vortexVelocity[c];\n"
263 "\n"
264 " source[c] = float4(velocity, 0.0f, density);\n"
265 "}\n";
266 
268 {
271 };
272 
274 {
277 };
static std::string const msHLSLInitializeSource
void Execute(std::shared_ptr< GraphicsEngine > const &engine)
static std::string const msGLSLGenerateSource
Fluid2InitializeSource(std::shared_ptr< ProgramFactory > const &factory, int xSize, int ySize, int numXThreads, int numYThreads, std::shared_ptr< ConstantBuffer > const &parameters)
std::shared_ptr< Texture2 > mVelocity0
static std::string const * msInitializeSource[ProgramFactory::PF_NUM_API]
static std::string const msHLSLGenerateSource
std::shared_ptr< ConstantBuffer > mExternal
GLsizei const GLchar *const * string
Definition: glcorearb.h:809
std::shared_ptr< Texture2 > mSource
DF_R32G32B32A32_FLOAT
Definition: GteDataFormat.h:20
std::shared_ptr< ConstantBuffer > mVortex
DF_R32G32_FLOAT
Definition: GteDataFormat.h:20
const GLdouble * v
Definition: glcorearb.h:832
std::shared_ptr< ComputeProgram > mInitializeSource
GLfloat f
Definition: glcorearb.h:1921
std::shared_ptr< ComputeProgram > mGenerateVortex
static std::string const msGLSLInitializeSource
std::shared_ptr< Texture2 > mVelocity1
static std::string const * msGenerateSource[ProgramFactory::PF_NUM_API]


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