26#include "OgrePixelFormat.h"
34 return rand() * ( 1.0f / ( RAND_MAX + 1.0f ) );
45 , angularFrequencies(0)
47 , mGPUNormalMapManager(0)
60 , angularFrequencies(0)
62 , mGPUNormalMapManager(0)
154 getTechnique(0)->getPass(0)->
155 getVertexProgramParameters()->
159 getTechnique(0)->getPass(0)->
160 getFragmentProgramParameters()->
164 getTechnique(0)->getPass(0)->
165 getFragmentProgramParameters()->
185 Ogre::TexturePtr mFFTTexture
186 = Ogre::TextureManager::getSingleton().
187 createManual(
"_Hydrax_FFT_Noise",
188 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
192 Ogre::TU_DYNAMIC_WRITE_ONLY);
200 Ogre::String VertexProgramData, FragmentProgramData;
201 Ogre::GpuProgramParametersSharedPtr VP_Parameters, FP_Parameters;
202 Ogre::String EntryPoints[2] = {
"main_vp",
"main_fp"};
203 Ogre::String GpuProgramsData[2]; Ogre::String GpuProgramNames[2];
215 "float4 iPosition : POSITION,\n" +
217 "out float4 oPosition : POSITION,\n" +
218 "out float3 oPosition_ : TEXCOORD0,\n" +
219 "out float4 oWorldUV : TEXCOORD1,\n" +
220 "out float oScale : TEXCOORD2,\n" +
221 "out float3 oCameraPos : TEXCOORD3,\n" +
222 "out float3 oCameraToPixel : TEXCOORD4,\n" +
224 "uniform float4x4 uWorldViewProj,\n" +
225 "uniform float4x4 uWorld, \n" +
226 "uniform float3 uCameraPos,\n"+
227 "uniform float uScale)\n" +
229 "oPosition = mul(uWorldViewProj, iPosition);\n" +
230 "oPosition_ = iPosition.xyz;\n" +
231 "float2 Scale = uScale*mul(uWorld, iPosition).xz*0.0078125;\n" +
232 "oWorldUV.xy = Scale;\n" +
233 "oWorldUV.zw = Scale*16;\n" +
234 "oScale = uScale;\n" +
235 "oCameraPos = uCameraPos,\n" +
236 "oCameraToPixel = iPosition - uCameraPos;\n"+
252 FragmentProgramData +=
256 "float3 iPosition : TEXCOORD0,\n" +
257 "float4 iWorldCoord : TEXCOORD1,\n" +
258 "float iScale : TEXCOORD2,\n" +
259 "float3 iCameraPos : TEXCOORD3,\n" +
260 "float3 iCameraToPixel : TEXCOORD4,\n" +
262 "out float4 oColor : COLOR,\n" +
264 "uniform float uStrength,\n" +
265 "uniform float3 uLODParameters,\n" +
266 "uniform float3 uCameraPos,\n" +
267 "uniform sampler2D uFFT : register(s0))\n" +
269 "float Distance = length(iCameraToPixel);\n" +
270 "float Attenuation = saturate(Distance/uLODParameters.z);\n" +
272 "uLODParameters.x += (uLODParameters.y-uLODParameters.x)*Attenuation;\n"+
273 "uLODParameters.x *= iScale;\n" +
275 "float AngleAttenuation = 1/abs(normalize(iCameraToPixel).y);\n"+
276 "uLODParameters.x *= AngleAttenuation;\n"+
278 "float2 dx = float2(uLODParameters.x*0.0078125, 0);\n" +
279 "float2 dy = float2(0, dx.x);\n" +
281 "float3 p_dx, m_dx, p_dy, m_dy;\n" +
285 "iPosition.x+uLODParameters.x,\n" +
287 "tex2D(uFFT, iWorldCoord.xy+dx).x,\n" +
293 "iPosition.x-uLODParameters.x,\n" +
295 "tex2D(uFFT, iWorldCoord.xy-dx).x, \n" +
303 "tex2D(uFFT, iWorldCoord.xy+dy).x,\n" +
305 "iPosition.z+uLODParameters.x);\n" +
311 "tex2D(uFFT, iWorldCoord.xy-dy).x,\n" +
313 "iPosition.z-uLODParameters.x);\n" +
315 "uStrength *= (1-Attenuation);\n" +
316 "p_dx.y *= uStrength; m_dx.y *= uStrength;\n" +
317 "p_dy.y *= uStrength; m_dy.y *= uStrength;\n" +
319 "float3 normal = normalize(cross(p_dx-m_dx, p_dy-m_dy));\n" +
321 "oColor = float4(saturate(1-(0.5+0.5*normal)),1);\n" +
335 mNormalMapMaterial = Ogre::MaterialManager::getSingleton().create(
"_Hydrax_GPU_Normal_Map_Material", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
337 Ogre::Pass *Technique0_Pass0 = mNormalMapMaterial->getTechnique(0)->getPass(0);
339 Technique0_Pass0->setLightingEnabled(
false);
340 Technique0_Pass0->setCullingMode(Ogre::CULL_NONE);
341 Technique0_Pass0->setDepthWriteEnabled(
true);
342 Technique0_Pass0->setDepthCheckEnabled(
true);
344 GpuProgramsData[0] = VertexProgramData; GpuProgramsData[1] = FragmentProgramData;
345 GpuProgramNames[0] =
"_Hydrax_GPU_Normal_Map_VP"; GpuProgramNames[1] =
"_Hydrax_GPU_Normal_Map_FP";
349 VP_Parameters = Technique0_Pass0->getVertexProgramParameters();
351 VP_Parameters->setNamedAutoConstant(
"uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
352 VP_Parameters->setNamedAutoConstant(
"uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
353 VP_Parameters->setNamedAutoConstant(
"uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
356 FP_Parameters = Technique0_Pass0->getFragmentProgramParameters();
362 ->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
364 mNormalMapMaterial->load();
374 Ogre::HardwarePixelBufferSharedPtr PixelBuffer
377 PixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
379 const Ogre::PixelBox& PixelBox = PixelBuffer->getCurrentLock();
381 Data = PixelBox.data;
385 Data[u] = (
re[u]*65535);
388 PixelBuffer->unlock();
442 Ogre::Vector2 wave = Ogre::Vector2(0,0);
461 temp=9.81f * wave.length();
462 *pAngularFrequenciesData++ = Ogre::Math::Sqrt(temp);
490 coswt = Ogre::Math::Cos(wt);
491 sinwt = Ogre::Math::Sin(wt);
494 positive_h0.real() * coswt - positive_h0.imag() * sinwt + negative_h0.real() * coswt - (-negative_h0.imag()) * (-sinwt),
496 positive_h0.real() * sinwt + positive_h0.imag() * coswt + negative_h0.real() * (-sinwt) + (-negative_h0.imag()) * coswt;
498 *pData++ = std::complex<float>(realVal, imagVal);
515 w = x1 * x1 + x2 * x2;
517 }
while (
w >= 1.0f );
519 w = Ogre::Math::Sqrt( (-2.0f * Ogre::Math::Log(
w ) ) /
w );
528 float k = waveVector.length();
537 float windVelocity = wind.length(),
538 l = pow(windVelocity,2.0f)/9.81f,
539 dot=waveVector.dotProduct(wind);
542 (Ogre::Math::Exp(-1 / pow(k * l,2)) / (Ogre::Math::Pow(k,2) *
543 Ogre::Math::Pow(k,2))) * Ogre::Math::Pow(-dot/ (k * windVelocity), kwPower_);
596 float tx = 0, ty = 0;
643 for(j = 0; j < l1; j++)
655 z = u1 * ca - u2 * sa;
656 u2 = u1 * sa + u2 * ca;
659 sa = Ogre::Math::Sqrt((1.0f - ca) / 2.0f);
660 ca = Ogre::Math::Sqrt((1.0f+ca) / 2.0f);
671 for(l = 0; l < l2m; l++)
677 for(j = 0; j < l1; j++)
689 z = u1 * ca - u2 * sa;
690 u2 = u1 * sa + u2 * ca;
693 sa = Ogre::Math::Sqrt((1.0f - ca) / 2.0f);
694 ca = Ogre::Math::Sqrt((1.0f+ca) / 2.0f);
702 if (((
x+
y) & 0x1)==1)
716 float scaleCoef = 0.000001f;
722 float min=
re[0], max=
re[0],
727 if (min>
re[i]) min=
re[i];
728 if (max<
re[i]) max=
re[i];
731 min=Ogre::Math::Abs(min);
732 max=Ogre::Math::Abs(max);
734 currentMax = (min>max) ? min : max;
752 re[i]=(
re[i]+scaleCoef)/(scaleCoef*2);
772 int xINT = (
x>0) ?
static_cast<int>(xScale) :
static_cast<int>(xScale-1),
773 yINT = (
y>0) ?
static_cast<int>(yScale) :
static_cast<int>(yScale-1);
776 float xDIFF = xScale-xINT,
795 return (A*_xDIFF*_yDIFF +
static Ogre::String _getCfgString(const Ogre::String &Name, const int &Value)
static Ogre::Real _getFloatValue(Ogre::ConfigFile &CfgFile, const Ogre::String Name)
Get float value.
static Ogre::Vector2 _getVector2Value(Ogre::ConfigFile &CfgFile, const Ogre::String Name)
Get vector2 value.
static int _getIntValue(Ogre::ConfigFile &CfgFile, const Ogre::String Name)
Get int value.
Class to manager GPU normal maps.
Ogre::TexturePtr & getTexture(const int &Index)
Get a texture.
Hydrax * getHydrax()
Get the Hydrax parent pointer.
void addTexture(Ogre::TexturePtr &Texture)
Create a texture.
Ogre::MaterialPtr & getNormalMapMaterial()
Get the normal map material.
const MaterialManager::ShaderMode & getShaderMode() const
Get current shader mode.
MaterialManager * getMaterialManager()
Get Hydrax::MaterialManager.
Material/Shader manager class.
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.
std::complex< float > * initialWaves
the data which is referred as h0{x,t), that is, the data of the simulation at the time 0.
void _calculeNoise(const float &delta)
Calcule noise.
void _initNoise()
Initialize noise.
void setOptions(const Options &Options)
Set/Update fft noise options.
float * angularFrequencies
the angular frequencies
Options mOptions
Perlin noise options.
void _executeInverseFFT()
Execute inverse fast fourier transform.
void _normalizeFFTData(const float &scale)
Normalize fft data.
float * re
Pointers to resolution*resolution float size arrays.
const float _getPhillipsSpectrum(const Ogre::Vector2 &waveVector, const Ogre::Vector2 &wind, const float &kwPower_=2.0f) const
Get the Philipps Spectrum, used to create the amplitudes and phases.
FFT()
Default constructor.
bool loadCfg(Ogre::ConfigFile &CfgFile)
Load config.
void saveCfg(Ogre::String &Data)
Save config.
const float _getGaussianRandomFloat() const
Get a Gaussian random number with mean 0 and standard deviation 1, using Box - muller transform.
int resolution
FFT resolution.
bool createGPUNormalMapResources(GPUNormalMapManager *g)
Create GPUNormalMap resources.
GPUNormalMapManager * mGPUNormalMapManager
GPUNormalMapManager pointer.
void _updateGPUNormalMapResources()
Update gpu normal map resources.
float maximalValue
The minimal value of the result data of the fft transformation.
float getValue(const float &x, const float &y)
Get the especified x/y noise value.
std::complex< float > * currentWaves
the data of the simulation at time t, which is formed using the data at time 0 and the angular freque...
void update(const Ogre::Real &timeSinceLastFrame)
Call it each frame.
Base noise class, Override it for create different ways of create water noise.
virtual void remove()
Remove.
const Ogre::String & getName() const
Get noise name.
const bool & areGPUNormalMapResourcesCreated() const
Are GPU normal map resources created?
virtual bool createGPUNormalMapResources(GPUNormalMapManager *g)
Create GPUNormalMap resources.
virtual bool loadCfg(Ogre::ConfigFile &CfgFile)
Load config.
const bool & isGPUNormalMapSupported() const
Is GPU Normal map generation supported.
virtual void removeGPUNormalMapResources(GPUNormalMapManager *g)
Remove GPUNormalMap resources.
virtual void saveCfg(Ogre::String &Data)
Save config.
virtual void create()
Create.
const bool & isCreated() const
Is created() called?
Struct wich contains fft noise module options.
Ogre::Vector3 GPU_LODParameters
LOD Parameters, in order to obtain a smooth normal map we need to decrease the detail level when the ...
float GPU_Strength
GPU Normal map generator parameters Only if GPU normal map generation is active.
float Amplitude
Noise amplitude.
int Resolution
Noise resolution (2^n)
Ogre::Vector2 WindDirection
Wind direction.
float AnimationSpeed
Animation speed.
float PhysicalResolution
Physical resolution.