Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add settings for water parallax and caustics #243

Merged
merged 3 commits into from
Apr 4, 2024
Merged
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
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
struct PerPassWaterCaustics
{
bool EnableWaterCaustics;
float pad[3];
};

StructuredBuffer<PerPassWaterCaustics> perPassWaterCaustics : register(t71);

#if defined(WATER)

Expand Down
10 changes: 10 additions & 0 deletions features/Water Parallax/Shaders/WaterParallax/WaterParallax.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
// http://www.diva-portal.org/smash/get/diva2:831762/FULLTEXT01.pdf
// https://bartwronski.files.wordpress.com/2014/03/ac4_gdc.pdf

struct PerPassWaterParallax
{
bool EnableWaterParallax;
float pad[3];
};

StructuredBuffer<PerPassWaterParallax> perPassWaterParallax : register(t72);

float GetMipLevel(float2 coords, Texture2D<float4> tex)
{
// Compute the current gradients:
Expand Down Expand Up @@ -39,6 +47,8 @@ float GetHeight(PS_INPUT input, float2 currentOffset, float3 normalScalesRcp, fl

float2 GetParallaxOffset(PS_INPUT input, float3 normalScalesRcp)
{
if (!perPassWaterParallax[0].EnableWaterParallax)
return 0.0.xx;
float3 viewDirection = normalize(input.WPosition.xyz);
float2 parallaxOffsetTS = viewDirection.xy / -viewDirection.z;

Expand Down
3 changes: 2 additions & 1 deletion package/Shaders/Lighting.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -2023,7 +2023,8 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
# endif

# if defined(WATER_CAUSTICS)
color.xyz *= ComputeWaterCaustics(waterHeight, input.WorldPosition.xyz, worldSpaceNormal);
if (perPassWaterCaustics[0].EnableWaterCaustics)
color.xyz *= ComputeWaterCaustics(waterHeight, input.WorldPosition.xyz, worldSpaceNormal);
# endif

color.xyz = Lin2sRGB(color.xyz);
Expand Down
3 changes: 2 additions & 1 deletion package/Shaders/Water.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,8 @@ float3 GetWaterDiffuseColor(PS_INPUT input, float3 normal, float3 viewDirection,
# endif

# if defined(WATER_CAUSTICS)
refractionColor *= lerp(1.0, caustics, refractionMul);
if (perPassWaterCaustics[0].EnableWaterCaustics)
refractionColor *= lerp(1.0, caustics, refractionMul);
# endif

return lerp(refractionColor * WaterParams.w, refractionDiffuseColor, refractionMul);
Expand Down
50 changes: 48 additions & 2 deletions src/Features/WaterCaustics.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,41 @@
#include "WaterCaustics.h"

#include "Util.h"
#include <DDSTextureLoader.h>

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(
WaterCaustics::Settings,
EnableWaterCaustics)

void WaterCaustics::DrawSettings()
{
if (ImGui::TreeNodeEx("Water Caustics", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::Checkbox("Enable Water Caustics", (bool*)&settings.EnableWaterCaustics);
if (auto _tt = Util::HoverTooltipWrapper()) {
ImGui::Text(
"Enables water caustics. "
"Water caustics are the way light bends to create dancing patterns at the bottom of bodies of water.");
}

ImGui::TreePop();
}
}

void WaterCaustics::Draw(const RE::BSShader*, const uint32_t)
{
auto& context = State::GetSingleton()->context;
context->PSSetShaderResources(70, 1, &causticsView);
PerPass data{};
data.settings = settings;

D3D11_MAPPED_SUBRESOURCE mapped;
DX::ThrowIfFailed(context->Map(perPass->resource.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped));
size_t bytes = sizeof(PerPass);
memcpy_s(mapped.pData, bytes, &data, bytes);
context->Unmap(perPass->resource.get(), 0);

ID3D11ShaderResourceView* views[1]{};
views[0] = perPass->srv.get();
context->PSSetShaderResources(71, ARRAYSIZE(views), views);
}

void WaterCaustics::SetupResources()
Expand All @@ -18,19 +44,39 @@ void WaterCaustics::SetupResources()
auto& context = State::GetSingleton()->context;

DirectX::CreateDDSTextureFromFile(device, context, L"Data\\Shaders\\WaterCaustics\\watercaustics.dds", nullptr, &causticsView);
D3D11_BUFFER_DESC sbDesc{};
sbDesc.Usage = D3D11_USAGE_DYNAMIC;
sbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
sbDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
sbDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
sbDesc.StructureByteStride = sizeof(PerPass);
sbDesc.ByteWidth = sizeof(PerPass);
perPass = std::make_unique<Buffer>(sbDesc);

D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = DXGI_FORMAT_UNKNOWN;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvDesc.Buffer.FirstElement = 0;
srvDesc.Buffer.NumElements = 1;
perPass->CreateSRV(srvDesc);
}

void WaterCaustics::Load(json& o_json)
{
if (o_json[GetName()].is_object())
settings = o_json[GetName()];

Feature::Load(o_json);
}

void WaterCaustics::Save(json&)
void WaterCaustics::Save(json& o_json)
{
o_json[GetName()] = settings;
}

void WaterCaustics::RestoreDefaultSettings()
{
settings = {};
}

bool WaterCaustics::HasShaderDefine(RE::BSShader::Type)
Expand Down
14 changes: 14 additions & 0 deletions src/Features/WaterCaustics.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ struct WaterCaustics : Feature
return &singleton;
}

struct Settings
{
uint32_t EnableWaterCaustics = 1;
};

struct PerPass
{
Settings settings;
};

Settings settings;

std::unique_ptr<Buffer> perPass = nullptr;

ID3D11ShaderResourceView* causticsView;

virtual inline std::string GetName() { return "Water Caustics"; }
Expand Down
50 changes: 49 additions & 1 deletion src/Features/WaterParallax.cpp
Original file line number Diff line number Diff line change
@@ -1,28 +1,76 @@
#include "WaterParallax.h"
#include "State.h"
#include "Util.h"

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(
WaterParallax::Settings,
EnableWaterParallax)

void WaterParallax::DrawSettings()
{
if (ImGui::TreeNodeEx("Water Parallax", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::Checkbox("Enable Water Parallax", (bool*)&settings.EnableWaterParallax);
if (auto _tt = Util::HoverTooltipWrapper()) {
ImGui::Text(
"Enables water parallax. "
"Parallax adds depth to the water surface to simulate greater detail.");
}

ImGui::TreePop();
}
}

void WaterParallax::Draw(const RE::BSShader*, const uint32_t)
{
auto& context = State::GetSingleton()->context;
PerPass data{};
data.settings = settings;

D3D11_MAPPED_SUBRESOURCE mapped;
DX::ThrowIfFailed(context->Map(perPass->resource.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped));
size_t bytes = sizeof(PerPass);
memcpy_s(mapped.pData, bytes, &data, bytes);
context->Unmap(perPass->resource.get(), 0);

ID3D11ShaderResourceView* views[1]{};
views[0] = perPass->srv.get();
context->PSSetShaderResources(72, ARRAYSIZE(views), views);
}

void WaterParallax::SetupResources()
{
D3D11_BUFFER_DESC sbDesc{};
sbDesc.Usage = D3D11_USAGE_DYNAMIC;
sbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
sbDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
sbDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
sbDesc.StructureByteStride = sizeof(PerPass);
sbDesc.ByteWidth = sizeof(PerPass);
perPass = std::make_unique<Buffer>(sbDesc);

D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = DXGI_FORMAT_UNKNOWN;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvDesc.Buffer.FirstElement = 0;
srvDesc.Buffer.NumElements = 1;
perPass->CreateSRV(srvDesc);
}

void WaterParallax::Load(json& o_json)
{
if (o_json[GetName()].is_object())
settings = o_json[GetName()];
Feature::Load(o_json);
}

void WaterParallax::Save(json&)
void WaterParallax::Save(json& o_json)
{
o_json[GetName()] = settings;
}

void WaterParallax::RestoreDefaultSettings()
{
settings = {};
}

bool WaterParallax::HasShaderDefine(RE::BSShader::Type)
Expand Down
16 changes: 15 additions & 1 deletion src/Features/WaterParallax.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#pragma once

#include "Buffer.h"
#include "Feature.h"

struct WaterParallax : Feature
Expand All @@ -11,6 +11,20 @@ struct WaterParallax : Feature
return &singleton;
}

struct Settings
{
uint32_t EnableWaterParallax = 1;
};

struct PerPass
{
Settings settings;
};

Settings settings;

std::unique_ptr<Buffer> perPass = nullptr;

virtual inline std::string GetName() { return "Water Parallax"; }
virtual inline std::string GetShortName() { return "WaterParallax"; }
inline std::string_view GetShaderDefineName() override { return "WATER_PARALLAX"; }
Expand Down
Loading