Skip to content

Commit

Permalink
refactor: rename Water Lighting
Browse files Browse the repository at this point in the history
  • Loading branch information
doodlum committed Nov 29, 2024
1 parent a8051ee commit 7ef4ddd
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 9 deletions.
2 changes: 2 additions & 0 deletions features/WaterEffects/Shaders/Features/WaterEffects.ini
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 features/WaterEffects/Shaders/WaterEffects/WaterCaustics.hlsli
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 features/WaterEffects/Shaders/WaterEffects/WaterParallax.hlsli
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.
14 changes: 11 additions & 3 deletions package/Shaders/Lighting.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -928,16 +928,16 @@ float GetSnowParameterY(float texProjTmp, float alpha)
# undef LIGHT_LIMIT_FIX
# undef WETNESS_EFFECTS
# undef DYNAMIC_CUBEMAPS
# undef WATER_LIGHTING
# undef WATER_EFFECTS
# endif

# if defined(WORLD_MAP)
# undef CLOUD_SHADOWS
# undef SKYLIGHTING
# endif

# if defined(WATER_LIGHTING)
# include "WaterLighting/WaterCaustics.hlsli"
# if defined(WATER_EFFECTS)
# include "WaterEffects/WaterCaustics.hlsli"
# endif

# if defined(EYE)
Expand Down Expand Up @@ -1853,6 +1853,14 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace

float3 dirLightColor = DirLightColor.xyz;
float3 dirLightColorMultiplier = 1;
<<<<<<< Updated upstream
=======

# if defined(WATER_EFFECTS)
dirLightColorMultiplier *= WaterEffects::ComputeCaustics(waterData, input.WorldPosition.xyz, worldSpaceNormal);
# endif

>>>>>>> Stashed changes
float selfShadowFactor = 1.0f;

float3 normalizedDirLightDirectionWS = DirLightDirection;
Expand Down
8 changes: 4 additions & 4 deletions package/Shaders/Water.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -433,12 +433,12 @@ float3 GetFlowmapNormal(PS_INPUT input, float2 uvShift, float multiplier, float
# endif

# if (defined(FLOWMAP) && !defined(BLEND_NORMALS)) || defined(LOD)
# undef WATER_LIGHTING
# undef WATER_EFFECTS
# endif

# if defined(WATER_LIGHTING) && !defined(VC)
# if defined(WATER_EFFECTS) && !defined(VC)
# define WATER_PARALLAX
# include "WaterLighting/WaterParallax.hlsli"
# include "WaterEffects/WaterParallax.hlsli"
# endif

# if defined(DYNAMIC_CUBEMAPS)
Expand All @@ -450,7 +450,7 @@ float3 GetWaterNormal(PS_INPUT input, float distanceFactor, float normalsDepthFa
float3 normalScalesRcp = rcp(input.NormalsScale.xyz);

# if defined(WATER_PARALLAX)
float2 parallaxOffset = WaterLighting::GetParallaxOffset(input, normalScalesRcp);
float2 parallaxOffset = WaterEffects::GetParallaxOffset(input, normalScalesRcp);
# endif

# if defined(FLOWMAP)
Expand Down
4 changes: 2 additions & 2 deletions src/Feature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include "Features/TerrainBlending.h"
#include "Features/TerrainShadows.h"
#include "Features/VolumetricLighting.h"
#include "Features/WaterLighting.h"
#include "Features/WaterEffects.h"
#include "Features/WetnessEffects.h"

#include "State.h"
Expand Down Expand Up @@ -127,7 +127,7 @@ const std::vector<Feature*>& Feature::GetFeatureList()
LightLimitFix::GetSingleton(),
DynamicCubemaps::GetSingleton(),
CloudShadows::GetSingleton(),
WaterLighting::GetSingleton(),
WaterEffects::GetSingleton(),
SubsurfaceScattering::GetSingleton(),
TerrainShadows::GetSingleton(),
ScreenSpaceGI::GetSingleton(),
Expand Down
26 changes: 26 additions & 0 deletions src/Features/WaterEffects.cpp
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;
}
29 changes: 29 additions & 0 deletions src/Features/WaterEffects.h
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; };
};

0 comments on commit 7ef4ddd

Please sign in to comment.