/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include #include #include #include #include namespace AZ { namespace Render { void ImageBasedLightFeatureProcessor::Reflect(ReflectContext* context) { if (auto* serializeContext = azrtti_cast(context)) { serializeContext ->Class() ->Version(0); } } void ImageBasedLightFeatureProcessor::Activate() { m_sceneSrg = GetParentScene()->GetShaderResourceGroup(); // Load default specular and diffuse cubemaps // These are assigned when Global IBL is disabled or removed from the scene to prevent a Vulkan TDR. // [GFX-TODO][ATOM-4181] This can be removed after Vulkan is changed to automatically handle this issue. LoadDefaultCubeMaps(); } void ImageBasedLightFeatureProcessor::Deactivate() { m_iblOrientationConstantIndex.Reset(); m_iblExposureConstantIndex.Reset(); m_diffuseEnvMapIndex.Reset(); m_specularEnvMapIndex.Reset(); m_sceneSrg = {}; } void ImageBasedLightFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet) { AZ_ATOM_PROFILE_FUNCTION("RPI", "ImageBasedLightFeatureProcessor: Simulate"); AZ_UNUSED(packet); m_sceneSrg->SetImage(m_specularEnvMapIndex, m_specular); m_sceneSrg->SetImage(m_diffuseEnvMapIndex, m_diffuse); m_sceneSrg->SetConstant(m_iblExposureConstantIndex, m_exposure); m_sceneSrg->SetConstant(m_iblOrientationConstantIndex, m_orientation); } void ImageBasedLightFeatureProcessor::SetSpecularImage(const Data::Asset& imageAsset) { m_specular = GetInstanceForImage(imageAsset, m_defaultSpecularImage); } void ImageBasedLightFeatureProcessor::SetDiffuseImage(const Data::Asset& imageAsset) { m_diffuse = GetInstanceForImage(imageAsset, m_defaultDiffuseImage); } void ImageBasedLightFeatureProcessor::SetExposure(float exposure) { m_exposure = exposure; } void ImageBasedLightFeatureProcessor::SetOrientation(const Quaternion& orientation) { m_orientation = orientation; } void ImageBasedLightFeatureProcessor::Reset() { m_specular = m_defaultSpecularImage; m_diffuse = m_defaultDiffuseImage; m_exposure = 0; } void ImageBasedLightFeatureProcessor::LoadDefaultCubeMaps() { const constexpr char* DefaultSpecularCubeMapPath = "textures/default/default_iblglobalcm_iblspecular.dds.streamingimage"; const constexpr char* DefaultDiffuseCubeMapPath = "textures/default/default_iblglobalcm_ibldiffuse.dds.streamingimage"; Data::AssetId specularAssetId; Data::AssetCatalogRequestBus::BroadcastResult( specularAssetId, &Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, DefaultSpecularCubeMapPath, azrtti_typeid(), false); Data::AssetId diffuseAssetId; Data::AssetCatalogRequestBus::BroadcastResult( diffuseAssetId, &Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, DefaultDiffuseCubeMapPath, azrtti_typeid(), false); auto specularAsset = Data::AssetManager::Instance().GetAsset(specularAssetId, AZ::Data::AssetLoadBehavior::PreLoad); auto diffuseAsset = Data::AssetManager::Instance().GetAsset(diffuseAssetId, AZ::Data::AssetLoadBehavior::PreLoad); specularAsset.BlockUntilLoadComplete(); diffuseAsset.BlockUntilLoadComplete(); m_defaultSpecularImage = RPI::StreamingImage::FindOrCreate(specularAsset); AZ_Assert(m_defaultSpecularImage, "Failed to load default specular cubemap"); m_defaultDiffuseImage = RPI::StreamingImage::FindOrCreate(diffuseAsset); AZ_Assert(m_defaultDiffuseImage, "Failed to load default diffuse cubemap"); } Data::Instance ImageBasedLightFeatureProcessor::GetInstanceForImage(const Data::Asset& imageAsset, const Data::Instance& defaultImage) { Data::Instance image; if (imageAsset.GetId().IsValid()) { image = RPI::StreamingImage::FindOrCreate(imageAsset); if (image && !ValidateIsCubemap(image)) { image = defaultImage; } } return image; } bool ImageBasedLightFeatureProcessor::ValidateIsCubemap(Data::Instance image) { const RHI::ImageDescriptor& desc = image->GetRHIImage()->GetDescriptor(); return (desc.m_isCubemap || desc.m_arraySize == 6); } } // namespace Render } // namespace AZ