Skip to content
This repository has been archived by the owner on May 28, 2024. It is now read-only.

Updated to UE 4.19 #46

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Content/Blueprints/OceanSimulator.uasset
Binary file not shown.
Binary file added Content/Blueprints/OceanSimulator_Debug.uasset
Binary file not shown.
Binary file added Content/Maps/Level_Test.umap
Binary file not shown.
Binary file added Content/Materials/HSL.uasset
Binary file not shown.
Binary file added Content/Materials/MI_OceanCS_Example.uasset
Binary file not shown.
Binary file modified Content/Materials/M_OceanCS.uasset
Binary file not shown.
Binary file added Content/Materials/Philips_Spec.uasset
Binary file not shown.
Binary file added Content/Materials/ShaderTesting.uasset
Binary file not shown.
Binary file added Content/Materials/SimpleWave.uasset
Binary file not shown.
Binary file added Content/Materials/Testing_Inst.uasset
Binary file not shown.
Binary file added Content/Materials/temp.uasset
Binary file not shown.
Binary file added Content/Materials/waterTest.uasset
Binary file not shown.
Binary file added Content/Materials/waveGenTest.uasset
Binary file not shown.
Binary file added Content/Textures/Dynamic_Tex_Test.uasset
Binary file not shown.
Binary file added Content/Textures/Rand_Tex.uasset
Binary file not shown.
Binary file added Content/Textures/SeaDistant_N.uasset
Binary file not shown.
Binary file added Content/Textures/SeaWavesB_N.uasset
Binary file not shown.
Binary file not shown.
Binary file added Content/Textures/foo.uasset
Binary file not shown.
Binary file added Content/Textures/uniformRan1.uasset
Binary file not shown.
Binary file added Content/Textures/uniformRan2.uasset
Binary file not shown.
Binary file added Content/Textures/uniformRan3.uasset
Binary file not shown.
Binary file added Content/Textures/uniformRan4.uasset
Binary file not shown.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ Overview
VaOcean is the ocean surface simulation plugin for [Unreal Engine 4](https://www.unrealengine.com/).

Key features:
* **@TODO** Plugin in development mode!!!
* Old version based on [NVIDIA SDK sample](https://developer.nvidia.com/dx11-samples) "FFT Ocean" lives in [archive_UE4.12](https://github.com/ufna/VaOcean/tree/archive_UE4.12) branch
* Component that renders displacement and gradient (normal) maps in real time
* Sample content, including water shader and grid meshes to be used on scene
* Set of global shaders that perform FFT calculation and other tech stuff on GPU

Check the **[Wiki](https://github.com/ufna/VaOcean/wiki)** tab to know more about the plugin.

Current version: **0.5 A 1** (UE 4.19)
Current version: **0.6 A 1** (UE 4.19)

Right now the plugin is a state of development. More features should be added soon!

To install this plugin simpy drop it into the plugin folder in your project root directory. The enable it from the plug in menu. An example map is included.

![SCREENSHOT](SCREENSHOT.jpg)

Expand Down
Binary file modified Resources/Icon128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified SCREENSHOT.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 65 additions & 0 deletions Shaders/Private/VaOcean_CS.usf
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Created 2014-2016 Vladimir Alyamkin. MIT license

#include "/Engine/Private/Common.ush"


#define PI 3.1415926536f
#define BLOCK_SIZE_X 16
#define BLOCK_SIZE_Y 16

// Immutable
uint g_ActualDim;
uint g_InWidth;
uint g_OutWidth;
uint g_OutHeight;
uint g_DtxAddressOffset;
uint g_DtyAddressOffset;

// Buffers
StructuredBuffer<float2> g_InputH0;
StructuredBuffer<float> g_InputOmega;
RWStructuredBuffer<float2> g_OutputHt;


//////////////////////////////////////////////////////////////////////////
// Pre-FFT data preparation: H(0) -> H(t)

[numthreads(BLOCK_SIZE_X, BLOCK_SIZE_Y, 1)]
void UpdateSpectrumCS(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] * PerFrameSp.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);
}

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;
}
}
167 changes: 167 additions & 0 deletions Shaders/Private/VaOcean_FFT.usf
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
// Created 2014-2016 Vladimir Alyamkin. MIT license

#include "/Engine/Private/Common.ush"

#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

// Source and destination buffers
StructuredBuffer<float2> g_SrcData;
RWStructuredBuffer<float2> g_DstData;


//////////////////////////////////////////////////////////////////////////
// FFT butterfly helper functions

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);
}


//////////////////////////////////////////////////////////////////////////
// Radix FFT compute shaders

