added raytraced reflections
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)");
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
wiSlider* aoRangeSlider;
|
||||
wiSlider* aoSampleCountSlider;
|
||||
wiCheckBox* ssrCheckBox;
|
||||
wiCheckBox* raytracedReflectionsCheckBox;
|
||||
wiCheckBox* sssCheckBox;
|
||||
wiCheckBox* eyeAdaptionCheckBox;
|
||||
wiCheckBox* motionBlurCheckBox;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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
@@ -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")]
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -379,6 +379,7 @@ enum CSTYPES
|
||||
enum RTTYPES
|
||||
{
|
||||
RTTYPE_RTAO,
|
||||
RTTYPE_RTREFLECTION,
|
||||
RTTYPE_COUNT
|
||||
};
|
||||
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user