-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
215 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[Info] | ||
Version = 1-0-0 |
49 changes: 49 additions & 0 deletions
49
features/WaterEffects/Shaders/WaterEffects/WaterCaustics.hlsli
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
Texture2D<float4> WaterCaustics : register(t70); | ||
|
||
namespace WaterEffects | ||
{ | ||
float2 PanCausticsUV(float2 uv, float speed, float tiling) | ||
{ | ||
return frac((float2(1, 0) * Timer * speed) + (uv * tiling)); | ||
} | ||
|
||
float3 SampleCaustics(float2 uv) | ||
{ | ||
return WaterCaustics.Sample(SampColorSampler, uv).r; | ||
} | ||
|
||
float3 ComputeCaustics(float4 waterData, float3 worldPosition, uint eyeIndex) | ||
{ | ||
float causticsDistToWater = waterData.w - worldPosition.z; | ||
float shoreFactorCaustics = saturate(causticsDistToWater / 64.0); | ||
|
||
if (shoreFactorCaustics > 0.0) { | ||
float causticsFade = 1.0 - saturate(causticsDistToWater / 1024.0); | ||
causticsFade *= causticsFade; | ||
|
||
float2 causticsUV = (worldPosition.xy + CameraPosAdjust[eyeIndex].xy) * 0.005; | ||
|
||
float2 causticsUV1 = PanCausticsUV(causticsUV, 0.5 * 0.2, 1.0); | ||
float2 causticsUV2 = PanCausticsUV(causticsUV, 1.0 * 0.2, -0.5); | ||
|
||
float3 causticsHigh = 1.0; | ||
|
||
if (causticsFade > 0.0) | ||
causticsHigh = min(SampleCaustics(causticsUV1), SampleCaustics(causticsUV2)) * 4.0; | ||
|
||
causticsUV *= 0.5; | ||
|
||
causticsUV1 = PanCausticsUV(causticsUV, 0.5 * 0.1, 1.0); | ||
causticsUV2 = PanCausticsUV(causticsUV, 1.0 * 0.1, -0.5); | ||
|
||
float3 causticsLow = 1.0; | ||
|
||
if (causticsFade < 1.0) | ||
causticsLow = min(SampleCaustics(causticsUV1), SampleCaustics(causticsUV2)) * 4.0; | ||
|
||
return lerp(causticsLow, causticsHigh, causticsFade); | ||
} | ||
|
||
return 1.0; | ||
} | ||
} |
92 changes: 92 additions & 0 deletions
92
features/WaterEffects/Shaders/WaterEffects/WaterParallax.hlsli
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
namespace WaterEffects | ||
{ | ||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
// PARALLAX | ||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
||
// https://github.com/tgjones/slimshader-cpp/blob/master/src/Shaders/Sdk/Direct3D11/DetailTessellation11/POM.hlsl | ||
// https://github.com/alandtse/SSEShaderTools/blob/main/shaders_vr/ParallaxEffect.h | ||
|
||
// https://github.com/marselas/Zombie-Direct3D-Samples/blob/5f53dc2d6f7deb32eb2e5e438d6b6644430fe9ee/Direct3D/ParallaxOcclusionMapping/ParallaxOcclusionMapping.fx | ||
// http://www.diva-portal.org/smash/get/diva2:831762/FULLTEXT01.pdf | ||
// https://bartwronski.files.wordpress.com/2014/03/ac4_gdc.pdf | ||
|
||
float GetMipLevel(float2 coords, Texture2D<float4> tex) | ||
{ | ||
// Compute the current gradients: | ||
float2 textureDims; | ||
tex.GetDimensions(textureDims.x, textureDims.y); | ||
|
||
#if defined(VR) | ||
textureDims /= 16.0; | ||
#else | ||
textureDims /= 8.0; | ||
#endif | ||
|
||
float2 texCoordsPerSize = coords * textureDims; | ||
|
||
float2 dxSize = ddx(texCoordsPerSize); | ||
float2 dySize = ddy(texCoordsPerSize); | ||
|
||
// Find min of change in u and v across quad: compute du and dv magnitude across quad | ||
float2 dTexCoords = dxSize * dxSize + dySize * dySize; | ||
|
||
// Standard mipmapping uses max here | ||
float minTexCoordDelta = max(dTexCoords.x, dTexCoords.y); | ||
|
||
// Compute the current mip level (* 0.5 is effectively computing a square root before ) | ||
float mipLevel = max(0.5 * log2(minTexCoordDelta), 0); | ||
|
||
return mipLevel; | ||
} | ||
|
||
float GetHeight(PS_INPUT input, float2 currentOffset, float3 normalScalesRcp, float3 mipLevels) | ||
{ | ||
float3 heights; | ||
heights.x = Normals01Tex.SampleLevel(Normals01Sampler, input.TexCoord1.xy + currentOffset * normalScalesRcp.x, mipLevels.x).w; | ||
heights.y = Normals02Tex.SampleLevel(Normals02Sampler, input.TexCoord1.zw + currentOffset * normalScalesRcp.y, mipLevels.y).w; | ||
heights.z = Normals03Tex.SampleLevel(Normals03Sampler, input.TexCoord2.xy + currentOffset * normalScalesRcp.z, mipLevels.z).w; | ||
return 1.0 - length(heights); | ||
} | ||
|
||
float2 GetParallaxOffset(PS_INPUT input, float3 normalScalesRcp) | ||
{ | ||
float3 viewDirection = normalize(input.WPosition.xyz); | ||
float2 parallaxOffsetTS = viewDirection.xy / -viewDirection.z; | ||
|
||
// Parallax scale is also multiplied by normalScalesRcp | ||
parallaxOffsetTS *= 20.0; | ||
|
||
float3 mipLevels; | ||
mipLevels.x = GetMipLevel(input.TexCoord1.xy, Normals01Tex); | ||
mipLevels.y = GetMipLevel(input.TexCoord1.zw, Normals02Tex); | ||
mipLevels.z = GetMipLevel(input.TexCoord2.xy, Normals03Tex); | ||
|
||
#if defined(VR) | ||
mipLevels = mipLevels + 4; | ||
#else | ||
mipLevels = mipLevels + 3; | ||
#endif | ||
|
||
float stepSize = rcp(16); | ||
float currBound = 0.0; | ||
float currHeight = 1.0; | ||
float prevHeight = 1.0; | ||
|
||
[loop] while (currHeight > currBound) | ||
{ | ||
prevHeight = currHeight; | ||
currBound += stepSize; | ||
currHeight = GetHeight(input, currBound * parallaxOffsetTS.xy, normalScalesRcp, mipLevels); | ||
} | ||
|
||
float prevBound = currBound - stepSize; | ||
|
||
float delta2 = prevBound - prevHeight; | ||
float delta1 = currBound - currHeight; | ||
float denominator = delta2 - delta1; | ||
float parallaxAmount = (currBound * delta2 - prevBound * delta1) / denominator; | ||
|
||
return parallaxOffsetTS.xy * parallaxAmount; | ||
} | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#include "WaterEffects.h" | ||
|
||
#include "State.h" | ||
#include "Util.h" | ||
|
||
#include <DDSTextureLoader.h> | ||
|
||
void WaterEffects::SetupResources() | ||
{ | ||
auto& device = State::GetSingleton()->device; | ||
auto& context = State::GetSingleton()->context; | ||
|
||
DirectX::CreateDDSTextureFromFile(device, context, L"Data\\Shaders\\WaterEffects\\watercaustics.dds", nullptr, causticsView.put()); | ||
} | ||
|
||
void WaterEffects::Prepass() | ||
{ | ||
auto& context = State::GetSingleton()->context; | ||
auto srv = causticsView.get(); | ||
context->PSSetShaderResources(70, 1, &srv); | ||
} | ||
|
||
bool WaterEffects::HasShaderDefine(RE::BSShader::Type) | ||
{ | ||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#pragma once | ||
|
||
#include <winrt/base.h> | ||
|
||
#include "Feature.h" | ||
|
||
struct WaterEffects : Feature | ||
{ | ||
public: | ||
static WaterEffects* GetSingleton() | ||
{ | ||
static WaterEffects singleton; | ||
return &singleton; | ||
} | ||
|
||
winrt::com_ptr<ID3D11ShaderResourceView> causticsView; | ||
|
||
virtual inline std::string GetName() override { return "Water Effects"; } | ||
virtual inline std::string GetShortName() override { return "WaterEffects"; } | ||
virtual inline std::string_view GetShaderDefineName() override { return "WATER_EFFECTS"; } | ||
|
||
bool HasShaderDefine(RE::BSShader::Type shaderType) override; | ||
|
||
virtual void SetupResources() override; | ||
|
||
virtual void Prepass() override; | ||
|
||
virtual bool SupportsVR() override { return true; }; | ||
}; |