merged in ocean

This commit is contained in:
Turanszki Janos
2017-11-13 20:58:43 +00:00
34 changed files with 2705 additions and 30 deletions
+1 -1
View File
@@ -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
View File
@@ -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()
{
+2
View File
@@ -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;
+2
View File
@@ -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">
+6
View File
@@ -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">
+103
View File
@@ -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);
}
+31
View File
@@ -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.
+22 -17
View File
@@ -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
+16
View File
@@ -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_
+76
View File
@@ -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_
+1
View File
@@ -56,6 +56,7 @@
#include "wiSpinLock.h"
#include "wiRectPacker.h"
#include "wiProfiler.h"
#include "wiOcean.h"
#include "RenderableComponent.h"
#include "Renderable2DComponent.h"
+30
View File
@@ -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">
+159
View File
@@ -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
+3
View File
@@ -0,0 +1,3 @@
#define FFT_V2
#include "fft_512x512_c2c_CS.hlsl"
+46
View File
@@ -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;
}
}
+24
View File
@@ -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_
+79
View File
@@ -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);
}
+4
View File
@@ -0,0 +1,4 @@
float4 main() : SV_TARGET
{
return float4(1.0f, 1.0f, 1.0f, 1.0f);
}
+46
View File
@@ -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);
}
+228
View File
@@ -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));
}
+57
View File
@@ -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_
+3
View File
@@ -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
View File
@@ -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
+239
View File
@@ -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
+25
View File
@@ -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);
}
}
+6
View File
@@ -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.