merged in ocean
This commit is contained in:
@@ -73,7 +73,7 @@ CameraWindow::CameraWindow(wiGUI* gui) :GUI(gui)
|
||||
|
||||
|
||||
|
||||
cameraWindow->Translate(XMFLOAT3(30, 30, 0));
|
||||
cameraWindow->Translate(XMFLOAT3(800, 500, 0));
|
||||
cameraWindow->SetVisible(false);
|
||||
}
|
||||
|
||||
|
||||
+38
-1
@@ -14,6 +14,7 @@
|
||||
#include "AnimationWindow.h"
|
||||
#include "EmitterWindow.h"
|
||||
#include "ForceFieldWindow.h"
|
||||
#include "OceanWindow.h"
|
||||
|
||||
#include <Commdlg.h> // openfile
|
||||
#include <WinBase.h>
|
||||
@@ -262,6 +263,7 @@ void EditorComponent::ChangeRenderPath(RENDERPATH path)
|
||||
emitterWnd = new EmitterWindow(&GetGUI());
|
||||
emitterWnd->SetMaterialWnd(materialWnd);
|
||||
forceFieldWnd = new ForceFieldWindow(&GetGUI());
|
||||
oceanWnd = new OceanWindow(&GetGUI());
|
||||
}
|
||||
void EditorComponent::DeleteWindows()
|
||||
{
|
||||
@@ -276,6 +278,7 @@ void EditorComponent::DeleteWindows()
|
||||
SAFE_DELETE(animWnd);
|
||||
SAFE_DELETE(emitterWnd);
|
||||
SAFE_DELETE(forceFieldWnd);
|
||||
SAFE_DELETE(oceanWnd);
|
||||
}
|
||||
|
||||
void EditorComponent::Initialize()
|
||||
@@ -292,6 +295,7 @@ void EditorComponent::Initialize()
|
||||
SAFE_INIT(animWnd);
|
||||
SAFE_INIT(emitterWnd);
|
||||
SAFE_INIT(forceFieldWnd);
|
||||
SAFE_INIT(oceanWnd);
|
||||
|
||||
|
||||
SAFE_INIT(loader);
|
||||
@@ -466,6 +470,15 @@ void EditorComponent::Load()
|
||||
});
|
||||
GetGUI().AddWidget(forceFieldWnd_Toggle);
|
||||
|
||||
wiButton* oceanWnd_Toggle = new wiButton("Ocean");
|
||||
oceanWnd_Toggle->SetTooltip("Ocean Simulator properties");
|
||||
oceanWnd_Toggle->SetPos(XMFLOAT2(x += step, screenH - 40));
|
||||
oceanWnd_Toggle->SetSize(XMFLOAT2(100, 40));
|
||||
oceanWnd_Toggle->OnClick([=](wiEventArgs args) {
|
||||
oceanWnd->oceanWindow->SetVisible(!oceanWnd->oceanWindow->IsVisible());
|
||||
});
|
||||
GetGUI().AddWidget(oceanWnd_Toggle);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -929,6 +942,24 @@ void EditorComponent::Update(float dt)
|
||||
originalMouse = wiInputManager::GetInstance()->getpointer();
|
||||
}
|
||||
|
||||
const float buttonrotSpeed = 2.0f / 60.0f;
|
||||
if (wiInputManager::GetInstance()->down(VK_LEFT))
|
||||
{
|
||||
xDif -= buttonrotSpeed;
|
||||
}
|
||||
if (wiInputManager::GetInstance()->down(VK_RIGHT))
|
||||
{
|
||||
xDif += buttonrotSpeed;
|
||||
}
|
||||
if (wiInputManager::GetInstance()->down(VK_UP))
|
||||
{
|
||||
yDif -= buttonrotSpeed;
|
||||
}
|
||||
if (wiInputManager::GetInstance()->down(VK_DOWN))
|
||||
{
|
||||
yDif += buttonrotSpeed;
|
||||
}
|
||||
|
||||
Camera* cam = wiRenderer::getCamera();
|
||||
|
||||
if (cameraWnd->fpscamera)
|
||||
@@ -1372,6 +1403,13 @@ void EditorComponent::Compose()
|
||||
{
|
||||
renderPath->Compose();
|
||||
|
||||
//if (wiRenderer::GetOcean())
|
||||
//{
|
||||
// wiImageEffects fx(500, 500, 500, 500);
|
||||
// fx.blendFlag = BLENDMODE_OPAQUE;
|
||||
// wiImage::Draw(wiRenderer::GetOcean()->getDisplacementMap(), fx, GRAPHICSTHREAD_IMMEDIATE);
|
||||
//}
|
||||
|
||||
//__super::Compose();
|
||||
|
||||
for (auto& x : wiRenderer::GetScene().models)
|
||||
@@ -1521,7 +1559,6 @@ void EditorComponent::Compose()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
void EditorComponent::Unload()
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ class LightWindow;
|
||||
class AnimationWindow;
|
||||
class EmitterWindow;
|
||||
class ForceFieldWindow;
|
||||
class OceanWindow;
|
||||
|
||||
class EditorLoadingScreen : public LoadingScreenComponent
|
||||
{
|
||||
@@ -45,6 +46,7 @@ public:
|
||||
AnimationWindow* animWnd;
|
||||
EmitterWindow* emitterWnd;
|
||||
ForceFieldWindow* forceFieldWnd;
|
||||
OceanWindow* oceanWnd;
|
||||
|
||||
Editor* main;
|
||||
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
<ClInclude Include="MaterialWindow.h" />
|
||||
<ClInclude Include="MeshWindow.h" />
|
||||
<ClInclude Include="ObjectWindow.h" />
|
||||
<ClInclude Include="OceanWindow.h" />
|
||||
<ClInclude Include="PostprocessWindow.h" />
|
||||
<ClInclude Include="RendererWindow.h" />
|
||||
<ClInclude Include="Resource.h" />
|
||||
@@ -197,6 +198,7 @@
|
||||
<ClCompile Include="MaterialWindow.cpp" />
|
||||
<ClCompile Include="MeshWindow.cpp" />
|
||||
<ClCompile Include="ObjectWindow.cpp" />
|
||||
<ClCompile Include="OceanWindow.cpp" />
|
||||
<ClCompile Include="PostprocessWindow.cpp" />
|
||||
<ClCompile Include="RendererWindow.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
||||
@@ -67,6 +67,9 @@
|
||||
<ClInclude Include="ForceFieldWindow.h">
|
||||
<Filter>Code</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="OceanWindow.h">
|
||||
<Filter>Code</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CameraWindow.cpp">
|
||||
@@ -117,6 +120,9 @@
|
||||
<ClCompile Include="ForceFieldWindow.cpp">
|
||||
<Filter>Code</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="OceanWindow.cpp">
|
||||
<Filter>Code</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="small.ico">
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
#include "stdafx.h"
|
||||
#include "OceanWindow.h"
|
||||
|
||||
|
||||
OceanWindow::OceanWindow(wiGUI* gui) :GUI(gui)
|
||||
{
|
||||
assert(GUI && "Invalid GUI!");
|
||||
|
||||
float screenW = (float)wiRenderer::GetDevice()->GetScreenWidth();
|
||||
float screenH = (float)wiRenderer::GetDevice()->GetScreenHeight();
|
||||
|
||||
|
||||
oceanWindow = new wiWindow(GUI, "Ocean Window");
|
||||
oceanWindow->SetSize(XMFLOAT2(700, 300));
|
||||
GUI->AddWidget(oceanWindow);
|
||||
|
||||
float x = 200;
|
||||
float y = 0;
|
||||
float inc = 35;
|
||||
|
||||
enabledCheckBox = new wiCheckBox("Ocean simulation enabled: ");
|
||||
enabledCheckBox->SetPos(XMFLOAT2(x, y += inc));
|
||||
enabledCheckBox->OnClick([&](wiEventArgs args) {
|
||||
wiRenderer::SetOceanEnabled(args.bValue, params);
|
||||
});
|
||||
enabledCheckBox->SetCheck(wiRenderer::GetOcean() != nullptr);
|
||||
oceanWindow->AddWidget(enabledCheckBox);
|
||||
|
||||
|
||||
patchSizeSlider = new wiSlider(1, 2000, 1000, 100000, "Patch size: ");
|
||||
patchSizeSlider->SetSize(XMFLOAT2(100, 30));
|
||||
patchSizeSlider->SetPos(XMFLOAT2(x, y += inc));
|
||||
patchSizeSlider->SetValue(params.patch_length);
|
||||
patchSizeSlider->OnSlide([&](wiEventArgs args) {
|
||||
params.patch_length = args.fValue;
|
||||
wiRenderer::SetOceanEnabled(enabledCheckBox->GetCheck(), params);
|
||||
});
|
||||
oceanWindow->AddWidget(patchSizeSlider);
|
||||
|
||||
waveAmplitudeSlider = new wiSlider(0, 100, 1000, 100000, "Wave amplitude: ");
|
||||
waveAmplitudeSlider->SetSize(XMFLOAT2(100, 30));
|
||||
waveAmplitudeSlider->SetPos(XMFLOAT2(x, y += inc));
|
||||
waveAmplitudeSlider->SetValue(params.wave_amplitude);
|
||||
waveAmplitudeSlider->OnSlide([&](wiEventArgs args) {
|
||||
params.wave_amplitude = args.fValue;
|
||||
wiRenderer::SetOceanEnabled(enabledCheckBox->GetCheck(), params);
|
||||
});
|
||||
oceanWindow->AddWidget(waveAmplitudeSlider);
|
||||
|
||||
choppyScaleSlider = new wiSlider(0, 10, 1000, 100000, "Choppiness: ");
|
||||
choppyScaleSlider->SetSize(XMFLOAT2(100, 30));
|
||||
choppyScaleSlider->SetPos(XMFLOAT2(x, y += inc));
|
||||
choppyScaleSlider->SetValue(params.choppy_scale);
|
||||
choppyScaleSlider->OnSlide([&](wiEventArgs args) {
|
||||
params.choppy_scale = args.fValue;
|
||||
wiRenderer::SetOceanEnabled(enabledCheckBox->GetCheck(), params);
|
||||
});
|
||||
oceanWindow->AddWidget(choppyScaleSlider);
|
||||
|
||||
windDependencySlider = new wiSlider(0, 1, 1000, 100000, "Wind dependency: ");
|
||||
windDependencySlider->SetSize(XMFLOAT2(100, 30));
|
||||
windDependencySlider->SetPos(XMFLOAT2(x, y += inc));
|
||||
windDependencySlider->SetValue(params.wind_dependency);
|
||||
windDependencySlider->OnSlide([&](wiEventArgs args) {
|
||||
params.wind_dependency = args.fValue;
|
||||
wiRenderer::SetOceanEnabled(enabledCheckBox->GetCheck(), params);
|
||||
});
|
||||
oceanWindow->AddWidget(windDependencySlider);
|
||||
|
||||
timeScaleSlider = new wiSlider(0, 4, 1000, 100000, "Time scale: ");
|
||||
timeScaleSlider->SetSize(XMFLOAT2(100, 30));
|
||||
timeScaleSlider->SetPos(XMFLOAT2(x, y += inc));
|
||||
timeScaleSlider->SetValue(params.time_scale);
|
||||
timeScaleSlider->OnSlide([&](wiEventArgs args) {
|
||||
params.time_scale = args.fValue;
|
||||
wiRenderer::SetOceanEnabled(enabledCheckBox->GetCheck(), params);
|
||||
});
|
||||
oceanWindow->AddWidget(timeScaleSlider);
|
||||
|
||||
|
||||
colorPicker = new wiColorPicker(GUI, "Water Color");
|
||||
colorPicker->SetPos(XMFLOAT2(380, 30));
|
||||
colorPicker->RemoveWidgets();
|
||||
colorPicker->SetVisible(true);
|
||||
colorPicker->SetEnabled(true);
|
||||
colorPicker->OnColorChanged([&](wiEventArgs args) {
|
||||
if (wiRenderer::GetOcean() != nullptr)
|
||||
wiRenderer::GetOcean()->waterColor = XMFLOAT3(args.color.x, args.color.y, args.color.z);
|
||||
});
|
||||
oceanWindow->AddWidget(colorPicker);
|
||||
|
||||
|
||||
oceanWindow->Translate(XMFLOAT3(800, 50, 0));
|
||||
oceanWindow->SetVisible(false);
|
||||
}
|
||||
|
||||
|
||||
OceanWindow::~OceanWindow()
|
||||
{
|
||||
oceanWindow->RemoveWidgets(true);
|
||||
GUI->RemoveWidget(oceanWindow);
|
||||
SAFE_DELETE(oceanWindow);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "wiOcean.h"
|
||||
|
||||
class wiGUI;
|
||||
class wiWindow;
|
||||
class wiLabel;
|
||||
class wiCheckBox;
|
||||
class wiSlider;
|
||||
class wiColorPicker;
|
||||
|
||||
class OceanWindow
|
||||
{
|
||||
public:
|
||||
OceanWindow(wiGUI* gui);
|
||||
~OceanWindow();
|
||||
|
||||
wiOceanParameter params;
|
||||
|
||||
wiGUI* GUI;
|
||||
|
||||
wiWindow* oceanWindow;
|
||||
wiCheckBox* enabledCheckBox;
|
||||
wiSlider* patchSizeSlider;
|
||||
wiSlider* waveAmplitudeSlider;
|
||||
wiSlider* choppyScaleSlider;
|
||||
wiSlider* windDependencySlider;
|
||||
wiSlider* timeScaleSlider;
|
||||
wiColorPicker* colorPicker;
|
||||
};
|
||||
|
||||
Binary file not shown.
@@ -6,30 +6,35 @@
|
||||
|
||||
// Persistent buffers:
|
||||
// These are bound once and are alive forever
|
||||
#define CBSLOT_RENDERER_WORLD 0
|
||||
#define CBSLOT_RENDERER_FRAME 1
|
||||
#define CBSLOT_RENDERER_CAMERA 2
|
||||
#define CBSLOT_RENDERER_MISC 3
|
||||
#define CBSLOT_RENDERER_WORLD 0
|
||||
#define CBSLOT_RENDERER_FRAME 1
|
||||
#define CBSLOT_RENDERER_CAMERA 2
|
||||
#define CBSLOT_RENDERER_MISC 3
|
||||
|
||||
#define CBSLOT_IMAGE_IMAGE 4
|
||||
#define CBSLOT_IMAGE_POSTPROCESS 5
|
||||
#define CBSLOT_IMAGE_IMAGE 4
|
||||
#define CBSLOT_IMAGE_POSTPROCESS 5
|
||||
|
||||
#define CBSLOT_API 6
|
||||
#define CBSLOT_API 6
|
||||
|
||||
|
||||
// On demand buffers:
|
||||
// These are bound on demand and alive until another is bound at the same slot
|
||||
#define CBSLOT_RENDERER_MATERIAL 7
|
||||
#define CBSLOT_RENDERER_CUBEMAPRENDER 8
|
||||
#define CBSLOT_RENDERER_VOLUMELIGHT 8
|
||||
#define CBSLOT_RENDERER_DECAL 8
|
||||
#define CBSLOT_RENDERER_TESSELLATION 8
|
||||
#define CBSLOT_RENDERER_DISPATCHPARAMS 8
|
||||
#define CBSLOT_RENDERER_VOXELIZER 8
|
||||
#define CBSLOT_RENDERER_MATERIAL 7
|
||||
#define CBSLOT_RENDERER_CUBEMAPRENDER 8
|
||||
#define CBSLOT_RENDERER_VOLUMELIGHT 8
|
||||
#define CBSLOT_RENDERER_DECAL 8
|
||||
#define CBSLOT_RENDERER_TESSELLATION 8
|
||||
#define CBSLOT_RENDERER_DISPATCHPARAMS 8
|
||||
#define CBSLOT_RENDERER_VOXELIZER 8
|
||||
|
||||
#define CBSLOT_OTHER_EMITTEDPARTICLE 8
|
||||
#define CBSLOT_OTHER_HAIRPARTICLE 8
|
||||
#define CBSLOT_OTHER_LENSFLARE 8
|
||||
#define CBSLOT_OTHER_EMITTEDPARTICLE 8
|
||||
#define CBSLOT_OTHER_HAIRPARTICLE 8
|
||||
#define CBSLOT_OTHER_LENSFLARE 8
|
||||
#define CBSLOT_OTHER_FFTGENERATOR 8
|
||||
#define CBSLOT_OTHER_OCEAN_SIMULATION_IMMUTABLE 8
|
||||
#define CBSLOT_OTHER_OCEAN_SIMULATION_PERFRAME 9
|
||||
#define CBSLOT_OTHER_OCEAN_RENDER_SHADING 8
|
||||
#define CBSLOT_OTHER_OCEAN_RENDER_PATCH 9
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef _SHADERINTEROP_FFTGENERATOR_H_
|
||||
#define _SHADERINTEROP_FFTGENERATOR_H_
|
||||
#include "ShaderInterop.h"
|
||||
|
||||
CBUFFER(FFTGeneratorCB, CBSLOT_OTHER_FFTGENERATOR)
|
||||
{
|
||||
uint thread_count;
|
||||
uint ostride;
|
||||
uint istride;
|
||||
uint pstride;
|
||||
|
||||
float phase_base;
|
||||
float3 FFTGeneratorCB_padding;
|
||||
};
|
||||
|
||||
#endif // _SHADERINTEROP_FFTGENERATOR_H_
|
||||
@@ -0,0 +1,76 @@
|
||||
#ifndef _SHADERINTEROP_OCEAN_H_
|
||||
#define _SHADERINTEROP_OCEAN_H_
|
||||
#include "ShaderInterop.h"
|
||||
|
||||
#define OCEAN_COMPUTE_TILESIZE 16
|
||||
|
||||
// Simulation constants:
|
||||
|
||||
CBUFFER(Ocean_Simulation_ImmutableCB, CBSLOT_OTHER_OCEAN_SIMULATION_IMMUTABLE)
|
||||
{
|
||||
uint g_ActualDim;
|
||||
uint g_InWidth;
|
||||
uint g_OutWidth;
|
||||
uint g_OutHeight;
|
||||
|
||||
uint g_DtxAddressOffset;
|
||||
uint g_DtyAddressOffset;
|
||||
uint2 Ocean_Simulation_ImmutableCB_padding;
|
||||
};
|
||||
|
||||
CBUFFER(Ocean_Simulation_PerFrameCB, CBSLOT_OTHER_OCEAN_SIMULATION_PERFRAME)
|
||||
{
|
||||
float g_Time;
|
||||
float g_ChoppyScale;
|
||||
float g_GridLen;
|
||||
float Ocean_Simulation_PerFrameCB_padding;
|
||||
};
|
||||
|
||||
|
||||
// Rendering constants:
|
||||
|
||||
CBUFFER(Ocean_Rendering_ShadingCB, CBSLOT_OTHER_OCEAN_RENDER_SHADING)
|
||||
{
|
||||
float3 g_SkyColor;
|
||||
float g_TexelLength_x2;
|
||||
|
||||
float3 g_WaterbodyColor;
|
||||
float g_UVScale;
|
||||
|
||||
float g_Shineness;
|
||||
float3 g_SunDir;
|
||||
|
||||
float g_UVOffset;
|
||||
float3 g_SunColor;
|
||||
|
||||
// The parameter is used for fixing an artifact
|
||||
float3 g_BendParam;
|
||||
float Ocean_Rendering_ShadingCB_padding0;
|
||||
|
||||
// Perlin noise for distant wave crest
|
||||
float g_PerlinSize;
|
||||
float3 g_PerlinAmplitude;
|
||||
|
||||
float3 g_PerlinOctave;
|
||||
float Ocean_Rendering_ShadingCB_padding1;
|
||||
|
||||
float3 g_PerlinGradient;
|
||||
float Ocean_Rendering_ShadingCB_padding2;
|
||||
};
|
||||
|
||||
// Per draw call constants
|
||||
CBUFFER(Ocean_Rendering_PatchCB, CBSLOT_OTHER_OCEAN_RENDER_PATCH)
|
||||
{
|
||||
// Transform matrices
|
||||
matrix g_matLocal;
|
||||
matrix g_matWorldViewProj;
|
||||
|
||||
// Misc per draw call constants
|
||||
float2 g_UVBase;
|
||||
float2 g_PerlinMovement;
|
||||
|
||||
float3 g_LocalEye;
|
||||
float Ocean_Rendering_PatchCB_padding;
|
||||
};
|
||||
|
||||
#endif // _SHADERINTEROP_OCEAN_H_
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "wiSpinLock.h"
|
||||
#include "wiRectPacker.h"
|
||||
#include "wiProfiler.h"
|
||||
#include "wiOcean.h"
|
||||
|
||||
#include "RenderableComponent.h"
|
||||
#include "Renderable2DComponent.h"
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<None Include="normalsCompressHF.hlsli" />
|
||||
<None Include="objectHF.hlsli" />
|
||||
<None Include="objectInputLayoutHF.hlsli" />
|
||||
<None Include="oceanSurfaceHF.hlsli" />
|
||||
<None Include="packHF.hlsli" />
|
||||
<None Include="postProcessHF.hlsli" />
|
||||
<None Include="quad.hlsli" />
|
||||
@@ -182,6 +183,14 @@
|
||||
<FxCompile Include="envMap_skyVS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Vertex</ShaderType>
|
||||
</FxCompile>
|
||||
<FxCompile Include="fft_512x512_c2c_CS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
|
||||
</FxCompile>
|
||||
<FxCompile Include="fft_512x512_c2c_v2_CS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
|
||||
</FxCompile>
|
||||
<FxCompile Include="fontPS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
@@ -445,6 +454,27 @@
|
||||
<FxCompile Include="objectVS_voxelizer.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Vertex</ShaderType>
|
||||
</FxCompile>
|
||||
<FxCompile Include="oceanSimulatorCS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
|
||||
</FxCompile>
|
||||
<FxCompile Include="oceanSurfacePS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
<FxCompile Include="oceanSurfaceSimplePS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
<FxCompile Include="oceanSurfaceVS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Vertex</ShaderType>
|
||||
</FxCompile>
|
||||
<FxCompile Include="oceanUpdateDisplacementMapCS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
|
||||
</FxCompile>
|
||||
<FxCompile Include="oceanUpdateGradientFoldingCS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
|
||||
</FxCompile>
|
||||
<FxCompile Include="outlinePS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
|
||||
@@ -115,6 +115,9 @@
|
||||
<None Include="hairparticleHF.hlsli">
|
||||
<Filter>HF</Filter>
|
||||
</None>
|
||||
<None Include="oceanSurfaceHF.hlsli">
|
||||
<Filter>HF</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FxCompile Include="objectHS.hlsl">
|
||||
@@ -651,6 +654,30 @@
|
||||
<FxCompile Include="gridGeneratorVS.hlsl">
|
||||
<Filter>VS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="fft_512x512_c2c_CS.hlsl">
|
||||
<Filter>CS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="fft_512x512_c2c_v2_CS.hlsl">
|
||||
<Filter>CS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="oceanSimulatorCS.hlsl">
|
||||
<Filter>CS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="oceanSurfaceVS.hlsl">
|
||||
<Filter>VS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="oceanSurfacePS.hlsl">
|
||||
<Filter>PS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="oceanSurfaceSimplePS.hlsl">
|
||||
<Filter>PS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="oceanUpdateDisplacementMapCS.hlsl">
|
||||
<Filter>CS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="oceanUpdateGradientFoldingCS.hlsl">
|
||||
<Filter>CS</Filter>
|
||||
</FxCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="PS">
|
||||
|
||||
@@ -236,10 +236,13 @@
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Include_DX11.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop_EmittedParticle.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop_FFTGenerator.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop_Ocean.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)TiledDeferredRenderableComponent.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)TiledForwardRenderableComponent.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)TiledForwardRenderableComponent_BindLua.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)wiArchive.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)wiFFTGenerator.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)wiIntersectables.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)wiHashString.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)LoadingScreenComponent.h" />
|
||||
@@ -333,6 +336,7 @@
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)wiMeshOptimizer.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)wiNetwork.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)wiNetwork_BindLua.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)wiOcean.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)wiPHYSICS.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)wiProfiler.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)wiRandom.h" />
|
||||
@@ -511,6 +515,7 @@
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)TiledForwardRenderableComponent.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)TiledForwardRenderableComponent_BindLua.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiArchive.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiFFTGenerator.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiGraphicsDevice.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiHashString.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)LoadingScreenComponent.cpp" />
|
||||
@@ -671,6 +676,7 @@
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiMath.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiNetwork.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiNetwork_BindLua.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiOcean.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiProfiler.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiRandom.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiRawInput.cpp" />
|
||||
|
||||
@@ -1104,6 +1104,18 @@
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop_EmittedParticle.h">
|
||||
<Filter>ENGINE\Graphics\GPUMapping</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)wiFFTGenerator.h">
|
||||
<Filter>ENGINE\Graphics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="C:\PROJECTS\WickedEngine\WickedEngine\wiOcean.h">
|
||||
<Filter>ENGINE\Graphics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop_Ocean.h">
|
||||
<Filter>ENGINE\Graphics\GPUMapping</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop_FFTGenerator.h">
|
||||
<Filter>ENGINE\Graphics\GPUMapping</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)LUA\lapi.c">
|
||||
@@ -1889,6 +1901,12 @@
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)TiledDeferredRenderableComponent.cpp">
|
||||
<Filter>ENGINE\Components</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiFFTGenerator.cpp">
|
||||
<Filter>ENGINE\Graphics</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="C:\PROJECTS\WickedEngine\WickedEngine\wiOcean.cpp">
|
||||
<Filter>ENGINE\Graphics</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="$(MSBuildThisFileDirectory)fonts\default_font.dds">
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
#include "ShaderInterop_FFTGenerator.h"
|
||||
|
||||
#define COS_PI_4_16 0.70710678118654752440084436210485f
|
||||
#define TWIDDLE_1_8 COS_PI_4_16, -COS_PI_4_16
|
||||
#define TWIDDLE_3_8 -COS_PI_4_16, -COS_PI_4_16
|
||||
|
||||
#define COHERENCY_GRANULARITY 128
|
||||
|
||||
|
||||
void FT2(inout float2 a, inout float2 b)
|
||||
{
|
||||
float t;
|
||||
|
||||
t = a.x;
|
||||
a.x += b.x;
|
||||
b.x = t - b.x;
|
||||
|
||||
t = a.y;
|
||||
a.y += b.y;
|
||||
b.y = t - b.y;
|
||||
}
|
||||
|
||||
void CMUL_forward(inout float2 a, float bx, float by)
|
||||
{
|
||||
float t = a.x;
|
||||
a.x = t * bx - a.y * by;
|
||||
a.y = t * by + a.y * bx;
|
||||
}
|
||||
|
||||
void UPD_forward(inout float2 a, inout float2 b)
|
||||
{
|
||||
float A = a.x;
|
||||
float B = b.y;
|
||||
|
||||
a.x += b.y;
|
||||
b.y = a.y + b.x;
|
||||
a.y -= b.x;
|
||||
b.x = A - B;
|
||||
}
|
||||
|
||||
void FFT_forward_4(inout float2 D[8])
|
||||
{
|
||||
FT2(D[0], D[2]);
|
||||
FT2(D[1], D[3]);
|
||||
FT2(D[0], D[1]);
|
||||
|
||||
UPD_forward(D[2], D[3]);
|
||||
}
|
||||
|
||||
void FFT_forward_8(inout float2 D[8])
|
||||
{
|
||||
FT2(D[0], D[4]);
|
||||
FT2(D[1], D[5]);
|
||||
FT2(D[2], D[6]);
|
||||
FT2(D[3], D[7]);
|
||||
|
||||
UPD_forward(D[4], D[6]);
|
||||
UPD_forward(D[5], D[7]);
|
||||
|
||||
CMUL_forward(D[5], TWIDDLE_1_8);
|
||||
CMUL_forward(D[7], TWIDDLE_3_8);
|
||||
|
||||
FFT_forward_4(D);
|
||||
FT2(D[4], D[5]);
|
||||
FT2(D[6], D[7]);
|
||||
}
|
||||
|
||||
void TWIDDLE(inout float2 d, float phase)
|
||||
{
|
||||
float tx, ty;
|
||||
|
||||
sincos(phase, ty, tx);
|
||||
float t = d.x;
|
||||
d.x = t * tx - d.y * ty;
|
||||
d.y = t * ty + d.y * tx;
|
||||
}
|
||||
|
||||
void TWIDDLE_8(inout float2 D[8], float phase)
|
||||
{
|
||||
TWIDDLE(D[4], 1 * phase);
|
||||
TWIDDLE(D[2], 2 * phase);
|
||||
TWIDDLE(D[6], 3 * phase);
|
||||
TWIDDLE(D[1], 4 * phase);
|
||||
TWIDDLE(D[5], 5 * phase);
|
||||
TWIDDLE(D[3], 6 * phase);
|
||||
TWIDDLE(D[7], 7 * phase);
|
||||
}
|
||||
|
||||
STRUCTUREDBUFFER(g_SrcData, float2, TEXSLOT_ONDEMAND0);
|
||||
RWSTRUCTUREDBUFFER(g_DstData, float2, 0);
|
||||
|
||||
#ifndef FFT_V2
|
||||
|
||||
[numthreads(COHERENCY_GRANULARITY, 1, 1)]
|
||||
void main(uint3 thread_id : SV_DispatchThreadID)
|
||||
{
|
||||
if (thread_id.x >= thread_count)
|
||||
return;
|
||||
|
||||
// Fetch 8 complex numbers
|
||||
float2 D[8];
|
||||
|
||||
uint i;
|
||||
uint imod = thread_id.x & (istride - 1);
|
||||
uint iaddr = ((thread_id.x - imod) << 3) + imod;
|
||||
for (i = 0; i < 8; i++)
|
||||
D[i] = g_SrcData[iaddr + i * istride];
|
||||
|
||||
// Math
|
||||
FFT_forward_8(D);
|
||||
uint p = thread_id.x & (istride - pstride);
|
||||
float phase = phase_base * (float)p;
|
||||
TWIDDLE_8(D, phase);
|
||||
|
||||
// Store the result
|
||||
uint omod = thread_id.x & (ostride - 1);
|
||||
uint oaddr = ((thread_id.x - omod) << 3) + omod;
|
||||
g_DstData[oaddr + 0 * ostride] = D[0];
|
||||
g_DstData[oaddr + 1 * ostride] = D[4];
|
||||
g_DstData[oaddr + 2 * ostride] = D[2];
|
||||
g_DstData[oaddr + 3 * ostride] = D[6];
|
||||
g_DstData[oaddr + 4 * ostride] = D[1];
|
||||
g_DstData[oaddr + 5 * ostride] = D[5];
|
||||
g_DstData[oaddr + 6 * ostride] = D[3];
|
||||
g_DstData[oaddr + 7 * ostride] = D[7];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
[numthreads(COHERENCY_GRANULARITY, 1, 1)]
|
||||
void main(uint3 thread_id : SV_DispatchThreadID)
|
||||
{
|
||||
if (thread_id.x >= thread_count)
|
||||
return;
|
||||
|
||||
// Fetch 8 complex numbers
|
||||
uint i;
|
||||
float2 D[8];
|
||||
uint iaddr = thread_id.x << 3;
|
||||
for (i = 0; i < 8; i++)
|
||||
D[i] = g_SrcData[iaddr + i];
|
||||
|
||||
// Math
|
||||
FFT_forward_8(D);
|
||||
|
||||
// Store the result
|
||||
uint omod = thread_id.x & (ostride - 1);
|
||||
uint oaddr = ((thread_id.x - omod) << 3) + omod;
|
||||
g_DstData[oaddr + 0 * ostride] = D[0];
|
||||
g_DstData[oaddr + 1 * ostride] = D[4];
|
||||
g_DstData[oaddr + 2 * ostride] = D[2];
|
||||
g_DstData[oaddr + 3 * ostride] = D[6];
|
||||
g_DstData[oaddr + 4 * ostride] = D[1];
|
||||
g_DstData[oaddr + 5 * ostride] = D[5];
|
||||
g_DstData[oaddr + 6 * ostride] = D[3];
|
||||
g_DstData[oaddr + 7 * ostride] = D[7];
|
||||
}
|
||||
|
||||
#endif // FFT_V2
|
||||
@@ -0,0 +1,3 @@
|
||||
#define FFT_V2
|
||||
|
||||
#include "fft_512x512_c2c_CS.hlsl"
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "ShaderInterop_Ocean.h"
|
||||
|
||||
#define PI 3.1415926536f
|
||||
|
||||
STRUCTUREDBUFFER(g_InputH0, float2, TEXSLOT_ONDEMAND0);
|
||||
STRUCTUREDBUFFER(g_InputOmega, float, TEXSLOT_ONDEMAND1);
|
||||
RWSTRUCTUREDBUFFER(g_OutputHt, float2, 0);
|
||||
|
||||
// H(0) -> H(t)
|
||||
[numthreads(OCEAN_COMPUTE_TILESIZE, OCEAN_COMPUTE_TILESIZE, 1)]
|
||||
void main(uint3 DTid : SV_DispatchThreadID)
|
||||
{
|
||||
int in_index = DTid.y * g_InWidth + DTid.x;
|
||||
int in_mindex = (g_ActualDim - DTid.y) * g_InWidth + (g_ActualDim - DTid.x);
|
||||
int out_index = DTid.y * g_OutWidth + DTid.x;
|
||||
|
||||
// H(0) -> H(t)
|
||||
float2 h0_k = g_InputH0[in_index];
|
||||
float2 h0_mk = g_InputH0[in_mindex];
|
||||
float sin_v, cos_v;
|
||||
sincos(g_InputOmega[in_index] * g_Time, sin_v, cos_v);
|
||||
|
||||
float2 ht;
|
||||
ht.x = (h0_k.x + h0_mk.x) * cos_v - (h0_k.y + h0_mk.y) * sin_v;
|
||||
ht.y = (h0_k.x - h0_mk.x) * sin_v + (h0_k.y - h0_mk.y) * cos_v;
|
||||
|
||||
// H(t) -> Dx(t), Dy(t)
|
||||
float kx = DTid.x - g_ActualDim * 0.5f;
|
||||
float ky = DTid.y - g_ActualDim * 0.5f;
|
||||
float sqr_k = kx * kx + ky * ky;
|
||||
float rsqr_k = 0;
|
||||
if (sqr_k > 1e-12f)
|
||||
rsqr_k = 1 / sqrt(sqr_k);
|
||||
//float rsqr_k = 1 / sqrtf(kx * kx + ky * ky);
|
||||
kx *= rsqr_k;
|
||||
ky *= rsqr_k;
|
||||
float2 dt_x = float2(ht.y * kx, -ht.x * kx);
|
||||
float2 dt_y = float2(ht.y * ky, -ht.x * ky);
|
||||
|
||||
if ((DTid.x < g_OutWidth) && (DTid.y < g_OutHeight))
|
||||
{
|
||||
g_OutputHt[out_index] = ht;
|
||||
g_OutputHt[out_index + g_DtxAddressOffset] = dt_x;
|
||||
g_OutputHt[out_index + g_DtyAddressOffset] = dt_y;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef _OCEAN_SURFACE_HF_
|
||||
#define _OCEAN_SURFACE_HF_
|
||||
#include "globals.hlsli"
|
||||
#include "ShaderInterop_Ocean.h"
|
||||
|
||||
|
||||
#define PATCH_BLEND_BEGIN 100
|
||||
#define PATCH_BLEND_END 2000
|
||||
|
||||
|
||||
#define g_texDisplacement texture_0 // FFT wave displacement map in VS
|
||||
#define g_texPerlin texture_1 // FFT wave gradient map in PS
|
||||
#define g_texGradient texture_2 // Perlin wave displacement & gradient map in both VS & PS
|
||||
TEXTURE1D(g_texFresnel, float4, TEXSLOT_ONDEMAND3); // Fresnel factor lookup table
|
||||
#define g_texReflectCube texture_env_global
|
||||
|
||||
struct VS_OUTPUT
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
float3 LocalPos : TEXCOORD1;
|
||||
};
|
||||
|
||||
#endif // _OCEAN_SURFACE_HF_
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "globals.hlsli"
|
||||
#include "oceanSurfaceHF.hlsli"
|
||||
|
||||
float4 main(VS_OUTPUT In) : SV_Target
|
||||
{
|
||||
// Calculate eye vector.
|
||||
float3 eye_vec = g_LocalEye - In.LocalPos;
|
||||
float3 eye_dir = normalize(eye_vec);
|
||||
|
||||
|
||||
// --------------- Blend perlin noise for reducing the tiling artifacts
|
||||
|
||||
// Blend displacement to avoid tiling artifact
|
||||
float dist_2d = length(eye_vec.xy);
|
||||
float blend_factor = (PATCH_BLEND_END - dist_2d) / (PATCH_BLEND_END - PATCH_BLEND_BEGIN);
|
||||
blend_factor = clamp(blend_factor * blend_factor * blend_factor, 0, 1);
|
||||
|
||||
// Compose perlin waves from three octaves
|
||||
float2 perlin_tc = In.TexCoord * g_PerlinSize + g_UVBase;
|
||||
float2 perlin_tc0 = (blend_factor < 1) ? perlin_tc * g_PerlinOctave.x + g_PerlinMovement : 0;
|
||||
float2 perlin_tc1 = (blend_factor < 1) ? perlin_tc * g_PerlinOctave.y + g_PerlinMovement : 0;
|
||||
float2 perlin_tc2 = (blend_factor < 1) ? perlin_tc * g_PerlinOctave.z + g_PerlinMovement : 0;
|
||||
|
||||
float2 perlin_0 = g_texPerlin.Sample(sampler_aniso_wrap, perlin_tc0).xy;
|
||||
float2 perlin_1 = g_texPerlin.Sample(sampler_aniso_wrap, perlin_tc1).xy;
|
||||
float2 perlin_2 = g_texPerlin.Sample(sampler_aniso_wrap, perlin_tc2).xy;
|
||||
|
||||
float2 perlin = (perlin_0 * g_PerlinGradient.x + perlin_1 * g_PerlinGradient.y + perlin_2 * g_PerlinGradient.z);
|
||||
|
||||
|
||||
// --------------- Water body color
|
||||
|
||||
// Texcoord mash optimization: Texcoord of FFT wave is not required when blend_factor > 1
|
||||
float2 fft_tc = (blend_factor > 0) ? In.TexCoord : 0;
|
||||
|
||||
float2 grad = g_texGradient.Sample(sampler_aniso_wrap, fft_tc).xy;
|
||||
grad = lerp(perlin, grad, blend_factor);
|
||||
|
||||
// Calculate normal here.
|
||||
float3 normal = normalize(float3(grad, g_TexelLength_x2));
|
||||
// Reflected ray
|
||||
float3 reflect_vec = reflect(-eye_dir, normal);
|
||||
// dot(N, V)
|
||||
float cos_angle = dot(normal, eye_dir);
|
||||
|
||||
// A coarse way to handle transmitted light
|
||||
float3 body_color = g_WaterbodyColor;
|
||||
|
||||
|
||||
// --------------- Reflected color
|
||||
|
||||
// ramp.x for fresnel term. ramp.y for sky blending
|
||||
float4 ramp = g_texFresnel.Sample(sampler_linear_clamp, cos_angle).xyzw;
|
||||
// A workaround to deal with "indirect reflection vectors" (which are rays requiring multiple
|
||||
// reflections to reach the sky).
|
||||
if (reflect_vec.z < g_BendParam.x)
|
||||
ramp = lerp(ramp, g_BendParam.z, (g_BendParam.x - reflect_vec.z) / (g_BendParam.x - g_BendParam.y));
|
||||
reflect_vec.z = max(0, reflect_vec.z);
|
||||
|
||||
float3 reflection = g_texReflectCube.Sample(sampler_linear_clamp, reflect_vec).xyz;
|
||||
// Hack bit: making higher contrast
|
||||
reflection = reflection * reflection * 2.5f;
|
||||
|
||||
// Blend with predefined sky color
|
||||
float3 reflected_color = lerp(g_SkyColor, reflection, ramp.y);
|
||||
|
||||
// Combine waterbody color and reflected color
|
||||
float3 water_color = lerp(body_color, reflected_color, ramp.x);
|
||||
|
||||
|
||||
// --------------- Sun spots
|
||||
|
||||
float cos_spec = clamp(dot(reflect_vec, g_SunDir), 0, 1);
|
||||
float sun_spot = pow(cos_spec, g_Shineness);
|
||||
water_color += g_SunColor * sun_spot;
|
||||
|
||||
|
||||
return float4(water_color, 1);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
float4 main() : SV_TARGET
|
||||
{
|
||||
return float4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "globals.hlsli"
|
||||
#include "oceanSurfaceHF.hlsli"
|
||||
|
||||
VS_OUTPUT main(float2 vPos : POSITION)
|
||||
{
|
||||
VS_OUTPUT Output;
|
||||
|
||||
// Local position
|
||||
float4 pos_local = mul(float4(vPos, 0, 1), g_matLocal);
|
||||
// UV
|
||||
float2 uv_local = pos_local.xy * g_UVScale + g_UVOffset;
|
||||
|
||||
// Blend displacement to avoid tiling artifact
|
||||
float3 eye_vec = pos_local.xyz - g_LocalEye;
|
||||
float dist_2d = length(eye_vec.xy);
|
||||
float blend_factor = (PATCH_BLEND_END - dist_2d) / (PATCH_BLEND_END - PATCH_BLEND_BEGIN);
|
||||
blend_factor = clamp(blend_factor, 0, 1);
|
||||
|
||||
// Add perlin noise to distant patches
|
||||
float perlin = 0;
|
||||
if (blend_factor < 1)
|
||||
{
|
||||
float2 perlin_tc = uv_local * g_PerlinSize + g_UVBase;
|
||||
float perlin_0 = g_texPerlin.SampleLevel(sampler_aniso_wrap, perlin_tc * g_PerlinOctave.x + g_PerlinMovement, 0).w;
|
||||
float perlin_1 = g_texPerlin.SampleLevel(sampler_aniso_wrap, perlin_tc * g_PerlinOctave.y + g_PerlinMovement, 0).w;
|
||||
float perlin_2 = g_texPerlin.SampleLevel(sampler_aniso_wrap, perlin_tc * g_PerlinOctave.z + g_PerlinMovement, 0).w;
|
||||
|
||||
perlin = perlin_0 * g_PerlinAmplitude.x + perlin_1 * g_PerlinAmplitude.y + perlin_2 * g_PerlinAmplitude.z;
|
||||
}
|
||||
|
||||
// Displacement map
|
||||
float3 displacement = 0;
|
||||
if (blend_factor > 0)
|
||||
displacement = g_texDisplacement.SampleLevel(sampler_point_wrap, uv_local, 0).xyz;
|
||||
displacement = lerp(float3(0, 0, perlin), displacement, blend_factor);
|
||||
pos_local.xyz += displacement;
|
||||
|
||||
// Transform
|
||||
Output.Position = mul(pos_local, g_matWorldViewProj);
|
||||
Output.LocalPos = pos_local.xyz;
|
||||
|
||||
// Pass thru texture coordinate
|
||||
Output.TexCoord = uv_local;
|
||||
|
||||
return Output;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "ShaderInterop_Ocean.h"
|
||||
|
||||
STRUCTUREDBUFFER(g_InputDxyz, float2, TEXSLOT_ONDEMAND0);
|
||||
RWTEXTURE2D(output, float4, 0);
|
||||
|
||||
[numthreads(OCEAN_COMPUTE_TILESIZE, OCEAN_COMPUTE_TILESIZE, 1)]
|
||||
void main(uint3 DTid : SV_DispatchThreadID)
|
||||
{
|
||||
uint addr = g_OutWidth * DTid.y + DTid.x;
|
||||
|
||||
// cos(pi * (m1 + m2))
|
||||
int sign_correction = ((DTid.x + DTid.y) & 1) ? -1 : 1;
|
||||
|
||||
float dx = g_InputDxyz[addr + g_DtxAddressOffset].x * sign_correction * g_ChoppyScale;
|
||||
float dy = g_InputDxyz[addr + g_DtyAddressOffset].x * sign_correction * g_ChoppyScale;
|
||||
float dz = g_InputDxyz[addr].x * sign_correction;
|
||||
|
||||
output[DTid.xy] = float4(dx, dy, dz, 1);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "globals.hlsli"
|
||||
#include "ShaderInterop_Ocean.h"
|
||||
|
||||
#define xDisplacementMap texture_0
|
||||
RWTEXTURE2D(output, float4, 0);
|
||||
|
||||
[numthreads(OCEAN_COMPUTE_TILESIZE, OCEAN_COMPUTE_TILESIZE, 1)]
|
||||
void main( uint3 DTid : SV_DispatchThreadID )
|
||||
{
|
||||
// Sample neighbour texels
|
||||
float2 one_texel = float2(1.0f / (float)g_OutWidth, 1.0f / (float)g_OutHeight);
|
||||
|
||||
float2 uv = (float2)DTid.xy / float2(g_OutWidth, g_OutHeight);
|
||||
|
||||
float2 tc_left = float2(uv.x - one_texel.x, uv.y);
|
||||
float2 tc_right = float2(uv.x + one_texel.x, uv.y);
|
||||
float2 tc_back = float2(uv.x, uv.y - one_texel.y);
|
||||
float2 tc_front = float2(uv.x, uv.y + one_texel.y);
|
||||
|
||||
float3 displace_left = xDisplacementMap.SampleLevel(sampler_linear_clamp, tc_left, 0).xyz;
|
||||
float3 displace_right = xDisplacementMap.SampleLevel(sampler_linear_clamp, tc_right, 0).xyz;
|
||||
float3 displace_back = xDisplacementMap.SampleLevel(sampler_linear_clamp, tc_back, 0).xyz;
|
||||
float3 displace_front = xDisplacementMap.SampleLevel(sampler_linear_clamp, tc_front, 0).xyz;
|
||||
|
||||
// Do not store the actual normal value. Using gradient instead, which preserves two differential values.
|
||||
float2 gradient = { -(displace_right.z - displace_left.z), -(displace_front.z - displace_back.z) };
|
||||
|
||||
|
||||
// Calculate Jacobian corelation from the partial differential of height field
|
||||
float2 Dx = (displace_right.xy - displace_left.xy) * g_ChoppyScale * g_GridLen;
|
||||
float2 Dy = (displace_front.xy - displace_back.xy) * g_ChoppyScale * g_GridLen;
|
||||
float J = (1.0f + Dx.x) * (1.0f + Dy.y) - Dx.y * Dy.x;
|
||||
|
||||
// Practical subsurface scale calculation: max[0, (1 - J) + Amplitude * (2 * Coverage - 1)].
|
||||
float fold = max(1.0f - J, 0);
|
||||
|
||||
// Output
|
||||
output[DTid.xy] = float4(gradient, 0, fold);
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
#include "wiFFTGenerator.h"
|
||||
#include "wiResourceManager.h"
|
||||
#include "wiRenderer.h"
|
||||
#include "ShaderInterop_FFTGenerator.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
using namespace wiGraphicsTypes;
|
||||
|
||||
ComputeShader* CSFFT_512x512_Data_t::pRadix008A_CS = nullptr;
|
||||
ComputeShader* CSFFT_512x512_Data_t::pRadix008A_CS2 = nullptr;
|
||||
|
||||
void radix008A(CSFFT512x512_Plan* fft_plan,
|
||||
GPUUnorderedResource* pUAV_Dst,
|
||||
GPUResource* pSRV_Src,
|
||||
UINT thread_count,
|
||||
UINT istride,
|
||||
GRAPHICSTHREAD threadID)
|
||||
{
|
||||
// Setup execution configuration
|
||||
UINT grid = thread_count / COHERENCY_GRANULARITY;
|
||||
|
||||
GraphicsDevice* device = wiRenderer::GetDevice();
|
||||
|
||||
// Buffers
|
||||
GPUResource* cs_srvs[1] = { pSRV_Src };
|
||||
device->BindResourcesCS(cs_srvs, TEXSLOT_ONDEMAND0, 1, threadID);
|
||||
|
||||
GPUUnorderedResource* cs_uavs[1] = { pUAV_Dst };
|
||||
device->BindUnorderedAccessResourcesCS(cs_uavs, 0, 1, threadID);
|
||||
|
||||
// Shader
|
||||
if (istride > 1)
|
||||
device->BindCS(fft_plan->pRadix008A_CS, threadID);
|
||||
else
|
||||
device->BindCS(fft_plan->pRadix008A_CS2, threadID);
|
||||
|
||||
// Execute
|
||||
device->Dispatch(grid, 1, 1, threadID);
|
||||
|
||||
// Unbind resource
|
||||
device->UnBindResources(TEXSLOT_ONDEMAND0, 1, threadID);
|
||||
device->UnBindUnorderedAccessResources(0, 1, threadID);
|
||||
}
|
||||
|
||||
void fft_512x512_c2c(CSFFT512x512_Plan* fft_plan,
|
||||
GPUUnorderedResource* pUAV_Dst,
|
||||
GPUResource* pSRV_Dst,
|
||||
GPUResource* pSRV_Src,
|
||||
GRAPHICSTHREAD threadID)
|
||||
{
|
||||
const UINT thread_count = fft_plan->slices * (512 * 512) / 8;
|
||||
GPUUnorderedResource* pUAV_Tmp = fft_plan->pUAV_Tmp;
|
||||
GPUResource* pSRV_Tmp = fft_plan->pSRV_Tmp;
|
||||
GraphicsDevice* device = wiRenderer::GetDevice();
|
||||
GPUBuffer* cs_cbs;
|
||||
|
||||
UINT istride = 512 * 512 / 8;
|
||||
cs_cbs = fft_plan->pRadix008A_CB[0];
|
||||
device->BindConstantBufferCS(&cs_cbs[0], CB_GETBINDSLOT(FFTGeneratorCB), threadID);
|
||||
radix008A(fft_plan, pUAV_Tmp, pSRV_Src, thread_count, istride, threadID);
|
||||
|
||||
istride /= 8;
|
||||
cs_cbs = fft_plan->pRadix008A_CB[1];
|
||||
device->BindConstantBufferCS(&cs_cbs[0], CB_GETBINDSLOT(FFTGeneratorCB), threadID);
|
||||
radix008A(fft_plan, pUAV_Dst, pSRV_Tmp, thread_count, istride, threadID);
|
||||
|
||||
istride /= 8;
|
||||
cs_cbs = fft_plan->pRadix008A_CB[2];
|
||||
device->BindConstantBufferCS(&cs_cbs[0], CB_GETBINDSLOT(FFTGeneratorCB), threadID);
|
||||
radix008A(fft_plan, pUAV_Tmp, pSRV_Dst, thread_count, istride, threadID);
|
||||
|
||||
istride /= 8;
|
||||
cs_cbs = fft_plan->pRadix008A_CB[3];
|
||||
device->BindConstantBufferCS(&cs_cbs[0], CB_GETBINDSLOT(FFTGeneratorCB), threadID);
|
||||
radix008A(fft_plan, pUAV_Dst, pSRV_Tmp, thread_count, istride, threadID);
|
||||
|
||||
istride /= 8;
|
||||
cs_cbs = fft_plan->pRadix008A_CB[4];
|
||||
device->BindConstantBufferCS(&cs_cbs[0], CB_GETBINDSLOT(FFTGeneratorCB), threadID);
|
||||
radix008A(fft_plan, pUAV_Tmp, pSRV_Dst, thread_count, istride, threadID);
|
||||
|
||||
istride /= 8;
|
||||
cs_cbs = fft_plan->pRadix008A_CB[5];
|
||||
device->BindConstantBufferCS(&cs_cbs[0], CB_GETBINDSLOT(FFTGeneratorCB), threadID);
|
||||
radix008A(fft_plan, pUAV_Dst, pSRV_Tmp, thread_count, istride, threadID);
|
||||
}
|
||||
|
||||
void create_cbuffers_512x512(CSFFT512x512_Plan* plan, GraphicsDevice* device, UINT slices)
|
||||
{
|
||||
// Create 6 cbuffers for 512x512 transform.
|
||||
|
||||
GPUBufferDesc cb_desc;
|
||||
cb_desc.Usage = USAGE_IMMUTABLE;
|
||||
cb_desc.BindFlags = BIND_CONSTANT_BUFFER;
|
||||
cb_desc.CPUAccessFlags = 0;
|
||||
cb_desc.MiscFlags = 0;
|
||||
cb_desc.ByteWidth = sizeof(FFTGeneratorCB);
|
||||
cb_desc.StructureByteStride = 0;
|
||||
|
||||
SubresourceData cb_data;
|
||||
cb_data.SysMemPitch = 0;
|
||||
cb_data.SysMemSlicePitch = 0;
|
||||
|
||||
//struct CB_Structure
|
||||
//{
|
||||
// UINT thread_count;
|
||||
// UINT ostride;
|
||||
// UINT istride;
|
||||
// UINT pstride;
|
||||
// float phase_base;
|
||||
//};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(plan->pRadix008A_CB); ++i)
|
||||
{
|
||||
plan->pRadix008A_CB[i] = new GPUBuffer;
|
||||
}
|
||||
|
||||
// Buffer 0
|
||||
const UINT thread_count = slices * (512 * 512) / 8;
|
||||
UINT ostride = 512 * 512 / 8;
|
||||
UINT istride = ostride;
|
||||
double phase_base = -TWO_PI / (512.0 * 512.0);
|
||||
|
||||
FFTGeneratorCB cb_data_buf0 = { thread_count, ostride, istride, 512, (float)phase_base };
|
||||
cb_data.pSysMem = &cb_data_buf0;
|
||||
|
||||
device->CreateBuffer(&cb_desc, &cb_data, plan->pRadix008A_CB[0]);
|
||||
assert(plan->pRadix008A_CB[0]);
|
||||
|
||||
// Buffer 1
|
||||
istride /= 8;
|
||||
phase_base *= 8.0;
|
||||
|
||||
FFTGeneratorCB cb_data_buf1 = { thread_count, ostride, istride, 512, (float)phase_base };
|
||||
cb_data.pSysMem = &cb_data_buf1;
|
||||
|
||||
device->CreateBuffer(&cb_desc, &cb_data, plan->pRadix008A_CB[1]);
|
||||
assert(plan->pRadix008A_CB[1]);
|
||||
|
||||
// Buffer 2
|
||||
istride /= 8;
|
||||
phase_base *= 8.0;
|
||||
|
||||
FFTGeneratorCB cb_data_buf2 = { thread_count, ostride, istride, 512, (float)phase_base };
|
||||
cb_data.pSysMem = &cb_data_buf2;
|
||||
|
||||
device->CreateBuffer(&cb_desc, &cb_data, plan->pRadix008A_CB[2]);
|
||||
assert(plan->pRadix008A_CB[2]);
|
||||
|
||||
// Buffer 3
|
||||
istride /= 8;
|
||||
phase_base *= 8.0;
|
||||
ostride /= 512;
|
||||
|
||||
FFTGeneratorCB cb_data_buf3 = { thread_count, ostride, istride, 1, (float)phase_base };
|
||||
cb_data.pSysMem = &cb_data_buf3;
|
||||
|
||||
device->CreateBuffer(&cb_desc, &cb_data, plan->pRadix008A_CB[3]);
|
||||
assert(plan->pRadix008A_CB[3]);
|
||||
|
||||
// Buffer 4
|
||||
istride /= 8;
|
||||
phase_base *= 8.0;
|
||||
|
||||
FFTGeneratorCB cb_data_buf4 = { thread_count, ostride, istride, 1, (float)phase_base };
|
||||
cb_data.pSysMem = &cb_data_buf4;
|
||||
|
||||
device->CreateBuffer(&cb_desc, &cb_data, plan->pRadix008A_CB[4]);
|
||||
assert(plan->pRadix008A_CB[4]);
|
||||
|
||||
// Buffer 5
|
||||
istride /= 8;
|
||||
phase_base *= 8.0;
|
||||
|
||||
FFTGeneratorCB cb_data_buf5 = { thread_count, ostride, istride, 1, (float)phase_base };
|
||||
cb_data.pSysMem = &cb_data_buf5;
|
||||
|
||||
device->CreateBuffer(&cb_desc, &cb_data, plan->pRadix008A_CB[5]);
|
||||
assert(plan->pRadix008A_CB[5]);
|
||||
}
|
||||
|
||||
void fft512x512_create_plan(CSFFT512x512_Plan* plan, UINT slices)
|
||||
{
|
||||
GraphicsDevice* device = wiRenderer::GetDevice();
|
||||
|
||||
plan->slices = slices;
|
||||
|
||||
|
||||
// Constants
|
||||
// Create 6 cbuffers for 512x512 transform
|
||||
create_cbuffers_512x512(plan, device, slices);
|
||||
|
||||
// Temp buffer
|
||||
GPUBufferDesc buf_desc;
|
||||
buf_desc.ByteWidth = sizeof(float) * 2 * (512 * slices) * 512;
|
||||
buf_desc.Usage = USAGE_DEFAULT;
|
||||
buf_desc.BindFlags = BIND_UNORDERED_ACCESS | BIND_SHADER_RESOURCE;
|
||||
buf_desc.CPUAccessFlags = 0;
|
||||
buf_desc.MiscFlags = RESOURCE_MISC_BUFFER_STRUCTURED;
|
||||
buf_desc.StructureByteStride = sizeof(float) * 2;
|
||||
|
||||
plan->pBuffer_Tmp = new GPUBuffer;
|
||||
device->CreateBuffer(&buf_desc, nullptr, plan->pBuffer_Tmp);
|
||||
|
||||
plan->pSRV_Tmp = (GPUResource*)plan->pBuffer_Tmp;
|
||||
plan->pUAV_Tmp = (GPUUnorderedResource*)plan->pBuffer_Tmp;
|
||||
}
|
||||
|
||||
void fft512x512_destroy_plan(CSFFT512x512_Plan* plan)
|
||||
{
|
||||
SAFE_DELETE(plan->pBuffer_Tmp);
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
SAFE_DELETE(plan->pRadix008A_CB[i]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CSFFT_512x512_Data_t::LoadShaders()
|
||||
{
|
||||
|
||||
pRadix008A_CS = static_cast<ComputeShader*>(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "fft_512x512_c2c_CS.cso", wiResourceManager::COMPUTESHADER));
|
||||
pRadix008A_CS2 = static_cast<ComputeShader*>(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "fft_512x512_c2c_v2_CS.cso", wiResourceManager::COMPUTESHADER));
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef _FFT_GENERATOR_H_
|
||||
#define _FFT_GENERATOR_H_
|
||||
|
||||
#include "CommonInclude.h"
|
||||
#include "wiGraphicsAPI.h"
|
||||
|
||||
|
||||
//Memory access coherency (in threads)
|
||||
#define COHERENCY_GRANULARITY 128
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Common types
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct CSFFT_512x512_Data_t
|
||||
{
|
||||
static wiGraphicsTypes::ComputeShader* pRadix008A_CS;
|
||||
static wiGraphicsTypes::ComputeShader* pRadix008A_CS2;
|
||||
|
||||
// More than one array can be transformed at same time
|
||||
UINT slices;
|
||||
|
||||
// For 512x512 config, we need 6 constant buffers
|
||||
wiGraphicsTypes::GPUBuffer* pRadix008A_CB[6];
|
||||
|
||||
// Temporary buffers
|
||||
wiGraphicsTypes::GPUBuffer* pBuffer_Tmp;
|
||||
wiGraphicsTypes::GPUUnorderedResource* pUAV_Tmp;
|
||||
wiGraphicsTypes::GPUResource* pSRV_Tmp;
|
||||
|
||||
static void LoadShaders();
|
||||
} CSFFT512x512_Plan;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Common constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define TWO_PI 6.283185307179586476925286766559
|
||||
|
||||
#define FFT_DIMENSIONS 3U
|
||||
#define FFT_PLAN_SIZE_LIMIT (1U << 27)
|
||||
|
||||
#define FFT_FORWARD -1
|
||||
#define FFT_INVERSE 1
|
||||
|
||||
|
||||
void fft512x512_create_plan(CSFFT512x512_Plan* plan, UINT slices);
|
||||
void fft512x512_destroy_plan(CSFFT512x512_Plan* plan);
|
||||
|
||||
void fft_512x512_c2c(CSFFT512x512_Plan* fft_plan,
|
||||
wiGraphicsTypes::GPUUnorderedResource* pUAV_Dst,
|
||||
wiGraphicsTypes::GPUResource* pSRV_Dst,
|
||||
wiGraphicsTypes::GPUResource* pSRV_Src,
|
||||
GRAPHICSTHREAD threadID);
|
||||
|
||||
|
||||
#endif // _FFT_GENERATOR_H_
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "wiBackLog.h"
|
||||
#include "wiCpuInfo.h"
|
||||
#include "wiSound.h"
|
||||
#include "wiOcean.h"
|
||||
#include "wiHelper.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -28,6 +29,8 @@ namespace wiInitializer
|
||||
wiFont::Initialize();
|
||||
wiFont::SetUpStaticComponents();
|
||||
|
||||
wiOcean::SetUpStatic();
|
||||
|
||||
if (FAILED(wiSoundEffect::Initialize()) || FAILED(wiMusic::Initialize()))
|
||||
{
|
||||
stringstream ss("");
|
||||
|
||||
+11
-11
@@ -1078,49 +1078,49 @@ struct Camera:public Transform{
|
||||
XMStoreFloat4x4(&this->InvProjection, InvP);
|
||||
}
|
||||
|
||||
XMVECTOR GetEye()
|
||||
XMVECTOR GetEye() const
|
||||
{
|
||||
return XMLoadFloat3(&translation);
|
||||
}
|
||||
XMVECTOR GetAt()
|
||||
XMVECTOR GetAt() const
|
||||
{
|
||||
return XMLoadFloat3(&At);
|
||||
}
|
||||
XMVECTOR GetUp()
|
||||
XMVECTOR GetUp() const
|
||||
{
|
||||
return XMLoadFloat3(&Up);
|
||||
}
|
||||
XMVECTOR GetRight()
|
||||
XMVECTOR GetRight() const
|
||||
{
|
||||
return XMVector3Cross(GetAt(), GetUp());
|
||||
}
|
||||
XMMATRIX GetView()
|
||||
XMMATRIX GetView() const
|
||||
{
|
||||
return XMLoadFloat4x4(&View);
|
||||
}
|
||||
XMMATRIX GetInvView()
|
||||
XMMATRIX GetInvView() const
|
||||
{
|
||||
return XMLoadFloat4x4(&InvView);
|
||||
}
|
||||
XMMATRIX GetProjection()
|
||||
XMMATRIX GetProjection() const
|
||||
{
|
||||
return XMLoadFloat4x4(&Projection);
|
||||
}
|
||||
XMMATRIX GetInvProjection()
|
||||
XMMATRIX GetInvProjection() const
|
||||
{
|
||||
return XMLoadFloat4x4(&InvProjection);
|
||||
}
|
||||
XMMATRIX GetViewProjection()
|
||||
XMMATRIX GetViewProjection() const
|
||||
{
|
||||
return XMLoadFloat4x4(&VP);
|
||||
}
|
||||
XMMATRIX GetInvViewProjection()
|
||||
XMMATRIX GetInvViewProjection() const
|
||||
{
|
||||
return XMLoadFloat4x4(&InvVP);
|
||||
}
|
||||
|
||||
// when the projection matrix is modified for reverse zbuffering, this returns the normal projection
|
||||
XMMATRIX GetRealProjection()
|
||||
XMMATRIX GetRealProjection() const
|
||||
{
|
||||
return XMLoadFloat4x4(&realProjection);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,239 @@
|
||||
#ifndef _OCEAN_SIMULATOR_H
|
||||
#define _OCEAN_SIMULATOR_H
|
||||
|
||||
#include "CommonInclude.h"
|
||||
#include "wiGraphicsAPI.h"
|
||||
#include "wiFFTGenerator.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
struct Camera;
|
||||
|
||||
struct wiOceanParameter
|
||||
{
|
||||
// Must be power of 2.
|
||||
int dmap_dim;
|
||||
// Typical value is 1000 ~ 2000
|
||||
float patch_length;
|
||||
|
||||
// Adjust the time interval for simulation.
|
||||
float time_scale;
|
||||
// Amplitude for transverse wave. Around 1.0
|
||||
float wave_amplitude;
|
||||
// Wind direction. Normalization not required.
|
||||
XMFLOAT2 wind_dir;
|
||||
// Around 100 ~ 1000
|
||||
float wind_speed;
|
||||
// This value damps out the waves against the wind direction.
|
||||
// Smaller value means higher wind dependency.
|
||||
float wind_dependency;
|
||||
// The amplitude for longitudinal wave. Must be positive.
|
||||
float choppy_scale;
|
||||
|
||||
wiOceanParameter()
|
||||
{
|
||||
// Original version:
|
||||
//dmap_dim = 512;
|
||||
//patch_length = 2000.0f;
|
||||
//time_scale = 0.8f;
|
||||
//wave_amplitude = 0.35f;
|
||||
//wind_dir = XMFLOAT2(0.8f, 0.6f);
|
||||
//wind_speed = 600.0f;
|
||||
//wind_dependency = 0.07f;
|
||||
//choppy_scale = 1.3f;
|
||||
|
||||
// Scaled version:
|
||||
dmap_dim = 512;
|
||||
patch_length = 200.0f;
|
||||
time_scale = 0.8f;
|
||||
wave_amplitude = 80.0f;
|
||||
wind_dir = XMFLOAT2(0.8f, 0.6f);
|
||||
wind_speed = 600.0f;
|
||||
wind_dependency = 0.07f;
|
||||
choppy_scale = 1.3f;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class wiOcean
|
||||
{
|
||||
public:
|
||||
wiOcean(const wiOceanParameter& params);
|
||||
~wiOcean();
|
||||
|
||||
// -------------------------- Initialization & simulation routines ------------------------
|
||||
|
||||
// Update ocean wave when tick arrives.
|
||||
void UpdateDisplacementMap(float time, GRAPHICSTHREAD threadID);
|
||||
void Render(const Camera* camera, float time, GRAPHICSTHREAD threadID);
|
||||
|
||||
// Texture access
|
||||
wiGraphicsTypes::Texture2D* getDisplacementMap();
|
||||
wiGraphicsTypes::Texture2D* getGradientMap();
|
||||
|
||||
const wiOceanParameter& getParameters();
|
||||
|
||||
static void LoadShaders();
|
||||
static void SetUpStatic();
|
||||
static void CleanUpStatic();
|
||||
|
||||
XMFLOAT3 waterColor = XMFLOAT3(0.07f, 0.15f, 0.2f);
|
||||
|
||||
protected:
|
||||
wiOceanParameter m_param;
|
||||
|
||||
// Simulation params:
|
||||
|
||||
wiGraphicsTypes::Texture2D* m_pDisplacementMap; // (RGBA32F)
|
||||
wiGraphicsTypes::Texture2D* m_pGradientMap; // (RGBA16F)
|
||||
|
||||
// Initialize the vector field.
|
||||
void initHeightMap(XMFLOAT2* out_h0, float* out_omega);
|
||||
|
||||
|
||||
// ----------------------------------- CS simulation data ---------------------------------
|
||||
|
||||
// Initial height field H(0) generated by Phillips spectrum & Gauss distribution.
|
||||
wiGraphicsTypes::GPUBuffer* m_pBuffer_Float2_H0;
|
||||
|
||||
// Angular frequency
|
||||
wiGraphicsTypes::GPUBuffer* m_pBuffer_Float_Omega;
|
||||
|
||||
// Height field H(t), choppy field Dx(t) and Dy(t) in frequency domain, updated each frame.
|
||||
wiGraphicsTypes::GPUBuffer* m_pBuffer_Float2_Ht;
|
||||
|
||||
// Height & choppy buffer in the space domain, corresponding to H(t), Dx(t) and Dy(t)
|
||||
wiGraphicsTypes::GPUBuffer* m_pBuffer_Float_Dxyz;
|
||||
|
||||
// Shaders, layouts and constants
|
||||
static wiGraphicsTypes::ComputeShader* m_pUpdateSpectrumCS;
|
||||
static wiGraphicsTypes::ComputeShader* m_pUpdateDisplacementMapCS;
|
||||
static wiGraphicsTypes::ComputeShader* m_pUpdateGradientFoldingCS;
|
||||
|
||||
wiGraphicsTypes::GPUBuffer* m_pImmutableCB;
|
||||
wiGraphicsTypes::GPUBuffer* m_pPerFrameCB;
|
||||
|
||||
// FFT wrap-up
|
||||
static CSFFT512x512_Plan m_fft_plan;
|
||||
|
||||
|
||||
|
||||
// Rendering params:
|
||||
struct ocean_vertex
|
||||
{
|
||||
float index_x;
|
||||
float index_y;
|
||||
};
|
||||
|
||||
// Mesh properties:
|
||||
|
||||
// Mesh grid dimension, must be 2^n. 4x4 ~ 256x256
|
||||
int g_MeshDim = 128;
|
||||
// Subdivision thredshold. Any quad covers more pixels than this value needs to be subdivided.
|
||||
float g_UpperGridCoverage = 64.0f;
|
||||
// Draw distance = g_PatchLength * 2^g_FurthestCover
|
||||
int g_FurthestCover = 8;
|
||||
|
||||
|
||||
// Shading properties:
|
||||
// Two colors for waterbody and sky color
|
||||
XMFLOAT3 g_SkyColor = XMFLOAT3(0.38f, 0.45f, 0.56f);
|
||||
// Blending term for sky cubemap
|
||||
float g_SkyBlending = 16.0f;
|
||||
|
||||
// Perlin wave parameters
|
||||
float g_PerlinSize = 1.0f;
|
||||
float g_PerlinSpeed = 0.06f;
|
||||
XMFLOAT3 g_PerlinAmplitude = XMFLOAT3(35, 42, 57);
|
||||
XMFLOAT3 g_PerlinGradient = XMFLOAT3(1.4f, 1.6f, 2.2f);
|
||||
XMFLOAT3 g_PerlinOctave = XMFLOAT3(1.12f, 0.59f, 0.23f);
|
||||
XMFLOAT2 g_WindDir;
|
||||
|
||||
XMFLOAT3 g_BendParam = XMFLOAT3(0.1f, -0.4f, 0.2f);
|
||||
|
||||
// Sunspot parameters
|
||||
XMFLOAT3 g_SunDir = XMFLOAT3(0.936016f, -0.343206f, 0.0780013f);
|
||||
XMFLOAT3 g_SunColor = XMFLOAT3(1.0f, 1.0f, 0.6f);
|
||||
float g_Shineness = 400.0f;
|
||||
|
||||
|
||||
|
||||
|
||||
struct QuadNode
|
||||
{
|
||||
XMFLOAT2 bottom_left;
|
||||
float length;
|
||||
int lod;
|
||||
|
||||
int sub_node[4];
|
||||
};
|
||||
|
||||
struct QuadRenderParam
|
||||
{
|
||||
UINT num_inner_verts;
|
||||
UINT num_inner_faces;
|
||||
UINT inner_start_index;
|
||||
|
||||
UINT num_boundary_verts;
|
||||
UINT num_boundary_faces;
|
||||
UINT boundary_start_index;
|
||||
};
|
||||
|
||||
// Quad-tree LOD, 0 to 9 (1x1 ~ 512x512)
|
||||
int g_Lods = 0;
|
||||
// Pattern lookup array. Filled at init time.
|
||||
QuadRenderParam g_mesh_patterns[9][3][3][3][3];
|
||||
// Pick a proper mesh pattern according to the adjacent patches.
|
||||
QuadRenderParam& selectMeshPattern(const QuadNode& quad_node);
|
||||
|
||||
// Rendering list
|
||||
std::vector<QuadNode> g_render_list;
|
||||
int buildNodeList(QuadNode& quad_node, const Camera& camera);
|
||||
|
||||
// D3D11 buffers and layout
|
||||
wiGraphicsTypes::GPUBuffer* g_pMeshVB = nullptr;
|
||||
wiGraphicsTypes::GPUBuffer* g_pMeshIB = nullptr;
|
||||
static wiGraphicsTypes::VertexLayout* g_pMeshLayout;
|
||||
|
||||
// Color look up 1D texture
|
||||
static wiGraphicsTypes::Texture1D* g_pFresnelMap;
|
||||
|
||||
// Distant perlin wave
|
||||
static wiGraphicsTypes::Texture2D* g_pPerlinMap;
|
||||
|
||||
// HLSL shaders
|
||||
static wiGraphicsTypes::VertexShader* g_pOceanSurfVS;
|
||||
static wiGraphicsTypes::PixelShader* g_pOceanSurfPS;
|
||||
static wiGraphicsTypes::PixelShader* g_pWireframePS;
|
||||
|
||||
static wiGraphicsTypes::GPUBuffer* g_pPerCallCB;
|
||||
static wiGraphicsTypes::GPUBuffer* g_pShadingCB;
|
||||
|
||||
// State blocks
|
||||
static wiGraphicsTypes::RasterizerState* g_pRSState_Solid;
|
||||
static wiGraphicsTypes::RasterizerState* g_pRSState_Wireframe;
|
||||
static wiGraphicsTypes::DepthStencilState* g_pDSState_Disable;
|
||||
static wiGraphicsTypes::BlendState* g_pBState_Transparent;
|
||||
|
||||
|
||||
// init & cleanup
|
||||
void initRenderResource();
|
||||
void cleanupRenderResource();
|
||||
// create a triangle strip mesh for ocean surface.
|
||||
void createSurfaceMesh();
|
||||
// create color/fresnel lookup table.
|
||||
void createFresnelMap();
|
||||
// create perlin noise texture for far-sight rendering
|
||||
void loadTextures();
|
||||
|
||||
int generateBoundaryMesh(int left_degree, int right_degree, int bottom_degree, int top_degree,
|
||||
RECT vert_rect, DWORD* output);
|
||||
int generateInnerMesh(RECT vert_rect, DWORD* output);
|
||||
bool checkNodeVisibility(const QuadNode& quad_node, const Camera& camera);
|
||||
float estimateGridCoverage(const QuadNode& quad_node, const Camera& camera, float screen_area);
|
||||
bool isLeaf(const QuadNode& quad_node);
|
||||
int searchLeaf(const std::vector<QuadNode>& node_list, const XMFLOAT2& point);
|
||||
};
|
||||
|
||||
#endif // _OCEAN_SIMULATOR_H
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "wiRectPacker.h"
|
||||
#include "wiBackLog.h"
|
||||
#include "wiProfiler.h"
|
||||
#include <wiOcean.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -76,6 +77,7 @@ int wiRenderer::visibleCount;
|
||||
wiRenderTarget wiRenderer::normalMapRT, wiRenderer::imagesRT, wiRenderer::imagesRTAdd;
|
||||
Camera *wiRenderer::cam = nullptr, *wiRenderer::refCam = nullptr, *wiRenderer::prevFrameCam = nullptr;
|
||||
PHYSICS* wiRenderer::physicsEngine = nullptr;
|
||||
wiOcean* wiRenderer::ocean = nullptr;
|
||||
|
||||
string wiRenderer::SHADERPATH = "shaders/";
|
||||
#pragma endregion
|
||||
@@ -936,6 +938,8 @@ void wiRenderer::ReloadShaders(const std::string& path)
|
||||
wiFont::LoadShaders();
|
||||
wiImage::LoadShaders();
|
||||
wiLensFlare::LoadShaders();
|
||||
wiOcean::LoadShaders();
|
||||
CSFFT_512x512_Data_t::LoadShaders();
|
||||
|
||||
GetDevice()->UNLOCK();
|
||||
}
|
||||
@@ -2126,6 +2130,12 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID)
|
||||
hair->ComputeCulling(getCamera(), threadID);
|
||||
}
|
||||
|
||||
// Compute water simulation:
|
||||
if (ocean != nullptr)
|
||||
{
|
||||
ocean->UpdateDisplacementMap(renderTime, threadID);
|
||||
}
|
||||
|
||||
// Render out of date environment probes:
|
||||
RefreshEnvProbes(threadID);
|
||||
|
||||
@@ -4669,6 +4679,11 @@ void wiRenderer::DrawWorldTransparent(Camera* camera, SHADERTYPE shaderType, Tex
|
||||
GetDevice()->BindResourcePS(resourceBuffers[RBTYPE_ENTITYINDEXLIST_TRANSPARENT], SBSLOT_ENTITYINDEXLIST, threadID);
|
||||
}
|
||||
|
||||
if (ocean != nullptr)
|
||||
{
|
||||
ocean->Render(camera, renderTime, threadID);
|
||||
}
|
||||
|
||||
if (grass)
|
||||
{
|
||||
GetDevice()->BindDepthStencilState(depthStencils[DSSTYPE_HAIRALPHACOMPOSITION], STENCILREF_DEFAULT, threadID); // minimizes overdraw by depthcomp = less
|
||||
@@ -6604,3 +6619,13 @@ bool wiRenderer::GetAdvancedRefractionsEnabled()
|
||||
{
|
||||
return advancedRefractions && GetDevice()->CheckCapability(GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_UNORDEREDACCESSTEXTURE_LOAD_FORMAT_EXT);
|
||||
}
|
||||
|
||||
void wiRenderer::SetOceanEnabled(bool enabled, const wiOceanParameter& params)
|
||||
{
|
||||
SAFE_DELETE(ocean);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
ocean = new wiOcean(params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ struct Cullable;
|
||||
class PHYSICS;
|
||||
class wiRenderTarget;
|
||||
class wiWaterPlane;
|
||||
class wiOcean;
|
||||
struct wiOceanParameter;
|
||||
|
||||
typedef std::map<std::string, Mesh*> MeshCollection;
|
||||
typedef std::map<std::string, Material*> MaterialCollection;
|
||||
@@ -534,6 +536,10 @@ public:
|
||||
static PHYSICS* physicsEngine;
|
||||
static void SynchronizeWithPhysicsEngine(float dt = 1.0f / 60.0f);
|
||||
|
||||
static wiOcean* ocean;
|
||||
static void SetOceanEnabled(bool enabled, const wiOceanParameter& params);
|
||||
static wiOcean* GetOcean() { return ocean; }
|
||||
|
||||
static Model* LoadModel(const std::string& dir, const std::string& name, const XMMATRIX& transform = XMMatrixIdentity(), const std::string& ident = "common");
|
||||
static void LoadWorldInfo(const std::string& dir, const std::string& name);
|
||||
static void LoadDefaultLighting();
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user