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:
@@ -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);
|
||||
|
||||
@@ -19,7 +19,6 @@ public:
|
||||
wiSlider widthSlider;
|
||||
wiSlider heightSlider;
|
||||
wiSlider fovSlider;
|
||||
wiSlider biasSlider;
|
||||
wiCheckBox shadowCheckBox;
|
||||
wiCheckBox haloCheckBox;
|
||||
wiCheckBox volumetricsCheckBox;
|
||||
|
||||
+20
-19
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -18,8 +18,6 @@ public:
|
||||
wiSlider aoSampleCountSlider;
|
||||
wiCheckBox ssrCheckBox;
|
||||
wiCheckBox raytracedReflectionsCheckBox;
|
||||
wiCheckBox sssCheckBox;
|
||||
wiSlider sssSlider;
|
||||
wiCheckBox eyeAdaptionCheckBox;
|
||||
wiCheckBox motionBlurCheckBox;
|
||||
wiSlider motionBlurStrengthSlider;
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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))
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user