[numthreads(COHERENCY_GRANULARITY, 1, 1)]
void Radix008A_CS(uint3 thread_id : SV_DispatchThreadID)
{
if (thread_id.x >= PerFrameFFT.ThreadCount)
return;

// Fetch 8 complex numbers
float2 D[8];

uint i;
uint imod = thread_id & (PerFrameFFT.istride - 1);
uint iaddr = ((thread_id - imod) << 3) + imod;
for (i = 0; i < 8; i++)
{
D[i] = g_SrcData[iaddr + i * PerFrameFFT.istride];
}

// Math
FFT_forward_8(D);
uint p = thread_id & (PerFrameFFT.istride - PerFrameFFT.pstride);
float phase = PerFrameFFT.PhaseBase * (float)p;
TWIDDLE_8(D, phase);

// Store the result
uint omod = thread_id & (PerFrameFFT.ostride - 1);
uint oaddr = ((thread_id - omod) << 3) + omod;
g_DstData[oaddr + 0 * PerFrameFFT.ostride] = D[0];
g_DstData[oaddr + 1 * PerFrameFFT.ostride] = D[4];
g_DstData[oaddr + 2 * PerFrameFFT.ostride] = D[2];
g_DstData[oaddr + 3 * PerFrameFFT.ostride] = D[6];
g_DstData[oaddr + 4 * PerFrameFFT.ostride] = D[1];
g_DstData[oaddr + 5 * PerFrameFFT.ostride] = D[5];
g_DstData[oaddr + 6 * PerFrameFFT.ostride] = D[3];
g_DstData[oaddr + 7 * PerFrameFFT.ostride] = D[7];
}

[numthreads(COHERENCY_GRANULARITY, 1, 1)]
void Radix008A_CS2(uint3 thread_id : SV_DispatchThreadID)
{
if(thread_id.x >= PerFrameFFT.ThreadCount)
return;

// Fetch 8 complex numbers
uint i;
float2 D[8];
uint iaddr = thread_id << 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 & (PerFrameFFT.ostride - 1);
uint oaddr = ((thread_id - omod) << 3) + omod;
g_DstData[oaddr + 0 * PerFrameFFT.ostride] = D[0];
g_DstData[oaddr + 1 * PerFrameFFT.ostride] = D[4];
g_DstData[oaddr + 2 * PerFrameFFT.ostride] = D[2];
g_DstData[oaddr + 3 * PerFrameFFT.ostride] = D[6];
g_DstData[oaddr + 4 * PerFrameFFT.ostride] = D[1];
g_DstData[oaddr + 5 * PerFrameFFT.ostride] = D[5];
g_DstData[oaddr + 6 * PerFrameFFT.ostride] = D[3];
g_DstData[oaddr + 7 * PerFrameFFT.ostride] = D[7];
}
87 changes: 87 additions & 0 deletions Shaders/Private/VaOcean_VS_PS.usf
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Created 2014-2016 Vladimir Alyamkin. MIT license .

#include "/Engine/Private/Common.ush"


//////////////////////////////////////////////////////////////////////////
// Vertex shaders

void QuadVS(
in float4 InPosition : ATTRIBUTE0,
in float2 InTexCoord : ATTRIBUTE1,
out float2 OutTexCoord : TEXCOORD0,
out float4 OutPosition : SV_POSITION)
{
OutPosition = InPosition;
OutTexCoord.x = 0.5f + InPosition.x * 0.5f;
OutTexCoord.y = 0.5f - InPosition.y * 0.5f;
}


//////////////////////////////////////////////////////////////////////////
// Pixel shaders

// Immutable
uint g_ActualDim;
uint g_InWidth;
uint g_OutWidth;
uint g_OutHeight;
uint g_DtxAddressOffset;
uint g_DtyAddressOffset;

// The following three should contains only real numbers. But we have only C2C FFT now.
StructuredBuffer<float2> g_InputDxyz;

// Post-FFT data wrap up: Dx, Dy, Dz -> Displacement
void UpdateDisplacementPS(float2 UV : TEXCOORD0, out float4 OutColor : SV_Target0)
{
uint index_x = (uint)(UV.x * (float)g_OutWidth);
uint index_y = (uint)(UV.y * (float)g_OutHeight);
uint addr = g_OutWidth * index_y + index_x;

// cos(pi * (m1 + m2))
int sign_correction = ((index_x + index_y) & 1) ? -1 : 1;

float dx = g_InputDxyz[addr + g_DtxAddressOffset].x * sign_correction * PerFrameDisp.ChoppyScale;
float dy = g_InputDxyz[addr + g_DtyAddressOffset].x * sign_correction * PerFrameDisp.ChoppyScale;
float dz = g_InputDxyz[addr].x * sign_correction;

OutColor = float4(dx, dy, dz, 1);
}


// Textures and sampling states
Texture2D DisplacementMap;
SamplerState DisplacementMapSampler;

// Displacement -> Normal, Folding
void GenGradientFoldingPS(float2 UV : TEXCOORD0, out float4 OutColor : SV_Target0)
{
// Sample neighbour texels
float2 one_texel = float2(1.0f / (float)g_OutWidth, 1.0f / (float)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 = DisplacementMap.Sample(DisplacementMapSampler, tc_left).xyz;
float3 displace_right = DisplacementMap.Sample(DisplacementMapSampler, tc_right).xyz;
float3 displace_back = DisplacementMap.Sample(DisplacementMapSampler, tc_back).xyz;
float3 displace_front = DisplacementMap.Sample(DisplacementMapSampler, tc_front).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) * PerFrameDisp.ChoppyScale * PerFrameDisp.GridLen;
float2 Dy = (displace_front.xy - displace_back.xy) * PerFrameDisp.ChoppyScale * PerFrameDisp.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
OutColor = float4(gradient, 0, fold);
}
23 changes: 0 additions & 23 deletions Source/VaOcean/Private/VaOcean.cpp

This file was deleted.

7 changes: 0 additions & 7 deletions Source/VaOcean/Private/VaOceanPrivate.h

This file was deleted.

15 changes: 0 additions & 15 deletions Source/VaOcean/Public/VaOcean.h

This file was deleted.

Loading