Subsurface Scattering Rewrite (#198)

* draft sss-rewrite

* original shadow culling

* fix: outline postprocess incorrectly removed

* -removed shadowbias and shadowkernel from shaderentities
-removed standard denoise
-refactors
This commit is contained in:
Turánszki János
2020-12-03 00:37:22 +01:00
committed by GitHub
parent 8df696f0ee
commit 78dc045dd4
36 changed files with 232 additions and 1088 deletions
-18
View File
@@ -103,20 +103,6 @@ void LightWindow::Create(EditorComponent* editor)
fovSlider.SetTooltip("Adjust the cone aperture for spotlight.");
AddWidget(&fovSlider);
biasSlider.Create(0.0f, 0.2f, 0, 100000, "ShadowBias: ");
biasSlider.SetSize(XMFLOAT2(100, hei));
biasSlider.SetPos(XMFLOAT2(x, y += step));
biasSlider.OnSlide([&](wiEventArgs args) {
LightComponent* light = wiScene::GetScene().lights.GetComponent(entity);
if (light != nullptr)
{
light->shadowBias = args.fValue;
}
});
biasSlider.SetEnabled(false);
biasSlider.SetTooltip("Adjust the shadow bias if shadow artifacts occur.");
AddWidget(&biasSlider);
shadowCheckBox.Create("Shadow: ");
shadowCheckBox.SetSize(XMFLOAT2(hei, hei));
shadowCheckBox.SetPos(XMFLOAT2(x, y += step));
@@ -218,7 +204,6 @@ void LightWindow::Create(EditorComponent* editor)
{
light->SetType((LightComponent::LightType)args.iValue);
SetLightType(light->GetType());
biasSlider.SetValue(light->shadowBias);
}
});
typeSelectorComboBox.AddItem("Directional");
@@ -311,8 +296,6 @@ void LightWindow::SetEntity(Entity entity)
widthSlider.SetValue(light->width);
heightSlider.SetValue(light->height);
fovSlider.SetValue(light->fov);
biasSlider.SetEnabled(true);
biasSlider.SetValue(light->shadowBias);
shadowCheckBox.SetEnabled(true);
shadowCheckBox.SetCheck(light->IsCastingShadow());
haloCheckBox.SetEnabled(true);
@@ -347,7 +330,6 @@ void LightWindow::SetEntity(Entity entity)
widthSlider.SetEnabled(false);
heightSlider.SetEnabled(false);
fovSlider.SetEnabled(false);
biasSlider.SetEnabled(false);
shadowCheckBox.SetEnabled(false);
haloCheckBox.SetEnabled(false);
volumetricsCheckBox.SetEnabled(false);
-1
View File
@@ -19,7 +19,6 @@ public:
wiSlider widthSlider;
wiSlider heightSlider;
wiSlider fovSlider;
wiSlider biasSlider;
wiCheckBox shadowCheckBox;
wiCheckBox haloCheckBox;
wiCheckBox volumetricsCheckBox;
+20 -19
View File
@@ -144,23 +144,6 @@ void MaterialWindow::Create(EditorComponent* editor)
blendModeComboBox.SetTooltip("Set the blend mode of the material.");
AddWidget(&blendModeComboBox);
sssComboBox.Create("Subsurface profile: ");
sssComboBox.SetPos(XMFLOAT2(x, y += step));
sssComboBox.SetSize(XMFLOAT2(wid, hei));
sssComboBox.OnSelect([&](wiEventArgs args) {
MaterialComponent* material = wiScene::GetScene().materials.GetComponent(entity);
if (material != nullptr && args.iValue >= 0)
{
material->subsurfaceProfile = (MaterialComponent::SUBSURFACE_PROFILE)args.iValue;
}
});
sssComboBox.AddItem("Solid");
sssComboBox.AddItem("Skin");
sssComboBox.AddItem("Snow");
sssComboBox.SetEnabled(false);
sssComboBox.SetTooltip("Set the subsurface profile of the material. Needs the SSS prost process enabled.");
AddWidget(&sssComboBox);
shadingRateComboBox.Create("Shading Rate: ");
shadingRateComboBox.SetTooltip("Select shading rate for this material. \nSelecting larger shading rate will decrease rendering quality of this material, \nbut increases performance.\nDX12 only and requires Tier1 hardware support for variable shading rate");
shadingRateComboBox.SetPos(XMFLOAT2(x, y += step));
@@ -234,7 +217,7 @@ void MaterialWindow::Create(EditorComponent* editor)
AddWidget(&metalnessSlider);
alphaRefSlider.Create(0, 1, 1.0f, 1000, "AlphaRef: ");
alphaRefSlider.SetTooltip("Adjust the alpha cutoff threshold. Some performance optimizations will be disabled.");
alphaRefSlider.SetTooltip("Adjust the alpha cutoff threshold. Alpha cutout can affect performance");
alphaRefSlider.SetSize(XMFLOAT2(wid, hei));
alphaRefSlider.SetPos(XMFLOAT2(x, y += step));
alphaRefSlider.OnSlide([&](wiEventArgs args) {
@@ -288,6 +271,17 @@ void MaterialWindow::Create(EditorComponent* editor)
});
AddWidget(&displacementMappingSlider);
subsurfaceScatteringSlider.Create(0, 2, 0.0f, 1000, "Subsurface Scattering: ");
subsurfaceScatteringSlider.SetTooltip("Subsurface scattering amount. \nYou can also adjust the subsurface color by selecting it in the color picker");
subsurfaceScatteringSlider.SetSize(XMFLOAT2(wid, hei));
subsurfaceScatteringSlider.SetPos(XMFLOAT2(x, y += step));
subsurfaceScatteringSlider.OnSlide([&](wiEventArgs args) {
MaterialComponent* material = wiScene::GetScene().materials.GetComponent(entity);
if (material != nullptr)
material->SetSubsurfaceScatteringAmount(args.fValue);
});
AddWidget(&subsurfaceScatteringSlider);
texAnimFrameRateSlider.Create(0, 60, 0, 60, "Texcoord anim FPS: ");
texAnimFrameRateSlider.SetTooltip("Adjust the texture animation frame rate (frames per second). Any value above 0 will make the material dynamic.");
texAnimFrameRateSlider.SetSize(XMFLOAT2(wid, hei));
@@ -752,6 +746,7 @@ void MaterialWindow::Create(EditorComponent* editor)
colorComboBox.SetPos(XMFLOAT2(x + 150, y += step));
colorComboBox.AddItem("Base color");
colorComboBox.AddItem("Emissive color");
colorComboBox.AddItem("Subsurface color");
colorComboBox.SetTooltip("Choose the destination data of the color picker.");
AddWidget(&colorComboBox);
@@ -777,6 +772,9 @@ void MaterialWindow::Create(EditorComponent* editor)
material->SetEmissiveColor(XMFLOAT4(col.x, col.y, col.z, material->GetEmissiveStrength()));
}
break;
case 2:
material->SetSubsurfaceScatteringColor(args.color.toFloat3());
break;
}
}
});
@@ -819,6 +817,7 @@ void MaterialWindow::SetEntity(Entity entity)
emissiveSlider.SetValue(material->emissiveColor.w);
pomSlider.SetValue(material->parallaxOcclusionMapping);
displacementMappingSlider.SetValue(material->displacementMapping);
subsurfaceScatteringSlider.SetValue(material->subsurfaceScattering.w);
texAnimFrameRateSlider.SetValue(material->texAnimFrameRate);
texAnimDirectionSliderU.SetValue(material->texAnimDirection.x);
texAnimDirectionSliderV.SetValue(material->texAnimDirection.y);
@@ -826,7 +825,6 @@ void MaterialWindow::SetEntity(Entity entity)
texMulSliderY.SetValue(material->texMulAdd.y);
alphaRefSlider.SetValue(material->alphaRef);
blendModeComboBox.SetSelected((int)material->userBlendMode);
sssComboBox.SetSelected((int)material->subsurfaceProfile);
if (material->GetCustomShaderID() >= 0)
{
shaderTypeComboBox.SetSelected(MaterialComponent::SHADERTYPE_COUNT + material->GetCustomShaderID());
@@ -864,6 +862,9 @@ void MaterialWindow::SetEntity(Entity entity)
case 1:
colorPicker.SetPickColor(wiColor::fromFloat3(XMFLOAT3(material->emissiveColor.x, material->emissiveColor.y, material->emissiveColor.z)));
break;
case 2:
colorPicker.SetPickColor(wiColor::fromFloat3(XMFLOAT3(material->subsurfaceScattering.x, material->subsurfaceScattering.y, material->subsurfaceScattering.z)));
break;
}
switch (material->shaderType)
+1 -1
View File
@@ -27,6 +27,7 @@ public:
wiSlider emissiveSlider;
wiSlider pomSlider;
wiSlider displacementMappingSlider;
wiSlider subsurfaceScatteringSlider;
wiSlider texAnimFrameRateSlider;
wiSlider texAnimDirectionSliderU;
wiSlider texAnimDirectionSliderV;
@@ -35,7 +36,6 @@ public:
wiSlider alphaRefSlider;
wiComboBox shaderTypeComboBox;
wiComboBox blendModeComboBox;
wiComboBox sssComboBox;
wiComboBox shadingRateComboBox;
wiLabel texture_baseColor_Label;
+1 -22
View File
@@ -11,7 +11,7 @@ using namespace wiGraphics;
void PostprocessWindow::Create(EditorComponent* editor)
{
wiWindow::Create("PostProcess Window");
SetSize(XMFLOAT2(420, 520));
SetSize(XMFLOAT2(420, 500));
float x = 150;
float y = 10;
@@ -156,27 +156,6 @@ void PostprocessWindow::Create(EditorComponent* editor)
AddWidget(&raytracedReflectionsCheckBox);
raytracedReflectionsCheckBox.SetEnabled(wiRenderer::GetDevice()->CheckCapability(GRAPHICSDEVICE_CAPABILITY_RAYTRACING));
sssCheckBox.Create("SSS: ");
sssCheckBox.SetTooltip("Enable Subsurface Scattering. Only for PBR shaders.");
sssCheckBox.SetScriptTip("RenderPath3D::SetSSSEnabled(bool value)");
sssCheckBox.SetSize(XMFLOAT2(hei, hei));
sssCheckBox.SetPos(XMFLOAT2(x, y += step));
sssCheckBox.SetCheck(editor->renderPath->getSSSEnabled());
sssCheckBox.OnClick([=](wiEventArgs args) {
editor->renderPath->setSSSEnabled(args.bValue);
});
AddWidget(&sssCheckBox);
sssSlider.Create(0.0f, 2.0f, 1, 1000, "Amount: ");
sssSlider.SetTooltip("Set SSS amount for subsurface materials.");
sssSlider.SetSize(XMFLOAT2(100, hei));
sssSlider.SetPos(XMFLOAT2(x + 100, y));
sssSlider.SetValue((float)editor->renderPath->getSSSBlurAmount());
sssSlider.OnSlide([=](wiEventArgs args) {
editor->renderPath->setSSSBlurAmount(args.fValue);
});
AddWidget(&sssSlider);
eyeAdaptionCheckBox.Create("EyeAdaption: ");
eyeAdaptionCheckBox.SetTooltip("Enable eye adaption for the overall screen luminance");
eyeAdaptionCheckBox.SetSize(XMFLOAT2(hei, hei));
-2
View File
@@ -18,8 +18,6 @@ public:
wiSlider aoSampleCountSlider;
wiCheckBox ssrCheckBox;
wiCheckBox raytracedReflectionsCheckBox;
wiCheckBox sssCheckBox;
wiSlider sssSlider;
wiCheckBox eyeAdaptionCheckBox;
wiCheckBox motionBlurCheckBox;
wiSlider motionBlurStrengthSlider;
+2 -1
View File
@@ -1,5 +1,6 @@
This file contains changelog of wiArchive versions
54: MaterialComponent::subsurfaceScattering color instead of profile
53: Support Morph Target
52: Serialized MaterialComponent::subsurfaceProfile
51: Serialized MeshComponent::vertex_tangents
@@ -55,4 +56,4 @@ This file contains changelog of wiArchive versions
2: serialized Material property planar_reflections
1: Refactor Archive
--VERSION_BARRIER------------------
0: Created archive
0: Created archive
+19 -217
View File
@@ -27,99 +27,25 @@ void RenderPath3D::ResizeBuffers()
desc.Width = wiRenderer::GetInternalResolution().x;
desc.Height = wiRenderer::GetInternalResolution().y;
desc.SampleCount = getMSAASampleCount();
desc.Format = FORMAT_R8G8B8A8_UNORM;
device->CreateTexture(&desc, nullptr, &rtGbuffer[GBUFFER_ALBEDO_ROUGHNESS]);
device->SetName(&rtGbuffer[GBUFFER_ALBEDO_ROUGHNESS], "rtGbuffer[GBUFFER_ALBEDO_ROUGHNESS]");
desc.Format = FORMAT_R16G16B16A16_FLOAT;
device->CreateTexture(&desc, nullptr, &rtGbuffer[GBUFFER_COLOR_ROUGHNESS]);
device->SetName(&rtGbuffer[GBUFFER_COLOR_ROUGHNESS], "rtGbuffer[GBUFFER_COLOR_ROUGHNESS]");
device->CreateTexture(&desc, nullptr, &rtGbuffer[GBUFFER_NORMAL_VELOCITY]);
device->SetName(&rtGbuffer[GBUFFER_NORMAL_VELOCITY], "rtGbuffer[GBUFFER_NORMAL_VELOCITY]");
desc.Format = FORMAT_R11G11B10_FLOAT;
device->CreateTexture(&desc, nullptr, &rtGbuffer[GBUFFER_LIGHTBUFFER_DIFFUSE]);
device->SetName(&rtGbuffer[GBUFFER_LIGHTBUFFER_DIFFUSE], "rtGbuffer[GBUFFER_LIGHTBUFFER_DIFFUSE]");
device->CreateTexture(&desc, nullptr, &rtGbuffer[GBUFFER_LIGHTBUFFER_SPECULAR]);
device->SetName(&rtGbuffer[GBUFFER_LIGHTBUFFER_SPECULAR], "rtGbuffer[GBUFFER_LIGHTBUFFER_SPECULAR]");
if (getMSAASampleCount() > 1)
{
desc.SampleCount = 1;
desc.BindFlags = BIND_RENDER_TARGET | BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS;
desc.Format = FORMAT_R8G8B8A8_UNORM;
device->CreateTexture(&desc, nullptr, &rtGbuffer_resolved[GBUFFER_ALBEDO_ROUGHNESS]);
device->SetName(&rtGbuffer_resolved[GBUFFER_ALBEDO_ROUGHNESS], "rtGbuffer_resolved[GBUFFER_ALBEDO_ROUGHNESS]");
device->CreateTexture(&desc, nullptr, &rtGbuffer_resolved[GBUFFER_COLOR_ROUGHNESS]);
device->SetName(&rtGbuffer_resolved[GBUFFER_COLOR_ROUGHNESS], "rtGbuffer_resolved[GBUFFER_COLOR_ROUGHNESS]");
desc.Format = FORMAT_R16G16B16A16_FLOAT;
device->CreateTexture(&desc, nullptr, &rtGbuffer_resolved[GBUFFER_NORMAL_VELOCITY]);
device->SetName(&rtGbuffer_resolved[GBUFFER_NORMAL_VELOCITY], "rtGbuffer_resolved[GBUFFER_NORMAL_VELOCITY]");
desc.Format = FORMAT_R11G11B10_FLOAT;
device->CreateTexture(&desc, nullptr, &rtGbuffer_resolved[GBUFFER_LIGHTBUFFER_DIFFUSE]);
device->SetName(&rtGbuffer_resolved[GBUFFER_LIGHTBUFFER_DIFFUSE], "rtGbuffer_resolved[GBUFFER_LIGHTBUFFER_DIFFUSE]");
device->CreateTexture(&desc, nullptr, &rtGbuffer_resolved[GBUFFER_LIGHTBUFFER_SPECULAR]);
device->SetName(&rtGbuffer_resolved[GBUFFER_LIGHTBUFFER_SPECULAR], "rtGbuffer_resolved[GBUFFER_LIGHTBUFFER_SPECULAR]");
}
if (device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_RAYTRACING_INLINE))
{
desc.BindFlags |= BIND_UNORDERED_ACCESS;
desc.Format = FORMAT_R11G11B10_FLOAT;
desc.SampleCount = 1;
device->CreateTexture(&desc, nullptr, &rtDiffuseTemporal[0]);
device->SetName(&rtDiffuseTemporal[0], "rtDiffuseTemporal[0]");
device->CreateTexture(&desc, nullptr, &rtDiffuseTemporal[1]);
device->SetName(&rtDiffuseTemporal[1], "rtDiffuseTemporal[1]");
device->CreateTexture(&desc, nullptr, &rtSpecularTemporal[0]);
device->SetName(&rtSpecularTemporal[0], "rtSpecularTemporal[0]");
device->CreateTexture(&desc, nullptr, &rtSpecularTemporal[1]);
device->SetName(&rtSpecularTemporal[1], "rtSpecularTemporal[1]");
}
}
{
TextureDesc desc;
desc.BindFlags = BIND_RENDER_TARGET | BIND_SHADER_RESOURCE;
if (getMSAASampleCount() == 1)
{
desc.BindFlags |= BIND_UNORDERED_ACCESS;
}
desc.Format = FORMAT_R11G11B10_FLOAT;
desc.Width = wiRenderer::GetInternalResolution().x;
desc.Height = wiRenderer::GetInternalResolution().y;
desc.SampleCount = getMSAASampleCount();
device->CreateTexture(&desc, nullptr, &rtDeferred);
device->SetName(&rtDeferred, "rtDeferred");
if (getMSAASampleCount() > 1)
{
desc.SampleCount = 1;
desc.BindFlags |= BIND_UNORDERED_ACCESS;
device->CreateTexture(&desc, nullptr, &rtDeferred_resolved);
device->SetName(&rtDeferred_resolved, "rtDeferred_resolved");
}
}
{
TextureDesc desc;
desc.BindFlags = BIND_RENDER_TARGET | BIND_SHADER_RESOURCE;
desc.Format = FORMAT_R11G11B10_FLOAT;
desc.Width = wiRenderer::GetInternalResolution().x;
desc.Height = wiRenderer::GetInternalResolution().y;
desc.SampleCount = getMSAASampleCount();
device->CreateTexture(&desc, nullptr, &rtSSS[0]);
device->SetName(&rtSSS[0], "rtSSS[0]");
device->CreateTexture(&desc, nullptr, &rtSSS[1]);
device->SetName(&rtSSS[1], "rtSSS[1]");
if (getMSAASampleCount() > 1)
{
desc.SampleCount = 1;
device->CreateTexture(&desc, nullptr, &rtSSS_resolved);
device->SetName(&rtSSS_resolved, "rtSSS_resolved");
}
}
{
@@ -406,10 +332,8 @@ void RenderPath3D::ResizeBuffers()
device->CreateRenderPass(&desc, &renderpass_depthprepass);
desc.attachments.clear();
desc.attachments.push_back(RenderPassAttachment::RenderTarget(&rtGbuffer[GBUFFER_ALBEDO_ROUGHNESS], RenderPassAttachment::LOADOP_DONTCARE));
desc.attachments.push_back(RenderPassAttachment::RenderTarget(&rtGbuffer[GBUFFER_COLOR_ROUGHNESS], RenderPassAttachment::LOADOP_DONTCARE));
desc.attachments.push_back(RenderPassAttachment::RenderTarget(&rtGbuffer[GBUFFER_NORMAL_VELOCITY], RenderPassAttachment::LOADOP_CLEAR));
desc.attachments.push_back(RenderPassAttachment::RenderTarget(&rtGbuffer[GBUFFER_LIGHTBUFFER_DIFFUSE], RenderPassAttachment::LOADOP_CLEAR));
desc.attachments.push_back(RenderPassAttachment::RenderTarget(&rtGbuffer[GBUFFER_LIGHTBUFFER_SPECULAR], RenderPassAttachment::LOADOP_CLEAR));
desc.attachments.push_back(
RenderPassAttachment::DepthStencil(
&depthBuffer,
@@ -422,16 +346,14 @@ void RenderPath3D::ResizeBuffers()
);
if (getMSAASampleCount() > 1)
{
desc.attachments.push_back(RenderPassAttachment::Resolve(GetGbuffer_Read(GBUFFER_ALBEDO_ROUGHNESS)));
desc.attachments.push_back(RenderPassAttachment::Resolve(GetGbuffer_Read(GBUFFER_COLOR_ROUGHNESS)));
desc.attachments.push_back(RenderPassAttachment::Resolve(GetGbuffer_Read(GBUFFER_NORMAL_VELOCITY)));
desc.attachments.push_back(RenderPassAttachment::Resolve(GetGbuffer_Read(GBUFFER_LIGHTBUFFER_DIFFUSE)));
desc.attachments.push_back(RenderPassAttachment::Resolve(GetGbuffer_Read(GBUFFER_LIGHTBUFFER_SPECULAR)));
}
device->CreateRenderPass(&desc, &renderpass_main);
}
{
RenderPassDesc desc;
desc.attachments.push_back(RenderPassAttachment::RenderTarget(&rtDeferred, RenderPassAttachment::LOADOP_LOAD));
desc.attachments.push_back(RenderPassAttachment::RenderTarget(&rtGbuffer[GBUFFER_COLOR_ROUGHNESS], RenderPassAttachment::LOADOP_LOAD));
desc.attachments.push_back(
RenderPassAttachment::DepthStencil(
&depthBuffer,
@@ -444,62 +366,10 @@ void RenderPath3D::ResizeBuffers()
);
if (getMSAASampleCount() > 1)
{
desc.attachments.push_back(RenderPassAttachment::Resolve(GetDeferred_Read()));
desc.attachments.push_back(RenderPassAttachment::Resolve(&rtGbuffer_resolved[GBUFFER_COLOR_ROUGHNESS]));
}
device->CreateRenderPass(&desc, &renderpass_transparent);
}
{
RenderPassDesc desc;
desc.attachments.push_back(RenderPassAttachment::RenderTarget(&rtDeferred, RenderPassAttachment::LOADOP_LOAD));
desc.attachments.push_back(RenderPassAttachment::RenderTarget(&rtGbuffer[GBUFFER_NORMAL_VELOCITY], RenderPassAttachment::LOADOP_LOAD));
desc.attachments.push_back(
RenderPassAttachment::DepthStencil(
&depthBuffer,
RenderPassAttachment::LOADOP_LOAD,
RenderPassAttachment::STOREOP_STORE,
IMAGE_LAYOUT_DEPTHSTENCIL_READONLY,
IMAGE_LAYOUT_DEPTHSTENCIL_READONLY,
IMAGE_LAYOUT_DEPTHSTENCIL_READONLY
)
);
if (getMSAASampleCount() > 1)
{
desc.attachments.push_back(RenderPassAttachment::Resolve(GetDeferred_Read()));
desc.attachments.push_back(RenderPassAttachment::Resolve(GetGbuffer_Read(GBUFFER_NORMAL_VELOCITY)));
}
device->CreateRenderPass(&desc, &renderpass_deferredcomposition);
}
{
RenderPassDesc desc;
desc.attachments.push_back(RenderPassAttachment::RenderTarget(&rtGbuffer[GBUFFER_LIGHTBUFFER_DIFFUSE], RenderPassAttachment::LOADOP_LOAD));
desc.attachments.push_back(
RenderPassAttachment::DepthStencil(
&depthBuffer,
RenderPassAttachment::LOADOP_LOAD,
RenderPassAttachment::STOREOP_STORE,
IMAGE_LAYOUT_DEPTHSTENCIL_READONLY,
IMAGE_LAYOUT_DEPTHSTENCIL_READONLY,
IMAGE_LAYOUT_DEPTHSTENCIL_READONLY
)
);
if (getMSAASampleCount() > 1)
{
desc.attachments.push_back(RenderPassAttachment::Resolve(&rtGbuffer_resolved[GBUFFER_LIGHTBUFFER_DIFFUSE]));
}
device->CreateRenderPass(&desc, &renderpass_SSS[0]);
if (getMSAASampleCount() > 1)
{
desc.attachments.back() = RenderPassAttachment::Resolve(&rtSSS_resolved);
}
desc.attachments[0].texture = &rtSSS[0];
device->CreateRenderPass(&desc, &renderpass_SSS[1]);
desc.attachments[0].texture = &rtSSS[1];
device->CreateRenderPass(&desc, &renderpass_SSS[2]);
}
{
RenderPassDesc desc;
desc.attachments.push_back(
@@ -704,7 +574,6 @@ void RenderPath3D::Render() const
wiRenderer::DRAWSCENE_OCCLUSIONCULLING
;
// Main scene:
cmd = device->BeginCommandList();
wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) {
@@ -815,7 +684,10 @@ void RenderPath3D::Render() const
device->BindResource(PS, getAOEnabled() ? &rtAO : wiTextureHelper::getWhite(), TEXSLOT_RENDERPATH_AO, cmd);
device->BindResource(PS, getSSREnabled() || getRaytracedReflectionEnabled() ? &rtSSR : wiTextureHelper::getTransparent(), TEXSLOT_RENDERPATH_SSR, cmd);
wiRenderer::DrawScene(visibility_main, RENDERPASS_MAIN, cmd, drawscene_flags);
wiRenderer::DrawSky(*scene, cmd);
RenderOutline(cmd);
device->RenderPassEnd(cmd);
wiProfiler::EndRange(range); // Opaque Scene
@@ -837,10 +709,6 @@ void RenderPath3D::Render() const
);
wiRenderer::BindCommonResources(cmd);
RenderSSS(cmd);
RenderDeferredComposition(cmd);
DownsampleDepthBuffer(cmd);
RenderLightShafts(cmd);
@@ -937,73 +805,6 @@ void RenderPath3D::RenderReflections(CommandList cmd) const
wiProfiler::EndRange(range); // Reflection Rendering
}
void RenderPath3D::RenderSSS(CommandList cmd) const
{
if (getSSSEnabled() && getSSSBlurAmount() > 0)
{
wiRenderer::Postprocess_SSS(
rtLinearDepth,
GetGbuffer_Read(),
renderpass_SSS[0],
renderpass_SSS[1],
renderpass_SSS[2],
cmd,
getSSSBlurAmount()
);
}
}
void RenderPath3D::RenderDeferredComposition(CommandList cmd) const
{
GraphicsDevice* device = wiRenderer::GetDevice();
auto range = wiProfiler::BeginRangeGPU("Sky and Composition", cmd);
if (wiRenderer::GetRaytracedShadowsEnabled() && device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_RAYTRACING_INLINE))
{
int output = device->GetFrameCount() % 2;
int history = 1 - output;
wiRenderer::Postprocess_Denoise(
*GetGbuffer_Read(GBUFFER_LIGHTBUFFER_DIFFUSE),
rtDiffuseTemporal[history],
rtDiffuseTemporal[output],
*GetGbuffer_Read(GBUFFER_NORMAL_VELOCITY),
rtLinearDepth,
depthBuffer_Copy1,
cmd
);
wiRenderer::Postprocess_Denoise(
*GetGbuffer_Read(GBUFFER_LIGHTBUFFER_SPECULAR),
rtSpecularTemporal[history],
rtSpecularTemporal[output],
*GetGbuffer_Read(GBUFFER_NORMAL_VELOCITY),
rtLinearDepth,
depthBuffer_Copy1,
cmd
);
}
device->RenderPassBegin(&renderpass_deferredcomposition, cmd);
Viewport vp;
vp.Width = (float)depthBuffer.GetDesc().Width;
vp.Height = (float)depthBuffer.GetDesc().Height;
device->BindViewports(1, &vp, cmd);
wiRenderer::DeferredComposition(
GetGbuffer_Read(),
depthBuffer_Copy,
cmd
);
wiRenderer::DrawSky(wiScene::Scene(), cmd);
RenderOutline(cmd);
device->RenderPassEnd(cmd);
wiProfiler::EndRange(range);
}
void RenderPath3D::RenderLinearDepth(CommandList cmd) const
{
wiRenderer::Postprocess_Lineardepth(depthBuffer_Copy, rtLinearDepth, cmd);
@@ -1193,7 +994,8 @@ void RenderPath3D::RenderSceneMIPChain(CommandList cmd) const
fx.enableFullScreen();
fx.sampleFlag = SAMPLEMODE_CLAMP;
fx.quality = QUALITY_LINEAR;
wiImage::Draw(GetDeferred_Read(), fx, cmd);
fx.blendFlag = BLENDMODE_OPAQUE;
wiImage::Draw(GetGbuffer_Read(GBUFFER_COLOR_ROUGHNESS), fx, cmd);
device->RenderPassEnd(cmd);
@@ -1209,8 +1011,8 @@ void RenderPath3D::RenderTransparents(CommandList cmd) const
GraphicsDevice* device = wiRenderer::GetDevice();
// Water ripple rendering:
if(wiRenderer::IsWaterrippleRendering())
{
// todo: refactor water ripples and avoid clear if there is none!
device->RenderPassBegin(&renderpass_waterripples, cmd);
Viewport vp;
@@ -1307,7 +1109,7 @@ void RenderPath3D::RenderPostprocessChain(CommandList cmd) const
GraphicsDevice* device = wiRenderer::GetDevice();
const Texture* rt_first = nullptr; // not ping-ponged with read / write
const Texture* rt_read = GetDeferred_Read();
const Texture* rt_read = GetGbuffer_Read(GBUFFER_COLOR_ROUGHNESS);
const Texture* rt_write = &rtPostprocess_HDR;
// 1.) HDR post process chain
@@ -1373,7 +1175,7 @@ void RenderPath3D::RenderPostprocessChain(CommandList cmd) const
wiRenderer::Postprocess_Tonemap(
*rt_read,
getEyeAdaptionEnabled() ? *wiRenderer::ComputeLuminance(*GetDeferred_Read(), cmd) : *wiTextureHelper::getColor(wiColor::Gray()),
getEyeAdaptionEnabled() ? *wiRenderer::ComputeLuminance(*GetGbuffer_Read(GBUFFER_COLOR_ROUGHNESS), cmd) : *wiTextureHelper::getColor(wiColor::Gray()),
getMSAASampleCount() > 1 ? rtParticleDistortion_Resolved : rtParticleDistortion,
*rt_write,
cmd,
-38
View File
@@ -35,7 +35,6 @@ private:
uint32_t aoSampleCount = 16;
float aoPower = 2.0f;
float chromaticAberrationAmount = 2.0f;
float sssBlurAmount = 1.0f;
AO ao = AO_DISABLED;
bool fxaaEnabled = false;
@@ -50,7 +49,6 @@ private:
bool lightShaftsEnabled = false;
bool lensFlareEnabled = true;
bool motionBlurEnabled = false;
bool sssEnabled = true;
bool depthOfFieldEnabled = false;
bool eyeAdaptionEnabled = false;
bool sharpenFilterEnabled = false;
@@ -65,10 +63,6 @@ private:
protected:
wiGraphics::Texture rtGbuffer[GBUFFER_COUNT];
wiGraphics::Texture rtGbuffer_resolved[GBUFFER_COUNT];
wiGraphics::Texture rtDeferred;
wiGraphics::Texture rtDeferred_resolved;
wiGraphics::Texture rtSSS[2];
wiGraphics::Texture rtSSS_resolved;
wiGraphics::Texture rtReflection; // contains the scene rendered for planar reflections
wiGraphics::Texture rtSSR; // standard screen-space reflection results
wiGraphics::Texture rtSceneCopy; // contains the rendered scene that can be fed into transparent pass for distortion effect
@@ -85,8 +79,6 @@ protected:
wiGraphics::Texture rtSun_resolved; // sun render target, but the resolved version if MSAA is enabled
wiGraphics::Texture rtGUIBlurredBackground[3]; // downsampled, gaussian blurred scene for GUI
wiGraphics::Texture rtShadingRate; // UINT8 shading rate per tile
wiGraphics::Texture rtDiffuseTemporal[2]; // raytraced shadows denoise
wiGraphics::Texture rtSpecularTemporal[2]; // raytraced shadows denoise
wiGraphics::Texture rtPostprocess_HDR; // ping-pong with main scene RT in HDR post-process chain
wiGraphics::Texture rtPostprocess_LDR[2]; // ping-pong with itself in LDR post-process chain
@@ -109,8 +101,6 @@ protected:
wiGraphics::RenderPass renderpass_volumetriclight;
wiGraphics::RenderPass renderpass_particledistortion;
wiGraphics::RenderPass renderpass_waterripples;
wiGraphics::RenderPass renderpass_deferredcomposition;
wiGraphics::RenderPass renderpass_SSS[3];
const constexpr wiGraphics::Texture* GetGbuffer_Read() const
{
@@ -134,28 +124,6 @@ protected:
return &rtGbuffer[i];
}
}
const constexpr wiGraphics::Texture* GetDeferred_Read() const
{
if (getMSAASampleCount() > 1)
{
return &rtDeferred_resolved;
}
else
{
return &rtDeferred;
}
}
const constexpr wiGraphics::Texture* GetSSS_Read(int i) const
{
if (getMSAASampleCount() > 1)
{
return &rtSSS_resolved;
}
else
{
return &rtSSS[i];
}
}
// Post-processes are ping-ponged, this function helps to obtain the last postprocess render target that was written
const wiGraphics::Texture* GetLastPostprocessRT() const
@@ -173,8 +141,6 @@ protected:
virtual void RenderFrameSetUp(wiGraphics::CommandList cmd) const;
virtual void RenderReflections(wiGraphics::CommandList cmd) const;
virtual void RenderSSS(wiGraphics::CommandList cmd) const;
virtual void RenderDeferredComposition(wiGraphics::CommandList cmd) const;
virtual void RenderLinearDepth(wiGraphics::CommandList cmd) const;
virtual void RenderAO(wiGraphics::CommandList cmd) const;
virtual void RenderSSR(wiGraphics::CommandList cmd) const;
@@ -213,7 +179,6 @@ public:
constexpr uint32_t getAOSampleCount() const { return aoSampleCount; }
constexpr float getAOPower() const { return aoPower; }
constexpr float getChromaticAberrationAmount() const { return chromaticAberrationAmount; }
constexpr float getSSSBlurAmount() const { return sssBlurAmount; }
constexpr bool getAOEnabled() const { return ao != AO_DISABLED; }
constexpr AO getAO() const { return ao; }
@@ -229,7 +194,6 @@ public:
constexpr bool getLightShaftsEnabled() const { return lightShaftsEnabled; }
constexpr bool getLensFlareEnabled() const { return lensFlareEnabled; }
constexpr bool getMotionBlurEnabled() const { return motionBlurEnabled; }
constexpr bool getSSSEnabled() const { return sssEnabled; }
constexpr bool getDepthOfFieldEnabled() const { return depthOfFieldEnabled; }
constexpr bool getEyeAdaptionEnabled() const { return eyeAdaptionEnabled; }
constexpr bool getSharpenFilterEnabled() const { return sharpenFilterEnabled && getSharpenFilterAmount() > 0; }
@@ -255,7 +219,6 @@ public:
constexpr void setAOSampleCount(uint32_t value) { aoSampleCount = value; }
constexpr void setAOPower(float value) { aoPower = value; }
constexpr void setChromaticAberrationAmount(float value) { chromaticAberrationAmount = value; }
constexpr void setSSSBlurAmount(float value) { sssBlurAmount = value; }
constexpr void setAO(AO value) { ao = value; }
constexpr void setSSREnabled(bool value){ ssrEnabled = value; }
@@ -270,7 +233,6 @@ public:
constexpr void setLightShaftsEnabled(bool value){ lightShaftsEnabled = value; }
constexpr void setLensFlareEnabled(bool value){ lensFlareEnabled = value; }
constexpr void setMotionBlurEnabled(bool value){ motionBlurEnabled = value; }
constexpr void setSSSEnabled(bool value){ sssEnabled = value; }
constexpr void setDepthOfFieldEnabled(bool value){ depthOfFieldEnabled = value; }
constexpr void setEyeAdaptionEnabled(bool value) { eyeAdaptionEnabled = value; }
constexpr void setSharpenFilterEnabled(bool value) { sharpenFilterEnabled = value; }
-14
View File
@@ -35,7 +35,6 @@ Luna<RenderPath3D_BindLua>::FunctionType RenderPath3D_BindLua::methods[] = {
lunamethod(RenderPath3D_BindLua, SetLightShaftsEnabled),
lunamethod(RenderPath3D_BindLua, SetLensFlareEnabled),
lunamethod(RenderPath3D_BindLua, SetMotionBlurEnabled),
lunamethod(RenderPath3D_BindLua, SetSSSEnabled),
lunamethod(RenderPath3D_BindLua, SetDitherEnabled),
lunamethod(RenderPath3D_BindLua, SetDepthOfFieldEnabled),
lunamethod(RenderPath3D_BindLua, SetEyeAdaptionEnabled),
@@ -229,19 +228,6 @@ int RenderPath3D_BindLua::SetMotionBlurEnabled(lua_State* L)
wiLua::SError(L, "SetMotionBlurEnabled(bool value) not enough arguments!");
return 0;
}
int RenderPath3D_BindLua::SetSSSEnabled(lua_State* L)
{
if (component == nullptr)
{
wiLua::SError(L, "SetSSSEnabled(bool value) component is null!");
return 0;
}
if (wiLua::SGetArgCount(L) > 0)
((RenderPath3D*)component)->setSSSEnabled(wiLua::SGetBool(L, 1));
else
wiLua::SError(L, "SetSSSEnabled(bool value) not enough arguments!");
return 0;
}
int RenderPath3D_BindLua::SetDitherEnabled(lua_State* L)
{
if (component == nullptr)
-1
View File
@@ -36,7 +36,6 @@ public:
int SetLightShaftsEnabled(lua_State* L);
int SetLensFlareEnabled(lua_State* L);
int SetMotionBlurEnabled(lua_State* L);
int SetSSSEnabled(lua_State* L);
int SetDitherEnabled(lua_State* L);
int SetDepthOfFieldEnabled(lua_State* L);
int SetEyeAdaptionEnabled(lua_State* L);
+32 -17
View File
@@ -13,6 +13,8 @@ struct ShaderMaterial
{
float4 baseColor;
float4 emissiveColor;
float4 subsurfaceScattering;
float4 subsurfaceScattering_inv;
float4 texMulAdd;
float roughness;
@@ -23,9 +25,9 @@ struct ShaderMaterial
float normalMapStrength;
float parallaxOcclusionMapping;
float alphaTest;
float padding1;
float displacementMapping;
int padding0;
int uvset_baseColorMap;
int uvset_surfaceMap;
int uvset_normalMap;
@@ -47,21 +49,30 @@ struct ShaderMaterial
inline bool IsUsingWind() { return options & SHADERMATERIAL_OPTION_BIT_USE_WIND; }
};
// Warning: the size of this structure directly affects shader performance.
// Try to reduce it as much as possible!
// Keep it aligned to 16 bytes for best performance!
// Right now, this is 96 bytes total
struct ShaderEntity
{
float3 positionVS;
uint params;
float3 directionVS;
float range;
float3 positionWS;
float energy;
float3 directionWS;
uint color;
float4 texMulAdd;
float coneAngleCos;
float shadowKernel;
float shadowBias;
uint userdata;
uint indices;
uint userdata0;
uint userdata1;
inline uint GetType()
{
@@ -81,22 +92,22 @@ struct ShaderEntity
params |= (flags & 0xFFFF) << 16;
}
inline void SetShadowIndices(uint shadowMatrixIndex, uint shadowMapIndex)
inline void SetIndices(uint matrixIndex, uint textureIndex)
{
userdata = shadowMatrixIndex & 0xFFFF;
userdata |= (shadowMapIndex & 0xFFFF) << 16;
indices = matrixIndex & 0xFFFF;
indices |= (textureIndex & 0xFFFF) << 16;
}
inline uint GetShadowMatrixIndex()
inline uint GetMatrixIndex()
{
return userdata & 0xFFFF;
return indices & 0xFFFF;
}
inline uint GetShadowMapIndex()
inline uint GetTextureIndex()
{
return (userdata >> 16) & 0xFFFF;
return (indices >> 16) & 0xFFFF;
}
inline bool IsCastingShadow()
{
return userdata != ~0;
return indices != ~0;
}
// Load uncompressed color:
@@ -104,10 +115,10 @@ struct ShaderEntity
{
float4 fColor;
fColor.x = (float)((color >> 0) & 0x000000FF) / 255.0f;
fColor.y = (float)((color >> 8) & 0x000000FF) / 255.0f;
fColor.z = (float)((color >> 16) & 0x000000FF) / 255.0f;
fColor.w = (float)((color >> 24) & 0x000000FF) / 255.0f;
fColor.x = (float)((color >> 0) & 0xFF) / 255.0f;
fColor.y = (float)((color >> 8) & 0xFF) / 255.0f;
fColor.z = (float)((color >> 16) & 0xFF) / 255.0f;
fColor.w = (float)((color >> 24) & 0xFF) / 255.0f;
return fColor;
}
@@ -243,6 +254,10 @@ CBUFFER(FrameCB, CBSLOT_RENDERER_FRAME)
float3 g_xFrame_WorldBoundsExtents_rcp; // world enclosing AABB 1.0f / abs(max - min)
uint g_xFrame_TemporalAASampleRotation;
float g_xFrame_ShadowKernel2D;
float g_xFrame_ShadowKernelCube;
float2 g_xFrame_padding0;
};
CBUFFER(CameraCB, CBSLOT_RENDERER_CAMERA)
-41
View File
@@ -469,27 +469,6 @@
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Vertex</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Vertex</ShaderType>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)deferredPS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Pixel</ShaderType>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)denoiseCS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">5.0</ShaderModel>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Compute</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Compute</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Compute</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Compute</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Compute</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Compute</ShaderType>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)depthoffield_kickjobsCS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
@@ -795,16 +774,6 @@
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Compute</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Compute</ShaderType>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)sssPS_snow.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Pixel</ShaderType>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)volumetriclight_directionalVS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Vertex</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Vertex</ShaderType>
@@ -2567,16 +2536,6 @@
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Compute</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Compute</ShaderType>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)sssPS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Pixel</ShaderType>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)sunPS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
@@ -542,9 +542,6 @@
<FxCompile Include="$(MSBuildThisFileDirectory)oceanSurfacePS.hlsl">
<Filter>PS</Filter>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)deferredPS.hlsl">
<Filter>PS</Filter>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)volumetricLight_SpotPS.hlsl">
<Filter>PS</Filter>
</FxCompile>
@@ -566,9 +563,6 @@
<FxCompile Include="$(MSBuildThisFileDirectory)sunPS.hlsl">
<Filter>PS</Filter>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)sssPS.hlsl">
<Filter>PS</Filter>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)skyPS_dynamic.hlsl">
<Filter>PS</Filter>
</FxCompile>
@@ -887,9 +881,6 @@
<FxCompile Include="$(MSBuildThisFileDirectory)volumetriclight_spotVS.hlsl">
<Filter>VS</Filter>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)denoiseCS.hlsl">
<Filter>CS</Filter>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)objectPS_anisotropic.hlsl">
<Filter>PS</Filter>
</FxCompile>
@@ -908,9 +899,6 @@
<FxCompile Include="$(MSBuildThisFileDirectory)objectPS_transparent_unlit.hlsl">
<Filter>PS</Filter>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)sssPS_snow.hlsl">
<Filter>PS</Filter>
</FxCompile>
<FxCompile Include="$(MSBuildThisFileDirectory)hairparticle_finishUpdateCS.hlsl">
<Filter>CS</Filter>
</FxCompile>
+25 -3
View File
@@ -42,6 +42,8 @@ struct Surface
float3 T; // tangent
float3 B; // bitangent
float anisotropy; // anisotropy factor [0 -> 1]
float4 sss; // subsurface scattering color * amount
float4 sss_inv; // 1 / (1 + sss)
float alphaRoughness; // roughness remapped from perceptual to a "more linear change in roughness"
float alphaRoughnessSq; // roughness input to brdf functions
@@ -111,6 +113,8 @@ inline Surface CreateSurface(
surface.pixel = 0;
surface.screenUV = 0;
surface.anisotropy = anisotropy;
surface.sss = 0;
surface.sss_inv = 1;
surface.T = T;
surface.B = B;
@@ -124,6 +128,7 @@ struct SurfaceToLight
float3 L; // surface to light vector (normalized)
float3 H; // half-vector between view vector and light vector
float NdotL; // cos angle between normal and light direction
float3 NdotL_sss; // NdotL with subsurface parameters applied
float NdotV; // cos angle between normal and view direction
float NdotH; // cos angle between normal and half vector
float LdotH; // cos angle between light direction and half vector
@@ -143,7 +148,10 @@ inline SurfaceToLight CreateSurfaceToLight(in Surface surface, in float3 L)
surfaceToLight.L = L;
surfaceToLight.H = normalize(L + surface.V);
surfaceToLight.NdotL = saturate(dot(surfaceToLight.L, surface.N));
surfaceToLight.NdotL = dot(surfaceToLight.L, surface.N);
surfaceToLight.NdotL_sss = (surfaceToLight.NdotL + surface.sss.rgb) * surface.sss_inv.rgb;
surfaceToLight.NdotV = saturate(dot(surface.N, surface.V));
surfaceToLight.NdotH = saturate(dot(surface.N, surfaceToLight.H));
surfaceToLight.LdotH = saturate(dot(surfaceToLight.L, surfaceToLight.H));
@@ -157,10 +165,22 @@ inline SurfaceToLight CreateSurfaceToLight(in Surface surface, in float3 L)
surfaceToLight.BdotH = dot(surface.B, surfaceToLight.H);
#ifdef BRDF_CARTOON
// SSS is handled differently in cartoon shader:
// 1) The diffuse wraparound is monochrome at first to avoid banding with smoothstep()
surfaceToLight.NdotL_sss = (surfaceToLight.NdotL + surface.sss.a) * surface.sss_inv.a;
surfaceToLight.NdotL = smoothstep(0.005, 0.05, surfaceToLight.NdotL);
surfaceToLight.NdotL_sss = smoothstep(0.005, 0.05, surfaceToLight.NdotL_sss);
surfaceToLight.NdotH = smoothstep(0.98, 0.99, surfaceToLight.NdotH);
// SSS is handled differently in cartoon shader:
// 2) The diffuse wraparound is tinted after smoothstep
surfaceToLight.NdotL_sss = (surfaceToLight.NdotL_sss + surface.sss.rgb) * surface.sss_inv.rgb;
#endif // BRDF_CARTOON
surfaceToLight.NdotL = saturate(surfaceToLight.NdotL);
surfaceToLight.NdotL_sss = saturate(surfaceToLight.NdotL_sss);
return surfaceToLight;
}
@@ -256,7 +276,9 @@ float3 BRDF_GetSpecular(in Surface surface, in SurfaceToLight surfaceToLight)
}
float3 BRDF_GetDiffuse(in Surface surface, in SurfaceToLight surfaceToLight)
{
return (1.0 - surfaceToLight.F) / PI;
// Note: subsurface scattering will remove Fresnel (F), because otherwise
// there would be artifact on backside where diffuse wraps
return (1.0 - lerp(surfaceToLight.F, 0, saturate(surface.sss.a))) / PI;
}
#endif // WI_BRDF_HF
#endif // WI_BRDF_HF
-22
View File
@@ -1,22 +0,0 @@
#include "globals.hlsli"
#include "brdf.hlsli"
#include "objectHF.hlsli"
#include "ShaderInterop_Postprocess.h"
TEXTURE2D(texture_diffuse, float4, TEXSLOT_ONDEMAND0);
TEXTURE2D(texture_specular, float4, TEXSLOT_ONDEMAND1);
float4 main(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_TARGET
{
float3 albedo = texture_gbuffer0[pos.xy].rgb;
float depth = texture_depth[pos.xy];
float3 diffuse = texture_diffuse[pos.xy].rgb;
float3 specular = texture_specular[pos.xy].rgb;
float4 color = float4(albedo * diffuse + specular, 1);
const float3 P = reconstructPosition(uv, depth);
ApplyFog(distance(P, g_xCamera_CamPos), color);
return max(0, color);
}
-140
View File
@@ -1,140 +0,0 @@
#include "globals.hlsli"
#include "stochasticSSRHF.hlsli"
#include "ShaderInterop_Postprocess.h"
TEXTURE2D(resolve_current, float4, TEXSLOT_ONDEMAND0);
TEXTURE2D(resolve_history, float4, TEXSLOT_ONDEMAND1);
TEXTURE2D(texture_depth_history, float, TEXSLOT_ONDEMAND2);
RWTEXTURE2D(output, float4, 0);
static const float temporalResponseMin = 0.9;
static const float temporalResponseMax = 1.0f;
static const float temporalScale = 50.0;
static const float temporalExposure = 10.0f;
inline float Luma4(float3 color)
{
return (color.g * 2) + (color.r + color.b);
}
inline float HdrWeight4(float3 color, float exposure)
{
return rcp(Luma4(color) * exposure + 4.0f);
}
float4 clip_aabb(float3 aabb_min, float3 aabb_max, float4 p, float4 q)
{
float3 p_clip = 0.5 * (aabb_max + aabb_min);
float3 e_clip = 0.5 * (aabb_max - aabb_min) + 0.00000001f;
float4 v_clip = q - float4(p_clip, p.w);
float3 v_unit = v_clip.xyz / e_clip;
float3 a_unit = abs(v_unit);
float ma_unit = max(a_unit.x, max(a_unit.y, a_unit.z));
if (ma_unit > 1.0)
return float4(p_clip, p.w) + v_clip / ma_unit;
else
return q; // point inside aabb
}
inline void ResolverAABB(Texture2D<float4> currentColor, SamplerState currentSampler, float sharpness, float exposureScale, float AABBScale, float2 uv, float2 texelSize, inout float4 currentMin, inout float4 currentMax, inout float4 currentAverage, inout float4 currentOutput)
{
const int2 SampleOffset[9] = { int2(-1.0, -1.0), int2(0.0, -1.0), int2(1.0, -1.0), int2(-1.0, 0.0), int2(0.0, 0.0), int2(1.0, 0.0), int2(-1.0, 1.0), int2(0.0, 1.0), int2(1.0, 1.0) };
// Modulate Luma HDR
float4 sampleColors[9];
[unroll]
for (uint i = 0; i < 9; i++)
{
sampleColors[i] = currentColor.SampleLevel(currentSampler, uv + (SampleOffset[i] / texelSize), 0.0f);
}
float sampleWeights[9];
[unroll]
for (uint j = 0; j < 9; j++)
{
sampleWeights[j] = HdrWeight4(sampleColors[j].rgb, exposureScale);
}
float totalWeight = 0;
[unroll]
for (uint k = 0; k < 9; k++)
{
totalWeight += sampleWeights[k];
}
sampleColors[4] = (sampleColors[0] * sampleWeights[0] + sampleColors[1] * sampleWeights[1] + sampleColors[2] * sampleWeights[2] + sampleColors[3] * sampleWeights[3] + sampleColors[4] * sampleWeights[4] +
sampleColors[5] * sampleWeights[5] + sampleColors[6] * sampleWeights[6] + sampleColors[7] * sampleWeights[7] + sampleColors[8] * sampleWeights[8]) / totalWeight;
// Variance Clipping (AABB)
float4 m1 = 0.0;
float4 m2 = 0.0;
[unroll]
for (uint x = 0; x < 9; x++)
{
m1 += sampleColors[x];
m2 += sampleColors[x] * sampleColors[x];
}
float4 mean = m1 / 9.0;
float4 stddev = sqrt((m2 / 9.0) - sqr(mean));
currentMin = mean - AABBScale * stddev;
currentMax = mean + AABBScale * stddev;
currentOutput = sampleColors[4];
currentMin = min(currentMin, currentOutput);
currentMax = max(currentMax, currentOutput);
currentAverage = mean;
}
[numthreads(POSTPROCESS_BLOCKSIZE, POSTPROCESS_BLOCKSIZE, 1)]
void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint3 Gid : SV_GroupID, uint groupIndex : SV_GroupIndex)
{
const float2 uv = (DTid.xy + 0.5f) * xPPResolution_rcp;
float2 velocity = texture_gbuffer1.SampleLevel(sampler_linear_clamp, uv, 0).zw;
float2 prevUV = uv + velocity;
// Disocclusion fallback:
float depth_current = texture_lineardepth[DTid.xy] * g_xCamera_ZFarP;
float depth_history = getLinearDepth(texture_depth_history.SampleLevel(sampler_point_clamp, prevUV, 0));
if (length(velocity) > 0.0025 && abs(depth_current - depth_history) > 1)
{
output[DTid.xy] = resolve_current.SampleLevel(sampler_point_clamp, uv, 0);
return;
}
float4 previous = resolve_history.SampleLevel(sampler_linear_clamp, prevUV, 0);
// Luma HDR and AABB minmax
float4 current = 0;
float4 currentMin, currentMax, currentAverage;
ResolverAABB(resolve_current, sampler_linear_clamp, 0, temporalExposure, temporalScale, uv, xPPResolution, currentMin, currentMax, currentAverage, current);
previous.xyz = clip_aabb(currentMin.xyz, currentMax.xyz, clamp(currentAverage, currentMin, currentMax), previous).xyz;
previous.a = clamp(previous.a, currentMin.a, currentMax.a);
// Blend color & history
// Feedback weight from unbiased luminance difference (Timothy Lottes)
float lumFiltered = Luminance(current.rgb); // Luma4(current.rgb)
float lumHistory = Luminance(previous.rgb);
float lumDifference = abs(lumFiltered - lumHistory) / max(lumFiltered, max(lumHistory, 0.2f));
float lumWeight = sqr(1.0f - lumDifference);
float blendFinal = lerp(temporalResponseMin, temporalResponseMax, lumWeight);
// Reduce ghosting by refreshing the blend by velocity (Unreal)
float2 velocityScreen = velocity * xPPResolution;
float velocityBlend = sqrt(dot(velocityScreen, velocityScreen));
blendFinal = lerp(blendFinal, 0.2, saturate(velocityBlend / 100.0));
float4 result = lerp(current, previous, blendFinal);
output[DTid.xy] = max(0, result);
}
+5 -1
View File
@@ -30,5 +30,9 @@ GBUFFEROutputType main(VertexToPixel input)
TiledLighting(surface, lighting);
return CreateGbuffer(surface, velocity, lighting);
ApplyLighting(surface, lighting, color);
ApplyFog(dist, color);
return CreateGbuffer(color, surface, velocity, lighting);
}
+6 -2
View File
@@ -34,5 +34,9 @@ GBUFFEROutputType main(VSOut input)
TiledLighting(surface, lighting);
return CreateGbuffer(surface, velocity, lighting);
}
ApplyLighting(surface, lighting, color);
ApplyFog(dist, color);
return CreateGbuffer(color, surface, velocity, lighting);
}
+1 -1
View File
@@ -285,7 +285,7 @@ void main(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid :
// frustum AABB in world space transformed into the space of the probe/decal OBB:
AABB b = GroupAABB_WS;
AABBtransform(b, MatrixArray[entity.userdata]);
AABBtransform(b, MatrixArray[entity.GetMatrixIndex()]);
if (IntersectAABB(a, b))
{
+47 -36
View File
@@ -7,6 +7,7 @@
#ifdef BRDF_CARTOON
#define DISABLE_SOFT_SHADOWMAP
#define DISABLE_SOFT_RTSHADOW
#endif // BRDF_CARTOON
struct LightingContribution
@@ -51,7 +52,7 @@ inline LightingPart CombineLighting(in Surface surface, in Lighting lighting)
inline float3 shadowCascade(in ShaderEntity light, in float3 shadowPos, in float2 shadowUV, in uint cascade)
{
const float realDistance = shadowPos.z + light.shadowBias;
const float realDistance = shadowPos.z;
float3 shadow = 0;
#ifndef DISABLE_SOFT_SHADOWMAP
const float range = 1.5f;
@@ -61,19 +62,19 @@ inline float3 shadowCascade(in ShaderEntity light, in float3 shadowPos, in float
[loop]
for (float x = -range; x <= range; x += 1.0f)
{
shadow.x += texture_shadowarray_2d.SampleCmpLevelZero(sampler_cmp_depth, float3(shadowUV + float2(x, y) * light.shadowKernel, light.GetShadowMapIndex() + cascade), realDistance);
shadow.x += texture_shadowarray_2d.SampleCmpLevelZero(sampler_cmp_depth, float3(shadowUV + float2(x, y) * g_xFrame_ShadowKernel2D, light.GetTextureIndex() + cascade), realDistance);
shadow.y++;
}
}
shadow = shadow.x / shadow.y;
#else
shadow = texture_shadowarray_2d.SampleCmpLevelZero(sampler_cmp_depth, float3(shadowUV, light.GetShadowMapIndex() + cascade), realDistance).r;
shadow = texture_shadowarray_2d.SampleCmpLevelZero(sampler_cmp_depth, float3(shadowUV, light.GetTextureIndex() + cascade), realDistance).r;
#endif // DISABLE_SOFT_SHADOWMAP
#ifndef DISABLE_TRANSPARENT_SHADOWMAP
if (g_xFrame_Options & OPTION_BIT_TRANSPARENTSHADOWS_ENABLED)
{
shadow *= texture_shadowarray_transparent.SampleLevel(sampler_linear_clamp, float3(shadowUV, light.GetShadowMapIndex() + cascade), 0);
shadow *= texture_shadowarray_transparent.SampleLevel(sampler_linear_clamp, float3(shadowUV, light.GetTextureIndex() + cascade), 0);
}
#endif //DISABLE_TRANSPARENT_SHADOWMAP
@@ -83,7 +84,7 @@ inline float3 shadowCascade(in ShaderEntity light, in float3 shadowPos, in float
inline float shadowCube(in ShaderEntity light, float3 Lunnormalized)
{
const float remappedDistance = light.GetCubemapDepthRemapNear() + light.GetCubemapDepthRemapFar() / max(max(abs(Lunnormalized.x), abs(Lunnormalized.y)), abs(Lunnormalized.z));
return texture_shadowarray_cube.SampleCmpLevelZero(sampler_cmp_depth, float4(-Lunnormalized, light.GetShadowMapIndex()), remappedDistance + light.shadowBias).r;
return texture_shadowarray_cube.SampleCmpLevelZero(sampler_cmp_depth, float4(-Lunnormalized, light.GetTextureIndex()), remappedDistance).r;
}
inline float shadowTrace(in Surface surface, in float3 L, in float dist)
@@ -101,7 +102,7 @@ inline float shadowTrace(in Surface surface, in float3 L, in float dist)
ray.Origin = surface.P + surface.N * 0.01;
ray.Direction = L;
#ifndef BRDF_CARTOON
#ifndef DISABLE_SOFT_RTSHADOW
float seed = g_xFrame_FrameCount * 0.001f;
float2 uv = surface.screenUV;
float3 sampling_offset = float3(rand(seed, uv), rand(seed, uv), rand(seed, uv)) * 2 - 1; // todo: should be specific to light surface
@@ -127,9 +128,9 @@ inline void DirectionalLight(in ShaderEntity light, in Surface surface, inout Li
SurfaceToLight surfaceToLight = CreateSurfaceToLight(surface, L);
[branch]
if (surfaceToLight.NdotL > 0)
if (any(surfaceToLight.NdotL_sss))
{
float3 sh = surfaceToLight.NdotL.xxx;
float3 shadow = 1;
[branch]
if (light.IsCastingShadow())
@@ -137,16 +138,16 @@ inline void DirectionalLight(in ShaderEntity light, in Surface surface, inout Li
[branch]
if (g_xFrame_Options & OPTION_BIT_RAYTRACED_SHADOWS)
{
sh *= shadowTrace(surface, normalize(L), 100000);
shadow *= shadowTrace(surface, normalize(L), 100000);
}
else
{
// Loop through cascades from closest (smallest) to farest (biggest)
// Loop through cascades from closest (smallest) to furthest (biggest)
[loop]
for (uint cascade = 0; cascade < g_xFrame_ShadowCascadeCount; ++cascade)
{
// Project into shadow map space (no need to divide by .w because ortho projection!):
float3 ShPos = mul(MatrixArray[light.GetShadowMatrixIndex() + cascade], float4(surface.P, 1)).xyz;
float3 ShPos = mul(MatrixArray[light.GetMatrixIndex() + cascade], float4(surface.P, 1)).xyz;
float3 ShTex = ShPos * float3(0.5f, -0.5f, 0.5f) + 0.5f;
// Determine if pixel is inside current cascade bounds and compute shadow if it is:
@@ -163,15 +164,15 @@ inline void DirectionalLight(in ShaderEntity light, in Surface surface, inout Li
{
// Project into next shadow cascade (no need to divide by .w because ortho projection!):
cascade += 1;
ShPos = mul(MatrixArray[light.GetShadowMatrixIndex() + cascade], float4(surface.P, 1)).xyz;
ShPos = mul(MatrixArray[light.GetMatrixIndex() + cascade], float4(surface.P, 1)).xyz;
ShTex = ShPos * float3(0.5f, -0.5f, 0.5f) + 0.5f;
const float3 shadow_fallback = shadowCascade(light, ShPos, ShTex.xy, cascade);
sh *= lerp(shadow_main, shadow_fallback, cascade_fade);
shadow *= lerp(shadow_main, shadow_fallback, cascade_fade);
}
else
{
sh *= shadow_main;
shadow *= shadow_main;
}
break;
}
@@ -180,7 +181,7 @@ inline void DirectionalLight(in ShaderEntity light, in Surface surface, inout Li
}
[branch]
if (any(sh))
if (any(shadow))
{
float3 atmosphereTransmittance = 1.0;
if (g_xFrame_Options & OPTION_BIT_REALISTIC_SKY)
@@ -189,9 +190,13 @@ inline void DirectionalLight(in ShaderEntity light, in Surface surface, inout Li
atmosphereTransmittance = GetAtmosphericLightTransmittance(Atmosphere, surface.P, L, texture_transmittancelut);
}
float3 lightColor = light.GetColor().rgb * light.energy * sh * atmosphereTransmittance;
lighting.direct.diffuse += max(0.0f, lightColor * BRDF_GetDiffuse(surface, surfaceToLight));
lighting.direct.specular += max(0.0f, lightColor * BRDF_GetSpecular(surface, surfaceToLight));
float3 lightColor = light.GetColor().rgb * light.energy * atmosphereTransmittance;
lighting.direct.diffuse +=
max(0.0f, lightColor * shadow * surfaceToLight.NdotL_sss * BRDF_GetDiffuse(surface, surfaceToLight));
lighting.direct.specular +=
max(0.0f, lightColor * shadow * surfaceToLight.NdotL * BRDF_GetSpecular(surface, surfaceToLight));
}
}
}
@@ -211,9 +216,9 @@ inline void PointLight(in ShaderEntity light, in Surface surface, inout Lighting
SurfaceToLight surfaceToLight = CreateSurfaceToLight(surface, L);
[branch]
if (surfaceToLight.NdotL > 0)
if (any(surfaceToLight.NdotL_sss))
{
float sh = surfaceToLight.NdotL;
float shadow = 1;
[branch]
if (light.IsCastingShadow())
@@ -221,25 +226,28 @@ inline void PointLight(in ShaderEntity light, in Surface surface, inout Lighting
[branch]
if (g_xFrame_Options & OPTION_BIT_RAYTRACED_SHADOWS)
{
sh *= shadowTrace(surface, L, dist);
shadow *= shadowTrace(surface, L, dist);
}
else
{
sh *= shadowCube(light, Lunnormalized);
shadow *= shadowCube(light, Lunnormalized);
}
}
[branch]
if (sh > 0)
if (any(shadow))
{
float3 lightColor = light.GetColor().rgb * light.energy * sh;
float3 lightColor = light.GetColor().rgb * light.energy;
const float att = saturate(1.0 - (dist2 / range2));
const float attenuation = att * att;
lightColor *= attenuation;
lighting.direct.diffuse += max(0.0f, lightColor * BRDF_GetDiffuse(surface, surfaceToLight));
lighting.direct.specular += max(0.0f, lightColor * BRDF_GetSpecular(surface, surfaceToLight));
lighting.direct.diffuse +=
max(0.0f, lightColor * shadow * surfaceToLight.NdotL_sss * BRDF_GetDiffuse(surface, surfaceToLight));
lighting.direct.specular +=
max(0.0f, lightColor * shadow * surfaceToLight.NdotL * BRDF_GetSpecular(surface, surfaceToLight));
}
}
}
@@ -259,7 +267,7 @@ inline void SpotLight(in ShaderEntity light, in Surface surface, inout Lighting
SurfaceToLight surfaceToLight = CreateSurfaceToLight(surface, L);
[branch]
if (surfaceToLight.NdotL > 0)
if (any(surfaceToLight.NdotL_sss))
{
const float SpotFactor = dot(L, light.directionWS);
const float spotCutOff = light.coneAngleCos;
@@ -267,7 +275,7 @@ inline void SpotLight(in ShaderEntity light, in Surface surface, inout Lighting
[branch]
if (SpotFactor > spotCutOff)
{
float3 sh = surfaceToLight.NdotL.xxx;
float3 shadow = 1;
[branch]
if (light.IsCastingShadow())
@@ -275,33 +283,36 @@ inline void SpotLight(in ShaderEntity light, in Surface surface, inout Lighting
[branch]
if (g_xFrame_Options & OPTION_BIT_RAYTRACED_SHADOWS)
{
sh *= shadowTrace(surface, L, dist);
shadow *= shadowTrace(surface, L, dist);
}
else
{
float4 ShPos = mul(MatrixArray[light.GetShadowMatrixIndex() + 0], float4(surface.P, 1));
float4 ShPos = mul(MatrixArray[light.GetMatrixIndex() + 0], float4(surface.P, 1));
ShPos.xyz /= ShPos.w;
float2 ShTex = ShPos.xy * float2(0.5f, -0.5f) + float2(0.5f, 0.5f);
[branch]
if (is_saturated(ShTex))
{
sh *= shadowCascade(light, ShPos.xyz, ShTex.xy, 0);
shadow *= shadowCascade(light, ShPos.xyz, ShTex.xy, 0);
}
}
}
[branch]
if (any(sh))
if (any(shadow))
{
float3 lightColor = light.GetColor().rgb * light.energy * sh;
float3 lightColor = light.GetColor().rgb * light.energy;
const float att = saturate(1.0 - (dist2 / range2));
float attenuation = att * att;
attenuation *= saturate((1.0 - (1.0 - SpotFactor) * 1.0 / (1.0 - spotCutOff)));
lightColor *= attenuation;
lighting.direct.diffuse += max(0.0f, lightColor * BRDF_GetDiffuse(surface, surfaceToLight));
lighting.direct.specular += max(0.0f, lightColor * BRDF_GetSpecular(surface, surfaceToLight));
lighting.direct.diffuse +=
max(0.0f, lightColor * shadow * surfaceToLight.NdotL_sss * BRDF_GetDiffuse(surface, surfaceToLight));
lighting.direct.specular +=
max(0.0f, lightColor * shadow * surfaceToLight.NdotL * BRDF_GetSpecular(surface, surfaceToLight));
}
}
}
@@ -861,7 +872,7 @@ inline float4 EnvironmentReflection_Local(in Surface surface, in ShaderEntity pr
float3 R_parallaxCorrected = IntersectPositionWS - probe.positionWS;
// Sample cubemap texture:
float3 envmapColor = texture_envmaparray.SampleLevel(sampler_linear_clamp, float4(R_parallaxCorrected, probe.shadowBias), MIP).rgb; // shadowBias stores textureIndex here...
float3 envmapColor = texture_envmaparray.SampleLevel(sampler_linear_clamp, float4(R_parallaxCorrected, probe.GetTextureIndex()), MIP).rgb; // GetFlags() stores textureIndex here...
// blend out if close to any cube edge:
float edgeBlend = 1 - pow(saturate(max(abs(clipSpacePos.x), max(abs(clipSpacePos.y), abs(clipSpacePos.z)))), 8);
+19 -13
View File
@@ -89,18 +89,18 @@ struct GBUFFEROutputType
{
float4 g0 : SV_Target0; // texture_gbuffer0
float4 g1 : SV_Target1; // texture_gbuffer1
float4 diffuse : SV_Target2;
float4 specular : SV_Target3;
//float4 diffuse : SV_Target2;
//float4 specular : SV_Target3;
};
inline GBUFFEROutputType CreateGbuffer(in Surface surface, in float2 velocity, in Lighting lighting)
inline GBUFFEROutputType CreateGbuffer(in float4 color, in Surface surface, in float2 velocity, in Lighting lighting)
{
LightingPart combined_lighting = CombineLighting(surface, lighting);
//LightingPart combined_lighting = CombineLighting(surface, lighting);
GBUFFEROutputType Out;
Out.g0 = float4(surface.albedo, surface.roughness); /*FORMAT_R8G8B8A8_UNORM*/
Out.g0 = float4(color.rgb, surface.roughness); /*FORMAT_R16G16B16A16_FLOAT*/
Out.g1 = float4(encodeNormal(surface.N), velocity); /*FORMAT_R16G16B16A16_FLOAT*/
Out.diffuse = float4(combined_lighting.diffuse, 1); /*FORMAT_R11G11B10_FLOAT*/
Out.specular = float4(combined_lighting.specular, 1); /*FORMAT_R11G11B10_FLOAT*/
//Out.diffuse = float4(combined_lighting.diffuse, 1); /*FORMAT_R11G11B10_FLOAT*/
//Out.specular = float4(combined_lighting.specular, 1); /*FORMAT_R11G11B10_FLOAT*/
return Out;
}
@@ -228,7 +228,7 @@ inline void ForwardLighting(inout Surface surface, inout Lighting lighting)
{
ShaderEntity decal = EntityArray[g_xFrame_DecalArrayOffset + entity_index];
const float4x4 decalProjection = MatrixArray[decal.userdata];
const float4x4 decalProjection = MatrixArray[decal.GetMatrixIndex()];
const float3 clipSpacePos = mul(decalProjection, float4(surface.P, 1)).xyz;
const float3 uvw = clipSpacePos.xyz*float3(0.5f, -0.5f, 0.5f) + 0.5f;
[branch]
@@ -294,7 +294,7 @@ inline void ForwardLighting(inout Surface surface, inout Lighting lighting)
{
ShaderEntity probe = EntityArray[g_xFrame_EnvProbeArrayOffset + entity_index];
const float4x4 probeProjection = MatrixArray[probe.userdata];
const float4x4 probeProjection = MatrixArray[probe.GetMatrixIndex()];
const float3 clipSpacePos = mul(probeProjection, float4(surface.P, 1)).xyz;
const float3 uvw = clipSpacePos.xyz*float3(0.5f, -0.5f, 0.5f) + 0.5f;
[branch]
@@ -450,7 +450,7 @@ inline void TiledLighting(inout Surface surface, inout Lighting lighting)
{
ShaderEntity decal = EntityArray[entity_index];
const float4x4 decalProjection = MatrixArray[decal.userdata];
const float4x4 decalProjection = MatrixArray[decal.GetMatrixIndex()];
const float3 clipSpacePos = mul(decalProjection, float4(surface.P, 1)).xyz;
const float3 uvw = clipSpacePos.xyz*float3(0.5f, -0.5f, 0.5f) + 0.5f;
[branch]
@@ -529,7 +529,7 @@ inline void TiledLighting(inout Surface surface, inout Lighting lighting)
{
ShaderEntity probe = EntityArray[entity_index];
const float4x4 probeProjection = MatrixArray[probe.userdata];
const float4x4 probeProjection = MatrixArray[probe.GetMatrixIndex()];
const float3 clipSpacePos = mul(probeProjection, float4(surface.P, 1)).xyz;
const float3 uvw = clipSpacePos.xyz*float3(0.5f, -0.5f, 0.5f) + 0.5f;
[branch]
@@ -1061,10 +1061,16 @@ GBUFFEROutputType main(PIXELINPUT input)
#endif // BRDF_ANISOTROPIC
);
surface.sss = g_xMaterial.subsurfaceScattering;
surface.sss_inv = g_xMaterial.subsurfaceScattering_inv;
surface.pixel = pixel;
surface.screenUV = ScreenCoord;
Lighting lighting = CreateLighting(0, 0, GetAmbient(surface.N), 0);
float3 ambient = GetAmbient(surface.N);
ambient = lerp(ambient, ambient * surface.sss.rgb, saturate(surface.sss.a));
Lighting lighting = CreateLighting(0, 0, ambient, 0);
#ifndef SIMPLE_INPUT
@@ -1174,7 +1180,7 @@ GBUFFEROutputType main(PIXELINPUT input)
// end point:
#ifndef ALPHATESTONLY
#ifdef OUTPUT_GBUFFER
return CreateGbuffer(surface, velocity, lighting);
return CreateGbuffer(color, surface, velocity, lighting);
#else
return color;
#endif // OUTPUT_GBUFFER
+2 -2
View File
@@ -284,7 +284,7 @@ void main(PSInput input)
if (light.IsCastingShadow() >= 0)
{
const uint cascade = g_xFrame_ShadowCascadeCount - 1; // biggest cascade (coarsest resolution) will be used to voxelize
float3 ShPos = mul(MatrixArray[light.GetShadowMatrixIndex() + cascade], float4(P, 1)).xyz; // ortho matrix, no divide by .w
float3 ShPos = mul(MatrixArray[light.GetMatrixIndex() + cascade], float4(P, 1)).xyz; // ortho matrix, no divide by .w
float3 ShTex = ShPos.xyz * float3(0.5f, -0.5f, 0.5f) + 0.5f;
[branch] if ((saturate(ShTex.x) == ShTex.x) && (saturate(ShTex.y) == ShTex.y) && (saturate(ShTex.z) == ShTex.z))
@@ -361,7 +361,7 @@ void main(PSInput input)
[branch]
if (light.IsCastingShadow() >= 0)
{
float4 ShPos = mul(MatrixArray[light.GetShadowMatrixIndex() + 0], float4(P, 1));
float4 ShPos = mul(MatrixArray[light.GetMatrixIndex() + 0], float4(P, 1));
ShPos.xyz /= ShPos.w;
float2 ShTex = ShPos.xy * float2(0.5f, -0.5f) + float2(0.5f, 0.5f);
[branch]
-4
View File
@@ -140,7 +140,6 @@ set(SHADERS_CS
"volumetricCloud_finalCS.hlsl"
"shadingRateClassificationCS.hlsl"
"shadingRateClassificationCS_DEBUG.hlsl"
"denoiseCS.hlsl"
"skyAtmosphere_transmittanceLutCS.hlsl"
"skyAtmosphere_skyViewLutCS.hlsl"
"skyAtmosphere_multiScatteredLuminanceLutCS.hlsl"
@@ -161,7 +160,6 @@ set(SHADERS_PS
"imagePS.hlsl"
"emittedparticlePS_soft_lighting.hlsl"
"oceanSurfacePS.hlsl"
"deferredPS.hlsl"
"hairparticlePS.hlsl"
"impostorPS.hlsl"
"volumetricLight_SpotPS.hlsl"
@@ -171,8 +169,6 @@ set(SHADERS_PS
"vertexcolorPS.hlsl"
"upsample_bilateralPS.hlsl"
"sunPS.hlsl"
"sssPS.hlsl"
"sssPS_snow.hlsl"
"skyPS_dynamic.hlsl"
"skyPS_static.hlsl"
"shadowPS_transparent.hlsl"
-79
View File
@@ -1,79 +0,0 @@
#include "globals.hlsli"
#include "ShaderInterop_Postprocess.h"
TEXTURE2D(texture_color, float4, TEXSLOT_ONDEMAND0);
// Gaussian weights for the six samples around the current pixel:
// -3 -2 -1 +1 +2 +3
//static const float w[6] = { 0.006, 0.061, 0.242, 0.242, 0.061, 0.006 };
//static const float o[6] = { -1.0, -0.6667, -0.3333, 0.3333, 0.6667, 1.0 };
#define SSSS_N_SAMPLES 11
#ifdef SSS_PROFILE_SNOW
// snow:
static const float4 kernel[] = {
float4(0.784728, 0.669086, 0.560479, 0),
float4(5.07566e-005, 0.000184771, 0.00471691, -2),
float4(0.00084214, 0.00282018, 0.0192831, -1.28),
float4(0.00643685, 0.0130999, 0.03639, -0.72),
float4(0.0209261, 0.0358608, 0.0821904, -0.32),
float4(0.0793803, 0.113491, 0.0771802, -0.08),
float4(0.0793803, 0.113491, 0.0771802, 0.08),
float4(0.0209261, 0.0358608, 0.0821904, 0.32),
float4(0.00643685, 0.0130999, 0.03639, 0.72),
float4(0.00084214, 0.00282018, 0.0192831, 1.28),
float4(5.07565e-005, 0.000184771, 0.00471691, 2),
};
#else
// skin:
static const float4 kernel[] = {
float4(0.560479, 0.669086, 0.784728, 0),
float4(0.00471691, 0.000184771, 5.07566e-005, -2),
float4(0.0192831, 0.00282018, 0.00084214, -1.28),
float4(0.03639, 0.0130999, 0.00643685, -0.72),
float4(0.0821904, 0.0358608, 0.0209261, -0.32),
float4(0.0771802, 0.113491, 0.0793803, -0.08),
float4(0.0771802, 0.113491, 0.0793803, 0.08),
float4(0.0821904, 0.0358608, 0.0209261, 0.32),
float4(0.03639, 0.0130999, 0.00643685, 0.72),
float4(0.0192831, 0.00282018, 0.00084214, 1.28),
float4(0.00471691, 0.000184771, 5.07565e-005, 2),
};
#endif // SSS_PROFILE_SNOW
float4 main(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_TARGET
{
const float4 color_ref = texture_color[pos.xy];
const float depth_ref = texture_lineardepth[pos.xy] * g_xCamera_ZFarP;
// Accumulate center sample, multiplying it with its gaussian weight:
float4 colorBlurred = color_ref;
colorBlurred.rgb *= kernel[0].rgb;
// Calculate the step that we will use to fetch the surrounding pixels,
// where "step" is:
// step = sssStrength * gaussianWidth * pixelSize * dir
// The closer the pixel, the stronger the effect needs to be, hence
// the factor 1.0 / depthM.
float2 finalStep = color_ref.a * sss_step.xy / depth_ref;
// Accumulate the other samples:
for (int i = 1; i < SSSS_N_SAMPLES; i++)
{
// Fetch color and depth for current sample:
float2 offset = uv + kernel[i].a * finalStep;
float3 color = texture_color.SampleLevel(sampler_linear_clamp, offset, 0).rgb;
float depth = texture_lineardepth.SampleLevel(sampler_point_clamp, offset, 0) * g_xCamera_ZFarP;
// If the difference in depth is huge, we lerp color back to "colorM":
const float edge_fallback = saturate(abs(depth_ref - depth));
color = lerp(color, color_ref.rgb, edge_fallback);
// Accumulate:
colorBlurred.rgb += kernel[i].rgb * color.rgb;
}
return colorBlurred;
}
-2
View File
@@ -1,2 +0,0 @@
#define SSS_PROFILE_SNOW
#include "sssPS.hlsl"
@@ -40,7 +40,7 @@ float4 main(VertexToPixel input) : SV_TARGET
for (uint cascade = 0; cascade < g_xFrame_ShadowCascadeCount; ++cascade)
{
float3 ShPos = mul(MatrixArray[light.GetShadowMatrixIndex() + cascade], float4(P, 1)).xyz; // ortho matrix, no divide by .w
float3 ShPos = mul(MatrixArray[light.GetMatrixIndex() + cascade], float4(P, 1)).xyz; // ortho matrix, no divide by .w
float3 ShTex = ShPos.xyz * float3(0.5f, -0.5f, 0.5f) + 0.5f;
[branch]if (is_saturated(ShTex))
+1 -1
View File
@@ -47,7 +47,7 @@ float4 main(VertexToPixel input) : SV_TARGET
[branch]
if (light.IsCastingShadow())
{
float4 ShPos = mul(MatrixArray[light.GetShadowMatrixIndex() + 0], float4(P, 1));
float4 ShPos = mul(MatrixArray[light.GetMatrixIndex() + 0], float4(P, 1));
ShPos.xyz /= ShPos.w;
float2 ShTex = ShPos.xy * float2(0.5f, -0.5f) + float2(0.5f, 0.5f);
[branch]
+1 -1
View File
@@ -7,7 +7,7 @@
using namespace std;
// this should always be only INCREMENTED and only if a new serialization is implemeted somewhere!
uint64_t __archiveVersion = 53;
uint64_t __archiveVersion = 54;
// this is the version number of which below the archive is not compatible with the current version
uint64_t __archiveVersionBarrier = 22;
+1 -11
View File
@@ -12,10 +12,8 @@ enum BLENDMODE
enum GBUFFER
{
GBUFFER_ALBEDO_ROUGHNESS,
GBUFFER_COLOR_ROUGHNESS,
GBUFFER_NORMAL_VELOCITY,
GBUFFER_LIGHTBUFFER_DIFFUSE,
GBUFFER_LIGHTBUFFER_SPECULAR,
GBUFFER_COUNT
};
@@ -58,8 +56,6 @@ enum STENCILREF
STENCILREF_EMPTY = 0,
STENCILREF_DEFAULT = 1,
STENCILREF_CUSTOMSHADER = 2,
STENCILREF_SKIN = 3,
STENCILREF_SNOW = 4,
STENCILREF_LAST = 15
};
@@ -208,9 +204,6 @@ enum SHADERTYPE
PSTYPE_RENDERLIGHTMAP,
PSTYPE_RAYTRACE_DEBUGBVH,
PSTYPE_DOWNSAMPLEDEPTHBUFFER,
PSTYPE_DEFERREDCOMPOSITION,
PSTYPE_POSTPROCESS_SSS_SKIN,
PSTYPE_POSTPROCESS_SSS_SNOW,
PSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL,
PSTYPE_POSTPROCESS_OUTLINE,
PSTYPE_LENSFLARE,
@@ -351,7 +344,6 @@ enum SHADERTYPE
CSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL_UNORM4,
CSTYPE_POSTPROCESS_DOWNSAMPLE4X,
CSTYPE_POSTPROCESS_NORMALSFROMDEPTH,
CSTYPE_POSTPROCESS_DENOISE,
@@ -405,8 +397,6 @@ enum DSSTYPES
DSSTYPE_ENVMAP,
DSSTYPE_CAPTUREIMPOSTOR,
DSSTYPE_WRITEONLY,
DSSTYPE_DEFERREDCOMPOSITION,
DSSTYPE_SSS,
DSSTYPE_COUNT
};
// blend states
+14 -310
View File
@@ -1056,9 +1056,6 @@ void LoadShaders()
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, shaders[PSTYPE_RENDERLIGHTMAP], "renderlightmapPS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, shaders[PSTYPE_RAYTRACE_DEBUGBVH], "raytrace_debugbvhPS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, shaders[PSTYPE_DOWNSAMPLEDEPTHBUFFER], "downsampleDepthBuffer4xPS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, shaders[PSTYPE_DEFERREDCOMPOSITION], "deferredPS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, shaders[PSTYPE_POSTPROCESS_SSS_SKIN], "sssPS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, shaders[PSTYPE_POSTPROCESS_SSS_SNOW], "sssPS_snow.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, shaders[PSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL], "upsample_bilateralPS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, shaders[PSTYPE_POSTPROCESS_OUTLINE], "outlinePS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(PS, shaders[PSTYPE_LENSFLARE], "lensFlarePS.cso"); });
@@ -1182,7 +1179,6 @@ void LoadShaders()
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, shaders[CSTYPE_POSTPROCESS_UPSAMPLE_BILATERAL_UNORM4], "upsample_bilateral_unorm4CS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, shaders[CSTYPE_POSTPROCESS_DOWNSAMPLE4X], "downsample4xCS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, shaders[CSTYPE_POSTPROCESS_NORMALSFROMDEPTH], "normalsfromdepthCS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(CS, shaders[CSTYPE_POSTPROCESS_DENOISE], "denoiseCS.cso"); });
wiJobSystem::Execute(ctx, [](wiJobArgs args) { LoadShader(HS, shaders[HSTYPE_OBJECT], "objectHS.cso"); });
@@ -1585,36 +1581,6 @@ void LoadShaders()
device->CreatePipelineState(&desc, &PSO_downsampledepthbuffer);
});
wiJobSystem::Execute(ctx, [](wiJobArgs args) {
PipelineStateDesc desc;
desc.vs = &shaders[VSTYPE_SCREEN];
desc.ps = &shaders[PSTYPE_DEFERREDCOMPOSITION];
desc.rs = &rasterizers[RSTYPE_DOUBLESIDED];
desc.bs = &blendStates[BSTYPE_OPAQUE];
desc.dss = &depthStencils[DSSTYPE_DEFERREDCOMPOSITION];
device->CreatePipelineState(&desc, &PSO_deferredcomposition);
});
wiJobSystem::Execute(ctx, [](wiJobArgs args) {
PipelineStateDesc desc;
desc.vs = &shaders[VSTYPE_SCREEN];
desc.ps = &shaders[PSTYPE_POSTPROCESS_SSS_SKIN];
desc.rs = &rasterizers[RSTYPE_DOUBLESIDED];
desc.bs = &blendStates[BSTYPE_OPAQUE];
desc.dss = &depthStencils[DSSTYPE_SSS];
device->CreatePipelineState(&desc, &PSO_sss_skin);
});
wiJobSystem::Execute(ctx, [](wiJobArgs args) {
PipelineStateDesc desc;
desc.vs = &shaders[VSTYPE_SCREEN];
desc.ps = &shaders[PSTYPE_POSTPROCESS_SSS_SNOW];
desc.rs = &rasterizers[RSTYPE_DOUBLESIDED];
desc.bs = &blendStates[BSTYPE_OPAQUE];
desc.dss = &depthStencils[DSSTYPE_SSS];
device->CreatePipelineState(&desc, &PSO_sss_snow);
});
wiJobSystem::Execute(ctx, [](wiJobArgs args) {
PipelineStateDesc desc;
desc.vs = &shaders[VSTYPE_SCREEN];
@@ -2016,25 +1982,15 @@ void SetUpStates()
rs.FillMode = FILL_SOLID;
rs.CullMode = CULL_BACK;
rs.FrontCounterClockwise = true;
rs.DepthBias = 0;
rs.DepthBias = -2;
rs.DepthBiasClamp = 0;
rs.SlopeScaledDepthBias = -2.0f;
rs.SlopeScaledDepthBias = -4.0f;
rs.DepthClipEnable = true;
rs.MultisampleEnable = false;
rs.AntialiasedLineEnable = false;
rs.ConservativeRasterizationEnable = false;
device->CreateRasterizerState(&rs, &rasterizers[RSTYPE_SHADOW]);
rs.FillMode = FILL_SOLID;
rs.CullMode = CULL_NONE;
rs.FrontCounterClockwise = true;
rs.DepthBias = 0;
rs.DepthBiasClamp = 0;
rs.SlopeScaledDepthBias = -2.0f;
rs.DepthClipEnable = true;
rs.MultisampleEnable = false;
rs.AntialiasedLineEnable = false;
rs.ConservativeRasterizationEnable = false;
device->CreateRasterizerState(&rs, &rasterizers[RSTYPE_SHADOW_DOUBLESIDED]);
rs.FillMode = FILL_WIREFRAME;
@@ -2159,55 +2115,6 @@ void SetUpStates()
dsd.StencilEnable = false;
device->CreateDepthStencilState(&dsd, &depthStencils[DSSTYPE_CAPTUREIMPOSTOR]);
dsd.DepthEnable = true;
dsd.DepthWriteMask = DEPTH_WRITE_MASK_ZERO;
dsd.DepthFunc = COMPARISON_LESS;
dsd.StencilEnable = false;
dsd.StencilReadMask = 0;
dsd.StencilWriteMask = 0;
dsd.FrontFace.StencilFunc = COMPARISON_GREATER_EQUAL;
dsd.FrontFace.StencilPassOp = STENCIL_OP_KEEP;
dsd.FrontFace.StencilFailOp = STENCIL_OP_KEEP;
dsd.FrontFace.StencilDepthFailOp = STENCIL_OP_KEEP;
dsd.BackFace.StencilFunc = COMPARISON_GREATER_EQUAL;
dsd.BackFace.StencilPassOp = STENCIL_OP_KEEP;
dsd.BackFace.StencilFailOp = STENCIL_OP_KEEP;
dsd.BackFace.StencilDepthFailOp = STENCIL_OP_KEEP;
//device->CreateDepthStencilState(&dsd, &depthStencils[DSSTYPE_DEFERREDLIGHT]);
dsd.DepthEnable = true;
dsd.DepthWriteMask = DEPTH_WRITE_MASK_ZERO;
dsd.DepthFunc = COMPARISON_LESS;
dsd.StencilEnable = false;
dsd.StencilReadMask = 0;
dsd.StencilWriteMask = 0;
dsd.FrontFace.StencilFunc = COMPARISON_LESS_EQUAL;
dsd.FrontFace.StencilPassOp = STENCIL_OP_KEEP;
dsd.FrontFace.StencilFailOp = STENCIL_OP_KEEP;
dsd.FrontFace.StencilDepthFailOp = STENCIL_OP_KEEP;
dsd.BackFace.StencilFunc = COMPARISON_LESS_EQUAL;
dsd.BackFace.StencilPassOp = STENCIL_OP_KEEP;
dsd.BackFace.StencilFailOp = STENCIL_OP_KEEP;
dsd.BackFace.StencilDepthFailOp = STENCIL_OP_KEEP;
device->CreateDepthStencilState(&dsd, &depthStencils[DSSTYPE_DEFERREDCOMPOSITION]);
dsd.DepthWriteMask = DEPTH_WRITE_MASK_ZERO;
dsd.DepthEnable = false;
dsd.StencilEnable = true;
dsd.DepthFunc = COMPARISON_GREATER;
dsd.StencilReadMask = STENCILREF_MASK_ENGINE;
dsd.StencilWriteMask = 0x00;
dsd.FrontFace.StencilFunc = COMPARISON_EQUAL;
dsd.FrontFace.StencilPassOp = STENCIL_OP_KEEP;
dsd.FrontFace.StencilFailOp = STENCIL_OP_KEEP;
dsd.FrontFace.StencilDepthFailOp = STENCIL_OP_KEEP;
dsd.BackFace.StencilFunc = COMPARISON_EQUAL;
dsd.BackFace.StencilPassOp = STENCIL_OP_KEEP;
dsd.BackFace.StencilFailOp = STENCIL_OP_KEEP;
dsd.BackFace.StencilDepthFailOp = STENCIL_OP_KEEP;
device->CreateDepthStencilState(&dsd, &depthStencils[DSSTYPE_SSS]);
dsd.DepthEnable = true;
dsd.StencilEnable = false;
@@ -3803,7 +3710,7 @@ void UpdateRenderData(const Visibility& vis, CommandList cmd)
entityArray[entityCounter].color = wiMath::CompressColor(XMFLOAT4(decal.color.x, decal.color.y, decal.color.z, decal.GetOpacity()));
entityArray[entityCounter].energy = decal.emissive;
entityArray[entityCounter].userdata = matrixCounter;
entityArray[entityCounter].SetIndices(matrixCounter, 0);
matrixArray[matrixCounter] = XMMatrixInverse(nullptr, XMLoadFloat4x4(&decal.world));
matrixCounter++;
@@ -3839,9 +3746,8 @@ void UpdateRenderData(const Visibility& vis, CommandList cmd)
entityArray[entityCounter].positionWS = probe.position;
XMStoreFloat3(&entityArray[entityCounter].positionVS, XMVector3TransformCoord(XMLoadFloat3(&probe.position), viewMatrix));
entityArray[entityCounter].range = probe.range;
entityArray[entityCounter].shadowBias = (float)probe.textureIndex;
entityArray[entityCounter].userdata = matrixCounter;
entityArray[entityCounter].SetIndices(matrixCounter, (uint32_t)probe.textureIndex);
matrixArray[matrixCounter] = XMLoadFloat4x4(&probe.inverseMatrix);
matrixCounter++;
@@ -3868,13 +3774,12 @@ void UpdateRenderData(const Visibility& vis, CommandList cmd)
entityArray[entityCounter].range = light.GetRange();
entityArray[entityCounter].color = wiMath::CompressColor(light.color);
entityArray[entityCounter].energy = light.energy;
entityArray[entityCounter].shadowBias = light.shadowBias;
entityArray[entityCounter].userdata = ~0;
entityArray[entityCounter].indices = ~0;
const bool shadow = light.IsCastingShadow() && light.shadowMap_index >= 0;
if (shadow)
{
entityArray[entityCounter].SetShadowIndices(matrixCounter, (uint)light.shadowMap_index);
entityArray[entityCounter].SetIndices(matrixCounter, (uint)light.shadowMap_index);
}
switch (light.GetType())
@@ -3882,7 +3787,6 @@ void UpdateRenderData(const Visibility& vis, CommandList cmd)
case LightComponent::DIRECTIONAL:
{
entityArray[entityCounter].directionWS = light.direction;
entityArray[entityCounter].shadowKernel = 1.0f / SHADOWRES_2D;
if (shadow)
{
@@ -3899,7 +3803,6 @@ void UpdateRenderData(const Visibility& vis, CommandList cmd)
entityArray[entityCounter].coneAngleCos = cosf(light.fov * 0.5f);
entityArray[entityCounter].directionWS = light.direction;
XMStoreFloat3(&entityArray[entityCounter].directionVS, XMVector3TransformNormal(XMLoadFloat3(&entityArray[entityCounter].directionWS), viewMatrix));
entityArray[entityCounter].shadowKernel = 1.0f / SHADOWRES_2D;
if (shadow)
{
@@ -3909,11 +3812,6 @@ void UpdateRenderData(const Visibility& vis, CommandList cmd)
}
}
break;
case LightComponent::POINT:
{
entityArray[entityCounter].shadowKernel = 1.0f / SHADOWRES_CUBE;
}
break;
case LightComponent::SPHERE:
case LightComponent::DISC:
case LightComponent::RECTANGLE:
@@ -8574,6 +8472,8 @@ void UpdateFrameCB(const Scene& scene, CommandList cmd)
}
cb.g_xFrame_TemporalAASampleRotation = (x & 0x000000FF) | ((y & 0x000000FF) << 8);
}
cb.g_xFrame_ShadowKernel2D = 1.0f / SHADOWRES_2D;
cb.g_xFrame_ShadowKernelCube = 1.0f / SHADOWRES_CUBE;
cb.g_xFrame_WorldBoundsMin = scene.bounds.getMin();
cb.g_xFrame_WorldBoundsMax = scene.bounds.getMax();
@@ -8805,26 +8705,6 @@ void ComputeShadingRateClassification(
device->EventEnd(cmd);
}
void DeferredComposition(
const Texture gbuffer[GBUFFER_COUNT],
const Texture& depth,
CommandList cmd
)
{
device->EventBegin("DeferredComposition", cmd);
device->BindPipelineState(&PSO_deferredcomposition, cmd);
device->BindResource(PS, &gbuffer[GBUFFER_ALBEDO_ROUGHNESS], TEXSLOT_GBUFFER0, cmd);
device->BindResource(PS, &gbuffer[GBUFFER_LIGHTBUFFER_DIFFUSE], TEXSLOT_ONDEMAND0, cmd);
device->BindResource(PS, &gbuffer[GBUFFER_LIGHTBUFFER_SPECULAR], TEXSLOT_ONDEMAND1, cmd);
device->BindResource(PS, &depth, TEXSLOT_DEPTH, cmd);
device->Draw(3, 0, cmd);
device->EventEnd(cmd);
}
void Postprocess_Blur_Gaussian(
const Texture& input,
const Texture& temp,
@@ -10147,7 +10027,7 @@ void Postprocess_RTReflection(
device->WriteDescriptor(&descriptorTable, 0, 0, &temp);
device->WriteDescriptor(&descriptorTable, 1, 0, &scene.TLAS);
device->WriteDescriptor(&descriptorTable, 2, 0, &depthbuffer);
device->WriteDescriptor(&descriptorTable, 3, 0, &gbuffer[GBUFFER_ALBEDO_ROUGHNESS]);
device->WriteDescriptor(&descriptorTable, 3, 0, &gbuffer[GBUFFER_COLOR_ROUGHNESS]);
device->WriteDescriptor(&descriptorTable, 4, 0, &gbuffer[GBUFFER_NORMAL_VELOCITY]);
device->WriteDescriptor(&descriptorTable, 5, 0, &textures[TEXTYPE_CUBEARRAY_ENVMAPARRAY]);
device->WriteDescriptor(&descriptorTable, 6, 0, &shadowMapArray_2D);
@@ -10341,7 +10221,7 @@ void Postprocess_SSR(
device->BindResource(CS, &depthbuffer, TEXSLOT_DEPTH, cmd);
device->BindResource(CS, &lineardepth, TEXSLOT_LINEARDEPTH, cmd);
device->BindResource(CS, &gbuffer[GBUFFER_ALBEDO_ROUGHNESS], TEXSLOT_GBUFFER0, cmd);
device->BindResource(CS, &gbuffer[GBUFFER_COLOR_ROUGHNESS], TEXSLOT_GBUFFER0, cmd);
device->BindResource(CS, &gbuffer[GBUFFER_NORMAL_VELOCITY], TEXSLOT_GBUFFER1, cmd);
device->BindResource(CS, &input, TEXSLOT_ONDEMAND0, cmd);
@@ -10472,112 +10352,6 @@ void Postprocess_SSR(
wiProfiler::EndRange(range);
device->EventEnd(cmd);
}
void Postprocess_SSS(
const Texture& lineardepth,
const Texture gbuffer[GBUFFER_COUNT],
const RenderPass& input_output_lightbuffer_diffuse,
const RenderPass& input_output_temp1,
const RenderPass& input_output_temp2,
CommandList cmd,
float amount
)
{
device->EventBegin("Postprocess_SSS", cmd);
auto range = wiProfiler::BeginRangeGPU("SSS", cmd);
device->BindResource(PS, &lineardepth, TEXSLOT_LINEARDEPTH, cmd);
for (uint32_t stencilref = STENCILREF_SKIN; stencilref <= STENCILREF_SNOW; ++stencilref)
{
device->BindStencilRef(stencilref, cmd);
switch (stencilref)
{
case STENCILREF_SKIN:
device->BindPipelineState(&PSO_sss_skin, cmd);
break;
case STENCILREF_SNOW:
device->BindPipelineState(&PSO_sss_snow, cmd);
break;
default:
assert(0);
break;
}
const RenderPass* rt_read = &input_output_lightbuffer_diffuse;
const RenderPass* rt_write = &input_output_temp1;
static int sssPassCount = 6;
for (int i = 0; i < sssPassCount; ++i)
{
device->UnbindResources(TEXSLOT_ONDEMAND0, 1, cmd);
if (i == sssPassCount - 1)
{
// last pass will write into light buffer, but still use the previous ping-pong result:
rt_write = &input_output_lightbuffer_diffuse;
}
const TextureDesc& desc = rt_write->GetDesc().attachments[0].texture->GetDesc();
device->RenderPassBegin(rt_write, cmd);
Viewport vp;
vp.Width = (float)desc.Width;
vp.Height = (float)desc.Height;
device->BindViewports(1, &vp, cmd);
PostProcessCB cb;
cb.xPPResolution.x = desc.Width;
cb.xPPResolution.y = desc.Height;
cb.xPPResolution_rcp.x = 1.0f / cb.xPPResolution.x;
cb.xPPResolution_rcp.y = 1.0f / cb.xPPResolution.y;
const float blur_strength = 400.0f * amount;
if (i % 2 == 0)
{
cb.sss_step.x = blur_strength * cb.xPPResolution_rcp.x;
cb.sss_step.y = 0;
}
else
{
cb.sss_step.x = 0;
cb.sss_step.y = blur_strength * cb.xPPResolution_rcp.y;
}
device->UpdateBuffer(&constantBuffers[CBTYPE_POSTPROCESS], &cb, cmd);
device->BindConstantBuffer(PS, &constantBuffers[CBTYPE_POSTPROCESS], CB_GETBINDSLOT(PostProcessCB), cmd);
if (rt_read->GetDesc().attachments.size() > 2)
{
// resolved input!
device->BindResource(PS, rt_read->GetDesc().attachments[2].texture, TEXSLOT_ONDEMAND0, cmd);
}
else
{
device->BindResource(PS, rt_read->GetDesc().attachments[0].texture, TEXSLOT_ONDEMAND0, cmd);
}
device->Draw(3, 0, cmd);
device->RenderPassEnd(cmd);
if (i == 0)
{
// first pass was reading from lightbuffer, so correct here for next pass ping-pong:
rt_read = &input_output_temp1;
rt_write = &input_output_temp2;
}
else
{
// ping-pong between temp render targets:
std::swap(rt_read, rt_write);
}
}
}
wiProfiler::EndRange(range);
device->EventEnd(cmd);
}
void Postprocess_LightShafts(
const Texture& input,
const Texture& output,
@@ -12156,80 +11930,6 @@ void Postprocess_NormalsFromDepth(
device->UnbindUAVs(0, arraysize(uavs), cmd);
device->EventEnd(cmd);
}
void Postprocess_Denoise(
const Texture& input_output_current,
const Texture& temporal_history,
const Texture& temporal_current,
const Texture& velocity,
const Texture& lineardepth,
const Texture& depth_history,
CommandList cmd
)
{
device->EventBegin("Postprocess_Denoise", cmd);
device->BindComputeShader(&shaders[CSTYPE_POSTPROCESS_DENOISE], cmd);
const TextureDesc& desc = input_output_current.GetDesc();
PostProcessCB cb;
cb.xPPResolution.x = desc.Width;
cb.xPPResolution.y = desc.Height;
cb.xPPResolution_rcp.x = 1.0f / cb.xPPResolution.x;
cb.xPPResolution_rcp.y = 1.0f / cb.xPPResolution.y;
device->UpdateBuffer(&constantBuffers[CBTYPE_POSTPROCESS], &cb, cmd);
device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_POSTPROCESS], CB_GETBINDSLOT(PostProcessCB), cmd);
device->BindResource(CS, &velocity, TEXSLOT_GBUFFER1, cmd);
{
device->BindResource(CS, &input_output_current, TEXSLOT_ONDEMAND0, cmd);
device->BindResource(CS, &temporal_history, TEXSLOT_ONDEMAND1, cmd);
device->BindResource(CS, &depth_history, TEXSLOT_ONDEMAND2, cmd);
device->BindResource(CS, &lineardepth, TEXSLOT_LINEARDEPTH, cmd);
const GPUResource* uavs[] = {
&temporal_current,
};
device->BindUAVs(CS, uavs, 0, arraysize(uavs), cmd);
device->Dispatch(
(desc.Width + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
(desc.Height + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
1,
cmd
);
GPUBarrier barriers[] = {
GPUBarrier::Memory(),
};
device->Barrier(barriers, arraysize(barriers), cmd);
device->UnbindUAVs(0, arraysize(uavs), cmd);
}
{
device->BindResource(CS, &temporal_current, TEXSLOT_ONDEMAND0, cmd);
device->BindResource(CS, &temporal_history, TEXSLOT_ONDEMAND1, cmd);
const GPUResource* uavs[] = {
&input_output_current,
};
device->BindUAVs(CS, uavs, 0, arraysize(uavs), cmd);
device->Dispatch(
(desc.Width + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
(desc.Height + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
1,
cmd
);
GPUBarrier barriers[] = {
GPUBarrier::Memory(),
};
device->Barrier(barriers, arraysize(barriers), cmd);
device->UnbindUAVs(0, arraysize(uavs), cmd);
}
device->EventEnd(cmd);
}
RAY GetPickRay(long cursorX, long cursorY, const CameraComponent& camera)
@@ -12422,5 +12122,9 @@ bool GetTessellationEnabled()
{
return tessellationEnabled;
}
bool IsWaterrippleRendering()
{
return !waterRipples.empty();
}
}
+1 -24
View File
@@ -228,12 +228,6 @@ namespace wiRenderer
wiGraphics::CommandList cmd
);
void DeferredComposition(
const wiGraphics::Texture gbuffer[GBUFFER_COUNT],
const wiGraphics::Texture& depth,
wiGraphics::CommandList cmd
);
void Postprocess_Blur_Gaussian(
const wiGraphics::Texture& input,
const wiGraphics::Texture& temp,
@@ -304,15 +298,6 @@ namespace wiRenderer
const wiGraphics::Texture& output,
wiGraphics::CommandList cmd
);
void Postprocess_SSS(
const wiGraphics::Texture& lineardepth,
const wiGraphics::Texture gbuffer[GBUFFER_COUNT],
const wiGraphics::RenderPass& input_output_lightbuffer_diffuse,
const wiGraphics::RenderPass& input_output_temp1,
const wiGraphics::RenderPass& input_output_temp2,
wiGraphics::CommandList cmd,
float amount = 1.0f
);
void Postprocess_LightShafts(
const wiGraphics::Texture& input,
const wiGraphics::Texture& output,
@@ -419,15 +404,6 @@ namespace wiRenderer
const wiGraphics::Texture& output,
wiGraphics::CommandList cmd
);
void Postprocess_Denoise(
const wiGraphics::Texture& input_output_current,
const wiGraphics::Texture& temporal_history,
const wiGraphics::Texture& temporal_current,
const wiGraphics::Texture& velocity,
const wiGraphics::Texture& lineardepth,
const wiGraphics::Texture& depth_history,
wiGraphics::CommandList cmd
);
// Build the scene BVH on GPU that can be used by ray traced rendering
void BuildSceneBVH(const wiScene::Scene& scene, wiGraphics::CommandList cmd);
@@ -589,6 +565,7 @@ namespace wiRenderer
bool GetRaytracedShadowsEnabled();
void SetTessellationEnabled(bool value);
bool GetTessellationEnabled();
bool IsWaterrippleRendering();
const wiGraphics::Texture* GetGlobalLightmap();
+8 -9
View File
@@ -284,6 +284,14 @@ namespace wiScene
dest->normalMapStrength = (normalMap == nullptr ? 0 : normalMapStrength);
dest->parallaxOcclusionMapping = parallaxOcclusionMapping;
dest->displacementMapping = displacementMapping;
dest->subsurfaceScattering = subsurfaceScattering;
dest->subsurfaceScattering.x *= dest->subsurfaceScattering.w;
dest->subsurfaceScattering.y *= dest->subsurfaceScattering.w;
dest->subsurfaceScattering.z *= dest->subsurfaceScattering.w;
dest->subsurfaceScattering_inv.x = 1.0f / (1 + dest->subsurfaceScattering.x);
dest->subsurfaceScattering_inv.y = 1.0f / (1 + dest->subsurfaceScattering.y);
dest->subsurfaceScattering_inv.z = 1.0f / (1 + dest->subsurfaceScattering.z);
dest->subsurfaceScattering_inv.w = 1.0f / (1 + dest->subsurfaceScattering.w);
dest->uvset_baseColorMap = baseColorMap == nullptr ? -1 : (int)uvset_baseColorMap;
dest->uvset_surfaceMap = surfaceMap == nullptr ? -1 : (int)uvset_surfaceMap;
dest->uvset_normalMap = normalMap == nullptr ? -1 : (int)uvset_normalMap;
@@ -2505,15 +2513,6 @@ namespace wiScene
material.engineStencilRef = STENCILREF_CUSTOMSHADER;
}
if (material.subsurfaceProfile == MaterialComponent::SUBSURFACE_SKIN)
{
material.engineStencilRef = STENCILREF_SKIN;
}
else if (material.subsurfaceProfile == MaterialComponent::SUBSURFACE_SNOW)
{
material.engineStencilRef = STENCILREF_SNOW;
}
if (material.IsDirty())
{
material.SetDirty(false);
+13 -11
View File
@@ -141,19 +141,13 @@ namespace wiScene
SHADERTYPE_COUNT
} shaderType = SHADERTYPE_PBR;
enum SUBSURFACE_PROFILE
{
SUBSURFACE_SOLID,
SUBSURFACE_SKIN,
SUBSURFACE_SNOW,
} subsurfaceProfile = SUBSURFACE_SOLID;
STENCILREF engineStencilRef = STENCILREF_DEFAULT;
uint8_t userStencilRef = 0;
BLENDMODE userBlendMode = BLENDMODE_OPAQUE;
XMFLOAT4 baseColor = XMFLOAT4(1, 1, 1, 1);
XMFLOAT4 emissiveColor = XMFLOAT4(1, 1, 1, 0);
XMFLOAT4 subsurfaceScattering = XMFLOAT4(1, 1, 1, 0);
XMFLOAT4 texMulAdd = XMFLOAT4(1, 1, 0, 0);
float roughness = 0.2f;
float reflectance = 0.02f;
@@ -243,6 +237,14 @@ namespace wiScene
inline void SetNormalMapStrength(float value) { SetDirty(); normalMapStrength = value; }
inline void SetParallaxOcclusionMapping(float value) { SetDirty(); parallaxOcclusionMapping = value; }
inline void SetDisplacementMapping(float value) { SetDirty(); displacementMapping = value; }
inline void SetSubsurfaceScatteringColor(XMFLOAT3 value)
{
SetDirty();
subsurfaceScattering.x = value.x;
subsurfaceScattering.y = value.y;
subsurfaceScattering.z = value.z;
}
inline void SetSubsurfaceScatteringAmount(float value) { SetDirty(); subsurfaceScattering.w = value; }
inline void SetOpacity(float value) { SetDirty(); baseColor.w = value; }
inline void SetAlphaRef(float value) { SetDirty(); alphaRef = value; }
inline void SetUseVertexColors(bool value) { SetDirty(); if (value) { _flags |= USE_VERTEXCOLORS; } else { _flags &= ~USE_VERTEXCOLORS; } }
@@ -775,10 +777,10 @@ namespace wiScene
float energy = 1.0f;
float range_local = 10.0f;
float fov = XM_PIDIV4;
float shadowBias = 0.0001f;
float radius = 1.0f; // area light
float width = 1.0f; // area light
float height = 1.0f; // area light
float shadowBias = 0.0001f; // deprecated!
float radius = 1.0f; // area light only
float width = 1.0f; // area light only
float height = 1.0f; // area light only
std::vector<std::string> lensFlareNames;
+11 -10
View File
@@ -104,12 +104,7 @@ namespace wiScene
archive >> refractionIndex;
if (archive.GetVersion() < 52)
{
float subsurfaceScattering;
archive >> subsurfaceScattering;
if (subsurfaceScattering > 0)
{
subsurfaceProfile = SUBSURFACE_SKIN;
}
archive >> subsurfaceScattering.w;
}
archive >> normalMapStrength;
archive >> parallaxOcclusionMapping;
@@ -168,9 +163,15 @@ namespace wiScene
}
}
if (archive.GetVersion() >= 52)
if (archive.GetVersion() >= 52 && archive.GetVersion() < 54)
{
archive >> (uint32_t&)subsurfaceProfile;
uint32_t subsurfaceProfile;
archive >> subsurfaceProfile;
}
if (archive.GetVersion() >= 54)
{
archive >> subsurfaceScattering;
}
wiJobSystem::Execute(seri.ctx, [&](wiJobArgs args) {
@@ -278,9 +279,9 @@ namespace wiScene
archive << customShaderID;
}
if (archive.GetVersion() >= 52)
if (archive.GetVersion() >= 54)
{
archive << (uint32_t&)subsurfaceProfile;
archive << subsurfaceScattering;
}
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates, breaking API changes
const int minor = 50;
// minor bug fixes, alterations, refactors, updates
const int revision = 7;
const int revision = 8;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);