added raytraced reflections

This commit is contained in:
Turanszki Janos
2020-09-21 22:01:07 +02:00
parent f7cacec78d
commit b7bc35bbda
24 changed files with 644 additions and 22 deletions
@@ -640,6 +640,7 @@ It inherits functions from RenderPath2D, so it can render a 2D overlay.
- AO_MSAO : int -- enable multi scale screen space ambient occlusion (use in SetAO() function)
- SetHBAOEnabled(bool value)
- SetSSREnabled(bool value)
- SetRaytracedReflectionsEnabled(bool value)
- SetShadowsEnabled(bool value)
- SetReflectionsEnabled(bool value)
- SetFXAAEnabled(bool value)
+11
View File
@@ -141,6 +141,17 @@ PostprocessWindow::PostprocessWindow(EditorComponent* editor) : GUI(&editor->Get
});
ppWindow->AddWidget(ssrCheckBox);
ssrCheckBox = new wiCheckBox("Ray Traced Reflections: ");
ssrCheckBox->SetTooltip("Enable Ray Traced Reflections. Only if GPU supports raytracing.");
ssrCheckBox->SetScriptTip("RenderPath3D::SetRaytracedReflectionsEnabled(bool value)");
ssrCheckBox->SetPos(XMFLOAT2(x + 200, y));
ssrCheckBox->SetCheck(editor->renderPath->getRaytracedReflectionEnabled());
ssrCheckBox->OnClick([=](wiEventArgs args) {
editor->renderPath->setRaytracedReflectionsEnabled(args.bValue);
});
ppWindow->AddWidget(ssrCheckBox);
ssrCheckBox->SetEnabled(wiRenderer::GetDevice()->CheckCapability(GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_RAYTRACING));
sssCheckBox = new wiCheckBox("SSS: ");
sssCheckBox->SetTooltip("Enable Subsurface Scattering. (Deferred only for now)");
sssCheckBox->SetScriptTip("RenderPath3D::SetSSSEnabled(bool value)");
+1
View File
@@ -28,6 +28,7 @@ public:
wiSlider* aoRangeSlider;
wiSlider* aoSampleCountSlider;
wiCheckBox* ssrCheckBox;
wiCheckBox* raytracedReflectionsCheckBox;
wiCheckBox* sssCheckBox;
wiCheckBox* eyeAdaptionCheckBox;
wiCheckBox* motionBlurCheckBox;
+6 -2
View File
@@ -436,7 +436,7 @@ void RenderPath3D::RenderFrameSetUp(CommandList cmd) const
device->BindResource(CS, &depthBuffer_Copy, TEXSLOT_DEPTH, cmd);
wiRenderer::UpdateRenderData(cmd);
if (getAO() == AO_RTAO || wiRenderer::GetRaytracedShadowsEnabled())
if (getAO() == AO_RTAO || wiRenderer::GetRaytracedShadowsEnabled() || getRaytracedReflectionEnabled())
{
wiRenderer::UpdateRaytracingAccelerationStructures(cmd);
}
@@ -556,7 +556,11 @@ void RenderPath3D::RenderAO(CommandList cmd) const
}
void RenderPath3D::RenderSSR(const Texture& gbuffer1, const Texture& gbuffer2, CommandList cmd) const
{
if (getSSREnabled())
if (getRaytracedReflectionEnabled())
{
wiRenderer::Postprocess_RTReflection(depthBuffer_Copy, gbuffer1, gbuffer2, rtSSR, cmd);
}
else if (getSSREnabled())
{
wiRenderer::Postprocess_SSR(rtSceneCopy, depthBuffer_Copy, rtLinearDepth, gbuffer1, gbuffer2, rtSSR, cmd);
}
+3
View File
@@ -38,6 +38,7 @@ private:
AO ao = AO_DISABLED;
bool fxaaEnabled = false;
bool ssrEnabled = false;
bool raytracedReflectionsEnabled = false;
bool reflectionsEnabled = true;
bool shadowsEnabled = true;
bool bloomEnabled = true;
@@ -145,6 +146,7 @@ public:
constexpr bool getAOEnabled() const { return ao != AO_DISABLED; }
constexpr AO getAO() const { return ao; }
constexpr bool getSSREnabled() const { return ssrEnabled; }
constexpr bool getRaytracedReflectionEnabled() const { return raytracedReflectionsEnabled; }
constexpr bool getShadowsEnabled() const { return shadowsEnabled; }
constexpr bool getReflectionsEnabled() const { return reflectionsEnabled; }
constexpr bool getFXAAEnabled() const { return fxaaEnabled; }
@@ -184,6 +186,7 @@ public:
constexpr void setAO(AO value) { ao = value; }
constexpr void setSSREnabled(bool value){ ssrEnabled = value; }
constexpr void setRaytracedReflectionsEnabled(bool value){ raytracedReflectionsEnabled = value; }
constexpr void setShadowsEnabled(bool value){ shadowsEnabled = value; }
constexpr void setReflectionsEnabled(bool value){ reflectionsEnabled = value; }
constexpr void setFXAAEnabled(bool value){ fxaaEnabled = value; }
+14
View File
@@ -24,6 +24,7 @@ Luna<RenderPath3D_BindLua>::FunctionType RenderPath3D_BindLua::methods[] = {
lunamethod(RenderPath3D_BindLua, SetAO),
lunamethod(RenderPath3D_BindLua, SetSSREnabled),
lunamethod(RenderPath3D_BindLua, SetRaytracedReflectionsEnabled),
lunamethod(RenderPath3D_BindLua, SetShadowsEnabled),
lunamethod(RenderPath3D_BindLua, SetReflectionsEnabled),
lunamethod(RenderPath3D_BindLua, SetFXAAEnabled),
@@ -83,6 +84,19 @@ int RenderPath3D_BindLua::SetSSREnabled(lua_State* L)
wiLua::SError(L, "SetSSREnabled(bool value) not enough arguments!");
return 0;
}
int RenderPath3D_BindLua::SetRaytracedReflectionsEnabled(lua_State* L)
{
if (component == nullptr)
{
wiLua::SError(L, "SetRaytracedReflectionsEnabled(bool value) component is null!");
return 0;
}
if (wiLua::SGetArgCount(L) > 0)
((RenderPath3D*)component)->setRaytracedReflectionsEnabled(wiLua::SGetBool(L, 1));
else
wiLua::SError(L, "SetRaytracedReflectionsEnabled(bool value) not enough arguments!");
return 0;
}
int RenderPath3D_BindLua::SetShadowsEnabled(lua_State* L)
{
if (component == nullptr)
+1
View File
@@ -20,6 +20,7 @@ public:
int SetAO(lua_State* L);
int SetSSREnabled(lua_State* L);
int SetRaytracedReflectionsEnabled(lua_State* L);
int SetShadowsEnabled(lua_State* L);
int SetReflectionsEnabled(lua_State* L);
int SetFXAAEnabled(lua_State* L);
@@ -23,6 +23,7 @@ Luna<RenderPath3D_Deferred_BindLua>::FunctionType RenderPath3D_Deferred_BindLua:
lunamethod(RenderPath3D_BindLua, SetAO),
lunamethod(RenderPath3D_BindLua, SetSSREnabled),
lunamethod(RenderPath3D_BindLua, SetRaytracedReflectionsEnabled),
lunamethod(RenderPath3D_BindLua, SetShadowsEnabled),
lunamethod(RenderPath3D_BindLua, SetReflectionsEnabled),
lunamethod(RenderPath3D_BindLua, SetFXAAEnabled),
@@ -23,6 +23,7 @@ Luna<RenderPath3D_Forward_BindLua>::FunctionType RenderPath3D_Forward_BindLua::m
lunamethod(RenderPath3D_BindLua, SetAO),
lunamethod(RenderPath3D_BindLua, SetSSREnabled),
lunamethod(RenderPath3D_BindLua, SetRaytracedReflectionsEnabled),
lunamethod(RenderPath3D_BindLua, SetShadowsEnabled),
lunamethod(RenderPath3D_BindLua, SetReflectionsEnabled),
lunamethod(RenderPath3D_BindLua, SetFXAAEnabled),
@@ -23,6 +23,7 @@ Luna<RenderPath3D_TiledDeferred_BindLua>::FunctionType RenderPath3D_TiledDeferre
lunamethod(RenderPath3D_BindLua, SetAO),
lunamethod(RenderPath3D_BindLua, SetSSREnabled),
lunamethod(RenderPath3D_BindLua, SetRaytracedReflectionsEnabled),
lunamethod(RenderPath3D_BindLua, SetShadowsEnabled),
lunamethod(RenderPath3D_BindLua, SetReflectionsEnabled),
lunamethod(RenderPath3D_BindLua, SetFXAAEnabled),
@@ -23,6 +23,7 @@ Luna<RenderPath3D_TiledForward_BindLua>::FunctionType RenderPath3D_TiledForward_
lunamethod(RenderPath3D_BindLua, SetAO),
lunamethod(RenderPath3D_BindLua, SetSSREnabled),
lunamethod(RenderPath3D_BindLua, SetRaytracedReflectionsEnabled),
lunamethod(RenderPath3D_BindLua, SetShadowsEnabled),
lunamethod(RenderPath3D_BindLua, SetReflectionsEnabled),
lunamethod(RenderPath3D_BindLua, SetFXAAEnabled),
+3
View File
@@ -29,6 +29,9 @@ CBUFFER(PostProcessCB, CBSLOT_RENDERER_POSTPROCESS)
#define rtao_power ssao_power
#define rtao_seed xPPParams0.w
#define rtreflection_range ssao_range
#define rtreflection_seed xPPParams0.w
static const uint POSTPROCESS_HBAO_THREADCOUNT = 320;
#define hbao_direction xPPParams0.xy
#define hbao_power xPPParams0.z
+5
View File
@@ -627,6 +627,11 @@
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Compute</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Compute</ShaderType>
</FxCompile>
<None Include="$(MSBuildThisFileDirectory)rtreflectionLIB.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0</ShaderModel>
<FileType>Document</FileType>
</None>
<None Include="$(MSBuildThisFileDirectory)emittedparticleMS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0</ShaderModel>
@@ -126,6 +126,9 @@
<None Include="$(MSBuildThisFileDirectory)emittedparticleMS.hlsl">
<Filter>MS</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)rtreflectionLIB.hlsl">
<Filter>LIB</Filter>
</None>
</ItemGroup>
<ItemGroup>
<FxCompile Include="$(MSBuildThisFileDirectory)hairparticle_simulateCS.hlsl">
+1 -1
View File
@@ -93,7 +93,7 @@ inline float shadowTrace(float3 P, float3 N, float3 L, float dist)
{
#ifdef RAYTRACING_INLINE
RayQuery<
RAY_FLAG_CULL_NON_OPAQUE |
RAY_FLAG_FORCE_OPAQUE |
RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES |
RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH
> q;
+25 -15
View File
@@ -4,13 +4,11 @@
RWTEXTURE2D(output, unorm float, 0);
#ifdef RAYTRACING_GEOMETRYINDEX
ConstantBuffer<ShaderMaterial> subsets_material[MAX_DESCRIPTOR_INDEXING] : register(b0, space1);
Texture2D<float4> subsets_texture_baseColor[MAX_DESCRIPTOR_INDEXING] : register(t0, space1);
Buffer<uint> subsets_indexBuffer[MAX_DESCRIPTOR_INDEXING] : register(t100000, space1);
Buffer<float2> subsets_vertexBuffer_UV0[MAX_DESCRIPTOR_INDEXING] : register(t300000, space1);
Buffer<float2> subsets_vertexBuffer_UV1[MAX_DESCRIPTOR_INDEXING] : register(t400000, space1);
#endif // RAYTRACING_GEOMETRYINDEX
typedef BuiltInTriangleIntersectionAttributes MyAttributes;
struct RayPayload
@@ -49,18 +47,23 @@ void RTAO_Raygen()
ray.TMax = rtao_range;
ray.Origin = P + N * 0.1;
RayPayload payload = { 0 };
RayPayload payload;
payload.color = 0;
for (uint i = 0; i < (uint)rtao_samplecount; ++i)
{
ray.Direction = SampleHemisphere_cos(N, seed, uv);
TraceRay(scene_acceleration_structure,
#ifndef RAYTRACING_GEOMETRYINDEX // tier 1_0 method of alpha test without GeometryIndex() is not implemented yet
RAY_FLAG_FORCE_OPAQUE |
RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH |
#endif // RAYTRACING_GEOMETRYINDEX
RAY_FLAG_SKIP_CLOSEST_HIT_SHADER
, ~0, 0, 1, 0, ray, payload);
TraceRay(
scene_acceleration_structure, // AccelerationStructure
RAY_FLAG_SKIP_CLOSEST_HIT_SHADER, // RayFlags
~0, // InstanceInclusionMask
0, // RayContributionToHitGroupIndex
0, // MultiplierForGeomtryContributionToShaderIndex
0, // MissShaderIndex
ray, // Ray
payload // Payload
);
}
payload.color /= rtao_samplecount;
@@ -76,15 +79,23 @@ void RTAO_ClosestHit(inout RayPayload payload, in MyAttributes attr)
[shader("anyhit")]
void RTAO_AnyHit(inout RayPayload payload, in MyAttributes attr)
{
#ifdef RAYTRACING_GEOMETRYINDEX
#ifndef SPIRV
float u = attr.barycentrics.x;
float v = attr.barycentrics.y;
float w = 1 - u - v;
uint primitiveIndex = PrimitiveIndex();
uint geometryOffset = InstanceID();
#ifdef RAYTRACING_GEOMETRYINDEX
uint geometryIndex = GeometryIndex(); // requires tier_1_1 GeometryIndex feature!!
#else
uint geometryIndex = 0;
#endif // RAYTRACING_GEOMETRYINDEX
uint descriptorIndex = geometryOffset + geometryIndex;
ShaderMaterial material = subsets_material[descriptorIndex];
if (material.uvset_baseColorMap < 0)
{
AcceptHitAndEndSearch();
}
uint i0 = subsets_indexBuffer[descriptorIndex][primitiveIndex * 3 + 0];
uint i1 = subsets_indexBuffer[descriptorIndex][primitiveIndex * 3 + 1];
uint i2 = subsets_indexBuffer[descriptorIndex][primitiveIndex * 3 + 2];
@@ -103,10 +114,9 @@ void RTAO_AnyHit(inout RayPayload payload, in MyAttributes attr)
}
float2 uv = uv0 * w + uv1 * u + uv2 * v;
float4 baseColor = material.baseColor;
baseColor *= subsets_texture_baseColor[descriptorIndex].SampleLevel(sampler_point_clamp, uv, 0);
float alpha = subsets_texture_baseColor[descriptorIndex].SampleLevel(sampler_point_wrap, uv, 2).a;
if (baseColor.a > 0.9)
if (alpha > 0.9)
{
AcceptHitAndEndSearch();
}
@@ -114,7 +124,7 @@ void RTAO_AnyHit(inout RayPayload payload, in MyAttributes attr)
{
IgnoreHit();
}
#endif // RAYTRACING_GEOMETRYINDEX
#endif // SPIRV
}
[shader("miss")]
+269
View File
@@ -0,0 +1,269 @@
#define DISABLE_SOFT_SHADOWMAP
#define DISABLE_TRANSPARENT_SHADOWMAP
#include "globals.hlsli"
#include "ShaderInterop_Postprocess.h"
#include "raytracingHF.hlsli"
#include "stochasticSSRHF.hlsli"
#include "lightingHF.hlsli"
RWTEXTURE2D(output, float4, 0);
ConstantBuffer<ShaderMaterial> subsets_material[MAX_DESCRIPTOR_INDEXING] : register(b0, space1);
Texture2D<float4> subsets_texture_baseColor[MAX_DESCRIPTOR_INDEXING] : register(t0, space1);
Buffer<uint> subsets_indexBuffer[MAX_DESCRIPTOR_INDEXING] : register(t100000, space1);
ByteAddressBuffer subsets_vertexBuffer_POS[MAX_DESCRIPTOR_INDEXING] : register(t200000, space1);
Buffer<float2> subsets_vertexBuffer_UV0[MAX_DESCRIPTOR_INDEXING] : register(t300000, space1);
Buffer<float2> subsets_vertexBuffer_UV1[MAX_DESCRIPTOR_INDEXING] : register(t400000, space1);
typedef BuiltInTriangleIntersectionAttributes MyAttributes;
struct RayPayload
{
float3 color;
float roughness;
};
[shader("raygeneration")]
void RTReflection_Raygen()
{
const float2 uv = ((float2)DispatchRaysIndex() + 0.5f) / (float2)DispatchRaysDimensions();
const float depth = texture_depth.SampleLevel(sampler_point_clamp, uv, 0);
if (depth == 0.0f)
return;
const float roughness = texture_gbuffer2.SampleLevel(sampler_linear_clamp, uv, 0).r;
const float3 P = reconstructPosition(uv, depth);
const float3 N = decodeNormal(texture_gbuffer1.SampleLevel(sampler_point_clamp, uv, 0).xy);
const float3 V = normalize(g_xCamera_CamPos - P);
float4 H;
if (roughness > 0.1f)
{
const float surfaceMargin = 0.0f;
const float maxRegenCount = 15.0f;
uint2 Random = Rand_PCG16(int3((DispatchRaysIndex().xy + 0.5f), g_xFrame_FrameCount)).xy;
// Pick the best rays
float RdotN = 0.0f;
float regenCount = 0;
[loop]
for (; RdotN <= surfaceMargin && regenCount < maxRegenCount; regenCount++)
{
// Low-discrepancy sequence
//float2 Xi = float2(Random) * rcp(65536.0); // equivalent to HammersleyRandom(0, 1, Random).
float2 Xi = HammersleyRandom16(regenCount, Random); // SingleSPP
Xi.y = lerp(Xi.y, 0.0f, BRDFBias);
// I should probably use importance sampling of visible normals http://jcgt.org/published/0007/04/01/paper.pdf
H = ImportanceSampleGGX(Xi, roughness);
H = TangentToWorld(H, N);
RdotN = dot(N, reflect(-V, H.xyz));
}
}
else
{
H = float4(N.xyz, 1.0f);
}
const float3 R = -reflect(V, H.xyz);
float seed = rtreflection_seed;
RayDesc ray;
ray.TMin = 0.001;
ray.TMax = rtreflection_range;
ray.Origin = P + N * 0.1;
ray.Direction = normalize(R);
RayPayload payload;
payload.color = 0;
payload.roughness = roughness;
TraceRay(
scene_acceleration_structure, // AccelerationStructure
0, // RayFlags
~0, // InstanceInclusionMask
0, // RayContributionToHitGroupIndex
0, // MultiplierForGeomtryContributionToShaderIndex
0, // MissShaderIndex
ray, // Ray
payload // Payload
);
output[DispatchRaysIndex().xy] = float4(payload.color, 1);
}
[shader("closesthit")]
void RTReflection_ClosestHit(inout RayPayload payload, in MyAttributes attr)
{
#ifndef SPIRV
float u = attr.barycentrics.x;
float v = attr.barycentrics.y;
float w = 1 - u - v;
uint primitiveIndex = PrimitiveIndex();
uint geometryOffset = InstanceID();
#ifdef RAYTRACING_GEOMETRYINDEX
uint geometryIndex = GeometryIndex(); // requires tier_1_1 GeometryIndex feature!!
#else
uint geometryIndex = 0;
#endif // RAYTRACING_GEOMETRYINDEX
uint descriptorIndex = geometryOffset + geometryIndex;
ShaderMaterial material = subsets_material[descriptorIndex];
uint i0 = subsets_indexBuffer[descriptorIndex][primitiveIndex * 3 + 0];
uint i1 = subsets_indexBuffer[descriptorIndex][primitiveIndex * 3 + 1];
uint i2 = subsets_indexBuffer[descriptorIndex][primitiveIndex * 3 + 2];
float4 uv0, uv1, uv2;
uv0.xy = subsets_vertexBuffer_UV0[descriptorIndex][i0];
uv1.xy = subsets_vertexBuffer_UV0[descriptorIndex][i1];
uv2.xy = subsets_vertexBuffer_UV0[descriptorIndex][i2];
uv0.zw = subsets_vertexBuffer_UV1[descriptorIndex][i0];
uv1.zw = subsets_vertexBuffer_UV1[descriptorIndex][i1];
uv2.zw = subsets_vertexBuffer_UV1[descriptorIndex][i2];
float3 n0, n1, n2;
n0 = unpack_unitvector(subsets_vertexBuffer_POS[descriptorIndex].Load4(i0 * 16).w);
n1 = unpack_unitvector(subsets_vertexBuffer_POS[descriptorIndex].Load4(i1 * 16).w);
n2 = unpack_unitvector(subsets_vertexBuffer_POS[descriptorIndex].Load4(i2 * 16).w);
float4 uvsets = uv0 * w + uv1 * u + uv2 * v;
float3 N = normalize(n0 * w + n1 * u + n2 * v);
float4 baseColor;
[branch]
if (material.uvset_baseColorMap >= 0)
{
const float2 UV_baseColorMap = material.uvset_baseColorMap == 0 ? uvsets.xy : uvsets.zw;
baseColor = subsets_texture_baseColor[descriptorIndex].SampleLevel(sampler_linear_wrap, UV_baseColorMap, 2);
baseColor.rgb = DEGAMMA(baseColor.rgb);
}
else
{
baseColor = 1;
}
baseColor *= material.baseColor;
float4 color = baseColor;
float4 emissiveColor = material.emissiveColor;
// Light sampling:
float3 P = WorldRayOrigin() + WorldRayDirection() * RayTCurrent();
float3 V = normalize(g_xCamera_CamPos - P);
Surface surface = CreateSurface(P, N, V, baseColor, 0.5f, 1, 0, 0);
Lighting lighting = CreateLighting(0, 0, 0, 0);
[loop]
for (uint iterator = 0; iterator < g_xFrame_LightArrayCount; iterator++)
{
ShaderEntity light = EntityArray[g_xFrame_LightArrayOffset + iterator];
if (light.GetFlags() & ENTITY_FLAG_LIGHT_STATIC)
{
continue; // static lights will be skipped (they are used in lightmap baking)
}
switch (light.GetType())
{
case ENTITY_TYPE_DIRECTIONALLIGHT:
{
DirectionalLight(light, surface, lighting);
}
break;
case ENTITY_TYPE_POINTLIGHT:
{
PointLight(light, surface, lighting);
}
break;
case ENTITY_TYPE_SPOTLIGHT:
{
SpotLight(light, surface, lighting);
}
break;
case ENTITY_TYPE_SPHERELIGHT:
{
SphereLight(light, surface, lighting);
}
break;
case ENTITY_TYPE_DISCLIGHT:
{
DiscLight(light, surface, lighting);
}
break;
case ENTITY_TYPE_RECTANGLELIGHT:
{
RectangleLight(light, surface, lighting);
}
break;
case ENTITY_TYPE_TUBELIGHT:
{
TubeLight(light, surface, lighting);
}
break;
}
}
payload.color = baseColor.rgb * (lighting.direct.diffuse + GetAmbient(surface.N)) + emissiveColor.rgb * emissiveColor.a;
#else
payload.color = float3(1, 0, 0);
#endif // SPIRV
}
[shader("anyhit")]
void RTReflection_AnyHit(inout RayPayload payload, in MyAttributes attr)
{
#ifndef SPIRV
float u = attr.barycentrics.x;
float v = attr.barycentrics.y;
float w = 1 - u - v;
uint primitiveIndex = PrimitiveIndex();
uint geometryOffset = InstanceID();
#ifdef RAYTRACING_GEOMETRYINDEX
uint geometryIndex = GeometryIndex(); // requires tier_1_1 GeometryIndex feature!!
#else
uint geometryIndex = 0;
#endif // RAYTRACING_GEOMETRYINDEX
uint descriptorIndex = geometryOffset + geometryIndex;
ShaderMaterial material = subsets_material[descriptorIndex];
if (material.uvset_baseColorMap < 0)
{
return;
}
uint i0 = subsets_indexBuffer[descriptorIndex][primitiveIndex * 3 + 0];
uint i1 = subsets_indexBuffer[descriptorIndex][primitiveIndex * 3 + 1];
uint i2 = subsets_indexBuffer[descriptorIndex][primitiveIndex * 3 + 2];
float2 uv0, uv1, uv2;
if (material.uvset_baseColorMap == 0)
{
uv0 = subsets_vertexBuffer_UV0[descriptorIndex][i0];
uv1 = subsets_vertexBuffer_UV0[descriptorIndex][i1];
uv2 = subsets_vertexBuffer_UV0[descriptorIndex][i2];
}
else
{
uv0 = subsets_vertexBuffer_UV1[descriptorIndex][i0];
uv1 = subsets_vertexBuffer_UV1[descriptorIndex][i1];
uv2 = subsets_vertexBuffer_UV1[descriptorIndex][i2];
}
float2 uv = uv0 * w + uv1 * u + uv2 * v;
float alpha = subsets_texture_baseColor[descriptorIndex].SampleLevel(sampler_point_wrap, uv, 2).a;
if (alpha < 0.9)
{
IgnoreHit();
}
#endif // SPIRV
}
[shader("miss")]
void RTReflection_Miss(inout RayPayload payload)
{
Surface surface;
surface.roughness = payload.roughness;
surface.R = WorldRayDirection();
payload.color = EnvironmentReflection_Global(surface, surface.roughness * g_xFrame_EnvProbeMipCount);
}
+1
View File
@@ -379,6 +379,7 @@ enum CSTYPES
enum RTTYPES
{
RTTYPE_RTAO,
RTTYPE_RTREFLECTION,
RTTYPE_COUNT
};
-1
View File
@@ -2206,7 +2206,6 @@ using namespace DX12_Internal;
hr = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5, &features_5, sizeof(features_5));
RAYTRACING = features_5.RaytracingTier >= D3D12_RAYTRACING_TIER_1_0;
// needs Windows SDK 10.19041 or greater, this can be commented out safely:
RAYTRACING_INLINE = features_5.RaytracingTier >= D3D12_RAYTRACING_TIER_1_1;
hr = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS6, &features_6, sizeof(features_6));
+279 -2
View File
@@ -10409,9 +10409,13 @@ void Postprocess_RTAO(
descriptorTable.resources.push_back({ TEXTURE2D, TEXSLOT_DEPTH });
descriptorTable.resources.push_back({ ACCELERATIONSTRUCTURE, TEXSLOT_ACCELERATION_STRUCTURE });
descriptorTable.resources.push_back({ RWTEXTURE2D, 0 });
descriptorTable.resources.push_back({ ROOT_CONSTANTBUFFER, CB_GETBINDSLOT(FrameCB) });
descriptorTable.resources.push_back({ ROOT_CONSTANTBUFFER, CB_GETBINDSLOT(CameraCB) });
descriptorTable.resources.push_back({ ROOT_CONSTANTBUFFER, CB_GETBINDSLOT(PostProcessCB) });
descriptorTable.staticsamplers.push_back({ samplers[SSLOT_POINT_CLAMP], SSLOT_POINT_CLAMP });
descriptorTable.staticsamplers.push_back({ samplers[SSLOT_LINEAR_CLAMP], SSLOT_LINEAR_CLAMP });
descriptorTable.staticsamplers.push_back({ samplers[SSLOT_POINT_WRAP], SSLOT_POINT_WRAP });
descriptorTable.staticsamplers.push_back({ samplers[SSLOT_LINEAR_WRAP], SSLOT_LINEAR_WRAP });
device->CreateDescriptorTable(&descriptorTable);
rootSignature = RootSignature();
@@ -10521,8 +10525,9 @@ void Postprocess_RTAO(
device->WriteDescriptor(&descriptorTable, 2, 0, &temp);
device->BindDescriptorTable(RAYTRACING, 0, &descriptorTable, cmd);
device->BindDescriptorTable(RAYTRACING, 1, &scene.descriptorTable, cmd);
device->BindRootDescriptor(RAYTRACING, 0, &constantBuffers[CBTYPE_CAMERA], 0, cmd);
device->BindRootDescriptor(RAYTRACING, 1, cb_alloc.buffer, cb_alloc.offset, cmd);
device->BindRootDescriptor(RAYTRACING, 0, &constantBuffers[CBTYPE_FRAME], 0, cmd);
device->BindRootDescriptor(RAYTRACING, 1, &constantBuffers[CBTYPE_CAMERA], 0, cmd);
device->BindRootDescriptor(RAYTRACING, 2, cb_alloc.buffer, cb_alloc.offset, cmd);
size_t shaderIdentifierSize = device->GetShaderIdentifierSize();
GraphicsDevice::GPUAllocation shadertable_raygen = device->AllocateGPU(shaderIdentifierSize, cmd);
@@ -10597,6 +10602,278 @@ void Postprocess_RTAO(
wiProfiler::EndRange(prof_range);
device->EventEnd(cmd);
}
void Postprocess_RTReflection(
const Texture& depthbuffer,
const Texture& gbuffer1,
const Texture& gbuffer2,
const Texture& output,
CommandList cmd,
float range
)
{
if (!wiRenderer::GetDevice()->CheckCapability(GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_RAYTRACING))
return;
if (!wiRenderer::GetDevice()->CheckCapability(GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_DESCRIPTOR_MANAGEMENT))
return;
const Scene& scene = wiScene::GetScene();
if (scene.objects.GetCount() <= 0)
{
return;
}
GraphicsDevice* device = GetDevice();
device->EventBegin("Postprocess_RTReflection", cmd);
auto prof_range = wiProfiler::BeginRangeGPU("RTReflection", cmd);
static Texture temp;
static Texture texture_temporal[2];
if (temp.desc.Width != output.desc.Width / 2 || temp.desc.Height != output.desc.Height / 2)
{
TextureDesc desc = output.desc;
desc.BindFlags |= BIND_UNORDERED_ACCESS;
desc.Width /= 2;
desc.Height /= 2;
device->CreateTexture(&desc, nullptr, &temp);
device->SetName(&temp, "rtreflection_temp");
device->CreateTexture(&desc, nullptr, &texture_temporal[0]);
device->CreateTexture(&desc, nullptr, &texture_temporal[1]);
}
static RaytracingPipelineState RTPSO;
static DescriptorTable descriptorTable;
static RootSignature rootSignature;
auto load_shaders = [&scene](uint64_t userdata) {
GraphicsDevice* device = GetDevice();
descriptorTable = DescriptorTable();
descriptorTable.resources.push_back({ RWTEXTURE2D, 0 });
descriptorTable.resources.push_back({ ACCELERATIONSTRUCTURE, TEXSLOT_ACCELERATION_STRUCTURE });
descriptorTable.resources.push_back({ TEXTURE2D, TEXSLOT_DEPTH });
descriptorTable.resources.push_back({ TEXTURE2D, TEXSLOT_GBUFFER1 });
descriptorTable.resources.push_back({ TEXTURE2D, TEXSLOT_GBUFFER2 });
descriptorTable.resources.push_back({ TEXTURECUBEARRAY, TEXSLOT_ENVMAPARRAY });
descriptorTable.resources.push_back({ TEXTURE2DARRAY, TEXSLOT_SHADOWARRAY_2D });
descriptorTable.resources.push_back({ TEXTURECUBEARRAY, TEXSLOT_SHADOWARRAY_CUBE });
descriptorTable.resources.push_back({ TEXTURECUBEARRAY, TEXSLOT_SHADOWARRAY_TRANSPARENT });
descriptorTable.resources.push_back({ STRUCTUREDBUFFER, SBSLOT_ENTITYARRAY });
descriptorTable.resources.push_back({ STRUCTUREDBUFFER, SBSLOT_MATRIXARRAY });
descriptorTable.resources.push_back({ ROOT_CONSTANTBUFFER, CB_GETBINDSLOT(FrameCB) });
descriptorTable.resources.push_back({ ROOT_CONSTANTBUFFER, CB_GETBINDSLOT(CameraCB) });
descriptorTable.resources.push_back({ ROOT_CONSTANTBUFFER, CB_GETBINDSLOT(PostProcessCB) });
descriptorTable.staticsamplers.push_back({ samplers[SSLOT_POINT_CLAMP], SSLOT_POINT_CLAMP });
descriptorTable.staticsamplers.push_back({ samplers[SSLOT_LINEAR_CLAMP], SSLOT_LINEAR_CLAMP });
descriptorTable.staticsamplers.push_back({ samplers[SSLOT_POINT_WRAP], SSLOT_POINT_WRAP });
descriptorTable.staticsamplers.push_back({ samplers[SSLOT_LINEAR_WRAP], SSLOT_LINEAR_WRAP });
descriptorTable.staticsamplers.push_back({ samplers[SSLOT_CMP_DEPTH], SSLOT_CMP_DEPTH });
device->CreateDescriptorTable(&descriptorTable);
rootSignature = RootSignature();
rootSignature.tables.push_back(descriptorTable);
rootSignature.tables.push_back(scene.descriptorTable);
device->CreateRootSignature(&rootSignature);
raytracingShaders[RTTYPE_RTREFLECTION].rootSignature = &rootSignature;
bool success = LoadShader(SHADERSTAGE_COUNT, raytracingShaders[RTTYPE_RTREFLECTION], "rtreflectionLIB.cso");
assert(success);
RaytracingPipelineStateDesc rtdesc;
rtdesc.rootSignature = &rootSignature;
rtdesc.shaderlibraries.emplace_back();
rtdesc.shaderlibraries.back().shader = &raytracingShaders[RTTYPE_RTREFLECTION];
rtdesc.shaderlibraries.back().function_name = "RTReflection_Raygen";
rtdesc.shaderlibraries.back().type = ShaderLibrary::RAYGENERATION;
rtdesc.shaderlibraries.emplace_back();
rtdesc.shaderlibraries.back().shader = &raytracingShaders[RTTYPE_RTREFLECTION];
rtdesc.shaderlibraries.back().function_name = "RTReflection_ClosestHit";
rtdesc.shaderlibraries.back().type = ShaderLibrary::CLOSESTHIT;
rtdesc.shaderlibraries.emplace_back();
rtdesc.shaderlibraries.back().shader = &raytracingShaders[RTTYPE_RTREFLECTION];
rtdesc.shaderlibraries.back().function_name = "RTReflection_AnyHit";
rtdesc.shaderlibraries.back().type = ShaderLibrary::ANYHIT;
rtdesc.shaderlibraries.emplace_back();
rtdesc.shaderlibraries.back().shader = &raytracingShaders[RTTYPE_RTREFLECTION];
rtdesc.shaderlibraries.back().function_name = "RTReflection_Miss";
rtdesc.shaderlibraries.back().type = ShaderLibrary::MISS;
rtdesc.hitgroups.emplace_back();
rtdesc.hitgroups.back().type = ShaderHitGroup::GENERAL;
rtdesc.hitgroups.back().name = "RTReflection_Raygen";
rtdesc.hitgroups.back().general_shader = 0;
rtdesc.hitgroups.emplace_back();
rtdesc.hitgroups.back().type = ShaderHitGroup::GENERAL;
rtdesc.hitgroups.back().name = "RTReflection_Miss";
rtdesc.hitgroups.back().general_shader = 3;
rtdesc.hitgroups.emplace_back();
rtdesc.hitgroups.back().type = ShaderHitGroup::TRIANGLES;
rtdesc.hitgroups.back().name = "RTReflection_Hitgroup";
rtdesc.hitgroups.back().closesthit_shader = 1;
rtdesc.hitgroups.back().anyhit_shader = 2;
rtdesc.max_trace_recursion_depth = 1;
rtdesc.max_payload_size_in_bytes = sizeof(float4);
rtdesc.max_attribute_size_in_bytes = sizeof(float2); // bary
success = device->CreateRaytracingPipelineState(&rtdesc, &RTPSO);
assert(success);
};
static wiEvent::Handle handle = wiEvent::Subscribe(SYSTEM_EVENT_RELOAD_SHADERS, load_shaders);
if (!RTPSO.IsValid())
{
load_shaders(0);
}
PostProcessCB cb;
cb.xPPResolution.x = temp.desc.Width;
cb.xPPResolution.y = temp.desc.Height;
cb.xPPResolution_rcp.x = 1.0f / cb.xPPResolution.x;
cb.xPPResolution_rcp.y = 1.0f / cb.xPPResolution.y;
cb.rtreflection_range = range;
cb.rtreflection_seed = renderTime;
GraphicsDevice::GPUAllocation cb_alloc = device->AllocateGPU(sizeof(cb), cmd);
memcpy(cb_alloc.data, &cb, sizeof(cb));
device->BindRaytracingPipelineState(&RTPSO, cmd);
device->WriteDescriptor(&descriptorTable, 0, 0, &temp);
device->WriteDescriptor(&descriptorTable, 1, 0, &scene.TLAS);
device->WriteDescriptor(&descriptorTable, 2, 0, &depthbuffer);
device->WriteDescriptor(&descriptorTable, 3, 0, &gbuffer1);
device->WriteDescriptor(&descriptorTable, 4, 0, &gbuffer2);
device->WriteDescriptor(&descriptorTable, 5, 0, &textures[TEXTYPE_CUBEARRAY_ENVMAPARRAY]);
device->WriteDescriptor(&descriptorTable, 6, 0, &shadowMapArray_2D);
device->WriteDescriptor(&descriptorTable, 7, 0, &shadowMapArray_Cube);
device->WriteDescriptor(&descriptorTable, 8, 0, &shadowMapArray_Transparent);
device->WriteDescriptor(&descriptorTable, 9, 0, &resourceBuffers[RBTYPE_ENTITYARRAY]);
device->WriteDescriptor(&descriptorTable, 10, 0, &resourceBuffers[RBTYPE_MATRIXARRAY]);
device->BindDescriptorTable(RAYTRACING, 0, &descriptorTable, cmd);
device->BindDescriptorTable(RAYTRACING, 1, &scene.descriptorTable, cmd);
device->BindRootDescriptor(RAYTRACING, 0, &constantBuffers[CBTYPE_FRAME], 0, cmd);
device->BindRootDescriptor(RAYTRACING, 1, &constantBuffers[CBTYPE_CAMERA], 0, cmd);
device->BindRootDescriptor(RAYTRACING, 2, cb_alloc.buffer, cb_alloc.offset, cmd);
size_t shaderIdentifierSize = device->GetShaderIdentifierSize();
GraphicsDevice::GPUAllocation shadertable_raygen = device->AllocateGPU(shaderIdentifierSize, cmd);
GraphicsDevice::GPUAllocation shadertable_miss = device->AllocateGPU(shaderIdentifierSize, cmd);
GraphicsDevice::GPUAllocation shadertable_hitgroup = device->AllocateGPU(shaderIdentifierSize, cmd);
device->WriteShaderIdentifier(&RTPSO, 0, shadertable_raygen.data);
device->WriteShaderIdentifier(&RTPSO, 1, shadertable_miss.data);
device->WriteShaderIdentifier(&RTPSO, 2, shadertable_hitgroup.data);
DispatchRaysDesc dispatchraysdesc;
dispatchraysdesc.raygeneration.buffer = shadertable_raygen.buffer;
dispatchraysdesc.raygeneration.offset = shadertable_raygen.offset;
dispatchraysdesc.raygeneration.size = shaderIdentifierSize;
dispatchraysdesc.miss.buffer = shadertable_miss.buffer;
dispatchraysdesc.miss.offset = shadertable_miss.offset;
dispatchraysdesc.miss.size = shaderIdentifierSize;
dispatchraysdesc.miss.stride = shaderIdentifierSize;
dispatchraysdesc.hitgroup.buffer = shadertable_hitgroup.buffer;
dispatchraysdesc.hitgroup.offset = shadertable_hitgroup.offset;
dispatchraysdesc.hitgroup.size = shaderIdentifierSize;
dispatchraysdesc.hitgroup.stride = shaderIdentifierSize;
dispatchraysdesc.Width = temp.desc.Width;
dispatchraysdesc.Height = temp.desc.Height;
device->DispatchRays(&dispatchraysdesc, cmd);
GPUBarrier barriers[] = {
GPUBarrier::Memory(),
};
device->Barrier(barriers, arraysize(barriers), cmd);
device->UpdateBuffer(&constantBuffers[CBTYPE_POSTPROCESS], &cb, cmd);
device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_POSTPROCESS], CB_GETBINDSLOT(PostProcessCB), cmd);
int temporal_output = device->GetFrameCount() % 2;
int temporal_history = 1 - temporal_output;
// Temporal pass:
{
device->EventBegin("Temporal pass", cmd);
device->BindComputeShader(&computeShaders[CSTYPE_POSTPROCESS_SSR_TEMPORAL], cmd);
device->BindResource(CS, &depthbuffer, TEXSLOT_DEPTH, cmd);
device->BindResource(CS, &temp, TEXSLOT_ONDEMAND0, cmd);
device->BindResource(CS, &texture_temporal[temporal_history], TEXSLOT_ONDEMAND1, cmd);
const GPUResource* uavs[] = {
&texture_temporal[temporal_output],
};
device->BindUAVs(CS, uavs, 0, arraysize(uavs), cmd);
device->Dispatch(
(texture_temporal[temporal_output].GetDesc().Width + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
(texture_temporal[temporal_output].GetDesc().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);
}
// Switch to full res
cb.xPPResolution.x = output.desc.Width;
cb.xPPResolution.y = output.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);
// Median blur pass:
{
device->EventBegin("Median blur pass", cmd);
device->BindComputeShader(&computeShaders[CSTYPE_POSTPROCESS_SSR_MEDIAN], cmd);
device->BindResource(CS, &depthbuffer, TEXSLOT_DEPTH, cmd);
device->BindResource(CS, &texture_temporal[temporal_output], TEXSLOT_ONDEMAND0, cmd);
const GPUResource* uavs[] = {
&output,
};
device->BindUAVs(CS, uavs, 0, arraysize(uavs), cmd);
device->Dispatch(
(output.desc.Width + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
(output.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);
}
wiProfiler::EndRange(prof_range);
device->EventEnd(cmd);
}
void Postprocess_SSR(
const Texture& input,
const Texture& depthbuffer,
+8
View File
@@ -243,6 +243,14 @@ namespace wiRenderer
uint32_t samplecount = 16,
float power = 2.0f
);
void Postprocess_RTReflection(
const wiGraphics::Texture& depthbuffer,
const wiGraphics::Texture& gbuffer1,
const wiGraphics::Texture& gbuffer2,
const wiGraphics::Texture& output,
wiGraphics::CommandList cmd,
float range = 1000.0f
);
void Postprocess_SSR(
const wiGraphics::Texture& input,
const wiGraphics::Texture& depthbuffer,
+7
View File
@@ -1158,6 +1158,7 @@ namespace wiScene
descriptorTable.resources[DESCRIPTORTABLE_ENTRY_SUBSETS_MATERIAL] = { CONSTANTBUFFER, 0, MAX_DESCRIPTOR_INDEXING };
descriptorTable.resources[DESCRIPTORTABLE_ENTRY_SUBSETS_TEXTURE_BASECOLOR] = { TEXTURE2D, 0, MAX_DESCRIPTOR_INDEXING };
descriptorTable.resources[DESCRIPTORTABLE_ENTRY_SUBSETS_INDEXBUFFER] = { TYPEDBUFFER, MAX_DESCRIPTOR_INDEXING, MAX_DESCRIPTOR_INDEXING };
descriptorTable.resources[DESCRIPTORTABLE_ENTRY_SUBSETS_VERTEXBUFFER_POSITION_NORMAL_WIND] = { RAWBUFFER, MAX_DESCRIPTOR_INDEXING * 2, MAX_DESCRIPTOR_INDEXING };
descriptorTable.resources[DESCRIPTORTABLE_ENTRY_SUBSETS_VERTEXBUFFER_UV0] = { TYPEDBUFFER, MAX_DESCRIPTOR_INDEXING * 3, MAX_DESCRIPTOR_INDEXING };
descriptorTable.resources[DESCRIPTORTABLE_ENTRY_SUBSETS_VERTEXBUFFER_UV1] = { TYPEDBUFFER, MAX_DESCRIPTOR_INDEXING * 4, MAX_DESCRIPTOR_INDEXING };
@@ -2174,6 +2175,12 @@ namespace wiScene
&mesh.indexBuffer,
-1, subset.indexOffset * mesh.GetIndexStride()
);
device->WriteDescriptor(
&descriptorTable,
DESCRIPTORTABLE_ENTRY_SUBSETS_VERTEXBUFFER_POSITION_NORMAL_WIND,
global_geometryIndex,
&mesh.vertexBuffer_POS
);
device->WriteDescriptor(
&descriptorTable,
DESCRIPTORTABLE_ENTRY_SUBSETS_VERTEXBUFFER_UV0,
+1
View File
@@ -1146,6 +1146,7 @@ namespace wiScene
DESCRIPTORTABLE_ENTRY_SUBSETS_MATERIAL,
DESCRIPTORTABLE_ENTRY_SUBSETS_TEXTURE_BASECOLOR,
DESCRIPTORTABLE_ENTRY_SUBSETS_INDEXBUFFER,
DESCRIPTORTABLE_ENTRY_SUBSETS_VERTEXBUFFER_POSITION_NORMAL_WIND,
DESCRIPTORTABLE_ENTRY_SUBSETS_VERTEXBUFFER_UV0,
DESCRIPTORTABLE_ENTRY_SUBSETS_VERTEXBUFFER_UV1,
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates, breaking API changes
const int minor = 47;
// minor bug fixes, alterations, refactors, updates
const int revision = 37;
const int revision = 38;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);