RigsofRods
Soft-body Physics Simulation
GodRaysManager.cpp
Go to the documentation of this file.
1 /*
2 --------------------------------------------------------------------------------
3 This source file is part of sssHydrax.
4 sssHydrax is a modified version of Hydrax (Copyright (C) 2008 Xavier Verguín González)
5 to adapt it to SonSilentSea.
6 
7 This program is free software; you can redistribute it and/or modify it under
8 the terms of the GNU Lesser General Public License as published by the Free Software
9 Foundation; either version 2 of the License, or (at your option) any later
10 version.
11 
12 This program is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
15 
16 You should have received a copy of the GNU Lesser General Public License along with
17 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
19 http://www.gnu.org/copyleft/lesser.txt.
20 
21 Author: Jose Luis Cercós Pita
22 --------------------------------------------------------------------------------
23 */
24 
25 #include <GodRaysManager.h>
26 
27 #include <Hydrax.h>
28 
29 #define _def_GodRays_Projector_Camera_Name "_Hydrax_GodRays_Projector_Camera"
30 #define _def_GodRays_ManualObject_Name "_Hydrax_GodRays_ManualObject"
31 #define _def_GodRays_Depth_Map "_Hydrax_GodRays_Depth_Map"
32 
33 #define _def_GodRays_Material_Name "_Hydrax_GodRays_Material"
34 #define _def_GodRays_Shader_VP_Name "_Hydrax_GodRays_VP"
35 #define _def_GodRays_Shader_FP_Name "_Hydrax_GodRays_FP"
36 
37 #define _def_GodRaysDepth_Material_Name "_Hydrax_GodRaysDepth_Material"
38 #define _def_GodRaysDepth_Shader_VP_Name "_Hydrax_GodRaysDepth_VP"
39 #define _def_GodRaysDepth_Shader_FP_Name "_Hydrax_GodRaysDepth_FP"
40 
41 const Ogre::Matrix4
43  0.5, 0, 0, 0.5,
44  0, -0.5, 0, 0.5,
45  0, 0, 1, 0,
46  0, 0, 0, 1);
47 
48 namespace Hydrax
49 {
51  : mCreated(false)
52  , mManualGodRays(0)
53  , mProjectorCamera(0)
54  , mProjectorSN(0)
55  , mPerlin(0)
56  , mNoiseDerivation(3)
57  , mNoisePositionMultiplier(50)
58  , mNoiseYNormalMultiplier(10)
59  , mNoiseNormalMultiplier(0.175)
60  , mSimulationSpeed(5.0f)
61  , mNumberOfRays(100)
62  , mRaysSize(0.03f)
63  , mObjectsIntersections(false)
64  , mHydrax(h)
65  {
66  for (int k = 0; k < 2; k++)
67  {
68  mMaterials[k].setNull();
69  }
70  }
71 
73  {
74  remove();
75  }
76 
78  {
79  if (mCreated)
80  {
81  remove();
82  }
83 
84  // Create our perlin noise module
85  mPerlin = new Noise::Perlin(Noise::Perlin::Options(8, 0.085f, 0.49, 2, 0.672));
86  mPerlin->create();
87 
88  // Initial values, some of them need to be updated each frame
90  mProjectorCamera->setProjectionType(Ogre::PT_PERSPECTIVE);
91  // Not forget to set near+far distance in materials
92  mProjectorCamera->setNearClipDistance(8);
93  mProjectorCamera->setFarClipDistance(40);
94  mProjectorCamera->setAspectRatio(1);
95  mProjectorCamera->setFOVy(Ogre::Degree(45.0f));
96  mProjectorCamera->setVisible(false);
97  mProjectorSN = mHydrax->getSceneManager()->getRootSceneNode()->createChildSceneNode();
98  mProjectorSN->setPosition(0,0,0);
99  mProjectorSN->attachObject(mProjectorCamera);
100  mProjectorSN->setDirection(0, -1, 0);
101 
103  {
104  _createDepthRTT();
105  }
106 
107  _createMaterials(HC);
108 
109  std::vector<Ogre::Technique*>::iterator TechIt;
110 
111  for(TechIt = mDepthTechniques.begin(); TechIt != mDepthTechniques.end(); TechIt++)
112  {
113  if (!(*TechIt))
114  {
115  mDepthTechniques.erase(TechIt);
116  // TechIt-- ?
117  continue;
118  }
119 
120  addDepthTechnique((*TechIt), false);
121  }
122 
123  _createGodRays();
124 
125  mCreated = true;
126  }
127 
129  {
131  mManualGodRays->setDynamic(true);
133 
134  mManualGodRays->begin(_def_GodRays_Material_Name, Ogre::RenderOperation::OT_TRIANGLE_LIST);
135  mManualGodRays->setRenderQueueGroup(Ogre::RENDER_QUEUE_9+1);
136 
137  for(int r = 0; r < mNumberOfRays; r++)
138  {
139  // Rays are modeled as pyramids, 12 vertex each ray
140  for (int k = 0; k < 12; k++)
141  {
142  mManualGodRays->position(0, 0, 0);
143  mManualGodRays->index(k);
144  }
145  }
146 
147  mManualGodRays->end();
148  mProjectorSN->attachObject(mManualGodRays);
149  }
150 
152  {
153  if (!mCreated)
154  {
155  return;
156  }
157 
158  delete mPerlin;
159  mPerlin = static_cast<Noise::Perlin*>(NULL);
160 
161  mHydrax->getSceneManager()->destroyManualObject(mManualGodRays);
162  mManualGodRays = static_cast<Ogre::ManualObject*>(NULL);
163 
164  if (Ogre::MaterialManager::getSingleton().resourceExists(_def_GodRays_Material_Name))
165  {
166  Ogre::MaterialManager::getSingleton().remove(_def_GodRays_Material_Name);
167 
168  Ogre::HighLevelGpuProgramManager::getSingleton().unload(_def_GodRays_Shader_VP_Name);
169  Ogre::HighLevelGpuProgramManager::getSingleton().unload(_def_GodRays_Shader_FP_Name);
170  Ogre::HighLevelGpuProgramManager::getSingleton().remove(_def_GodRays_Shader_VP_Name);
171  Ogre::HighLevelGpuProgramManager::getSingleton().remove(_def_GodRays_Shader_FP_Name);
172  }
173 
174  if (Ogre::MaterialManager::getSingleton().resourceExists(_def_GodRaysDepth_Material_Name))
175  {
176  Ogre::MaterialManager::getSingleton().remove(_def_GodRaysDepth_Material_Name);
177 
178  Ogre::HighLevelGpuProgramManager::getSingleton().unload(_def_GodRaysDepth_Shader_VP_Name);
179  Ogre::HighLevelGpuProgramManager::getSingleton().unload(_def_GodRaysDepth_Shader_FP_Name);
180  Ogre::HighLevelGpuProgramManager::getSingleton().remove(_def_GodRaysDepth_Shader_VP_Name);
181  Ogre::HighLevelGpuProgramManager::getSingleton().remove(_def_GodRaysDepth_Shader_FP_Name);
182  }
183 
184  for (int k = 0; k < 2; k++)
185  {
186  mMaterials[k].setNull();
187  }
188 
189  if (!mProjectorRTT.isNull())
190  {
191  Ogre::RenderTarget* RT = mProjectorRTT->getBuffer()->getRenderTarget();
192  RT->removeAllListeners();
193  RT->removeAllViewports();
194 
195  Ogre::TextureManager::getSingleton().remove(mProjectorRTT->getName());
196  mProjectorRTT.setNull();
197  }
198 
199  mHydrax->getSceneManager()->destroyCamera(mProjectorCamera);
200  mProjectorCamera = static_cast<Ogre::Camera*>(NULL);
201 
202  mProjectorSN->detachAllObjects();
203  mProjectorSN->getParentSceneNode()->removeAndDestroyChild(mProjectorSN);
204  mProjectorSN = static_cast<Ogre::SceneNode*>(NULL);
205 
206  mCreated = false;
207  }
208 
209  void GodRaysManager::update(const Ogre::Real& timeSinceLastFrame)
210  {
212  {
213  return;
214  }
215 
216  mPerlin->update(timeSinceLastFrame);
217 
218  _updateRays();
220 
222  {
224  mProjectorRTT->getBuffer()->getRenderTarget()->update();
225  }
226  }
227 
229  {
230  // Get frustum corners to calculate far plane dimensions
231  const Ogre::Vector3 *FrustumCorners = mProjectorCamera->getWorldSpaceCorners();
232  // Calcule far plane dimensions
233  float FarWidth = (FrustumCorners[4] - FrustumCorners[5]).length();
234  Ogre::Real RaysLength = mProjectorCamera->getFarClipDistance();
235 
236  mManualGodRays->beginUpdate(0);
237 
238  Ogre::Vector2 Pos;
239  Ogre::Real Dis, RayLength;
240 
241  // Rays are modeled as piramids, 12 vertex each ray
242  //
243  // // 0\\
244  // /| | |
245  // || | |
246  // || | | (0,0) (1,0)
247  // || | | A B
248  // || | |
249  // |A----|-|B (0,1) (1,1)
250  // |/ |/ C D
251  // C------D
252 
253  for(int k = 0; k < mNumberOfRays; k++)
254  {
255  Pos = _calculateRayPosition(k);
256  Dis = mRaysSize*RaysLength;
257  RayLength = RaysLength*(0.95+Pos.length());
258 
259  Pos *= FarWidth/2;
260 
261  // 4 Planes, 3 vertices each plane, 12 vertices per ray
262  // ----> 1/4
263  // 0
264  mManualGodRays->position(0, 0, 0);
265  // A
266  mManualGodRays->position(Pos.x, Pos.y, -RayLength);
267  // B
268  mManualGodRays->position(Pos.x+Dis, Pos.y, -RayLength);
269  // ----> 2/4
270  // 0
271  mManualGodRays->position(0, 0, 0);
272  // D
273  mManualGodRays->position(Pos.x+Dis, Pos.y+Dis, -RayLength);
274  // B
275  mManualGodRays->position(Pos.x+Dis, Pos.y, -RayLength);
276  // ----> 3/4
277  // 0
278  mManualGodRays->position(0, 0, 0);
279  // C
280  mManualGodRays->position(Pos.x, Pos.y+Dis, -RayLength);
281  // D
282  mManualGodRays->position(Pos.x+Dis, Pos.y+Dis, -RayLength);
283  // ----> 4/4
284  // 0
285  mManualGodRays->position(0, 0, 0);
286  // C
287  mManualGodRays->position(Pos.x, Pos.y+Dis, -RayLength);
288  // A
289  mManualGodRays->position(Pos.x, Pos.y, -RayLength);
290  }
291 
292  mManualGodRays->end();
293  }
294 
295  Ogre::Vector2 GodRaysManager::_calculateRayPosition(const int& RayNumber)
296  {
297  Ogre::Real sqrt_NumberOfRays = Ogre::Math::Sqrt(mNumberOfRays);
298  Ogre::Real XCoord = RayNumber;
299 
300  while (XCoord >= sqrt_NumberOfRays)
301  {
302  XCoord -= sqrt_NumberOfRays;
303  }
304 
305  Ogre::Vector2 RayPos =
306  Ogre::Vector2( // X coord
307  static_cast<int>(XCoord),
308  // Y coord
309  static_cast<int>((RayNumber+sqrt_NumberOfRays)/sqrt_NumberOfRays)-1);
310 
311  RayPos /= sqrt_NumberOfRays;
312  RayPos -= Ogre::Vector2(0.5, 0.5);
313  RayPos *= 2;
314 
315  Ogre::Vector2 Position = RayPos*mNoisePositionMultiplier + Ogre::Vector2(mProjectorSN->getPosition().x, mProjectorSN->getPosition().z);
316 
317  Ogre::Vector3
318  m_x = Ogre::Vector3(Position.x-mNoiseDerivation, mPerlin->getValue(Position.x-mNoiseDerivation,0), 0),
319  p_x = Ogre::Vector3(Position.x+mNoiseDerivation, mPerlin->getValue(Position.x+mNoiseDerivation,0), 0),
320  m_y = Ogre::Vector3(0, mPerlin->getValue(0,Position.y-mNoiseDerivation), Position.y-mNoiseDerivation),
321  p_y = Ogre::Vector3(0, mPerlin->getValue(0,Position.y+mNoiseDerivation), Position.y+mNoiseDerivation);
322 
325 
326  Ogre::Vector3 Normal = (p_x-m_x).crossProduct((p_y-m_y));
327 
328  Normal *= mNoiseNormalMultiplier;
329 
330  return RayPos + Ogre::Vector2(Normal.x, Normal.z);
331  }
332 
333  void GodRaysManager::setNumberOfRays(const int& NumberOfRays)
334  {
335  mNumberOfRays = NumberOfRays;
336 
337  if (!mCreated)
338  {
339  return;
340  }
341 
342  mProjectorSN->detachObject(mManualGodRays);
343 
344  mHydrax->getSceneManager()->destroyManualObject(mManualGodRays);
345  mManualGodRays = static_cast<Ogre::ManualObject*>(NULL);
346 
347  _createGodRays();
348  }
349 
351  {
352  mObjectsIntersections = Enable;
353 
354  const HydraxComponent& Components = mHydrax->getComponents();
355 
356  create(Components);
357  }
358 
360  {
362  {
363  return;
364  }
365 
366  Ogre::GpuProgramParametersSharedPtr VP_Parameters, FP_Parameters;
367 
368  // God rays material
369  VP_Parameters = mMaterials[0]->getTechnique(0)->getPass(0)->getVertexProgramParameters();
370  FP_Parameters = mMaterials[0]->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
371 
372  Ogre::Matrix4 TexViewProj =
374  mProjectorCamera->getProjectionMatrixWithRSDepth() *
375  mProjectorCamera->getViewMatrix();
376 
377  VP_Parameters->setNamedConstant("uTexViewProj", TexViewProj);
378 
379  FP_Parameters->setNamedConstant("uLightPosition", mProjectorSN->getPosition());
380  FP_Parameters->setNamedConstant("uLightFarClipDistance", mProjectorCamera->getFarClipDistance());
381 
382  // Depth material
383  FP_Parameters = mMaterials[1]->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
384 
385  FP_Parameters->setNamedConstant("uLightPosition", mProjectorSN->getPosition());
386  FP_Parameters->setNamedConstant("uLightFarClipDistance", mProjectorCamera->getFarClipDistance());
387 
388  std::vector<Ogre::Technique*>::iterator TechIt;
389 
390  for(TechIt = mDepthTechniques.begin(); TechIt != mDepthTechniques.end(); TechIt++)
391  {
392  if (!(*TechIt))
393  {
394  mDepthTechniques.erase(TechIt);
395  // TechIt-- ?
396  continue;
397  }
398 
399  (*TechIt)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("uLightPosition", mProjectorSN->getPosition());
400  (*TechIt)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("uLightFarClipDistance", mProjectorCamera->getFarClipDistance());
401  }
402  }
403 
405  {
406  const Ogre::Vector3& SunPosition = mHydrax->getSunPosition();
407  const Ogre::Vector3& CameraPosition = mHydrax->getCamera()->getDerivedPosition();
408 
409  Ogre::Plane WaterPlane = Ogre::Plane(Ogre::Vector3(0,1,0), mHydrax->getPosition());
410  Ogre::Ray SunToCameraRay = Ogre::Ray(SunPosition, CameraPosition-SunPosition);
411 
412  Ogre::Vector3 WaterProjectionPoint = SunToCameraRay.getPoint(SunToCameraRay.intersects(WaterPlane).second);
413 
414  mProjectorSN->setPosition(WaterProjectionPoint);
415  mProjectorCamera->setFarClipDistance((WaterProjectionPoint-CameraPosition).length());
416  mProjectorSN->setDirection(-(WaterProjectionPoint-CameraPosition).normalisedCopy(), Ogre::Node::TS_WORLD);
417  }
418 
420  {
421  Ogre::String VertexProgramData, FragmentProgramData;
422  Ogre::GpuProgramParametersSharedPtr VP_Parameters, FP_Parameters;
423  Ogre::String EntryPoints[2];
425  {
426  EntryPoints[0] = Ogre::String("main");
427  EntryPoints[1] = Ogre::String("main");
428  }
429  else
430  {
431  EntryPoints[0] = Ogre::String("main_vp");
432  EntryPoints[1] = Ogre::String("main_fp");
433  }
434  Ogre::String GpuProgramsData[2]; Ogre::String GpuProgramNames[2];
435  MaterialManager *mMaterialManager = mHydrax->getMaterialManager();
436 
437  int NumberOfDepthChannels = 0;
438  Ogre::String GB[2] = {"0, 1, 0", "0, 0, 1"};
439 
441  {
442  NumberOfDepthChannels++;
443  }
444 
445  // God Rays material
446 
447  VertexProgramData = "";
448  FragmentProgramData = "";
449 
450  // Vertex program
451 
452  switch (mHydrax->getShaderMode())
453  {
455  {
456  VertexProgramData +=
457  Ogre::String(
458  "void main_vp(\n") +
459  // IN
460  "float4 iPosition : POSITION,\n" +
461  // OUT
462  "out float4 oPosition : POSITION,\n";
464  {
465  VertexProgramData += Ogre::String(
466  "out float3 oPosition_ : TEXCOORD0,\n") +
467  "out float4 oProjUV : TEXCOORD1,\n" +
468  // UNIFORM
469  "uniform float4x4 uWorld,\n" +
470  "uniform float4x4 uTexViewProj,\n";
471  }
472  VertexProgramData += Ogre::String(
473  "uniform float4x4 uWorldViewProj)\n") +
474  "{\n" +
475  "oPosition = mul(uWorldViewProj, iPosition);\n";
477  {
478  VertexProgramData += Ogre::String(
479  "float4 wPos = mul(uWorld, iPosition);\n")+
480  "oPosition_ = wPos.xyz;\n"+
481  "oProjUV = mul(uTexViewProj, wPos);\n";
482  }
483  VertexProgramData +=
484  "}\n";
485  }
486  break;
487 
489  {
490  VertexProgramData += Ogre::String( "\n" );
491  // UNIFORMS
493  {
494  VertexProgramData += Ogre::String(
495  "uniform mat4 uWorld;\n") +
496  "uniform mat4 uTexViewProj;\n";
497  }
498  // IN
499  // OUT
501  {
502  VertexProgramData += Ogre::String(
503  "varying vec3 Position_;\n") +
504  "varying vec4 ProjUV;\n";
505  }
506  // main function
507  VertexProgramData += Ogre::String(
508  "void main()\n") +
509  "{\n" +
510  "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n";
512  {
513  VertexProgramData += Ogre::String(
514  "vec4 wPos = uWorld * gl_Vertex);\n")+
515  "Position_ = wPos.xyz;\n"+
516  "ProjUV = uTexViewProj * wPos;\n";
517  }
518  VertexProgramData +=
519  "}\n";
520  }
521  break;
522  }
523 
524  // Fragment program
525 
526  switch (mHydrax->getShaderMode())
527  {
529  {
531  FragmentProgramData +=
532  Ogre::String(
533  "void main_fp(\n") +
534  // IN
535  "float3 iPosition : TEXCOORD0,\n" +
536  "float4 iProjUV : TEXCOORD1,\n" +
537  // OUT
538  "out float4 oColor : COLOR,\n" +
539  // UNIFORM
540  "uniform float3 uLightPosition,\n"+
541  "uniform float uLightFarClipDistance,\n" +
542  "uniform sampler2D uDepthMap : register(s0))\n" +
543  "{\n" +
544  "iProjUV = iProjUV / iProjUV.w;\n"+
545  "float Depth = tex2D(uDepthMap, iProjUV.xy).r;\n"+
546  "if (Depth < saturate( length(iPosition-uLightPosition) / uLightFarClipDistance ))\n"+
547  "{\n"+
548  "oColor = float4(0,0,0,1);\n"+
549  "}\n"+
550  "else\n"+
551  "{\n"+
552  "oColor = float4(float3(" + GB[NumberOfDepthChannels] + ") * 0.1, 1);\n"+
553  "}\n"+
554  "}\n";
555  else
556  FragmentProgramData +=
557  Ogre::String(
558  "void main_fp(\n") +
559  // OUT
560  "out float4 oColor : COLOR)\n" +
561  "{\n" +
562  "oColor = float4(float3(" + GB[NumberOfDepthChannels] + ") * 0.1, 1);\n"+
563  "}\n";
564  }
565  break;
566 
568  {
570  FragmentProgramData += Ogre::String( "\n" ) +
571  // UNIFORMS
572  "uniform vec3 uLightPosition;\n"+
573  "uniform float uLightFarClipDistance;\n" +
574  "uniform sampler2D uDepthMap;\n" +
575  // IN
576  "varying vec3 Position_;\n" +
577  "varying vec4 ProjUV;\n" +
578  // OUT
579  // main function
580  "void main()\n" +
581  "{\n" +
582  "ProjUV /= ProjUV.w;\n" +
583  "float Depth = texture2D(uDepthMap, ProjUV.xy).x;\n" +
584  "if(Depth < clamp( length(Position_-uLightPosition) / uLightFarClipDistance ), 0.0, 1.0)\n" +
585  "{\n"+
586  "gl_FragColor = vec4(0.0,0.0,0.0,1.0);\n"+
587  "}\n"+
588  "else\n"+
589  "{\n"+
590  "gl_FragColor = vec4(vec3(" + GB[NumberOfDepthChannels] + ") * 0.1, 1.0);\n"+
591  "}\n"+
592  "}\n";
593  else
594  FragmentProgramData += Ogre::String( "\n" ) +
595  // UNIFORMS
596  "uniform vec3 uLightPosition;\n"+
597  "uniform float uLightFarClipDistance;\n" +
598  "uniform sampler2D uDepthMap;\n" +
599  // IN
600  "varying vec3 Position_;\n" +
601  "varying vec4 ProjUV;\n" +
602  // OUT
603  // main function
604  "void main()\n" +
605  "{\n" +
606  "gl_FragColor = vec4(vec3(" + GB[NumberOfDepthChannels] + ") * 0.1, 1.0);\n"+
607  "}\n";
608  }
609  break;
610  }
611 
612  // Build our material
613  mMaterials[0] = Ogre::MaterialManager::getSingleton().
615  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
616 
617  Ogre::Pass *GR_Technique0_Pass0 = mMaterials[0]->getTechnique(0)->getPass(0);
618 
619  GR_Technique0_Pass0->setLightingEnabled(false);
620  GR_Technique0_Pass0->setCullingMode(Ogre::CULL_NONE);
621  GR_Technique0_Pass0->setDepthWriteEnabled(false);
622  GR_Technique0_Pass0->setDepthCheckEnabled(mObjectsIntersections);
623  GR_Technique0_Pass0->setSceneBlending(Ogre::SBT_ADD);
624 
625  GpuProgramsData[0] = VertexProgramData; GpuProgramsData[1] = FragmentProgramData;
626  GpuProgramNames[0] = _def_GodRays_Shader_VP_Name; GpuProgramNames[1] = _def_GodRays_Shader_FP_Name;
627 
628  mMaterialManager->fillGpuProgramsToPass(GR_Technique0_Pass0, GpuProgramNames, mHydrax->getShaderMode(), EntryPoints, GpuProgramsData);
629 
630  VP_Parameters = GR_Technique0_Pass0->getVertexProgramParameters();
631  FP_Parameters = GR_Technique0_Pass0->getFragmentProgramParameters();
632 
634  {
635  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
636  }
637 
639  {
640  return;
641  }
642 
643  Ogre::Matrix4 TexViewProj =
645  mProjectorCamera->getProjectionMatrixWithRSDepth() *
646  mProjectorCamera->getViewMatrix();
647 
648  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
649  VP_Parameters->setNamedConstant("uTexViewProj", TexViewProj);
650 
651  FP_Parameters->setNamedConstant("uLightPosition", mProjectorSN->getPosition());
652  FP_Parameters->setNamedConstant("uLightFarClipDistance", mProjectorCamera->getFarClipDistance());
653 
654  int GLSLTextUnit = 0;
656  {
657  FP_Parameters->setNamedConstant("uDepthMap", GLSLTextUnit);
658  GLSLTextUnit++;
659  }
660  GR_Technique0_Pass0->createTextureUnitState(_def_GodRays_Depth_Map)->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
661  GR_Technique0_Pass0->getTextureUnitState(0)->setTextureName(_def_GodRays_Depth_Map);
662 
663  // Depth material
664 
665  VertexProgramData = "";
666  FragmentProgramData = "";
667 
668  // Vertex program
669 
670  switch (mHydrax->getShaderMode())
671  {
673  {
674  VertexProgramData +=
675  Ogre::String(
676  "void main_vp(\n") +
677  // IN
678  "float4 iPosition : POSITION,\n" +
679  "float2 iUV : TEXCOORD0,\n" +
680  // OUT
681  "out float4 oPosition : POSITION,\n" +
682  "out float3 oPosition_ : TEXCOORD0,\n" +
683  // UNIFORM
684  "uniform float4x4 uWorld,\n" +
685  "uniform float4x4 uWorldViewProj)\n" +
686  "{\n" +
687  "oPosition = mul(uWorldViewProj, iPosition);\n"+
688  "float4 wPos = mul(uWorld, iPosition);\n"+
689  "oPosition_ = wPos.xyz;\n"+
690  "}\n";
691  }
692  break;
693 
695  {
696  VertexProgramData += Ogre::String( "\n" ) +
697  // UNIFORMS
698  "uniform mat4 uWorld;\n" +
699  // IN
700  // OUT
701  "varying vec3 Position_;\n" +
702  // main function
703  "void main()\n" +
704  "{\n" +
705  "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"+
706  "vec4 wPos = uWorld * gl_Vertex;\n"+
707  "Position_ = wPos.xyz;\n"+
708  "}\n";
709  }
710  break;
711  }
712 
713  // Fragment program
714 
715  switch (mHydrax->getShaderMode())
716  {
718  {
719  FragmentProgramData +=
720  Ogre::String(
721  "void main_fp(\n") +
722  // IN
723  "float3 iPosition : TEXCOORD0,\n" +
724  // OUT
725  "out float4 oColor : COLOR,\n" +
726  // UNIFORM
727  "uniform float3 uLightPosition,\n" +
728  "uniform float uLightFarClipDistance)\n" +
729  "{\n" +
730  "float depth = saturate( length(iPosition-uLightPosition) / uLightFarClipDistance );\n"+
731  "oColor = float4(depth, 0, 0, 0);\n"+
732  "}\n";
733  }
734  break;
735 
737  {
738  VertexProgramData += Ogre::String( "\n" ) +
739  // UNIFORMS
740  "uniform vec3 uLightPosition;\n" +
741  "uniform float uLightFarClipDistance;\n" +
742  // IN
743  "varying vec3 Position_;\n" +
744  // OUT
745  // main function
746  "void main()\n" +
747  "{\n" +
748  "float depth = clamp( length(Position_-uLightPosition) / uLightFarClipDistance , 0.0, 1.0);\n"+
749  "gl_FragColor = vec4(depth, 0.0, 0.0, 0.0);\n"+
750  "}\n";
751  }
752  break;
753  }
754 
755  // Build our material
756  mMaterials[1] = Ogre::MaterialManager::getSingleton().
758  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
759 
760  Ogre::Pass *GRD_Technique0_Pass0 = mMaterials[1]->getTechnique(0)->getPass(0);
761 
762  mMaterials[1]->getTechnique(0)->setSchemeName("HydraxGodRaysDepth");
763 
764  GRD_Technique0_Pass0->setLightingEnabled(false);
765  GRD_Technique0_Pass0->setCullingMode(Ogre::CULL_NONE);
766 
767  GpuProgramsData[0] = VertexProgramData; GpuProgramsData[1] = FragmentProgramData;
768  GpuProgramNames[0] = _def_GodRaysDepth_Shader_VP_Name; GpuProgramNames[1] = _def_GodRaysDepth_Shader_FP_Name;
769 
770  mMaterialManager->fillGpuProgramsToPass(GRD_Technique0_Pass0, GpuProgramNames, mHydrax->getShaderMode(), EntryPoints, GpuProgramsData);
771 
772  VP_Parameters = GRD_Technique0_Pass0->getVertexProgramParameters();
773  FP_Parameters = GRD_Technique0_Pass0->getFragmentProgramParameters();
774 
776  {
777  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
778  }
779  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
780 
781  FP_Parameters->setNamedConstant("uLightPosition", mProjectorSN->getPosition());
782  FP_Parameters->setNamedConstant("uLightFarClipDistance", mProjectorCamera->getFarClipDistance());
783  }
784 
785  void GodRaysManager::addDepthTechnique(Ogre::Technique *Technique, const bool& AutoUpdate)
786  {
787  if (!Ogre::MaterialManager::getSingleton().resourceExists(_def_GodRaysDepth_Material_Name))
788  {
789  HydraxLOG("GodRaysManager::addDepthTechnique(...) Objects intersection must be enabled and Hydrax::create() already called, skipping...");
790 
791  return;
792  }
793 
794  Technique->removeAllPasses();
795  Technique->createPass();
796  Technique->setSchemeName("HydraxGodRaysDepth");
797 
798  Ogre::Pass *DM_Technique_Pass0 = Technique->getPass(0);
799 
800  DM_Technique_Pass0->setVertexProgram(_def_GodRaysDepth_Shader_VP_Name);
801  DM_Technique_Pass0->setFragmentProgram(_def_GodRaysDepth_Shader_FP_Name);
802 
803  Ogre::GpuProgramParametersSharedPtr VP_Parameters = DM_Technique_Pass0->getVertexProgramParameters();
804  Ogre::GpuProgramParametersSharedPtr FP_Parameters = DM_Technique_Pass0->getFragmentProgramParameters();
805 
807  {
808  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
809  }
810  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
811 
812  FP_Parameters->setNamedConstant("uLightPosition", mProjectorSN->getPosition());
813  FP_Parameters->setNamedConstant("uLightFarClipDistance", mProjectorCamera->getFarClipDistance());
814 
815  if (AutoUpdate)
816  {
817  mDepthTechniques.push_back(Technique);
818  }
819  }
820 
821  bool GodRaysManager::_isComponent(const HydraxComponent &List, const HydraxComponent &ToCheck) const
822  {
823  if (List & ToCheck)
824  {
825  return true;
826  }
827 
828  if (ToCheck == HYDRAX_COMPONENTS_NONE && List == HYDRAX_COMPONENTS_NONE)
829  {
830  return true;
831  }
832 
833  if (ToCheck == HYDRAX_COMPONENTS_ALL && List == HYDRAX_COMPONENTS_ALL)
834  {
835  return true;
836  }
837 
838  return false;
839  }
840 
842  {
843  mProjectorRTT = Ogre::TextureManager::getSingleton()
844  .createManual(_def_GodRays_Depth_Map,
845  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
846  Ogre::TEX_TYPE_2D,
847  // 256*256 must be sufficient
848  256,
849  256,
850  0,
851  // Only one channel
852  Ogre::PF_L8,
853  Ogre::TU_RENDERTARGET);
854 
855  Ogre::RenderTarget* RT_Texture = mProjectorRTT->getBuffer()->getRenderTarget();
856  RT_Texture->setAutoUpdated(false);
857 
858  Ogre::Viewport *RT_Texture_Viewport = RT_Texture->addViewport(mProjectorCamera);
859  RT_Texture_Viewport->setClearEveryFrame(true);
860  RT_Texture_Viewport->setMaterialScheme("HydraxGodRaysDepth");
861  RT_Texture_Viewport->setBackgroundColour(Ogre::ColourValue::White);
862  RT_Texture_Viewport->setOverlaysEnabled(false);
863  RT_Texture_Viewport->setSkiesEnabled(false);
864  RT_Texture_Viewport->setShadowsEnabled(false);
866  RT_Texture->addListener(&mDepthMapListener);
867  }
868 
869  void GodRaysManager::DepthMapListener::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
870  {
871  Ogre::SceneManager::MovableObjectIterator EntityIterator = mGodRaysManager->mHydrax->getSceneManager()->getMovableObjectIterator("Entity");
872  Ogre::Entity * CurrentEntity = NULL;
873  unsigned int k = 0;
874 
875  mMaterials.empty();
876 
877  mGodRaysManager->mHydrax->getMesh()->getEntity()->setVisible(false);
878 
879  while( EntityIterator.hasMoreElements() )
880  {
881  CurrentEntity = static_cast<Ogre::Entity *>(EntityIterator.peekNextValue());
882 
883  for( k = 0; k < CurrentEntity->getNumSubEntities(); k++ )
884  {
885  mMaterials.push(CurrentEntity->getSubEntity(k)->getMaterialName());
886  CurrentEntity->getSubEntity(k)->setMaterialName(_def_GodRaysDepth_Material_Name);
887  }
888 
889  EntityIterator.moveNext();
890  }
891  }
892 
893  void GodRaysManager::DepthMapListener::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
894  {
895  Ogre::SceneManager::MovableObjectIterator EntityIterator = mGodRaysManager->mHydrax->getSceneManager()->getMovableObjectIterator("Entity");
896  Ogre::Entity * CurrentEntity = NULL;
897  unsigned int k = 0;
898 
899  mGodRaysManager->mHydrax->getMesh()->getEntity()->setVisible(true);
900 
901  while( EntityIterator.hasMoreElements() )
902  {
903  CurrentEntity = static_cast<Ogre::Entity *>(EntityIterator.peekNextValue());
904 
905  for( k = 0; k < CurrentEntity->getNumSubEntities(); k++ )
906  {
907  CurrentEntity->getSubEntity(k)->setMaterialName(mMaterials.front());
908  mMaterials.pop();
909  }
910 
911  EntityIterator.moveNext();
912  }
913  }
914 }
Hydrax::Noise::Perlin::getValue
float getValue(const float &x, const float &y)
Get the especified x/y noise value.
Definition: Perlin.cpp:403
Hydrax::GodRaysManager::_updateMaterialsParameters
void _updateMaterialsParameters()
Update materials parameters.
Definition: GodRaysManager.cpp:359
Hydrax::GodRaysManager::_createDepthRTT
void _createDepthRTT()
Create depth RTT.
Definition: GodRaysManager.cpp:841
Hydrax::GodRaysManager::mProjectorSN
Ogre::SceneNode * mProjectorSN
Projector scene node.
Definition: GodRaysManager.h:299
_def_GodRays_Material_Name
#define _def_GodRays_Material_Name
Definition: GodRaysManager.cpp:33
Hydrax::GodRaysManager::addDepthTechnique
void addDepthTechnique(Ogre::Technique *Technique, const bool &AutoUpdate=true)
Add god rays depth technique to an especified material.
Definition: GodRaysManager.cpp:785
Hydrax::GodRaysManager::DepthMapListener::mMaterials
std::queue< std::string > mMaterials
std::string to store entity's original materials name
Definition: GodRaysManager.h:238
Hydrax::GodRaysManager::GodRaysManager
GodRaysManager(Hydrax *h)
Constructor.
Definition: GodRaysManager.cpp:50
_def_GodRays_ManualObject_Name
#define _def_GodRays_ManualObject_Name
Definition: GodRaysManager.cpp:30
Hydrax::GodRaysManager::mNoiseDerivation
Ogre::Real mNoiseDerivation
Noise parameters (Used in _calculateRayPosition(...))
Definition: GodRaysManager.h:307
Hydrax::MaterialManager::SM_GLSL
@ SM_GLSL
Definition: MaterialManager.h:95
Hydrax::HYDRAX_COMPONENTS_ALL
@ HYDRAX_COMPONENTS_ALL
Definition: Enums.h:71
Hydrax::Hydrax::getPosition
const Ogre::Vector3 & getPosition() const
Get water position.
Definition: Hydrax.h:413
Hydrax::GodRaysManager::_isComponent
bool _isComponent(const HydraxComponent &List, const HydraxComponent &ToCheck) const
Is component in the given list?
Definition: GodRaysManager.cpp:821
Hydrax::Hydrax::getMesh
Mesh * getMesh()
Get Hydrax::Mesh.
Definition: Hydrax.h:317
Hydrax
Definition: CfgFileManager.cpp:28
_def_GodRays_Shader_FP_Name
#define _def_GodRays_Shader_FP_Name
Definition: GodRaysManager.cpp:35
Hydrax::Hydrax::getMaterialManager
MaterialManager * getMaterialManager()
Get Hydrax::MaterialManager.
Definition: Hydrax.h:325
Hydrax::GodRaysManager::mManualGodRays
Ogre::ManualObject * mManualGodRays
Manual object to create god rays.
Definition: GodRaysManager.h:295
Hydrax::GodRaysManager::mNoisePositionMultiplier
Ogre::Real mNoisePositionMultiplier
PositionMultiplier value.
Definition: GodRaysManager.h:309
Hydrax::GodRaysManager::remove
void remove()
Remove.
Definition: GodRaysManager.cpp:151
Hydrax.h
Hydrax::MaterialManager
Material/Shader manager class.
Definition: MaterialManager.h:44
Hydrax::GodRaysManager::mHydrax
Hydrax * mHydrax
Hydrax parent pointer.
Definition: GodRaysManager.h:337
Hydrax::GodRaysManager::mProjectorRTT
Ogre::TexturePtr mProjectorRTT
For rays intersection with objects we use a depth map based technique Depth RTT texture.
Definition: GodRaysManager.h:332
Hydrax::GodRaysManager::setObjectIntersectionsEnabled
void setObjectIntersectionsEnabled(const bool &Enable)
Set objects intersections enabled.
Definition: GodRaysManager.cpp:350
_def_GodRaysDepth_Shader_FP_Name
#define _def_GodRaysDepth_Shader_FP_Name
Definition: GodRaysManager.cpp:39
Hydrax::GodRaysManager::mNumberOfRays
int mNumberOfRays
Number of rays.
Definition: GodRaysManager.h:324
Hydrax::GodRaysManager::_createMaterials
void _createMaterials(const HydraxComponent &HC)
Create materials that we need(God rays depth too if it's needed)
Definition: GodRaysManager.cpp:419
Hydrax::Hydrax::getShaderMode
const MaterialManager::ShaderMode & getShaderMode() const
Get current shader mode.
Definition: Hydrax.h:405
_def_GodRays_Depth_Map
#define _def_GodRays_Depth_Map
Definition: GodRaysManager.cpp:31
_def_GodRays_Projector_Camera_Name
#define _def_GodRays_Projector_Camera_Name
Definition: GodRaysManager.cpp:29
_def_GodRays_Shader_VP_Name
#define _def_GodRays_Shader_VP_Name
Definition: GodRaysManager.cpp:34
Hydrax::GodRaysManager::_createGodRays
void _createGodRays()
Create god rays manual object.
Definition: GodRaysManager.cpp:128
Hydrax::MaterialManager::fillGpuProgramsToPass
bool fillGpuProgramsToPass(Ogre::Pass *Pass, const Ogre::String GpuProgramNames[2], const ShaderMode &SM, const Ogre::String EntryPoints[2], const Ogre::String Data[2])
Fill GPU vertex and fragment program to a pass.
Definition: MaterialManager.cpp:239
Hydrax::MaterialManager::SM_HLSL
@ SM_HLSL
Definition: MaterialManager.h:91
Hydrax::GodRaysManager::mProjectorCamera
Ogre::Camera * mProjectorCamera
Camera used to project rays.
Definition: GodRaysManager.h:297
Hydrax::GodRaysManager::_calculateRayPosition
Ogre::Vector2 _calculateRayPosition(const int &RayNumber)
Calculate the current position of a ray.
Definition: GodRaysManager.cpp:295
Hydrax::GodRaysManager::mNoiseNormalMultiplier
Ogre::Real mNoiseNormalMultiplier
Normal multiplier.
Definition: GodRaysManager.h:313
Hydrax::Hydrax::getSceneManager
Ogre::SceneManager * getSceneManager()
Get scene manager.
Definition: Hydrax.h:309
Hydrax::Hydrax::getCamera
Ogre::Camera * getCamera()
Get rendering camera.
Definition: Hydrax.h:293
Hydrax::Hydrax::getComponents
const HydraxComponent & getComponents() const
Get hydrax components selected.
Definition: Hydrax.h:389
HydraxLOG
#define HydraxLOG(msg)
Definition: Application.h:59
Hydrax::GodRaysManager::mRaysSize
Ogre::Real mRaysSize
God rays size.
Definition: GodRaysManager.h:326
Hydrax::GodRaysManager::create
void create(const HydraxComponent &HC)
Create.
Definition: GodRaysManager.cpp:77
Hydrax::GodRaysManager::_updateProjector
void _updateProjector()
Update projector.
Definition: GodRaysManager.cpp:404
GodRaysManager.h
Hydrax::GodRaysManager::mMaterials
Ogre::MaterialPtr mMaterials[2]
God rays materials 0-God rays, 1-Depth.
Definition: GodRaysManager.h:317
Hydrax::GodRaysManager::_updateRays
void _updateRays()
Update god rays.
Definition: GodRaysManager.cpp:228
Hydrax::Noise::Perlin::update
void update(const Ogre::Real &timeSinceLastFrame)
Call it each frame.
Definition: Perlin.cpp:367
Hydrax::GodRaysManager::update
void update(const Ogre::Real &timeSinceLastFrame)
Call each frame.
Definition: GodRaysManager.cpp:209
Hydrax::GodRaysManager::mCreated
bool mCreated
Has been create() already called?
Definition: GodRaysManager.h:292
Hydrax::GodRaysManager::setNumberOfRays
void setNumberOfRays(const int &NumberOfRays)
Set the number of god rays.
Definition: GodRaysManager.cpp:333
PROJECTIONCLIPSPACE2DTOIMAGESPACE_PERSPECTIVE
const Ogre::Matrix4 PROJECTIONCLIPSPACE2DTOIMAGESPACE_PERSPECTIVE(0.5, 0, 0, 0.5, 0, -0.5, 0, 0.5, 0, 0, 1, 0, 0, 0, 0, 1)
Hydrax::Hydrax::getSunPosition
const Ogre::Vector3 & getSunPosition() const
Get sun position.
Definition: Hydrax.h:468
_def_GodRaysDepth_Material_Name
#define _def_GodRaysDepth_Material_Name
Definition: GodRaysManager.cpp:37
Hydrax::HydraxComponent
HydraxComponent
Hydrax flags to select components wich we want to use.
Definition: Enums.h:57
Hydrax::HYDRAX_COMPONENTS_NONE
@ HYDRAX_COMPONENTS_NONE
Definition: Enums.h:70
Hydrax::Noise::Perlin::Options
Struct wich contains Perlin noise module options.
Definition: Perlin.h:78
Hydrax::HYDRAX_COMPONENT_CAUSTICS
@ HYDRAX_COMPONENT_CAUSTICS
Definition: Enums.h:64
Hydrax::Noise::Perlin::create
void create()
Create.
Definition: Perlin.cpp:63
Hydrax::Hydrax::_isCurrentFrameUnderwater
const bool & _isCurrentFrameUnderwater() const
Is current frame underwater?
Definition: Hydrax.h:621
Hydrax::GodRaysManager::mPerlin
Noise::Perlin * mPerlin
Our Perlin noise module.
Definition: GodRaysManager.h:302
Hydrax::MaterialManager::SM_CG
@ SM_CG
Definition: MaterialManager.h:93
Hydrax::GodRaysManager::DepthMapListener::mGodRaysManager
GodRaysManager * mGodRaysManager
God rays manager pointer.
Definition: GodRaysManager.h:235
Hydrax::GodRaysManager::DepthMapListener::postRenderTargetUpdate
void postRenderTargetUpdate(const Ogre::RenderTargetEvent &evt)
Funtion that is called after the Rtt will render.
Definition: GodRaysManager.cpp:893
Hydrax::GodRaysManager::mObjectsIntersections
bool mObjectsIntersections
Are god rays objects intersections active?
Definition: GodRaysManager.h:328
Hydrax::Noise::Perlin
Perlin noise module class.
Definition: Perlin.h:73
Hydrax::GodRaysManager::mNoiseYNormalMultiplier
Ogre::Real mNoiseYNormalMultiplier
Y normal component multiplier.
Definition: GodRaysManager.h:311
_def_GodRaysDepth_Shader_VP_Name
#define _def_GodRaysDepth_Shader_VP_Name
Definition: GodRaysManager.cpp:38
Hydrax::Mesh::getEntity
Ogre::Entity * getEntity()
Get entity.
Definition: Mesh.h:221
Hydrax::GodRaysManager::~GodRaysManager
~GodRaysManager()
Destructor.
Definition: GodRaysManager.cpp:72
Hydrax::GodRaysManager::mDepthTechniques
std::vector< Ogre::Technique * > mDepthTechniques
Technique vector for addDepthTechnique(...)
Definition: GodRaysManager.h:319
Hydrax::GodRaysManager::mDepthMapListener
DepthMapListener mDepthMapListener
Depth RTT listener.
Definition: GodRaysManager.h:334
Hydrax::GodRaysManager::DepthMapListener::preRenderTargetUpdate
void preRenderTargetUpdate(const Ogre::RenderTargetEvent &evt)
Funtion that is called before the Rtt will render.
Definition: GodRaysManager.cpp:869