Switched to a single merged ProbeData texture instead of separate textures for Relocation and Classification.

Switched to HDR irradiance.
SDK Update.
Fixed a Vulkan validation error on RayTracingSceneSrg::MeshInfo.
Improvements to DiffuseProbeGrid blending.

Signed-off-by: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com>
This commit is contained in:
dmcdiarmid-ly
2021-12-08 18:35:45 -07:00
parent 003727ca57
commit c58a742296
61 changed files with 197 additions and 388 deletions
@@ -134,15 +134,13 @@ ShaderResourceGroup RayTracingSceneSrg : SRG_RayTracingScene
uint m_normalOffset;
uint m_tangentOffset;
uint m_bitangentOffset;
uint m_uvOffset;
float m_padding0[2];
float4 m_irradianceColor;
float3x3 m_worldInvTranspose;
float m_padding1;
uint m_uvOffset;
uint m_bufferFlags;
uint m_bufferStartIndex;
float4 m_irradianceColor;
float3x4 m_worldInvTranspose;
};
// hit shaders can retrieve the MeshInfo for a mesh hit using: RayTracingSceneSrg::m_meshInfo[InstanceIndex()]
@@ -163,4 +161,4 @@ ShaderResourceGroup RayTracingSceneSrg : SRG_RayTracingScene
// - Optional stream buffers such as Tangent, Bitangent, and UV are indicated in the MeshInfo.m_bufferFlags field
// - Buffers for a particular mesh start at MeshInfo.m_bufferStartIndex
ByteAddressBuffer m_meshBuffers[];
}
}
@@ -124,4 +124,4 @@ VertexData GetHitInterpolatedVertexData(RayTracingSceneSrg::MeshInfo meshInfo, f
vertexData.m_bitangent = normalize(vertexData.m_bitangent);
return vertexData;
}
}
@@ -68,9 +68,7 @@ float3 SampleProbeIrradiance(uint sampleIndex, uint2 probeIrradianceCoords, floa
if (abs(depth - downsampledDepth) <= DepthTolerance)
{
// use this irradiance sample
float3 probeIrradiance = PassSrg::m_downsampledProbeIrradiance.Load(probeIrradianceCoords, sampleIndex).rgb;
probeIrradiance = saturate(probeIrradiance);
return probeIrradiance;
return PassSrg::m_downsampledProbeIrradiance.Load(probeIrradianceCoords, sampleIndex).rgb;
}
}
@@ -99,9 +97,7 @@ float3 SampleProbeIrradiance(uint sampleIndex, uint2 probeIrradianceCoords, floa
float downsampledDepth = PassSrg::m_downsampledDepth.Load(probeIrradianceCoords + int2(x, y), sampleIndex).r;
if (abs(depth - downsampledDepth) <= DepthTolerance)
{
float3 probeIrradiance = PassSrg::m_downsampledProbeIrradiance.Load(probeIrradianceCoords + int2(x, y), sampleIndex).rgb;
probeIrradiance = saturate(probeIrradiance);
return probeIrradiance;
return PassSrg::m_downsampledProbeIrradiance.Load(probeIrradianceCoords + int2(x, y), sampleIndex).rgb;
}
closestDot = normalDot;
@@ -111,9 +107,7 @@ float3 SampleProbeIrradiance(uint sampleIndex, uint2 probeIrradianceCoords, floa
}
}
float3 probeIrradiance = PassSrg::m_downsampledProbeIrradiance.Load(probeIrradianceCoords + closestOffset, sampleIndex).rgb;
probeIrradiance = saturate(probeIrradiance);
return probeIrradiance;
return PassSrg::m_downsampledProbeIrradiance.Load(probeIrradianceCoords + closestOffset, sampleIndex).rgb;
}
// retrieve irradiance from the global IBL diffuse cubemap
@@ -156,22 +150,23 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
float4 encodedNormal = PassSrg::m_normal.Load(screenCoords, sampleIndex);
float3 normal = DecodeNormalSignedOctahedron(encodedNormal.rgb);
float4 albedo = PassSrg::m_albedo.Load(screenCoords, sampleIndex);
float useProbeIrradiance = PassSrg::m_downsampledProbeIrradiance.Load(probeIrradianceCoords, sampleIndex).a;
float probeIrradianceBlendWeight = PassSrg::m_downsampledProbeIrradiance.Load(probeIrradianceCoords, sampleIndex).a;
float3 diffuse = float3(0.0f, 0.0f, 0.0f);
if (useProbeIrradiance > 0.0f)
{
float3 irradiance = SampleProbeIrradiance(sampleIndex, probeIrradianceCoords, depth, normal, albedo, PassSrg::m_imageScale);
diffuse = (albedo.rgb / PI) * irradiance;
}
else
if (probeIrradianceBlendWeight > 0.0f)
{
float3 irradiance = SampleGlobalIBL(sampleIndex, screenCoords, depth, normal);
diffuse = albedo * irradiance;
float3 probeIrradiance = SampleProbeIrradiance(sampleIndex, probeIrradianceCoords, depth, normal, albedo, PassSrg::m_imageScale);
diffuse = (albedo.rgb / PI) * probeIrradiance * probeIrradianceBlendWeight;
}
// adjust IBL lighting by exposure.
float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
diffuse *= iblExposureFactor;
if (probeIrradianceBlendWeight < 1.0f)
{
float3 globalIrradiance = SampleGlobalIBL(sampleIndex, screenCoords, depth, normal);
// adjust IBL lighting by exposure
float3 globalDiffuse = (albedo * globalIrradiance) * pow(2.0, SceneSrg::m_iblExposure);
diffuse += globalDiffuse * (1.0f - probeIrradianceBlendWeight);
}
PSOutput OUT;
@@ -43,16 +43,14 @@ namespace AZ
RHI::Size m_size;
};
static const char* DiffuseProbeGridIrradianceFileName = "Irradiance_lutrgba16.dds";
static const char* DiffuseProbeGridIrradianceFileName = "Irradiance_lutrgba16f.dds";
static const char* DiffuseProbeGridDistanceFileName = "Distance_lutrg32f.dds";
static const char* DiffuseProbeGridRelocationFileName = "Relocation_lutrgba16f.dds";
static const char* DiffuseProbeGridClassificationFileName = "Classification_lutr32f.dds";
static const char* DiffuseProbeGridProbeDataFileName = "ProbeData_lutrgba16f.dds";
using DiffuseProbeGridBakeTexturesCallback = AZStd::function<void(
DiffuseProbeGridTexture irradianceTexture,
DiffuseProbeGridTexture distanceTexture,
DiffuseProbeGridTexture relocationTexture,
DiffuseProbeGridTexture classificationTexture)>;
DiffuseProbeGridTexture probeDataTexture)>;
struct DiffuseProbeGridBakedTextures
{
@@ -63,14 +61,8 @@ namespace AZ
Data::Instance<RPI::Image> m_distanceImage;
AZStd::string m_distanceImageRelativePath;
// relocation and classification images need to be recreated as RW textures
RHI::ImageDescriptor m_relocationImageDescriptor;
AZStd::array_view<uint8_t> m_relocationImageData;
AZStd::string m_relocationImageRelativePath;
RHI::ImageDescriptor m_classificationImageDescriptor;
AZStd::array_view<uint8_t> m_classificationImageData;
AZStd::string m_classificationImageRelativePath;
Data::Instance<RPI::Image> m_probeDataImage;
AZStd::string m_probeDataImageRelativePath;
};
// DiffuseProbeGridFeatureProcessorInterface provides an interface to the feature processor for code outside of Atom
@@ -102,8 +94,7 @@ namespace AZ
DiffuseProbeGridBakeTexturesCallback callback,
const AZStd::string& irradianceTextureRelativePath,
const AZStd::string& distanceTextureRelativePath,
const AZStd::string& relocationTextureRelativePath,
const AZStd::string& classificationTextureRelativePath) = 0;
const AZStd::string& probeDataTextureRelativePath) = 0;
// check for and retrieve a new baked texture asset (does not apply to hot-reloaded assets, only initial bakes)
virtual bool CheckTextureAssetNotification(
@@ -114,8 +105,7 @@ namespace AZ
virtual bool AreBakedTexturesReferenced(
const AZStd::string& irradianceTextureRelativePath,
const AZStd::string& distanceTextureRelativePath,
const AZStd::string& relocationTextureRelativePath,
const AZStd::string& classificationTextureRelativePath) = 0;
const AZStd::string& probeDataTextureRelativePath) = 0;
};
} // namespace Render
@@ -42,8 +42,7 @@ namespace AZ
m_rayTraceImageAttachmentId = AZStd::string::format("ProbeRayTraceImageAttachmentId_%s", uuidString.c_str());
m_irradianceImageAttachmentId = AZStd::string::format("ProbeIrradianceImageAttachmentId_%s", uuidString.c_str());
m_distanceImageAttachmentId = AZStd::string::format("ProbeDistanceImageAttachmentId_%s", uuidString.c_str());
m_relocationImageAttachmentId = AZStd::string::format("ProbeRelocationImageAttachmentId_%s", uuidString.c_str());
m_classificationImageAttachmentId = AZStd::string::format("ProbeClassificationImageAttachmentId_%s", uuidString.c_str());
m_probeDataImageAttachmentId = AZStd::string::format("ProbeDataImageAttachmentId_%s", uuidString.c_str());
// setup culling
m_cullable.m_cullData.m_scene = m_scene;
@@ -93,7 +92,7 @@ namespace AZ
}
}
m_probeRayRotationTransform = AZ::Matrix4x4::CreateIdentity();
m_probeRayRotation = AZ::Quaternion::CreateIdentity();
}
bool DiffuseProbeGrid::ValidateProbeSpacing(const AZ::Vector3& newSpacing)
@@ -182,58 +181,24 @@ namespace AZ
}
m_updateTextures = true;
// probes need to be relocated since the mode has changed
m_remainingRelocationIterations = DefaultNumRelocationIterations;
}
void DiffuseProbeGrid::SetBakedTextures(const DiffuseProbeGridBakedTextures& bakedTextures)
{
AZ_Assert(bakedTextures.m_irradianceImage.get(), "Invalid Irradiance image passed to SetBakedTextures");
AZ_Assert(bakedTextures.m_distanceImage.get(), "Invalid Distance image passed to SetBakedTextures");
AZ_Assert(bakedTextures.m_relocationImageData.size() > 0, "Invalid Relocation image data passed to SetBakedTextures");
AZ_Assert(bakedTextures.m_classificationImageData.size() > 0, "Invalid Classification image data passed to SetBakedTextures");
AZ_Assert(bakedTextures.m_probeDataImage.get(), "Invalid ProbeData image passed to SetBakedTextures");
m_bakedIrradianceImage = bakedTextures.m_irradianceImage;
m_bakedDistanceImage = bakedTextures.m_distanceImage;
m_bakedProbeDataImage = bakedTextures.m_probeDataImage;
m_bakedIrradianceRelativePath = bakedTextures.m_irradianceImageRelativePath;
m_bakedDistanceRelativePath = bakedTextures.m_distanceImageRelativePath;
m_bakedRelocationRelativePath = bakedTextures.m_relocationImageRelativePath;
m_bakedClassificationRelativePath = bakedTextures.m_classificationImageRelativePath;
m_bakedRelocationImageData.resize(bakedTextures.m_relocationImageData.size());
memcpy(m_bakedRelocationImageData.data(), bakedTextures.m_relocationImageData.data(), bakedTextures.m_relocationImageData.size());
m_bakedClassificationImageData.resize(bakedTextures.m_classificationImageData.size());
memcpy(m_bakedClassificationImageData.data(), bakedTextures.m_classificationImageData.data(), bakedTextures.m_classificationImageData.size());
// create the relocation and distance RW textures now, these are needed for shader compatibility
// (image data is copied in UpdateTextures)
{
m_bakedRelocationImage = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest initRequest;
initRequest.m_image = m_bakedRelocationImage.get();
initRequest.m_descriptor = RHI::ImageDescriptor::Create2D(
RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead,
bakedTextures.m_relocationImageDescriptor.m_size.m_width,
bakedTextures.m_relocationImageDescriptor.m_size.m_height,
bakedTextures.m_relocationImageDescriptor.m_format);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(initRequest);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize Relocation image");
}
{
m_bakedClassificationImage = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest initRequest;
initRequest.m_image = m_bakedClassificationImage.get();
initRequest.m_descriptor = RHI::ImageDescriptor::Create2D(
RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead,
bakedTextures.m_classificationImageDescriptor.m_size.m_width,
bakedTextures.m_classificationImageDescriptor.m_size.m_height,
bakedTextures.m_classificationImageDescriptor.m_format);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(initRequest);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize Classification image");
}
m_bakedProbeDataRelativePath = bakedTextures.m_probeDataImageRelativePath;
m_updateTextures = true;
}
@@ -242,8 +207,7 @@ namespace AZ
{
return m_bakedIrradianceImage.get() &&
m_bakedDistanceImage.get() &&
m_bakedRelocationImage.get() &&
m_bakedClassificationImage.get();
m_bakedProbeDataImage.get();
}
void DiffuseProbeGrid::ResetCullingVisibility()
@@ -344,63 +308,18 @@ namespace AZ
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeDistanceImage image");
}
// probe relocation
// probe data
{
uint32_t width = probeCountX;
uint32_t height = probeCountY;
m_relocationImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
m_probeDataImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_relocationImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead, width, height, DiffuseProbeGridRenderData::RelocationImageFormat);
request.m_image = m_probeDataImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead, width, height, DiffuseProbeGridRenderData::ProbeDataImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeRelocationImage image");
}
// probe classification
{
uint32_t width = probeCountX;
uint32_t height = probeCountY;
m_classificationImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_classificationImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead, width, height, DiffuseProbeGridRenderData::ClassificationImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeClassificationImage image");
}
}
else if (m_mode == DiffuseProbeGridMode::Baked && HasValidBakedTextures())
{
// copy the baked relocation and classification texture data to the RW textures
// (these need to be RW for shader compatibility)
RHI::ImageSubresourceRange range{ 0, 0, 0 ,0 };
RHI::ImageSubresourceLayoutPlaced layout;
// relocation
{
m_bakedRelocationImage->GetSubresourceLayouts(range, &layout, nullptr);
RHI::ImageUpdateRequest updateRequest;
updateRequest.m_image = m_bakedRelocationImage.get();
updateRequest.m_sourceSubresourceLayout = layout;
updateRequest.m_sourceData = m_bakedRelocationImageData.data();
updateRequest.m_imageSubresourcePixelOffset = RHI::Origin(0, 0, 0);
m_renderData->m_imagePool->UpdateImageContents(updateRequest);
}
// classification
{
m_bakedClassificationImage->GetSubresourceLayouts(range, &layout, nullptr);
RHI::ImageUpdateRequest updateRequest;
updateRequest.m_image = m_bakedClassificationImage.get();
updateRequest.m_sourceSubresourceLayout = layout;
updateRequest.m_sourceData = m_bakedClassificationImageData.data();
updateRequest.m_imageSubresourcePixelOffset = RHI::Origin(0, 0, 0);
m_renderData->m_imagePool->UpdateImageContents(updateRequest);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeDataImage image");
}
}
@@ -472,39 +391,24 @@ namespace AZ
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.rotation"));
srg->SetConstant(constantIndex, m_transform.GetRotation());
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.numRaysPerProbe"));
srg->SetConstant(constantIndex, m_numRaysPerProbe);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeRayRotation"));
srg->SetConstant(constantIndex, m_probeRayRotation);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeGridSpacing"));
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.movementType"));
srg->SetConstant(constantIndex, 0);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeSpacing"));
srg->SetConstant(constantIndex, m_probeSpacing);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeMaxRayDistance"));
srg->SetConstant(constantIndex, m_probeMaxRayDistance);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeGridCounts"));
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeCounts"));
uint32_t probeGridCounts[3];
probeGridCounts[0] = m_probeCountX;
probeGridCounts[1] = m_probeCountY;
probeGridCounts[2] = m_probeCountZ;
srg->SetConstantRaw(constantIndex, &probeGridCounts[0], sizeof(probeGridCounts));
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeDistanceExponent"));
srg->SetConstant(constantIndex, m_probeDistanceExponent);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeHysteresis"));
srg->SetConstant(constantIndex, m_probeHysteresis);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeChangeThreshold"));
srg->SetConstant(constantIndex, m_probeChangeThreshold);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeBrightnessThreshold"));
srg->SetConstant(constantIndex, m_probeBrightnessThreshold);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeIrradianceEncodingGamma"));
srg->SetConstant(constantIndex, m_probeIrradianceEncodingGamma);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeInverseIrradianceEncodingGamma"));
srg->SetConstant(constantIndex, m_probeInverseIrradianceEncodingGamma);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeNumRays"));
srg->SetConstant(constantIndex, m_numRaysPerProbe);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeNumIrradianceTexels"));
srg->SetConstant(constantIndex, DefaultNumIrradianceTexels);
@@ -512,20 +416,57 @@ namespace AZ
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeNumDistanceTexels"));
srg->SetConstant(constantIndex, DefaultNumDistanceTexels);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.normalBias"));
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeHysteresis"));
srg->SetConstant(constantIndex, m_probeHysteresis);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeMaxRayDistance"));
srg->SetConstant(constantIndex, m_probeMaxRayDistance);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeNormalBias"));
srg->SetConstant(constantIndex, m_normalBias);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.viewBias"));
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeViewBias"));
srg->SetConstant(constantIndex, m_viewBias);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeMinFrontfaceDistance"));
srg->SetConstant(constantIndex, m_probeMinFrontfaceDistance);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeDistanceExponent"));
srg->SetConstant(constantIndex, m_probeDistanceExponent);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeIrradianceThreshold"));
srg->SetConstant(constantIndex, m_probeIrradianceThreshold);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeBrightnessThreshold"));
srg->SetConstant(constantIndex, m_probeBrightnessThreshold);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeIrradianceEncodingGamma"));
srg->SetConstant(constantIndex, m_probeIrradianceEncodingGamma);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeBackfaceThreshold"));
srg->SetConstant(constantIndex, m_probeBackfaceThreshold);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeRayRotationTransform"));
srg->SetConstant(constantIndex, m_probeRayRotationTransform);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeMinFrontfaceDistance"));
srg->SetConstant(constantIndex, m_probeMinFrontfaceDistance);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeScrollOffsets"));
srg->SetConstant(constantIndex, Vector3::CreateZero());
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeRayDataFormat"));
srg->SetConstant(constantIndex, 1);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeIrradianceFormat"));
srg->SetConstant(constantIndex, 1);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeRelocationEnabled"));
srg->SetConstant(constantIndex, true);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeClassificationEnabled"));
srg->SetConstant(constantIndex, true);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeScrollClear[0]"));
srg->SetConstant(constantIndex, false);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeScrollClear[1]"));
srg->SetConstant(constantIndex, false);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeGrid.probeScrollClear[2]"));
srg->SetConstant(constantIndex, false);
}
void DiffuseProbeGrid::UpdateRayTraceSrg(const Data::Instance<RPI::Shader>& shader, const RHI::Ptr<RHI::ShaderResourceGroupLayout>& layout)
@@ -552,13 +493,9 @@ namespace AZ
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeDistance"));
m_rayTraceSrg->SetImageView(imageIndex, m_distanceImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeDistanceImageViewDescriptor).get());
// probe relocation
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeOffsets"));
m_rayTraceSrg->SetImageView(imageIndex, m_relocationImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeRelocationImageViewDescriptor).get());
// probe classification
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeStates"));
m_rayTraceSrg->SetImageView(imageIndex, m_classificationImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeClassificationImageViewDescriptor).get());
// probe data
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeData"));
m_rayTraceSrg->SetImageView(imageIndex, m_probeDataImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeDataImageViewDescriptor).get());
// grid settings
constantIndex = srgLayout->FindShaderInputConstantIndex(Name("m_ambientMultiplier"));
@@ -590,8 +527,8 @@ namespace AZ
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeIrradiance"));
m_blendIrradianceSrg->SetImageView(imageIndex, m_irradianceImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeIrradianceImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeStates"));
m_blendIrradianceSrg->SetImageView(imageIndex, m_classificationImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeClassificationImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeData"));
m_blendIrradianceSrg->SetImageView(imageIndex, m_probeDataImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeDataImageViewDescriptor).get());
SetGridConstants(m_blendIrradianceSrg);
}
@@ -613,8 +550,8 @@ namespace AZ
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeDistance"));
m_blendDistanceSrg->SetImageView(imageIndex, m_distanceImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeDistanceImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeStates"));
m_blendDistanceSrg->SetImageView(imageIndex, m_classificationImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeClassificationImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeData"));
m_blendDistanceSrg->SetImageView(imageIndex, m_probeDataImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeDataImageViewDescriptor).get());
SetGridConstants(m_blendDistanceSrg);
}
@@ -715,8 +652,8 @@ namespace AZ
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeRayTrace"));
m_relocationSrg->SetImageView(imageIndex, m_rayTraceImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeRayTraceImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeRelocation"));
m_relocationSrg->SetImageView(imageIndex, m_relocationImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeRelocationImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeData"));
m_relocationSrg->SetImageView(imageIndex, m_probeDataImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeDataImageViewDescriptor).get());
float probeDistanceScale = (aznumeric_cast<float>(m_remainingRelocationIterations) / DefaultNumRelocationIterations);
constantIndex = srgLayout->FindShaderInputConstantIndex(AZ::Name("m_probeDistanceScale"));
@@ -739,8 +676,8 @@ namespace AZ
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeRayTrace"));
m_classificationSrg->SetImageView(imageIndex, m_rayTraceImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeRayTraceImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeStates"));
m_classificationSrg->SetImageView(imageIndex, m_classificationImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeClassificationImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(AZ::Name("m_probeData"));
m_classificationSrg->SetImageView(imageIndex, m_probeDataImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeDataImageViewDescriptor).get());
SetGridConstants(m_classificationSrg);
}
@@ -785,11 +722,8 @@ namespace AZ
imageIndex = srgLayout->FindShaderInputImageIndex(Name("m_probeDistance"));
m_renderObjectSrg->SetImageView(imageIndex, GetDistanceImage()->GetImageView(m_renderData->m_probeDistanceImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(Name("m_probeOffsets"));
m_renderObjectSrg->SetImageView(imageIndex, GetRelocationImage()->GetImageView(m_renderData->m_probeRelocationImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(Name("m_probeStates"));
m_renderObjectSrg->SetImageView(imageIndex, GetClassificationImage()->GetImageView(m_renderData->m_probeClassificationImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(Name("m_probeData"));
m_renderObjectSrg->SetImageView(imageIndex, GetProbeDataImage()->GetImageView(m_renderData->m_probeDataImageViewDescriptor).get());
SetGridConstants(m_renderObjectSrg);
@@ -23,12 +23,10 @@ namespace AZ
struct DiffuseProbeGridRenderData
{
// [GFX TODO][ATOM-15650] Change DiffuseProbeGrid Classification texture to R8_UINT
static const RHI::Format RayTraceImageFormat = RHI::Format::R32G32B32A32_FLOAT;
static const RHI::Format IrradianceImageFormat = RHI::Format::R16G16B16A16_UNORM;
static const RHI::Format IrradianceImageFormat = RHI::Format::R16G16B16A16_FLOAT;
static const RHI::Format DistanceImageFormat = RHI::Format::R32G32_FLOAT;
static const RHI::Format RelocationImageFormat = RHI::Format::R16G16B16A16_FLOAT;
static const RHI::Format ClassificationImageFormat = RHI::Format::R32_FLOAT;
static const RHI::Format ProbeDataImageFormat = RHI::Format::R16G16B16A16_FLOAT;
// image pool
RHI::Ptr<RHI::ImagePool> m_imagePool;
@@ -41,8 +39,7 @@ namespace AZ
RHI::ImageViewDescriptor m_probeRayTraceImageViewDescriptor;
RHI::ImageViewDescriptor m_probeIrradianceImageViewDescriptor;
RHI::ImageViewDescriptor m_probeDistanceImageViewDescriptor;
RHI::ImageViewDescriptor m_probeRelocationImageViewDescriptor;
RHI::ImageViewDescriptor m_probeClassificationImageViewDescriptor;
RHI::ImageViewDescriptor m_probeDataImageViewDescriptor;
// render pipeline state
RPI::Ptr<RPI::PipelineStateForDraw> m_pipelineState;
@@ -142,20 +139,17 @@ namespace AZ
const RHI::Ptr<RHI::Image> GetRayTraceImage() { return m_rayTraceImage[m_currentImageIndex]; }
const RHI::Ptr<RHI::Image> GetIrradianceImage() { return m_mode == DiffuseProbeGridMode::RealTime ? m_irradianceImage[m_currentImageIndex] : m_bakedIrradianceImage->GetRHIImage(); }
const RHI::Ptr<RHI::Image> GetDistanceImage() { return m_mode == DiffuseProbeGridMode::RealTime ? m_distanceImage[m_currentImageIndex] : m_bakedDistanceImage->GetRHIImage(); }
const RHI::Ptr<RHI::Image> GetRelocationImage() { return m_mode == DiffuseProbeGridMode::RealTime ? m_relocationImage[m_currentImageIndex] : m_bakedRelocationImage; }
const RHI::Ptr<RHI::Image> GetClassificationImage() { return m_mode == DiffuseProbeGridMode::RealTime ? m_classificationImage[m_currentImageIndex] : m_bakedClassificationImage; }
const RHI::Ptr<RHI::Image> GetProbeDataImage() { return m_mode == DiffuseProbeGridMode::RealTime ? m_probeDataImage[m_currentImageIndex] : m_bakedProbeDataImage->GetRHIImage(); }
const AZStd::string& GetBakedIrradianceRelativePath() const { return m_bakedIrradianceRelativePath; }
const AZStd::string& GetBakedDistanceRelativePath() const { return m_bakedDistanceRelativePath; }
const AZStd::string& GetBakedRelocationRelativePath() const { return m_bakedRelocationRelativePath; }
const AZStd::string& GetBakedClassificationRelativePath() const { return m_bakedClassificationRelativePath; }
const AZStd::string& GetBakedProbeDataRelativePath() const { return m_bakedProbeDataRelativePath; }
// attachment Ids
const RHI::AttachmentId GetRayTraceImageAttachmentId() const { return m_rayTraceImageAttachmentId; }
const RHI::AttachmentId GetIrradianceImageAttachmentId() const { return m_irradianceImageAttachmentId; }
const RHI::AttachmentId GetDistanceImageAttachmentId() const { return m_distanceImageAttachmentId; }
const RHI::AttachmentId GetRelocationImageAttachmentId() const { return m_relocationImageAttachmentId; }
const RHI::AttachmentId GetClassificationImageAttachmentId() const { return m_classificationImageAttachmentId; }
const RHI::AttachmentId GetProbeDataImageAttachmentId() const { return m_probeDataImageAttachmentId; }
const DiffuseProbeGridRenderData* GetRenderData() const { return m_renderData; }
@@ -208,10 +202,9 @@ namespace AZ
float m_probeMaxRayDistance = 30.0f;
float m_probeDistanceExponent = 50.0f;
float m_probeHysteresis = 0.95f;
float m_probeChangeThreshold = 0.2f;
float m_probeIrradianceThreshold = 0.2f;
float m_probeBrightnessThreshold = 1.0f;
float m_probeIrradianceEncodingGamma = 5.0f;
float m_probeInverseIrradianceEncodingGamma = 1.0f / m_probeIrradianceEncodingGamma;
float m_probeMinFrontfaceDistance = 1.0f;
float m_probeBackfaceThreshold = 0.25f;
float m_ambientMultiplier = 1.0f;
@@ -219,7 +212,7 @@ namespace AZ
bool m_useDiffuseIbl = true;
// rotation transform applied to probe rays
AZ::Matrix4x4 m_probeRayRotationTransform;
AZ::Quaternion m_probeRayRotation;
AZ::SimpleLcgRandom m_random;
// probe relocation settings
@@ -247,8 +240,7 @@ namespace AZ
RHI::Ptr<RHI::Image> m_rayTraceImage[ImageFrameCount];
RHI::Ptr<RHI::Image> m_irradianceImage[ImageFrameCount];
RHI::Ptr<RHI::Image> m_distanceImage[ImageFrameCount];
RHI::Ptr<RHI::Image> m_relocationImage[ImageFrameCount];
RHI::Ptr<RHI::Image> m_classificationImage[ImageFrameCount];
RHI::Ptr<RHI::Image> m_probeDataImage[ImageFrameCount];
uint32_t m_currentImageIndex = 0;
bool m_updateTextures = false;
bool m_irradianceClearRequired = true;
@@ -256,18 +248,12 @@ namespace AZ
// baked textures
Data::Instance<RPI::Image> m_bakedIrradianceImage;
Data::Instance<RPI::Image> m_bakedDistanceImage;
RHI::Ptr<RHI::Image> m_bakedRelocationImage;
RHI::Ptr<RHI::Image> m_bakedClassificationImage;
Data::Instance<RPI::Image> m_bakedProbeDataImage;
// baked texture relative paths
AZStd::string m_bakedIrradianceRelativePath;
AZStd::string m_bakedDistanceRelativePath;
AZStd::string m_bakedRelocationRelativePath;
AZStd::string m_bakedClassificationRelativePath;
// baked texture data (only needed for the relocation and classification textures)
AZStd::vector<uint8_t> m_bakedRelocationImageData;
AZStd::vector<uint8_t> m_bakedClassificationImageData;
AZStd::string m_bakedProbeDataRelativePath;
// texture readback
DiffuseProbeGridTextureReadback m_textureReadback;
@@ -289,8 +275,7 @@ namespace AZ
RHI::AttachmentId m_rayTraceImageAttachmentId;
RHI::AttachmentId m_irradianceImageAttachmentId;
RHI::AttachmentId m_distanceImageAttachmentId;
RHI::AttachmentId m_relocationImageAttachmentId;
RHI::AttachmentId m_classificationImageAttachmentId;
RHI::AttachmentId m_probeDataImageAttachmentId;
};
} // namespace Render
} // namespace AZ
@@ -112,11 +112,11 @@ namespace AZ
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
}
// probe classification image
// probe data image
{
RHI::ImageScopeAttachmentDescriptor desc;
desc.m_attachmentId = diffuseProbeGrid->GetClassificationImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeClassificationImageViewDescriptor;
desc.m_attachmentId = diffuseProbeGrid->GetProbeDataImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeDataImageViewDescriptor;
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
@@ -102,23 +102,13 @@ namespace AZ
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
}
// probe irradiance image
// probe data image
{
RHI::ImageScopeAttachmentDescriptor desc;
desc.m_attachmentId = diffuseProbeGrid->GetIrradianceImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeIrradianceImageViewDescriptor;
desc.m_attachmentId = diffuseProbeGrid->GetProbeDataImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeDataImageViewDescriptor;
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
}
// probe classification image
{
RHI::ImageScopeAttachmentDescriptor desc;
desc.m_attachmentId = diffuseProbeGrid->GetClassificationImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeClassificationImageViewDescriptor;
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
}
}
@@ -106,11 +106,11 @@ namespace AZ
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
}
// probe classification image
// probe data image
{
RHI::ImageScopeAttachmentDescriptor desc;
desc.m_attachmentId = diffuseProbeGrid->GetClassificationImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeClassificationImageViewDescriptor;
desc.m_attachmentId = diffuseProbeGrid->GetProbeDataImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeDataImageViewDescriptor;
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
@@ -69,8 +69,7 @@ namespace AZ
m_probeGridRenderData.m_probeRayTraceImageViewDescriptor = RHI::ImageViewDescriptor::Create(DiffuseProbeGridRenderData::RayTraceImageFormat, 0, 0);
m_probeGridRenderData.m_probeIrradianceImageViewDescriptor = RHI::ImageViewDescriptor::Create(DiffuseProbeGridRenderData::IrradianceImageFormat, 0, 0);
m_probeGridRenderData.m_probeDistanceImageViewDescriptor = RHI::ImageViewDescriptor::Create(DiffuseProbeGridRenderData::DistanceImageFormat, 0, 0);
m_probeGridRenderData.m_probeRelocationImageViewDescriptor = RHI::ImageViewDescriptor::Create(DiffuseProbeGridRenderData::RelocationImageFormat, 0, 0);
m_probeGridRenderData.m_probeClassificationImageViewDescriptor = RHI::ImageViewDescriptor::Create(DiffuseProbeGridRenderData::ClassificationImageFormat, 0, 0);
m_probeGridRenderData.m_probeDataImageViewDescriptor = RHI::ImageViewDescriptor::Create(DiffuseProbeGridRenderData::ProbeDataImageFormat, 0, 0);
// load shader
// Note: the shader may not be available on all platforms
@@ -325,15 +324,13 @@ namespace AZ
DiffuseProbeGridBakeTexturesCallback callback,
const AZStd::string& irradianceTextureRelativePath,
const AZStd::string& distanceTextureRelativePath,
const AZStd::string& relocationTextureRelativePath,
const AZStd::string& classificationTextureRelativePath)
const AZStd::string& probeDataTextureRelativePath)
{
AZ_Assert(probeGrid.get(), "BakeTextures called with an invalid handle");
AddNotificationEntry(irradianceTextureRelativePath);
AddNotificationEntry(distanceTextureRelativePath);
AddNotificationEntry(relocationTextureRelativePath);
AddNotificationEntry(classificationTextureRelativePath);
AddNotificationEntry(probeDataTextureRelativePath);
probeGrid->GetTextureReadback().BeginTextureReadback(callback);
}
@@ -415,15 +412,13 @@ namespace AZ
bool DiffuseProbeGridFeatureProcessor::AreBakedTexturesReferenced(
const AZStd::string& irradianceTextureRelativePath,
const AZStd::string& distanceTextureRelativePath,
const AZStd::string& relocationTextureRelativePath,
const AZStd::string& classificationTextureRelativePath)
const AZStd::string& probeDataTextureRelativePath)
{
for (auto& diffuseProbeGrid : m_diffuseProbeGrids)
{
if ((diffuseProbeGrid->GetBakedIrradianceRelativePath() == irradianceTextureRelativePath) ||
(diffuseProbeGrid->GetBakedDistanceRelativePath() == distanceTextureRelativePath) ||
(diffuseProbeGrid->GetBakedRelocationRelativePath() == relocationTextureRelativePath) ||
(diffuseProbeGrid->GetBakedClassificationRelativePath() == classificationTextureRelativePath))
(diffuseProbeGrid->GetBakedProbeDataRelativePath() == probeDataTextureRelativePath))
{
return true;
}
@@ -51,8 +51,7 @@ namespace AZ
DiffuseProbeGridBakeTexturesCallback callback,
const AZStd::string& irradianceTextureRelativePath,
const AZStd::string& distanceTextureRelativePath,
const AZStd::string& relocationTextureRelativePath,
const AZStd::string& classificationTextureRelativePath) override;
const AZStd::string& probeDataTextureRelativePath) override;
bool CheckTextureAssetNotification(
const AZStd::string& relativePath,
@@ -62,8 +61,7 @@ namespace AZ
bool AreBakedTexturesReferenced(
const AZStd::string& irradianceTextureRelativePath,
const AZStd::string& distanceTextureRelativePath,
const AZStd::string& relocationTextureRelativePath,
const AZStd::string& classificationTextureRelativePath) override;
const AZStd::string& probeDataTextureRelativePath) override;
// FeatureProcessor overrides
void Activate() override;
@@ -216,27 +216,14 @@ namespace AZ
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
}
// probe relocation
// probe data
{
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(diffuseProbeGrid->GetRelocationImageAttachmentId(), diffuseProbeGrid->GetRelocationImage());
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import probeRelocationImage");
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(diffuseProbeGrid->GetProbeDataImageAttachmentId(), diffuseProbeGrid->GetProbeDataImage());
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import ProbeDataImage");
RHI::ImageScopeAttachmentDescriptor desc;
desc.m_attachmentId = diffuseProbeGrid->GetRelocationImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeRelocationImageViewDescriptor;
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
}
// probe classification
{
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(diffuseProbeGrid->GetClassificationImageAttachmentId(), diffuseProbeGrid->GetClassificationImage());
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import probeClassificationImage");
RHI::ImageScopeAttachmentDescriptor desc;
desc.m_attachmentId = diffuseProbeGrid->GetClassificationImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeClassificationImageViewDescriptor;
desc.m_attachmentId = diffuseProbeGrid->GetProbeDataImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeDataImageViewDescriptor;
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
@@ -130,11 +130,11 @@ namespace AZ
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
}
// probe relocation image
// probe data image
{
RHI::ImageScopeAttachmentDescriptor desc;
desc.m_attachmentId = diffuseProbeGrid->GetRelocationImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeRelocationImageViewDescriptor;
desc.m_attachmentId = diffuseProbeGrid->GetProbeDataImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeDataImageViewDescriptor;
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
@@ -125,38 +125,21 @@ namespace AZ
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read);
}
// probe relocation image
// probe data image
{
if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::Baked)
{
// import the relocation image now, since it is baked and therefore was not imported during the raytracing pass
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(diffuseProbeGrid->GetRelocationImageAttachmentId(), diffuseProbeGrid->GetRelocationImage());
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import probeRelocationImage");
// import the probe data image now, since it is baked and therefore was not imported during the raytracing pass
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(diffuseProbeGrid->GetProbeDataImageAttachmentId(), diffuseProbeGrid->GetProbeDataImage());
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import ProbeDataImage");
}
RHI::ImageScopeAttachmentDescriptor desc;
desc.m_attachmentId = diffuseProbeGrid->GetRelocationImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeRelocationImageViewDescriptor;
desc.m_attachmentId = diffuseProbeGrid->GetProbeDataImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeDataImageViewDescriptor;
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
}
// probe classification image
{
if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::Baked)
{
// import the classification image now, since it is baked and therefore was not imported during the raytracing pass
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(diffuseProbeGrid->GetClassificationImageAttachmentId(), diffuseProbeGrid->GetClassificationImage());
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import probeClassificationImage");
}
RHI::ImageScopeAttachmentDescriptor desc;
desc.m_attachmentId = diffuseProbeGrid->GetClassificationImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeClassificationImageViewDescriptor;
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read);
}
diffuseProbeGrid->GetTextureReadback().Update(GetName());
@@ -76,24 +76,15 @@ namespace AZ
callbackFunction = [this](const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
{
m_distanceReadbackResult = readbackResult;
m_readbackState = DiffuseProbeGridReadbackState::Relocation;
m_readbackState = DiffuseProbeGridReadbackState::ProbeData;
};
break;
case DiffuseProbeGridReadbackState::Relocation:
descriptor = m_diffuseProbeGrid->GetRelocationImage()->GetDescriptor();
attachmentId = m_diffuseProbeGrid->GetRelocationImageAttachmentId();
case DiffuseProbeGridReadbackState::ProbeData:
descriptor = m_diffuseProbeGrid->GetProbeDataImage()->GetDescriptor();
attachmentId = m_diffuseProbeGrid->GetProbeDataImageAttachmentId();
callbackFunction = [this](const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
{
m_relocationReadbackResult = readbackResult;
m_readbackState = DiffuseProbeGridReadbackState::Classification;
};
break;
case DiffuseProbeGridReadbackState::Classification:
descriptor = m_diffuseProbeGrid->GetClassificationImage()->GetDescriptor();
attachmentId = m_diffuseProbeGrid->GetClassificationImageAttachmentId();
callbackFunction = [this](const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
{
m_classificationReadbackResult = readbackResult;
m_probeDataReadbackResult = readbackResult;
m_readbackState = DiffuseProbeGridReadbackState::Complete;
};
break;
@@ -131,8 +122,7 @@ namespace AZ
m_callback(
{ m_irradianceReadbackResult.m_dataBuffer, m_irradianceReadbackResult.m_imageDescriptor.m_format, m_irradianceReadbackResult.m_imageDescriptor.m_size },
{ m_distanceReadbackResult.m_dataBuffer, m_distanceReadbackResult.m_imageDescriptor.m_format, m_distanceReadbackResult.m_imageDescriptor.m_size },
{ m_relocationReadbackResult.m_dataBuffer, m_relocationReadbackResult.m_imageDescriptor.m_format, m_relocationReadbackResult.m_imageDescriptor.m_size },
{ m_classificationReadbackResult.m_dataBuffer, m_classificationReadbackResult.m_imageDescriptor.m_format, m_classificationReadbackResult.m_imageDescriptor.m_size });
{ m_probeDataReadbackResult.m_dataBuffer, m_probeDataReadbackResult.m_imageDescriptor.m_format, m_probeDataReadbackResult.m_imageDescriptor.m_size });
m_readbackState = DiffuseProbeGridReadbackState::Idle;
m_attachmentReadback.reset();
@@ -24,8 +24,7 @@ namespace AZ
Initializing,
Irradiance,
Distance,
Relocation,
Classification,
ProbeData,
Complete
};
@@ -52,8 +51,7 @@ namespace AZ
AZ::RPI::AttachmentReadback::ReadbackResult m_irradianceReadbackResult;
AZ::RPI::AttachmentReadback::ReadbackResult m_distanceReadbackResult;
AZ::RPI::AttachmentReadback::ReadbackResult m_relocationReadbackResult;
AZ::RPI::AttachmentReadback::ReadbackResult m_classificationReadbackResult;
AZ::RPI::AttachmentReadback::ReadbackResult m_probeDataReadbackResult;
// number of frames to delay before starting the texture readbacks, this allows the textures to settle
static constexpr int32_t DefaultNumInitializationFrames = 50;
@@ -317,7 +317,8 @@ namespace AZ
}
subMesh.m_irradianceColor.StoreToFloat4(meshInfo.m_irradianceColor.data());
rotationMatrix.StoreToRowMajorFloat9(meshInfo.m_worldInvTranspose.data());
Matrix3x4 worldInvTranspose3x4 = Matrix3x4::CreateFromMatrix3x3(rotationMatrix);
worldInvTranspose3x4.StoreToRowMajorFloat12(meshInfo.m_worldInvTranspose.data());
meshInfo.m_bufferFlags = subMesh.m_bufferFlags;
meshInfo.m_bufferStartIndex = bufferStartIndex;
@@ -235,14 +235,12 @@ namespace AZ
uint32_t m_tangentOffset;
uint32_t m_bitangentOffset;
uint32_t m_uvOffset;
float m_padding0[2];
AZStd::array<float, 4> m_irradianceColor; // float4
AZStd::array<float, 9> m_worldInvTranspose; // float3x3
float m_padding1;
RayTracingSubMeshBufferFlags m_bufferFlags = RayTracingSubMeshBufferFlags::None;
uint32_t m_bufferStartIndex = 0;
AZStd::array<float, 4> m_irradianceColor; // float4
AZStd::array<float, 12> m_worldInvTranspose; // float3x4
};
// buffer containing a MeshInfo for each sub-mesh
@@ -34,7 +34,7 @@ namespace AZ
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
{
serializeContext->Class<DiffuseProbeGridComponentConfig>()
->Version(0)
->Version(1)
->Field("ProbeSpacing", &DiffuseProbeGridComponentConfig::m_probeSpacing)
->Field("Extents", &DiffuseProbeGridComponentConfig::m_extents)
->Field("AmbientMultiplier", &DiffuseProbeGridComponentConfig::m_ambientMultiplier)
@@ -44,12 +44,10 @@ namespace AZ
->Field("RuntimeMode", &DiffuseProbeGridComponentConfig::m_runtimeMode)
->Field("BakedIrradianceTextureRelativePath", &DiffuseProbeGridComponentConfig::m_bakedIrradianceTextureRelativePath)
->Field("BakedDistanceTextureRelativePath", &DiffuseProbeGridComponentConfig::m_bakedDistanceTextureRelativePath)
->Field("BakedRelocationTextureRelativePath", &DiffuseProbeGridComponentConfig::m_bakedRelocationTextureRelativePath)
->Field("BakedClassificationTextureRelativePath", &DiffuseProbeGridComponentConfig::m_bakedClassificationTextureRelativePath)
->Field("BakedProbeDataTextureRelativePath", &DiffuseProbeGridComponentConfig::m_bakedProbeDataTextureRelativePath)
->Field("BakedIrradianceTextureAsset", &DiffuseProbeGridComponentConfig::m_bakedIrradianceTextureAsset)
->Field("BakedDistanceTextureAsset", &DiffuseProbeGridComponentConfig::m_bakedDistanceTextureAsset)
->Field("BakedRelocationTextureAsset", &DiffuseProbeGridComponentConfig::m_bakedRelocationTextureAsset)
->Field("BakedClassificationTextureAsset", &DiffuseProbeGridComponentConfig::m_bakedClassificationTextureAsset)
->Field("BakedProbeDataTextureAsset", &DiffuseProbeGridComponentConfig::m_bakedProbeDataTextureAsset)
;
}
}
@@ -121,19 +119,16 @@ namespace AZ
if (m_featureProcessor->AreBakedTexturesReferenced(
m_configuration.m_bakedIrradianceTextureRelativePath,
m_configuration.m_bakedDistanceTextureRelativePath,
m_configuration.m_bakedRelocationTextureRelativePath,
m_configuration.m_bakedClassificationTextureRelativePath))
m_configuration.m_bakedProbeDataTextureRelativePath))
{
// clear the baked texture paths and assets, since they belong to the original entity (not the clone)
m_configuration.m_bakedIrradianceTextureRelativePath.clear();
m_configuration.m_bakedDistanceTextureRelativePath.clear();
m_configuration.m_bakedRelocationTextureRelativePath.clear();
m_configuration.m_bakedClassificationTextureRelativePath.clear();
m_configuration.m_bakedProbeDataTextureRelativePath.clear();
m_configuration.m_bakedIrradianceTextureAsset.Reset();
m_configuration.m_bakedDistanceTextureAsset.Reset();
m_configuration.m_bakedRelocationTextureAsset.Reset();
m_configuration.m_bakedClassificationTextureAsset.Reset();
m_configuration.m_bakedProbeDataTextureAsset.Reset();
}
// add this diffuse probe grid to the feature processor
@@ -147,25 +142,22 @@ namespace AZ
// load the baked texture assets, but only if they are all valid
if (m_configuration.m_bakedIrradianceTextureAsset.GetId().IsValid() &&
m_configuration.m_bakedDistanceTextureAsset.GetId().IsValid() &&
m_configuration.m_bakedRelocationTextureAsset.GetId().IsValid() &&
m_configuration.m_bakedClassificationTextureAsset.GetId().IsValid())
m_configuration.m_bakedProbeDataTextureAsset.GetId().IsValid())
{
Data::AssetBus::MultiHandler::BusConnect(m_configuration.m_bakedIrradianceTextureAsset.GetId());
Data::AssetBus::MultiHandler::BusConnect(m_configuration.m_bakedDistanceTextureAsset.GetId());
Data::AssetBus::MultiHandler::BusConnect(m_configuration.m_bakedRelocationTextureAsset.GetId());
Data::AssetBus::MultiHandler::BusConnect(m_configuration.m_bakedClassificationTextureAsset.GetId());
Data::AssetBus::MultiHandler::BusConnect(m_configuration.m_bakedProbeDataTextureAsset.GetId());
m_configuration.m_bakedIrradianceTextureAsset.QueueLoad();
m_configuration.m_bakedDistanceTextureAsset.QueueLoad();
m_configuration.m_bakedRelocationTextureAsset.QueueLoad();
m_configuration.m_bakedClassificationTextureAsset.QueueLoad();
m_configuration.m_bakedProbeDataTextureAsset.QueueLoad();
}
else if (m_configuration.m_runtimeMode == DiffuseProbeGridMode::Baked ||
m_configuration.m_runtimeMode == DiffuseProbeGridMode::AutoSelect ||
m_configuration.m_editorMode == DiffuseProbeGridMode::Baked ||
m_configuration.m_editorMode == DiffuseProbeGridMode::AutoSelect)
{
AZ_Error("DiffuseProbeGrid", false, "DiffuseProbeGrid mdoe is set to Baked or Auto-Select, but it does not have baked texture assets. Please re-bake this DiffuseProbeGrid.");
AZ_Error("DiffuseProbeGrid", false, "DiffuseProbeGrid mode is set to Baked or Auto-Select, but it does not have baked texture assets. Please re-bake this DiffuseProbeGrid.");
}
m_featureProcessor->SetMode(m_handle, m_configuration.m_runtimeMode);
@@ -191,13 +183,11 @@ namespace AZ
// if all assets are ready we can set the baked texture images
if (m_configuration.m_bakedIrradianceTextureAsset.IsReady() &&
m_configuration.m_bakedDistanceTextureAsset.IsReady() &&
m_configuration.m_bakedRelocationTextureAsset.IsReady() &&
m_configuration.m_bakedClassificationTextureAsset.IsReady())
m_configuration.m_bakedProbeDataTextureAsset.IsReady())
{
Data::AssetBus::MultiHandler::BusDisconnect(m_configuration.m_bakedIrradianceTextureAsset.GetId());
Data::AssetBus::MultiHandler::BusDisconnect(m_configuration.m_bakedDistanceTextureAsset.GetId());
Data::AssetBus::MultiHandler::BusDisconnect(m_configuration.m_bakedRelocationTextureAsset.GetId());
Data::AssetBus::MultiHandler::BusDisconnect(m_configuration.m_bakedClassificationTextureAsset.GetId());
Data::AssetBus::MultiHandler::BusDisconnect(m_configuration.m_bakedProbeDataTextureAsset.GetId());
UpdateBakedTextures();
}
@@ -365,8 +355,7 @@ namespace AZ
callback,
m_configuration.m_bakedIrradianceTextureRelativePath,
m_configuration.m_bakedDistanceTextureRelativePath,
m_configuration.m_bakedRelocationTextureRelativePath,
m_configuration.m_bakedClassificationTextureRelativePath);
m_configuration.m_bakedProbeDataTextureRelativePath);
}
void DiffuseProbeGridComponentController::UpdateBakedTextures()
@@ -381,12 +370,8 @@ namespace AZ
bakedTextures.m_irradianceImageRelativePath = m_configuration.m_bakedIrradianceTextureRelativePath;
bakedTextures.m_distanceImage = RPI::StreamingImage::FindOrCreate(m_configuration.m_bakedDistanceTextureAsset);
bakedTextures.m_distanceImageRelativePath = m_configuration.m_bakedDistanceTextureRelativePath;
bakedTextures.m_relocationImageDescriptor = m_configuration.m_bakedRelocationTextureAsset->GetImageDescriptor();
bakedTextures.m_relocationImageData = m_configuration.m_bakedRelocationTextureAsset->GetSubImageData(0, 0);
bakedTextures.m_relocationImageRelativePath = m_configuration.m_bakedRelocationTextureRelativePath;
bakedTextures.m_classificationImageDescriptor = m_configuration.m_bakedClassificationTextureAsset->GetImageDescriptor();
bakedTextures.m_classificationImageData = m_configuration.m_bakedClassificationTextureAsset->GetSubImageData(0, 0);
bakedTextures.m_classificationImageRelativePath = m_configuration.m_bakedClassificationTextureRelativePath;
bakedTextures.m_probeDataImage = RPI::StreamingImage::FindOrCreate(m_configuration.m_bakedProbeDataTextureAsset);
bakedTextures.m_probeDataImageRelativePath = m_configuration.m_bakedProbeDataTextureRelativePath;
m_featureProcessor->SetBakedTextures(m_handle, bakedTextures);
}
@@ -41,13 +41,11 @@ namespace AZ
AZStd::string m_bakedIrradianceTextureRelativePath;
AZStd::string m_bakedDistanceTextureRelativePath;
AZStd::string m_bakedRelocationTextureRelativePath;
AZStd::string m_bakedClassificationTextureRelativePath;
AZStd::string m_bakedProbeDataTextureRelativePath;
Data::Asset<RPI::StreamingImageAsset> m_bakedIrradianceTextureAsset;
Data::Asset<RPI::StreamingImageAsset> m_bakedDistanceTextureAsset;
Data::Asset<RPI::StreamingImageAsset> m_bakedRelocationTextureAsset;
Data::Asset<RPI::StreamingImageAsset> m_bakedClassificationTextureAsset;
Data::Asset<RPI::StreamingImageAsset> m_bakedProbeDataTextureAsset;
AZ::u64 m_entityId{ EntityId::InvalidEntityId };
};
@@ -182,8 +182,7 @@ namespace AZ
CheckTextureAssetNotification(configuration.m_bakedIrradianceTextureRelativePath, configuration.m_bakedIrradianceTextureAsset);
CheckTextureAssetNotification(configuration.m_bakedDistanceTextureRelativePath, configuration.m_bakedDistanceTextureAsset);
CheckTextureAssetNotification(configuration.m_bakedRelocationTextureRelativePath, configuration.m_bakedRelocationTextureAsset);
CheckTextureAssetNotification(configuration.m_bakedClassificationTextureRelativePath, configuration.m_bakedClassificationTextureAsset);
CheckTextureAssetNotification(configuration.m_bakedProbeDataTextureRelativePath, configuration.m_bakedProbeDataTextureAsset);
}
void EditorDiffuseProbeGridComponent::CheckTextureAssetNotification(const AZStd::string& relativePath, Data::Asset<RPI::StreamingImageAsset>& configurationAsset)
@@ -201,8 +200,7 @@ namespace AZ
if (m_controller.m_configuration.m_bakedIrradianceTextureAsset.IsReady() &&
m_controller.m_configuration.m_bakedDistanceTextureAsset.IsReady() &&
m_controller.m_configuration.m_bakedClassificationTextureAsset.IsReady() &&
m_controller.m_configuration.m_bakedRelocationTextureAsset.IsReady())
m_controller.m_configuration.m_bakedProbeDataTextureAsset.IsReady())
{
m_controller.UpdateBakedTextures();
}
@@ -337,8 +335,7 @@ namespace AZ
{
if (!m_controller.m_configuration.m_bakedIrradianceTextureAsset.GetId().IsValid() ||
!m_controller.m_configuration.m_bakedDistanceTextureAsset.GetId().IsValid() ||
!m_controller.m_configuration.m_bakedRelocationTextureAsset.GetId().IsValid() ||
!m_controller.m_configuration.m_bakedClassificationTextureAsset.GetId().IsValid())
!m_controller.m_configuration.m_bakedProbeDataTextureAsset.GetId().IsValid())
{
return AZ::Failure(AZStd::string("Please bake textures before changing the Diffuse Probe Grid to Baked or Auto-Select mode."));
}
@@ -385,8 +382,7 @@ namespace AZ
// Note: we need to make sure to use the same source image for each bake
AZStd::string irradianceTextureRelativePath = ValidateOrCreateNewTexturePath(configuration.m_bakedIrradianceTextureRelativePath, DiffuseProbeGridIrradianceFileName);
AZStd::string distanceTextureRelativePath = ValidateOrCreateNewTexturePath(configuration.m_bakedDistanceTextureRelativePath, DiffuseProbeGridDistanceFileName);
AZStd::string relocationTextureRelativePath = ValidateOrCreateNewTexturePath(configuration.m_bakedRelocationTextureRelativePath, DiffuseProbeGridRelocationFileName);
AZStd::string classificationTextureRelativePath = ValidateOrCreateNewTexturePath(configuration.m_bakedClassificationTextureRelativePath, DiffuseProbeGridClassificationFileName);
AZStd::string probeDataTextureRelativePath = ValidateOrCreateNewTexturePath(configuration.m_bakedProbeDataTextureRelativePath, DiffuseProbeGridProbeDataFileName);
// create the full paths
char projectPath[AZ_MAX_PATH_LEN];
@@ -396,10 +392,8 @@ namespace AZ
AzFramework::StringFunc::Path::Join(projectPath, irradianceTextureRelativePath.c_str(), irradianceTextureFullPath, true, true);
AZStd::string distanceTextureFullPath;
AzFramework::StringFunc::Path::Join(projectPath, distanceTextureRelativePath.c_str(), distanceTextureFullPath, true, true);
AZStd::string relocationTextureFullPath;
AzFramework::StringFunc::Path::Join(projectPath, relocationTextureRelativePath.c_str(), relocationTextureFullPath, true, true);
AZStd::string classificationTextureFullPath;
AzFramework::StringFunc::Path::Join(projectPath, classificationTextureRelativePath.c_str(), classificationTextureFullPath, true, true);
AZStd::string probeDataTextureFullPath;
AzFramework::StringFunc::Path::Join(projectPath, probeDataTextureRelativePath.c_str(), probeDataTextureFullPath, true, true);
// make sure the folder is created
AZStd::string diffuseProbeGridFolder;
@@ -409,23 +403,20 @@ namespace AZ
// check out the files in source control
CheckoutSourceTextureFile(irradianceTextureFullPath);
CheckoutSourceTextureFile(distanceTextureFullPath);
CheckoutSourceTextureFile(relocationTextureFullPath);
CheckoutSourceTextureFile(classificationTextureFullPath);
CheckoutSourceTextureFile(probeDataTextureFullPath);
// update the configuration
AzToolsFramework::ScopedUndoBatch undoBatch("DiffuseProbeGrid bake");
configuration.m_bakedIrradianceTextureRelativePath = irradianceTextureRelativePath;
configuration.m_bakedDistanceTextureRelativePath = distanceTextureRelativePath;
configuration.m_bakedRelocationTextureRelativePath = relocationTextureRelativePath;
configuration.m_bakedClassificationTextureRelativePath = classificationTextureRelativePath;
configuration.m_bakedProbeDataTextureRelativePath = probeDataTextureRelativePath;
SetDirty();
// callback for the texture readback
DiffuseProbeGridBakeTexturesCallback bakeTexturesCallback = [=](
DiffuseProbeGridTexture irradianceTexture,
DiffuseProbeGridTexture distanceTexture,
DiffuseProbeGridTexture relocationTexture,
DiffuseProbeGridTexture classificationTexture)
DiffuseProbeGridTexture probeDataTexture)
{
// irradiance
{
@@ -441,18 +432,11 @@ namespace AZ
AZ_Assert(outcome.IsSuccess(), "Failed to write Distance texture .dds file [%s]", distanceTextureFullPath.c_str());
}
// relocation
// probe data
{
AZ::DdsFile::DdsFileData fileData = { relocationTexture.m_size, relocationTexture.m_format, relocationTexture.m_data.get() };
[[maybe_unused]] const auto outcome = AZ::DdsFile::WriteFile(relocationTextureFullPath, fileData);
AZ_Assert(outcome.IsSuccess(), "Failed to write Relocation texture .dds file [%s]", relocationTextureFullPath.c_str());
}
// classification
{
AZ::DdsFile::DdsFileData fileData = { classificationTexture.m_size, classificationTexture.m_format, classificationTexture.m_data.get() };
[[maybe_unused]] const auto outcome = AZ::DdsFile::WriteFile(classificationTextureFullPath, fileData);
AZ_Assert(outcome.IsSuccess(), "Failed to write Classification texture .dds file [%s]", classificationTextureFullPath.c_str());
AZ::DdsFile::DdsFileData fileData = { probeDataTexture.m_size, probeDataTexture.m_format, probeDataTexture.m_data.get() };
[[maybe_unused]] const auto outcome = AZ::DdsFile::WriteFile(probeDataTextureFullPath, fileData);
AZ_Assert(outcome.IsSuccess(), "Failed to write ProbeData texture .dds file [%s]", probeDataTextureFullPath.c_str());
}
m_bakeInProgress = false;