Merge pull request #5752 from aws-lumberyard-dev/puvvadar/gitflow_211118_o3de
Merge stabilization/2110
This commit is contained in:
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <aws/cognito-identity/CognitoIdentityClient.h>
|
||||
#include <aws/identity-management/auth/CognitoCachingCredentialsProvider.h>
|
||||
#include <aws/identity-management/auth/PersistentCognitoIdentityProvider.h>
|
||||
|
||||
namespace AWSClientAuth
|
||||
{
|
||||
//! Cognito Caching Credentials Provider implementation that is derived from AWS Native SDK.
|
||||
//! For use with authenticated credentials.
|
||||
class AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider
|
||||
: public Aws::Auth::CognitoCachingCredentialsProvider
|
||||
{
|
||||
public:
|
||||
AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider(
|
||||
const std::shared_ptr<Aws::Auth::PersistentCognitoIdentityProvider>& identityRepository,
|
||||
const std::shared_ptr<Aws::CognitoIdentity::CognitoIdentityClient>& cognitoIdentityClient = nullptr);
|
||||
|
||||
protected:
|
||||
Aws::CognitoIdentity::Model::GetCredentialsForIdentityOutcome GetCredentialsFromCognito() const override;
|
||||
};
|
||||
|
||||
//! Cognito Caching Credentials Provider implementation that is eventually derived from AWS Native SDK.
|
||||
//! For use with anonymous credentials.
|
||||
class AWSClientAuthCachingAnonymousCredsProvider : public AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider
|
||||
{
|
||||
public:
|
||||
AWSClientAuthCachingAnonymousCredsProvider(
|
||||
const std::shared_ptr<Aws::Auth::PersistentCognitoIdentityProvider>& identityRepository,
|
||||
const std::shared_ptr<Aws::CognitoIdentity::CognitoIdentityClient>& cognitoIdentityClient = nullptr);
|
||||
|
||||
protected:
|
||||
Aws::CognitoIdentity::Model::GetCredentialsForIdentityOutcome GetCredentialsFromCognito() const override;
|
||||
};
|
||||
|
||||
} // namespace AWSClientAuth
|
||||
+3
-2
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Authorization/AWSCognitoAuthorizationBus.h>
|
||||
#include <Authorization/AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.h>
|
||||
#include <Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h>
|
||||
#include <Authentication/AuthenticationProviderBus.h>
|
||||
#include <Credential/AWSCredentialBus.h>
|
||||
@@ -51,8 +52,8 @@ namespace AWSClientAuth
|
||||
|
||||
std::shared_ptr<AWSClientAuthPersistentCognitoIdentityProvider> m_persistentCognitoIdentityProvider;
|
||||
std::shared_ptr<AWSClientAuthPersistentCognitoIdentityProvider> m_persistentAnonymousCognitoIdentityProvider;
|
||||
std::shared_ptr<Aws::Auth::CognitoCachingAuthenticatedCredentialsProvider> m_cognitoCachingCredentialsProvider;
|
||||
std::shared_ptr<Aws::Auth::CognitoCachingAnonymousCredentialsProvider> m_cognitoCachingAnonymousCredentialsProvider;
|
||||
std::shared_ptr<AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider> m_cognitoCachingCredentialsProvider;
|
||||
std::shared_ptr<AWSClientAuthCachingAnonymousCredsProvider> m_cognitoCachingAnonymousCredentialsProvider;
|
||||
|
||||
AZStd::string m_cognitoIdentityPoolId;
|
||||
AZStd::string m_formattedCognitoUserPoolId;
|
||||
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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 <Authorization/AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.h>
|
||||
|
||||
#include <AzCore/Debug/Trace.h>
|
||||
|
||||
#include <aws/cognito-identity/CognitoIdentityClient.h>
|
||||
#include <aws/cognito-identity/model/GetCredentialsForIdentityRequest.h>
|
||||
#include <aws/cognito-identity/model/GetIdRequest.h>
|
||||
#include <aws/core/utils/Outcome.h>
|
||||
#include <aws/core/utils/logging/LogMacros.h>
|
||||
#include <aws/identity-management/auth/CognitoCachingCredentialsProvider.h>
|
||||
#include <aws/identity-management/auth/PersistentCognitoIdentityProvider.h>
|
||||
|
||||
|
||||
namespace AWSClientAuth
|
||||
{
|
||||
static const char* AUTH_LOG_TAG = "AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider";
|
||||
static const char* ANON_LOG_TAG = "AWSClientAuthCachingAnonymousCredsProvider";
|
||||
|
||||
// Modification of https://github.com/aws/aws-sdk-cpp/blob/main/aws-cpp-sdk-identity-management/source/auth/CognitoCachingCredentialsProvider.cpp#L92
|
||||
// to work around account ID requirement. Account id is not required for call to succeed and is not set unless provided.
|
||||
// see: https://github.com/aws/aws-sdk-cpp/issues/1448
|
||||
Aws::CognitoIdentity::Model::GetCredentialsForIdentityOutcome FetchCredsFromCognito(
|
||||
const Aws::CognitoIdentity::CognitoIdentityClient& cognitoIdentityClient,
|
||||
Aws::Auth::PersistentCognitoIdentityProvider& identityRepository,
|
||||
const char* logTag,
|
||||
bool includeLogins)
|
||||
{
|
||||
auto logins = identityRepository.GetLogins();
|
||||
Aws::Map<Aws::String, Aws::String> cognitoLogins;
|
||||
for (auto& login : logins)
|
||||
{
|
||||
cognitoLogins[login.first] = login.second.accessToken;
|
||||
}
|
||||
|
||||
if (!identityRepository.HasIdentityId())
|
||||
{
|
||||
auto accountId = identityRepository.GetAccountId();
|
||||
auto identityPoolId = identityRepository.GetIdentityPoolId();
|
||||
|
||||
Aws::CognitoIdentity::Model::GetIdRequest getIdRequest;
|
||||
getIdRequest.SetIdentityPoolId(identityPoolId);
|
||||
|
||||
if (!accountId.empty()) // new check
|
||||
{
|
||||
getIdRequest.SetAccountId(accountId);
|
||||
AWS_LOGSTREAM_INFO(logTag, "Identity not found, requesting an id for accountId "
|
||||
<< accountId << " identity pool id "
|
||||
<< identityPoolId << " with logins.");
|
||||
}
|
||||
else
|
||||
{
|
||||
AWS_LOGSTREAM_INFO(
|
||||
logTag, "Identity not found, requesting an id for identity pool id %s" << identityPoolId << " with logins.");
|
||||
}
|
||||
if (includeLogins)
|
||||
{
|
||||
getIdRequest.SetLogins(cognitoLogins);
|
||||
}
|
||||
|
||||
auto getIdOutcome = cognitoIdentityClient.GetId(getIdRequest);
|
||||
if (getIdOutcome.IsSuccess())
|
||||
{
|
||||
auto identityId = getIdOutcome.GetResult().GetIdentityId();
|
||||
AWS_LOGSTREAM_INFO(logTag, "Successfully retrieved identity: " << identityId);
|
||||
identityRepository.PersistIdentityId(identityId);
|
||||
}
|
||||
else
|
||||
{
|
||||
AWS_LOGSTREAM_ERROR(
|
||||
logTag,
|
||||
"Failed to retrieve identity. Error: " << getIdOutcome.GetError().GetExceptionName() << " "
|
||||
<< getIdOutcome.GetError().GetMessage());
|
||||
return Aws::CognitoIdentity::Model::GetCredentialsForIdentityOutcome(getIdOutcome.GetError());
|
||||
}
|
||||
}
|
||||
|
||||
Aws::CognitoIdentity::Model::GetCredentialsForIdentityRequest getCredentialsForIdentityRequest;
|
||||
getCredentialsForIdentityRequest.SetIdentityId(identityRepository.GetIdentityId());
|
||||
if (includeLogins)
|
||||
{
|
||||
getCredentialsForIdentityRequest.SetLogins(cognitoLogins);
|
||||
}
|
||||
|
||||
return cognitoIdentityClient.GetCredentialsForIdentity(getCredentialsForIdentityRequest);
|
||||
}
|
||||
|
||||
AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider::AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider(
|
||||
const std::shared_ptr<Aws::Auth::PersistentCognitoIdentityProvider>& identityRepository,
|
||||
const std::shared_ptr<Aws::CognitoIdentity::CognitoIdentityClient>& cognitoIdentityClient)
|
||||
: CognitoCachingCredentialsProvider(identityRepository, cognitoIdentityClient)
|
||||
{
|
||||
}
|
||||
|
||||
Aws::CognitoIdentity::Model::GetCredentialsForIdentityOutcome
|
||||
AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider::GetCredentialsFromCognito() const
|
||||
{
|
||||
return FetchCredsFromCognito(*m_cognitoIdentityClient, *m_identityRepository, AUTH_LOG_TAG, true);
|
||||
}
|
||||
|
||||
AWSClientAuthCachingAnonymousCredsProvider::AWSClientAuthCachingAnonymousCredsProvider(
|
||||
const std::shared_ptr<Aws::Auth::PersistentCognitoIdentityProvider>& identityRepository,
|
||||
const std::shared_ptr<Aws::CognitoIdentity::CognitoIdentityClient>& cognitoIdentityClient)
|
||||
: AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider(identityRepository, cognitoIdentityClient)
|
||||
{
|
||||
}
|
||||
|
||||
Aws::CognitoIdentity::Model::GetCredentialsForIdentityOutcome AWSClientAuthCachingAnonymousCredsProvider::
|
||||
GetCredentialsFromCognito() const
|
||||
{
|
||||
return FetchCredsFromCognito(*m_cognitoIdentityClient, *m_identityRepository, ANON_LOG_TAG, false);
|
||||
}
|
||||
|
||||
|
||||
} // namespace AWSClientAuth
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AWSClientAuthBus.h>
|
||||
#include <AWSCoreBus.h>
|
||||
#include <Authorization/AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.h>
|
||||
#include <Authorization/AWSCognitoAuthorizationController.h>
|
||||
#include <ResourceMapping/AWSResourceMappingBus.h>
|
||||
#include <AWSClientAuthResourceMappingConstants.h>
|
||||
@@ -38,10 +39,12 @@ namespace AWSClientAuth
|
||||
auto identityClient = AZ::Interface<IAWSClientAuthRequests>::Get()->GetCognitoIdentityClient();
|
||||
|
||||
m_cognitoCachingCredentialsProvider =
|
||||
std::make_shared<Aws::Auth::CognitoCachingAuthenticatedCredentialsProvider>(m_persistentCognitoIdentityProvider, identityClient);
|
||||
std::make_shared<AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider>(
|
||||
m_persistentCognitoIdentityProvider, identityClient);
|
||||
|
||||
m_cognitoCachingAnonymousCredentialsProvider =
|
||||
std::make_shared<Aws::Auth::CognitoCachingAnonymousCredentialsProvider>(m_persistentAnonymousCognitoIdentityProvider, identityClient);
|
||||
std::make_shared<AWSClientAuthCachingAnonymousCredsProvider>(
|
||||
m_persistentAnonymousCognitoIdentityProvider, identityClient);
|
||||
}
|
||||
|
||||
AWSCognitoAuthorizationController::~AWSCognitoAuthorizationController()
|
||||
@@ -65,9 +68,13 @@ namespace AWSClientAuth
|
||||
AWSCore::AWSResourceMappingRequestBus::BroadcastResult(
|
||||
m_cognitoIdentityPoolId, &AWSCore::AWSResourceMappingRequests::GetResourceNameId, CognitoIdentityPoolIdResourceMappingKey);
|
||||
|
||||
if (m_awsAccountId.empty() || m_cognitoIdentityPoolId.empty())
|
||||
if (m_awsAccountId.empty())
|
||||
{
|
||||
AZ_TracePrintf("AWSCognitoAuthorizationController", "AWS account id not not configured. Proceeding without it.");
|
||||
}
|
||||
|
||||
if (m_cognitoIdentityPoolId.empty())
|
||||
{
|
||||
AZ_Warning("AWSCognitoAuthorizationController", !m_awsAccountId.empty(), "Missing AWS account id not configured.");
|
||||
AZ_Warning("AWSCognitoAuthorizationController", !m_cognitoIdentityPoolId.empty(), "Missing Cognito Identity pool id in resource mappings.");
|
||||
return false;
|
||||
}
|
||||
|
||||
+10
-10
@@ -62,6 +62,14 @@ TEST_F(AWSCognitoAuthorizationControllerTest, Initialize_Success)
|
||||
ASSERT_TRUE(m_mockController->m_cognitoIdentityPoolId == AWSClientAuthUnitTest::TEST_RESOURCE_NAME_ID);
|
||||
}
|
||||
|
||||
TEST_F(AWSCognitoAuthorizationControllerTest, Initialize_Success_GetAWSAccountEmpty)
|
||||
{
|
||||
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetResourceNameId(testing::_)).Times(2);
|
||||
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetDefaultAccountId()).Times(1).WillOnce(testing::Return(""));
|
||||
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetDefaultRegion()).Times(1);
|
||||
ASSERT_TRUE(m_mockController->Initialize());
|
||||
}
|
||||
|
||||
TEST_F(AWSCognitoAuthorizationControllerTest, RequestAWSCredentials_WithLogins_Success)
|
||||
{
|
||||
AWSClientAuth::AuthenticationTokens tokens(
|
||||
@@ -121,7 +129,7 @@ TEST_F(AWSCognitoAuthorizationControllerTest, MultipleCalls_UsesCacheCredentials
|
||||
m_mockController->RequestAWSCredentialsAsync();
|
||||
}
|
||||
|
||||
TEST_F(AWSCognitoAuthorizationControllerTest, RequestAWSCredentials_Fail_GetIdError)
|
||||
TEST_F(AWSCognitoAuthorizationControllerTest, RequestAWSCredentials_Fail_GetIdError) // fail
|
||||
{
|
||||
AWSClientAuth::AuthenticationTokens cognitoTokens(
|
||||
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
|
||||
@@ -325,7 +333,7 @@ TEST_F(AWSCognitoAuthorizationControllerTest, GetCredentialsProvider_NoPersisted
|
||||
EXPECT_TRUE(actualCredentialsProvider == m_mockController->m_cognitoCachingAnonymousCredentialsProvider);
|
||||
}
|
||||
|
||||
TEST_F(AWSCognitoAuthorizationControllerTest, GetCredentialsProvider_NoPersistedLogins_NoAnonymousCredentials_ResultNullPtr)
|
||||
TEST_F(AWSCognitoAuthorizationControllerTest, GetCredentialsProvider_NoPersistedLogins_NoAnonymousCredentials_ResultNullPtr) // fails
|
||||
{
|
||||
Aws::Client::AWSError<Aws::CognitoIdentity::CognitoIdentityErrors> error;
|
||||
error.SetExceptionName(AWSClientAuthUnitTest::TEST_EXCEPTION);
|
||||
@@ -437,11 +445,3 @@ TEST_F(AWSCognitoAuthorizationControllerTest, Initialize_Fail_GetResourceNameEmp
|
||||
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetDefaultAccountId()).Times(1);
|
||||
ASSERT_FALSE(m_mockController->Initialize());
|
||||
}
|
||||
|
||||
TEST_F(AWSCognitoAuthorizationControllerTest, Initialize_Fail_GetAWSAccountEmpty)
|
||||
{
|
||||
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetResourceNameId(testing::_)).Times(1);
|
||||
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetDefaultAccountId()).Times(1).WillOnce(testing::Return(""));
|
||||
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetDefaultRegion()).Times(0);
|
||||
ASSERT_FALSE(m_mockController->Initialize());
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ set(FILES
|
||||
Include/Private/Authorization/AWSCognitoAuthorizationController.h
|
||||
Include/Private/Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h
|
||||
Include/Private/Authorization/AWSCognitoAuthorizationNotificationBusBehaviorHandler.h
|
||||
Include/Private/Authorization/AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.h
|
||||
|
||||
Include/Private/UserManagement/AWSCognitoUserManagementController.h
|
||||
Include/Private/UserManagement/UserManagementNotificationBusBehaviorHandler.h
|
||||
@@ -45,6 +46,7 @@ set(FILES
|
||||
Source/Authorization/ClientAuthAWSCredentials.cpp
|
||||
Source/Authorization/AWSCognitoAuthorizationController.cpp
|
||||
Source/Authorization/AWSClientAuthPersistentCognitoIdentityProvider.cpp
|
||||
Source/Authorization/AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.cpp
|
||||
|
||||
Source/UserManagement/AWSCognitoUserManagementController.cpp
|
||||
)
|
||||
|
||||
@@ -84,7 +84,7 @@ static constexpr const char TEST_VALID_EMPTY_ACCOUNTID_RESOURCE_MAPPING_CONFIG_F
|
||||
},
|
||||
"AccountId": "",
|
||||
"Region": "us-west-2",
|
||||
"Version": "1.0.0"
|
||||
"Version": "1.1.0"
|
||||
})";
|
||||
|
||||
static constexpr const char TEST_INVALID_RESOURCE_MAPPING_CONFIG_FILE[] =
|
||||
|
||||
@@ -24,7 +24,7 @@ _RESOURCE_MAPPING_TYPE_JSON_KEY_NAME: str = "Type"
|
||||
_RESOURCE_MAPPING_NAMEID_JSON_KEY_NAME: str = "Name/ID"
|
||||
_RESOURCE_MAPPING_REGION_JSON_KEY_NAME: str = "Region"
|
||||
_RESOURCE_MAPPING_VERSION_JSON_KEY_NAME: str = "Version"
|
||||
_RESOURCE_MAPPING_JSON_FORMAT_VERSION: str = "1.0.0"
|
||||
_RESOURCE_MAPPING_JSON_FORMAT_VERSION: str = "1.1.0"
|
||||
|
||||
RESOURCE_MAPPING_ACCOUNTID_JSON_KEY_NAME: str = "AccountId"
|
||||
RESOURCE_MAPPING_ACCOUNTID_TEMPLATE_VALUE: str = "EMPTY"
|
||||
|
||||
-50
@@ -7,16 +7,6 @@
|
||||
"UUID": "{08A95286-ADB2-41E4-96EB-DB48F4726D6A}",
|
||||
"Name": "Albedo",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_basecolor",
|
||||
"_diff",
|
||||
"_color",
|
||||
"_col",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "BC1",
|
||||
"DiscardAlpha": true,
|
||||
"IsPowerOf2": true,
|
||||
@@ -29,16 +19,6 @@
|
||||
"UUID": "{08A95286-ADB2-41E4-96EB-DB48F4726D6A}",
|
||||
"Name": "Albedo",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_diff",
|
||||
"_color",
|
||||
"_col",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_basecolor",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "ASTC_6x6",
|
||||
"MaxTextureSize": 2048,
|
||||
"DiscardAlpha": true,
|
||||
@@ -51,16 +31,6 @@
|
||||
"UUID": "{08A95286-ADB2-41E4-96EB-DB48F4726D6A}",
|
||||
"Name": "Albedo",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_diff",
|
||||
"_color",
|
||||
"_col",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_basecolor",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "ASTC_6x6",
|
||||
"MaxTextureSize": 2048,
|
||||
"DiscardAlpha": true,
|
||||
@@ -73,16 +43,6 @@
|
||||
"UUID": "{08A95286-ADB2-41E4-96EB-DB48F4726D6A}",
|
||||
"Name": "Albedo",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_diff",
|
||||
"_color",
|
||||
"_col",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_basecolor",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "BC1",
|
||||
"DiscardAlpha": true,
|
||||
"IsPowerOf2": true,
|
||||
@@ -94,16 +54,6 @@
|
||||
"UUID": "{08A95286-ADB2-41E4-96EB-DB48F4726D6A}",
|
||||
"Name": "Albedo",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_diff",
|
||||
"_color",
|
||||
"_col",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_basecolor",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "BC1",
|
||||
"DiscardAlpha": true,
|
||||
"IsPowerOf2": true,
|
||||
-45
@@ -7,15 +7,6 @@
|
||||
"UUID": "{57ED16B1-407B-4E29-BCFC-D3BAE60F2C85}",
|
||||
"Name": "AlbedoWithCoverage",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_diff",
|
||||
"_color",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_basecolor",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "BC1a",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
@@ -27,15 +18,6 @@
|
||||
"UUID": "{57ED16B1-407B-4E29-BCFC-D3BAE60F2C85}",
|
||||
"Name": "AlbedoWithCoverage",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_diff",
|
||||
"_color",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_basecolor",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "ASTC_6x6",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
@@ -46,15 +28,6 @@
|
||||
"UUID": "{57ED16B1-407B-4E29-BCFC-D3BAE60F2C85}",
|
||||
"Name": "AlbedoWithCoverage",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_diff",
|
||||
"_color",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_basecolor",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "ASTC_6x6",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
@@ -65,15 +38,6 @@
|
||||
"UUID": "{57ED16B1-407B-4E29-BCFC-D3BAE60F2C85}",
|
||||
"Name": "AlbedoWithCoverage",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_diff",
|
||||
"_color",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_basecolor",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "BC1a",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
@@ -84,15 +48,6 @@
|
||||
"UUID": "{57ED16B1-407B-4E29-BCFC-D3BAE60F2C85}",
|
||||
"Name": "AlbedoWithCoverage",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_diff",
|
||||
"_color",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_basecolor",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "BC1a",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
+1
-51
@@ -7,17 +7,7 @@
|
||||
"UUID": "{5D9ECB52-4CD9-4CB8-80E3-10CAE5EFB8A2}",
|
||||
"Name": "AlbedoWithGenericAlpha",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_diff",
|
||||
"_color",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_basecolor",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "BC3",
|
||||
"IsPowerOf2": true,
|
||||
"PixelFormat": "ASTC_4x4",
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
@@ -27,18 +17,8 @@
|
||||
"UUID": "{5D9ECB52-4CD9-4CB8-80E3-10CAE5EFB8A2}",
|
||||
"Name": "AlbedoWithGenericAlpha",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_diff",
|
||||
"_color",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_basecolor",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "ASTC_6x6",
|
||||
"MaxTextureSize": 2048,
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
@@ -47,18 +27,8 @@
|
||||
"UUID": "{5D9ECB52-4CD9-4CB8-80E3-10CAE5EFB8A2}",
|
||||
"Name": "AlbedoWithGenericAlpha",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_diff",
|
||||
"_color",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_basecolor",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "ASTC_6x6",
|
||||
"MaxTextureSize": 2048,
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
@@ -67,17 +37,7 @@
|
||||
"UUID": "{5D9ECB52-4CD9-4CB8-80E3-10CAE5EFB8A2}",
|
||||
"Name": "AlbedoWithGenericAlpha",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_diff",
|
||||
"_color",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_basecolor",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "BC3",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
@@ -86,17 +46,7 @@
|
||||
"UUID": "{5D9ECB52-4CD9-4CB8-80E3-10CAE5EFB8A2}",
|
||||
"Name": "AlbedoWithGenericAlpha",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_diff",
|
||||
"_color",
|
||||
"_albedo",
|
||||
"_alb",
|
||||
"_basecolor",
|
||||
"_bc",
|
||||
"_diffuse"
|
||||
],
|
||||
"PixelFormat": "BC3",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
-30
@@ -8,12 +8,6 @@
|
||||
"Name": "AmbientOcclusion",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ao",
|
||||
"_ambocc",
|
||||
"_amb",
|
||||
"_ambientocclusion"
|
||||
],
|
||||
"PixelFormat": "BC4"
|
||||
},
|
||||
"PlatformsPresets": {
|
||||
@@ -22,12 +16,6 @@
|
||||
"Name": "AmbientOcclusion",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ao",
|
||||
"_ambocc",
|
||||
"_amb",
|
||||
"_ambientocclusion"
|
||||
],
|
||||
"MaxTextureSize": 2048,
|
||||
"PixelFormat": "ASTC_4x4"
|
||||
},
|
||||
@@ -36,12 +24,6 @@
|
||||
"Name": "AmbientOcclusion",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ao",
|
||||
"_ambocc",
|
||||
"_amb",
|
||||
"_ambientocclusion"
|
||||
],
|
||||
"MaxTextureSize": 2048,
|
||||
"PixelFormat": "ASTC_4x4"
|
||||
},
|
||||
@@ -50,12 +32,6 @@
|
||||
"Name": "AmbientOcclusion",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ao",
|
||||
"_ambocc",
|
||||
"_amb",
|
||||
"_ambientocclusion"
|
||||
],
|
||||
"PixelFormat": "BC4"
|
||||
},
|
||||
"provo": {
|
||||
@@ -63,12 +39,6 @@
|
||||
"Name": "AmbientOcclusion",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ao",
|
||||
"_ambocc",
|
||||
"_amb",
|
||||
"_ambientocclusion"
|
||||
],
|
||||
"PixelFormat": "BC4"
|
||||
}
|
||||
}
|
||||
-20
@@ -8,10 +8,6 @@
|
||||
"Name": "ConvolvedCubemap",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ccm",
|
||||
"_convolvedcubemap"
|
||||
],
|
||||
"SuppressEngineReduce": true,
|
||||
"PixelFormat": "R9G9B9E5",
|
||||
"DiscardAlpha": true,
|
||||
@@ -35,10 +31,6 @@
|
||||
"Name": "ConvolvedCubemap",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ccm",
|
||||
"_convolvedcubemap"
|
||||
],
|
||||
"SuppressEngineReduce": true,
|
||||
"PixelFormat": "R9G9B9E5",
|
||||
"DiscardAlpha": true,
|
||||
@@ -61,10 +53,6 @@
|
||||
"Name": "ConvolvedCubemap",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ccm",
|
||||
"_convolvedcubemap"
|
||||
],
|
||||
"SuppressEngineReduce": true,
|
||||
"PixelFormat": "R9G9B9E5",
|
||||
"DiscardAlpha": true,
|
||||
@@ -87,10 +75,6 @@
|
||||
"Name": "ConvolvedCubemap",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ccm",
|
||||
"_convolvedcubemap"
|
||||
],
|
||||
"SuppressEngineReduce": true,
|
||||
"PixelFormat": "R9G9B9E5",
|
||||
"DiscardAlpha": true,
|
||||
@@ -113,10 +97,6 @@
|
||||
"Name": "ConvolvedCubemap",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ccm",
|
||||
"_convolvedcubemap"
|
||||
],
|
||||
"SuppressEngineReduce": true,
|
||||
"PixelFormat": "R9G9B9E5",
|
||||
"DiscardAlpha": true,
|
||||
-15
@@ -6,9 +6,6 @@
|
||||
"DefaultPreset": {
|
||||
"UUID": "{E06B5087-2640-49B6-B9BA-D40048162B90}",
|
||||
"Name": "Decal_AlbedoWithOpacity",
|
||||
"FileMasks": [
|
||||
"_decal"
|
||||
],
|
||||
"PixelFormat": "BC7t",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
@@ -21,9 +18,6 @@
|
||||
"android": {
|
||||
"UUID": "{E06B5087-2640-49B6-B9BA-D40048162B90}",
|
||||
"Name": "Decal_AlbedoWithOpacity",
|
||||
"FileMasks": [
|
||||
"_decal"
|
||||
],
|
||||
"PixelFormat": "ASTC_4x4",
|
||||
"MaxTextureSize": 2048,
|
||||
"IsPowerOf2": true,
|
||||
@@ -36,9 +30,6 @@
|
||||
"ios": {
|
||||
"UUID": "{E06B5087-2640-49B6-B9BA-D40048162B90}",
|
||||
"Name": "Decal_AlbedoWithOpacity",
|
||||
"FileMasks": [
|
||||
"_decal"
|
||||
],
|
||||
"PixelFormat": "ASTC_4x4",
|
||||
"MaxTextureSize": 2048,
|
||||
"IsPowerOf2": true,
|
||||
@@ -51,9 +42,6 @@
|
||||
"mac": {
|
||||
"UUID": "{E06B5087-2640-49B6-B9BA-D40048162B90}",
|
||||
"Name": "Decal_AlbedoWithOpacity",
|
||||
"FileMasks": [
|
||||
"_decal"
|
||||
],
|
||||
"PixelFormat": "BC3",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
@@ -65,9 +53,6 @@
|
||||
"provo": {
|
||||
"UUID": "{E06B5087-2640-49B6-B9BA-D40048162B90}",
|
||||
"Name": "Decal_AlbedoWithOpacity",
|
||||
"FileMasks": [
|
||||
"_decal"
|
||||
],
|
||||
"PixelFormat": "BC7t",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
-60
@@ -8,18 +8,6 @@
|
||||
"Name": "Displacement",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_displ",
|
||||
"_disp",
|
||||
"_dsp",
|
||||
"_d",
|
||||
"_dm",
|
||||
"_displacement",
|
||||
"_height",
|
||||
"_hm",
|
||||
"_ht",
|
||||
"_h"
|
||||
],
|
||||
"PixelFormat": "BC4",
|
||||
"DiscardAlpha": true,
|
||||
"IsPowerOf2": true,
|
||||
@@ -33,18 +21,6 @@
|
||||
"Name": "Displacement",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_displ",
|
||||
"_disp",
|
||||
"_dsp",
|
||||
"_d",
|
||||
"_dm",
|
||||
"_displacement",
|
||||
"_height",
|
||||
"_hm",
|
||||
"_ht",
|
||||
"_h"
|
||||
],
|
||||
"PixelFormat": "ASTC_4x4",
|
||||
"MaxTextureSize": 2048,
|
||||
"DiscardAlpha": true,
|
||||
@@ -59,18 +35,6 @@
|
||||
"Name": "Displacement",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_displ",
|
||||
"_disp",
|
||||
"_dsp",
|
||||
"_d",
|
||||
"_dm",
|
||||
"_displacement",
|
||||
"_height",
|
||||
"_hm",
|
||||
"_ht",
|
||||
"_h"
|
||||
],
|
||||
"PixelFormat": "ASTC_4x4",
|
||||
"MaxTextureSize": 2048,
|
||||
"DiscardAlpha": true,
|
||||
@@ -84,18 +48,6 @@
|
||||
"Name": "Displacement",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_displ",
|
||||
"_disp",
|
||||
"_dsp",
|
||||
"_d",
|
||||
"_dm",
|
||||
"_displacement",
|
||||
"_height",
|
||||
"_hm",
|
||||
"_ht",
|
||||
"_h"
|
||||
],
|
||||
"PixelFormat": "BC4",
|
||||
"DiscardAlpha": true,
|
||||
"IsPowerOf2": true,
|
||||
@@ -108,18 +60,6 @@
|
||||
"Name": "Displacement",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_displ",
|
||||
"_disp",
|
||||
"_dsp",
|
||||
"_d",
|
||||
"_dm",
|
||||
"_displacement",
|
||||
"_height",
|
||||
"_hm",
|
||||
"_ht",
|
||||
"_h"
|
||||
],
|
||||
"PixelFormat": "BC4",
|
||||
"DiscardAlpha": true,
|
||||
"IsPowerOf2": true,
|
||||
-35
@@ -7,13 +7,6 @@
|
||||
"UUID": "{07041D83-E0C3-4726-8735-CA0FE550C9A0}",
|
||||
"Name": "Emissive",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_emissive",
|
||||
"_e",
|
||||
"_glow",
|
||||
"_em",
|
||||
"_emit"
|
||||
],
|
||||
"PixelFormat": "BC7",
|
||||
"DiscardAlpha": true
|
||||
},
|
||||
@@ -22,13 +15,6 @@
|
||||
"UUID": "{07041D83-E0C3-4726-8735-CA0FE550C9A0}",
|
||||
"Name": "Emissive",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_emissive",
|
||||
"_e",
|
||||
"_glow",
|
||||
"_em",
|
||||
"_emit"
|
||||
],
|
||||
"PixelFormat": "ASTC_6x6",
|
||||
"MaxTextureSize": 2048,
|
||||
"DiscardAlpha": true
|
||||
@@ -37,13 +23,6 @@
|
||||
"UUID": "{07041D83-E0C3-4726-8735-CA0FE550C9A0}",
|
||||
"Name": "Emissive",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_emissive",
|
||||
"_e",
|
||||
"_glow",
|
||||
"_em",
|
||||
"_emit"
|
||||
],
|
||||
"PixelFormat": "ASTC_6x6",
|
||||
"MaxTextureSize": 2048,
|
||||
"DiscardAlpha": true
|
||||
@@ -52,13 +31,6 @@
|
||||
"UUID": "{07041D83-E0C3-4726-8735-CA0FE550C9A0}",
|
||||
"Name": "Emissive",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_emissive",
|
||||
"_e",
|
||||
"_glow",
|
||||
"_em",
|
||||
"_emit"
|
||||
],
|
||||
"PixelFormat": "BC7",
|
||||
"DiscardAlpha": true
|
||||
},
|
||||
@@ -66,13 +38,6 @@
|
||||
"UUID": "{07041D83-E0C3-4726-8735-CA0FE550C9A0}",
|
||||
"Name": "Emissive",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"FileMasks": [
|
||||
"_emissive",
|
||||
"_e",
|
||||
"_glow",
|
||||
"_em",
|
||||
"_emit"
|
||||
],
|
||||
"PixelFormat": "BC7",
|
||||
"DiscardAlpha": true
|
||||
}
|
||||
+5
-20
@@ -8,11 +8,8 @@
|
||||
"Name": "Greyscale",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_mask"
|
||||
],
|
||||
"PixelFormat": "BC4",
|
||||
"IsPowerOf2": true,
|
||||
"Swizzle": "rrr1",
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
@@ -23,11 +20,8 @@
|
||||
"Name": "Greyscale",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_mask"
|
||||
],
|
||||
"PixelFormat": "ASTC_4x4",
|
||||
"IsPowerOf2": true,
|
||||
"Swizzle": "rrr1",
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
@@ -37,11 +31,8 @@
|
||||
"Name": "Greyscale",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_mask"
|
||||
],
|
||||
"PixelFormat": "ASTC_4x4",
|
||||
"IsPowerOf2": true,
|
||||
"Swizzle": "rrr1",
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
@@ -51,11 +42,8 @@
|
||||
"Name": "Greyscale",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_mask"
|
||||
],
|
||||
"PixelFormat": "BC4",
|
||||
"IsPowerOf2": true,
|
||||
"Swizzle": "rrr1",
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
@@ -65,11 +53,8 @@
|
||||
"Name": "Greyscale",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_mask"
|
||||
],
|
||||
"PixelFormat": "BC4",
|
||||
"IsPowerOf2": true,
|
||||
"Swizzle": "rrr1",
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
-15
@@ -7,9 +7,6 @@
|
||||
"UUID": "{E3706342-BF21-4D9C-AE28-9670EB3EF3C5}",
|
||||
"Name": "IBLDiffuse",
|
||||
"Description": "The input cubemap generates an IBL diffuse output cubemap.",
|
||||
"FileMasks": [
|
||||
"_ibldiffusecm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -31,9 +28,6 @@
|
||||
"android": {
|
||||
"UUID": "{E3706342-BF21-4D9C-AE28-9670EB3EF3C5}",
|
||||
"Name": "IBLDiffuse",
|
||||
"FileMasks": [
|
||||
"_ibldiffusecm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -54,9 +48,6 @@
|
||||
"ios": {
|
||||
"UUID": "{E3706342-BF21-4D9C-AE28-9670EB3EF3C5}",
|
||||
"Name": "IBLDiffuse",
|
||||
"FileMasks": [
|
||||
"_ibldiffusecm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -77,9 +68,6 @@
|
||||
"mac": {
|
||||
"UUID": "{E3706342-BF21-4D9C-AE28-9670EB3EF3C5}",
|
||||
"Name": "IBLDiffuse",
|
||||
"FileMasks": [
|
||||
"_ibldiffusecm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -100,9 +88,6 @@
|
||||
"provo": {
|
||||
"UUID": "{E3706342-BF21-4D9C-AE28-9670EB3EF3C5}",
|
||||
"Name": "IBLDiffuse",
|
||||
"FileMasks": [
|
||||
"_ibldiffusecm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
-5
@@ -8,11 +8,6 @@
|
||||
"Name": "IBLGlobal",
|
||||
"Description": "The input cubemap generates IBL specular and diffuse cubemaps.",
|
||||
"GenerateIBLOnly": true,
|
||||
"FileMasks": [
|
||||
"_iblglobalcm",
|
||||
"_cubemap",
|
||||
"_cm"
|
||||
],
|
||||
"CubemapSettings": {
|
||||
"GenerateIBLSpecular": true,
|
||||
"IBLSpecularPreset": "IBLSpecular",
|
||||
-15
@@ -7,9 +7,6 @@
|
||||
"UUID": "{E6441EAC-9843-484B-8EFC-C03B2935B48D}",
|
||||
"Name": "IBLSkybox",
|
||||
"Description": "The input cubemap generates a skybox, IBL specular, and IBL diffuse output cubemaps.",
|
||||
"FileMasks": [
|
||||
"_iblskyboxcm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -29,9 +26,6 @@
|
||||
"android": {
|
||||
"UUID": "{E6441EAC-9843-484B-8EFC-C03B2935B48D}",
|
||||
"Name": "IBLSkybox",
|
||||
"FileMasks": [
|
||||
"_iblskyboxcm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -50,9 +44,6 @@
|
||||
"ios": {
|
||||
"UUID": "{E6441EAC-9843-484B-8EFC-C03B2935B48D}",
|
||||
"Name": "IBLSkybox",
|
||||
"FileMasks": [
|
||||
"_iblskyboxcm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -71,9 +62,6 @@
|
||||
"mac": {
|
||||
"UUID": "{E6441EAC-9843-484B-8EFC-C03B2935B48D}",
|
||||
"Name": "IBLSkybox",
|
||||
"FileMasks": [
|
||||
"_iblskyboxcm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -92,9 +80,6 @@
|
||||
"provo": {
|
||||
"UUID": "{E6441EAC-9843-484B-8EFC-C03B2935B48D}",
|
||||
"Name": "IBLSkybox",
|
||||
"FileMasks": [
|
||||
"_iblskyboxcm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
-20
@@ -7,10 +7,6 @@
|
||||
"UUID": "{908DA68C-97FB-4C4A-97BC-5A55F30F14FA}",
|
||||
"Name": "IBLSpecular",
|
||||
"Description": "The input cubemap generates an IBL specular output cubemap.",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm",
|
||||
"_iblspecularcm256"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -34,10 +30,6 @@
|
||||
"android": {
|
||||
"UUID": "{908DA68C-97FB-4C4A-97BC-5A55F30F14FA}",
|
||||
"Name": "IBLSpecular",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm",
|
||||
"_iblspecularcm256"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -60,10 +52,6 @@
|
||||
"ios": {
|
||||
"UUID": "{908DA68C-97FB-4C4A-97BC-5A55F30F14FA}",
|
||||
"Name": "IBLSpecular",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm",
|
||||
"_iblspecularcm256"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -86,10 +74,6 @@
|
||||
"mac": {
|
||||
"UUID": "{908DA68C-97FB-4C4A-97BC-5A55F30F14FA}",
|
||||
"Name": "IBLSpecular",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm",
|
||||
"_iblspecularcm256"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -112,10 +96,6 @@
|
||||
"provo": {
|
||||
"UUID": "{908DA68C-97FB-4C4A-97BC-5A55F30F14FA}",
|
||||
"Name": "IBLSpecular",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm",
|
||||
"_iblspecularcm256"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
-15
@@ -7,9 +7,6 @@
|
||||
"UUID": "{B66395E1-8D0E-4159-989B-FC2B9F091B75}",
|
||||
"Name": "IBLSpecularHigh",
|
||||
"Description": "The input cubemap generates an IBL specular output cubemap.",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm512"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -33,9 +30,6 @@
|
||||
"android": {
|
||||
"UUID": "{B66395E1-8D0E-4159-989B-FC2B9F091B75}",
|
||||
"Name": "IBLSpecularHigh",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm512"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -58,9 +52,6 @@
|
||||
"ios": {
|
||||
"UUID": "{B66395E1-8D0E-4159-989B-FC2B9F091B75}",
|
||||
"Name": "IBLSpecularHigh",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm512"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -83,9 +74,6 @@
|
||||
"mac": {
|
||||
"UUID": "{B66395E1-8D0E-4159-989B-FC2B9F091B75}",
|
||||
"Name": "IBLSpecularHigh",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm512"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -108,9 +96,6 @@
|
||||
"provo": {
|
||||
"UUID": "{B66395E1-8D0E-4159-989B-FC2B9F091B75}",
|
||||
"Name": "IBLSpecularHigh",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm512"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
-15
@@ -7,9 +7,6 @@
|
||||
"UUID": "{7273ACAE-6E34-487C-AF71-99423A6E1CB0}",
|
||||
"Name": "IBLSpecularLow",
|
||||
"Description": "The input cubemap generates an IBL specular output cubemap.",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm128"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -33,9 +30,6 @@
|
||||
"android": {
|
||||
"UUID": "{7273ACAE-6E34-487C-AF71-99423A6E1CB0}",
|
||||
"Name": "IBLSpecularLow",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm128"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -58,9 +52,6 @@
|
||||
"ios": {
|
||||
"UUID": "{7273ACAE-6E34-487C-AF71-99423A6E1CB0}",
|
||||
"Name": "IBLSpecularLow",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm128"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -83,9 +74,6 @@
|
||||
"mac": {
|
||||
"UUID": "{7273ACAE-6E34-487C-AF71-99423A6E1CB0}",
|
||||
"Name": "IBLSpecularLow",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm128"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -108,9 +96,6 @@
|
||||
"provo": {
|
||||
"UUID": "{7273ACAE-6E34-487C-AF71-99423A6E1CB0}",
|
||||
"Name": "IBLSpecularLow",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm128"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
-15
@@ -7,9 +7,6 @@
|
||||
"UUID": "{5CD1AFA6-915B-4716-893C-A5B1F4074C22}",
|
||||
"Name": "IBLSpecularVeryHigh",
|
||||
"Description": "The input cubemap generates an IBL specular output cubemap.",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm1024"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -33,9 +30,6 @@
|
||||
"android": {
|
||||
"UUID": "{5CD1AFA6-915B-4716-893C-A5B1F4074C22}",
|
||||
"Name": "IBLSpecularVeryHigh",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm1024"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -58,9 +52,6 @@
|
||||
"ios": {
|
||||
"UUID": "{5CD1AFA6-915B-4716-893C-A5B1F4074C22}",
|
||||
"Name": "IBLSpecularVeryHigh",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm1024"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -83,9 +74,6 @@
|
||||
"mac": {
|
||||
"UUID": "{5CD1AFA6-915B-4716-893C-A5B1F4074C22}",
|
||||
"Name": "IBLSpecularVeryHigh",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm1024"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -108,9 +96,6 @@
|
||||
"provo": {
|
||||
"UUID": "{5CD1AFA6-915B-4716-893C-A5B1F4074C22}",
|
||||
"Name": "IBLSpecularVeryHigh",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm1024"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
-15
@@ -7,9 +7,6 @@
|
||||
"UUID": "{8293C236-D3E8-4352-8B18-C2E82EEE6547}",
|
||||
"Name": "IBLSpecularVeryLow",
|
||||
"Description": "The input cubemap generates an IBL specular output cubemap.",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm64"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -33,9 +30,6 @@
|
||||
"android": {
|
||||
"UUID": "{8293C236-D3E8-4352-8B18-C2E82EEE6547}",
|
||||
"Name": "IBLSpecularVeryLow",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm64"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -58,9 +52,6 @@
|
||||
"ios": {
|
||||
"UUID": "{8293C236-D3E8-4352-8B18-C2E82EEE6547}",
|
||||
"Name": "IBLSpecularVeryLow",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm64"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -83,9 +74,6 @@
|
||||
"mac": {
|
||||
"UUID": "{8293C236-D3E8-4352-8B18-C2E82EEE6547}",
|
||||
"Name": "IBLSpecularVeryLow",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm64"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -108,9 +96,6 @@
|
||||
"provo": {
|
||||
"UUID": "{8293C236-D3E8-4352-8B18-C2E82EEE6547}",
|
||||
"Name": "IBLSpecularVeryLow",
|
||||
"FileMasks": [
|
||||
"_iblspecularcm64"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -0,0 +1,154 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "BuilderSettingManager",
|
||||
"ClassData": {
|
||||
"BuildSettings": {
|
||||
"android": {
|
||||
"GlossScale": 16.0,
|
||||
"GlossBias": 0.0,
|
||||
"Streaming": false,
|
||||
"Enable": true
|
||||
},
|
||||
"ios": {
|
||||
"GlossScale": 16.0,
|
||||
"GlossBias": 0.0,
|
||||
"Streaming": false,
|
||||
"Enable": true
|
||||
},
|
||||
"mac": {
|
||||
"GlossScale": 16.0,
|
||||
"GlossBias": 0.0,
|
||||
"Streaming": false,
|
||||
"Enable": true
|
||||
},
|
||||
"pc": {
|
||||
"GlossScale": 16.0,
|
||||
"GlossBias": 0.0,
|
||||
"Streaming": false,
|
||||
"Enable": true
|
||||
},
|
||||
"linux": {
|
||||
"GlossScale": 16.0,
|
||||
"GlossBias": 0.0,
|
||||
"Streaming": false,
|
||||
"Enable": true
|
||||
},
|
||||
"provo": {
|
||||
"GlossScale": 16.0,
|
||||
"GlossBias": 0.0,
|
||||
"Streaming": false,
|
||||
"Enable": false
|
||||
}
|
||||
},
|
||||
"PresetsByFileMask": {
|
||||
// albedo
|
||||
"_basecolor": [ "Albedo", "AlbedoWithGenericAlpha", "AlbedoWithCoverage" ],
|
||||
"_diff": [ "Albedo", "AlbedoWithGenericAlpha", "AlbedoWithCoverage" ],
|
||||
"_diffuse": [ "Albedo", "AlbedoWithGenericAlpha", "AlbedoWithCoverage" ],
|
||||
"_color": [ "Albedo", "AlbedoWithGenericAlpha", "AlbedoWithCoverage" ],
|
||||
"_col": [ "Albedo", "AlbedoWithGenericAlpha", "AlbedoWithCoverage" ],
|
||||
"_albedo": [ "Albedo", "AlbedoWithGenericAlpha", "AlbedoWithCoverage" ],
|
||||
"_alb": [ "Albedo", "AlbedoWithGenericAlpha", "AlbedoWithCoverage" ],
|
||||
"_bc": [ "Albedo", "AlbedoWithGenericAlpha", "AlbedoWithCoverage" ],
|
||||
// normals
|
||||
"_ddn": [ "Normals" ],
|
||||
"_normal": [ "Normals" ],
|
||||
"_normalmap": [ "Normals" ],
|
||||
"_normals": [ "Normals" ],
|
||||
"_norm": [ "Normals" ],
|
||||
"_nor": [ "Normals" ],
|
||||
"_nrm": [ "Normals" ],
|
||||
"_nm": [ "Normals" ],
|
||||
"_n": [ "Normals" ],
|
||||
"_ddna": [ "NormalsWithSmoothness" ],
|
||||
"_normala": [ "NormalsWithSmoothness" ],
|
||||
"_nrma": [ "NormalsWithSmoothness" ],
|
||||
"_nma": [ "NormalsWithSmoothness" ],
|
||||
"_na": [ "NormalsWithSmoothness" ],
|
||||
// refelctance
|
||||
"_spec": [ "Reflectance" ],
|
||||
"_specular": [ "Reflectance" ],
|
||||
"_metallic": [ "Reflectance" ],
|
||||
"_refl": [ "Reflectance" ],
|
||||
"_ref": [ "Reflectance" ],
|
||||
"_rf": [ "Reflectance" ],
|
||||
"_gloss": [ "Reflectance" ],
|
||||
"_g": [ "Reflectance" ],
|
||||
"_f0": [ "Reflectance" ],
|
||||
"_specf0": [ "Reflectance" ],
|
||||
"_metal": [ "Reflectance" ],
|
||||
"_mtl": [ "Reflectance" ],
|
||||
"_m": [ "Reflectance" ],
|
||||
"_mt": [ "Reflectance" ],
|
||||
"_metalness": [ "Reflectance" ],
|
||||
"_rough": [ "Reflectance" ],
|
||||
"_roughness": [ "Reflectance" ],
|
||||
// opacity
|
||||
"_sss": [ "Opacity" ],
|
||||
"_trans": [ "Opacity" ],
|
||||
"_opac": [ "Opacity" ],
|
||||
"_opacity": [ "Opacity" ],
|
||||
"_o": [ "Opacity" ],
|
||||
"_op": [ "Opacity" ],
|
||||
"_mask": [ "Opacity", "Greyscale" ],
|
||||
"_msk": [ "Opacity" ],
|
||||
"_blend": [ "Opacity" ],
|
||||
// AO
|
||||
"_ao": [ "AmbientOcclusion" ],
|
||||
"_ambocc": [ "AmbientOcclusion" ],
|
||||
"_amb": [ "AmbientOcclusion" ],
|
||||
"_ambientocclusion": [ "AmbientOcclusion" ],
|
||||
// emissive
|
||||
"_emissive": [ "Emissive" ],
|
||||
"_e": [ "Emissive" ],
|
||||
"_glow": [ "Emissive" ],
|
||||
"_em": [ "Emissive" ],
|
||||
"_emit": [ "Emissive" ],
|
||||
// displacement
|
||||
"_displ": [ "Displacement" ],
|
||||
"_disp": [ "Displacement" ],
|
||||
"_dsp": [ "Displacement" ],
|
||||
"_d": [ "Displacement" ],
|
||||
"_dm": [ "Displacement" ],
|
||||
"_displacement": [ "Displacement" ],
|
||||
"_height": [ "Displacement" ],
|
||||
"_hm": [ "Displacement" ],
|
||||
"_ht": [ "Displacement" ],
|
||||
"_h": [ "Displacement" ],
|
||||
// cubemap
|
||||
"_ibldiffusecm": [ "IBLDiffuse" ],
|
||||
"_iblskyboxcm": [ "IBLSkybox" ],
|
||||
"_iblspecularcm": [ "IBLSpecular" ],
|
||||
"_iblspecularcm64": [ "IBLSpecularVeryLow" ],
|
||||
"_iblspecularcm128": [ "IBLSpecularLow" ],
|
||||
"_iblspecularcm256": [ "IBLSpecular" ],
|
||||
"_iblspecularcm512": [ "IBLSpecularHigh" ],
|
||||
"_iblspecularcm1024": [ "IBLSpecularVeryHigh" ],
|
||||
"_skyboxcm": [ "Skybox" ],
|
||||
"_ccm": [ "ConvolvedCubemap" ],
|
||||
"_convolvedcubemap": [ "ConvolvedCubemap" ],
|
||||
"_iblglobalcm": [ "IBLGlobal" ],
|
||||
"_cubemap": [ "IBLGlobal" ],
|
||||
"_cm": [ "IBLGlobal" ],
|
||||
// lut
|
||||
"_lut": [ "LUT_RG8" ],
|
||||
"_lutr32f": [ "LUT_R32F" ],
|
||||
"_lutrgba8": [ "LUT_RGBA8" ],
|
||||
"_lutrgba16": [ "LUT_RGBA16" ],
|
||||
"_lutrgba16f": [ "LUT_RGBA16F" ],
|
||||
"_lutrg16": [ "LUT_RG16" ],
|
||||
"_lutrg32f": [ "LUT_RG32F" ],
|
||||
"_lutrgba32f": [ "LUT_RGBA32F" ],
|
||||
// layer mask
|
||||
"_layers": [ "LayerMask" ],
|
||||
"_rgbmask": [ "LayerMask" ],
|
||||
// decal
|
||||
"_decal": [ "Decal_AlbedoWithOpacity" ],
|
||||
// ui
|
||||
"_ui": [ "UserInterface_Compressed","UserInterface_Lossless" ]
|
||||
},
|
||||
"DefaultPreset": "Albedo",
|
||||
"DefaultPresetAlpha": "AlbedoWithGenericAlpha"
|
||||
}
|
||||
}
|
||||
-1
@@ -6,7 +6,6 @@
|
||||
"DefaultPreset": {
|
||||
"UUID": "{10D4D7D8-23E2-4FC5-BE6A-DA9949D2C603}",
|
||||
"Name": "LUT_R32F",
|
||||
"FileMasks": ["_lutr32f"],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"PixelFormat": "R32F"
|
||||
-1
@@ -6,7 +6,6 @@
|
||||
"DefaultPreset": {
|
||||
"UUID": "{52470B8B-0798-4E03-B0D3-039D5141CFEC}",
|
||||
"Name": "LUT_RG32F",
|
||||
"FileMasks": ["_lutrg32f"],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"PixelFormat": "R32G32F"
|
||||
-15
@@ -8,9 +8,6 @@
|
||||
"Name": "LUT_RG8",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lut"
|
||||
],
|
||||
"PixelFormat": "R8G8"
|
||||
},
|
||||
"PlatformsPresets": {
|
||||
@@ -19,9 +16,6 @@
|
||||
"Name": "LUT_RG8",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lut"
|
||||
],
|
||||
"PixelFormat": "R8G8"
|
||||
},
|
||||
"ios": {
|
||||
@@ -29,9 +23,6 @@
|
||||
"Name": "LUT_RG8",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lut"
|
||||
],
|
||||
"PixelFormat": "R8G8"
|
||||
},
|
||||
"mac": {
|
||||
@@ -39,9 +30,6 @@
|
||||
"Name": "LUT_RG8",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lut"
|
||||
],
|
||||
"PixelFormat": "R8G8"
|
||||
},
|
||||
"provo": {
|
||||
@@ -49,9 +37,6 @@
|
||||
"Name": "LUT_RG8",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lut"
|
||||
],
|
||||
"PixelFormat": "R8G8"
|
||||
}
|
||||
}
|
||||
-15
@@ -8,9 +8,6 @@
|
||||
"Name": "LUT_RGBA16",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lutrgba16"
|
||||
],
|
||||
"PixelFormat": "R16G16B16A16"
|
||||
},
|
||||
"PlatformsPresets": {
|
||||
@@ -19,9 +16,6 @@
|
||||
"Name": "LUT_RGBA16",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lutrgba16"
|
||||
],
|
||||
"PixelFormat": "R16G16B16A16"
|
||||
},
|
||||
"ios": {
|
||||
@@ -29,9 +23,6 @@
|
||||
"Name": "LUT_RGBA16",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lutrgba16"
|
||||
],
|
||||
"PixelFormat": "R16G16B16A16"
|
||||
},
|
||||
"osx_gl": {
|
||||
@@ -39,9 +30,6 @@
|
||||
"Name": "LUT_RGBA16",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lutrgba16"
|
||||
],
|
||||
"PixelFormat": "R16G16B16A16"
|
||||
},
|
||||
"provo": {
|
||||
@@ -49,9 +37,6 @@
|
||||
"Name": "LUT_RGBA16",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lutrgba16"
|
||||
],
|
||||
"PixelFormat": "R16G16B16A16"
|
||||
}
|
||||
}
|
||||
-15
@@ -8,9 +8,6 @@
|
||||
"Name": "LUT_RGBA16F",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lutrgba16f"
|
||||
],
|
||||
"PixelFormat": "R16G16B16A16F"
|
||||
},
|
||||
"PlatformsPresets": {
|
||||
@@ -19,9 +16,6 @@
|
||||
"Name": "LUT_RGBA16F",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lutrgba16f"
|
||||
],
|
||||
"PixelFormat": "R16G16B16A16F"
|
||||
},
|
||||
"ios": {
|
||||
@@ -29,9 +23,6 @@
|
||||
"Name": "LUT_RGBA16F",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lutrgba16f"
|
||||
],
|
||||
"PixelFormat": "R16G16B16A16F"
|
||||
},
|
||||
"osx_gl": {
|
||||
@@ -39,9 +30,6 @@
|
||||
"Name": "LUT_RGBA16F",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lutrgba16f"
|
||||
],
|
||||
"PixelFormat": "R16G16B16A16F"
|
||||
},
|
||||
"provo": {
|
||||
@@ -49,9 +37,6 @@
|
||||
"Name": "LUT_RGBA16F",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_lutrgba16f"
|
||||
],
|
||||
"PixelFormat": "R16G16B16A16F"
|
||||
}
|
||||
}
|
||||
-1
@@ -6,7 +6,6 @@
|
||||
"DefaultPreset": {
|
||||
"UUID": "{AC4C49D4-2C70-425A-8DBF-E7FB2C61CF8D}",
|
||||
"Name": "LUT_RGBA32F",
|
||||
"FileMasks": ["_lutrgba32f"],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"PixelFormat": "R32G32B32A32F"
|
||||
-20
@@ -8,10 +8,6 @@
|
||||
"Name": "LayerMask",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_layers",
|
||||
"_rgbmask"
|
||||
],
|
||||
"PixelFormat": "R8G8B8X8"
|
||||
},
|
||||
"PlatformsPresets": {
|
||||
@@ -20,10 +16,6 @@
|
||||
"Name": "LayerMask",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_layers",
|
||||
"_rgbmask"
|
||||
],
|
||||
"PixelFormat": "R8G8B8X8"
|
||||
},
|
||||
"ios": {
|
||||
@@ -31,10 +23,6 @@
|
||||
"Name": "LayerMask",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_layers",
|
||||
"_rgbmask"
|
||||
],
|
||||
"PixelFormat": "R8G8B8X8"
|
||||
},
|
||||
"mac": {
|
||||
@@ -42,10 +30,6 @@
|
||||
"Name": "LayerMask",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_layers",
|
||||
"_rgbmask"
|
||||
],
|
||||
"PixelFormat": "R8G8B8X8"
|
||||
},
|
||||
"provo": {
|
||||
@@ -53,10 +37,6 @@
|
||||
"Name": "LayerMask",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_layers",
|
||||
"_rgbmask"
|
||||
],
|
||||
"PixelFormat": "R8G8B8X8"
|
||||
}
|
||||
}
|
||||
-55
@@ -8,17 +8,6 @@
|
||||
"Name": "Normals",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ddn",
|
||||
"_normal",
|
||||
"_normalmap",
|
||||
"_normals",
|
||||
"_norm",
|
||||
"_nor",
|
||||
"_nrm",
|
||||
"_nm",
|
||||
"_n"
|
||||
],
|
||||
"PixelFormat": "BC5s",
|
||||
"DiscardAlpha": true,
|
||||
"IsPowerOf2": true,
|
||||
@@ -33,17 +22,6 @@
|
||||
"Name": "Normals",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ddn",
|
||||
"_normal",
|
||||
"_normalmap",
|
||||
"_normals",
|
||||
"_norm",
|
||||
"_nor",
|
||||
"_nrm",
|
||||
"_nm",
|
||||
"_n"
|
||||
],
|
||||
"PixelFormat": "ASTC_4x4",
|
||||
"DiscardAlpha": true,
|
||||
"MaxTextureSize": 1024,
|
||||
@@ -58,17 +36,6 @@
|
||||
"Name": "Normals",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ddn",
|
||||
"_normal",
|
||||
"_normalmap",
|
||||
"_normals",
|
||||
"_norm",
|
||||
"_nor",
|
||||
"_nrm",
|
||||
"_nm",
|
||||
"_n"
|
||||
],
|
||||
"PixelFormat": "ASTC_4x4",
|
||||
"DiscardAlpha": true,
|
||||
"MaxTextureSize": 1024,
|
||||
@@ -83,17 +50,6 @@
|
||||
"Name": "Normals",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ddn",
|
||||
"_normal",
|
||||
"_normalmap",
|
||||
"_normals",
|
||||
"_norm",
|
||||
"_nor",
|
||||
"_nrm",
|
||||
"_nm",
|
||||
"_n"
|
||||
],
|
||||
"PixelFormat": "BC5s",
|
||||
"DiscardAlpha": true,
|
||||
"IsPowerOf2": true,
|
||||
@@ -107,17 +63,6 @@
|
||||
"Name": "Normals",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ddn",
|
||||
"_normal",
|
||||
"_normalmap",
|
||||
"_normals",
|
||||
"_norm",
|
||||
"_nor",
|
||||
"_nrm",
|
||||
"_nm",
|
||||
"_n"
|
||||
],
|
||||
"PixelFormat": "BC5s",
|
||||
"DiscardAlpha": true,
|
||||
"IsPowerOf2": true,
|
||||
-35
@@ -8,13 +8,6 @@
|
||||
"Name": "NormalsWithSmoothness",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ddna",
|
||||
"_normala",
|
||||
"_nrma",
|
||||
"_nma",
|
||||
"_na"
|
||||
],
|
||||
"PixelFormat": "BC5s",
|
||||
"PixelFormatAlpha": "BC4",
|
||||
"IsPowerOf2": true,
|
||||
@@ -30,13 +23,6 @@
|
||||
"Name": "NormalsWithSmoothness",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ddna",
|
||||
"_normala",
|
||||
"_nrma",
|
||||
"_nma",
|
||||
"_na"
|
||||
],
|
||||
"PixelFormat": "ASTC_4x4",
|
||||
"PixelFormatAlpha": "ASTC_4x4",
|
||||
"MaxTextureSize": 2048,
|
||||
@@ -52,13 +38,6 @@
|
||||
"Name": "NormalsWithSmoothness",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ddna",
|
||||
"_normala",
|
||||
"_nrma",
|
||||
"_nma",
|
||||
"_na"
|
||||
],
|
||||
"PixelFormat": "ASTC_4x4",
|
||||
"PixelFormatAlpha": "ASTC_4x4",
|
||||
"MaxTextureSize": 2048,
|
||||
@@ -74,13 +53,6 @@
|
||||
"Name": "NormalsWithSmoothness",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ddna",
|
||||
"_normala",
|
||||
"_nrma",
|
||||
"_nma",
|
||||
"_na"
|
||||
],
|
||||
"PixelFormat": "BC5s",
|
||||
"PixelFormatAlpha": "BC4",
|
||||
"IsPowerOf2": true,
|
||||
@@ -95,13 +67,6 @@
|
||||
"Name": "NormalsWithSmoothness",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_ddna",
|
||||
"_normala",
|
||||
"_nrma",
|
||||
"_nma",
|
||||
"_na"
|
||||
],
|
||||
"PixelFormat": "BC5s",
|
||||
"PixelFormatAlpha": "BC4",
|
||||
"IsPowerOf2": true,
|
||||
+5
-60
@@ -8,19 +8,8 @@
|
||||
"Name": "Opacity",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_sss",
|
||||
"_trans",
|
||||
"_opac",
|
||||
"_opacity",
|
||||
"_o",
|
||||
"_opac",
|
||||
"_op",
|
||||
"_mask",
|
||||
"_msk",
|
||||
"_blend"
|
||||
],
|
||||
"PixelFormat": "BC4",
|
||||
"Swizzle": "rrr1",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
@@ -32,19 +21,8 @@
|
||||
"Name": "Opacity",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_sss",
|
||||
"_trans",
|
||||
"_opac",
|
||||
"_opacity",
|
||||
"_o",
|
||||
"_opac",
|
||||
"_op",
|
||||
"_mask",
|
||||
"_msk",
|
||||
"_blend"
|
||||
],
|
||||
"PixelFormat": "ASTC_4x4",
|
||||
"Swizzle": "rrr1",
|
||||
"MaxTextureSize": 2048,
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
@@ -56,19 +34,8 @@
|
||||
"Name": "Opacity",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_sss",
|
||||
"_trans",
|
||||
"_opac",
|
||||
"_opacity",
|
||||
"_o",
|
||||
"_opac",
|
||||
"_op",
|
||||
"_mask",
|
||||
"_msk",
|
||||
"_blend"
|
||||
],
|
||||
"PixelFormat": "ASTC_4x4",
|
||||
"Swizzle": "rrr1",
|
||||
"MaxTextureSize": 2048,
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
@@ -80,19 +47,8 @@
|
||||
"Name": "Opacity",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_sss",
|
||||
"_trans",
|
||||
"_opac",
|
||||
"_opacity",
|
||||
"_o",
|
||||
"_opac",
|
||||
"_op",
|
||||
"_mask",
|
||||
"_msk",
|
||||
"_blend"
|
||||
],
|
||||
"PixelFormat": "BC4",
|
||||
"Swizzle": "rrr1",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
@@ -103,19 +59,8 @@
|
||||
"Name": "Opacity",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_sss",
|
||||
"_trans",
|
||||
"_opac",
|
||||
"_opacity",
|
||||
"_o",
|
||||
"_opac",
|
||||
"_op",
|
||||
"_mask",
|
||||
"_msk",
|
||||
"_blend"
|
||||
],
|
||||
"PixelFormat": "BC4",
|
||||
"Swizzle": "rrr1",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "MultiplatformPresetSettings",
|
||||
"ClassData": {
|
||||
"DefaultPreset": {
|
||||
"UUID": "{7A3CC95E-0A0C-4CA1-8357-5712B028B77D}",
|
||||
"Name": "Reflectance",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"PixelFormat": "BC4",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
},
|
||||
"PlatformsPresets": {
|
||||
"android": {
|
||||
"UUID": "{7A3CC95E-0A0C-4CA1-8357-5712B028B77D}",
|
||||
"Name": "Reflectance",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"PixelFormat": "ASTC_6x6",
|
||||
"Swizzle": "rrr1",
|
||||
"MaxTextureSize": 2048,
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
},
|
||||
"ios": {
|
||||
"UUID": "{7A3CC95E-0A0C-4CA1-8357-5712B028B77D}",
|
||||
"Name": "Reflectance",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"PixelFormat": "ASTC_6x6",
|
||||
"Swizzle": "rrr1",
|
||||
"MaxTextureSize": 2048,
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
},
|
||||
"mac": {
|
||||
"UUID": "{7A3CC95E-0A0C-4CA1-8357-5712B028B77D}",
|
||||
"Name": "Reflectance",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"PixelFormat": "BC4",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
},
|
||||
"provo": {
|
||||
"UUID": "{7A3CC95E-0A0C-4CA1-8357-5712B028B77D}",
|
||||
"Name": "Reflectance",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"PixelFormat": "BC4",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-15
@@ -6,9 +6,6 @@
|
||||
"DefaultPreset": {
|
||||
"UUID": "{F359CD3B-37E6-4627-B4F6-2DFC2C0E3C1C}",
|
||||
"Name": "Skybox",
|
||||
"FileMasks": [
|
||||
"_skyboxcm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -24,9 +21,6 @@
|
||||
"android": {
|
||||
"UUID": "{F359CD3B-37E6-4627-B4F6-2DFC2C0E3C1C}",
|
||||
"Name": "Skybox",
|
||||
"FileMasks": [
|
||||
"_skyboxcm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -41,9 +35,6 @@
|
||||
"ios": {
|
||||
"UUID": "{F359CD3B-37E6-4627-B4F6-2DFC2C0E3C1C}",
|
||||
"Name": "Skybox",
|
||||
"FileMasks": [
|
||||
"_skyboxcm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -58,9 +49,6 @@
|
||||
"mac": {
|
||||
"UUID": "{F359CD3B-37E6-4627-B4F6-2DFC2C0E3C1C}",
|
||||
"Name": "Skybox",
|
||||
"FileMasks": [
|
||||
"_skyboxcm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
@@ -75,9 +63,6 @@
|
||||
"provo": {
|
||||
"UUID": "{F359CD3B-37E6-4627-B4F6-2DFC2C0E3C1C}",
|
||||
"Name": "Skybox",
|
||||
"FileMasks": [
|
||||
"_skyboxcm"
|
||||
],
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"SuppressEngineReduce": true,
|
||||
+1
-2
@@ -9,8 +9,7 @@
|
||||
"SuppressEngineReduce": true,
|
||||
"PixelFormat": "R8G8B8A8",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [ "_ui" ]
|
||||
"DestColor": "Linear"
|
||||
},
|
||||
"PlatformsPresets": {
|
||||
"android": {
|
||||
+1
-2
@@ -9,8 +9,7 @@
|
||||
"SuppressEngineReduce": true,
|
||||
"PixelFormat": "R8G8B8A8",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [ "_ui" ]
|
||||
"DestColor": "Linear"
|
||||
},
|
||||
"PlatformsPresets": {
|
||||
"android": {
|
||||
+298
-125
@@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
#include "BuilderSettingManager.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QDirIterator>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
@@ -17,8 +18,9 @@
|
||||
#include <BuilderSettings/CubemapSettings.h>
|
||||
#include <BuilderSettings/TextureSettings.h>
|
||||
#include <Converters/Cubemap.h>
|
||||
#include <Processing/PixelFormatInfo.h>
|
||||
#include <Processing/ImageToProcess.h>
|
||||
#include <Processing/PixelFormatInfo.h>
|
||||
#include <Processing/Utils.h>
|
||||
#include <ImageLoader/ImageLoaders.h>
|
||||
#include <ImageProcessing_Traits_Platform.h>
|
||||
|
||||
@@ -41,13 +43,18 @@
|
||||
|
||||
namespace ImageProcessingAtom
|
||||
{
|
||||
const char* BuilderSettingManager::s_defaultConfigRelativeFolder = "Gems/Atom/Asset/ImageProcessingAtom/Config/";
|
||||
const char* BuilderSettingManager::s_defaultConfigRelativeFolder = "Gems/Atom/Asset/ImageProcessingAtom/Assets/Config/";
|
||||
const char* BuilderSettingManager::s_projectConfigRelativeFolder = "Config/AtomImageBuilder/";
|
||||
const char* BuilderSettingManager::s_builderSettingFileName = "ImageBuilder.settings";
|
||||
const char* BuilderSettingManager::s_presetFileExtension = ".preset";
|
||||
const char* BuilderSettingManager::s_presetFileExtension = "preset";
|
||||
|
||||
const char FileMaskDelimiter = '_';
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr const char* const LogWindow = "Image Processing";
|
||||
}
|
||||
|
||||
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
|
||||
#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3) \
|
||||
namespace ImageProcess##PrivateName \
|
||||
@@ -69,13 +76,15 @@ namespace ImageProcessingAtom
|
||||
if (serialize)
|
||||
{
|
||||
serialize->Class<BuilderSettingManager>()
|
||||
->Version(1)
|
||||
->Field("AnalysisFingerprint", &BuilderSettingManager::m_analysisFingerprint)
|
||||
->Version(2)
|
||||
->Field("BuildSettings", &BuilderSettingManager::m_builderSettings)
|
||||
->Field("DefaultPresetsByFileMask", &BuilderSettingManager::m_defaultPresetByFileMask)
|
||||
->Field("PresetsByFileMask", &BuilderSettingManager::m_presetFilterMap)
|
||||
->Field("DefaultPreset", &BuilderSettingManager::m_defaultPreset)
|
||||
->Field("DefaultPresetAlpha", &BuilderSettingManager::m_defaultPresetAlpha)
|
||||
->Field("DefaultPresetNonePOT", &BuilderSettingManager::m_defaultPresetNonePOT);
|
||||
->Field("DefaultPresetNonePOT", &BuilderSettingManager::m_defaultPresetNonePOT)
|
||||
// deprecated properties
|
||||
->Field("DefaultPresetsByFileMask", &BuilderSettingManager::m_defaultPresetByFileMask)
|
||||
->Field("AnalysisFingerprint", &BuilderSettingManager::m_analysisFingerprint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +131,7 @@ namespace ImageProcessingAtom
|
||||
s_globalInstance.Reset();
|
||||
}
|
||||
|
||||
const PresetSettings* BuilderSettingManager::GetPreset(const PresetName& presetName, const PlatformName& platform, AZStd::string_view* settingsFilePathOut)
|
||||
const PresetSettings* BuilderSettingManager::GetPreset(const PresetName& presetName, const PlatformName& platform, AZStd::string_view* settingsFilePathOut) const
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
||||
auto itr = m_presets.find(presetName);
|
||||
@@ -137,16 +146,36 @@ namespace ImageProcessingAtom
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const BuilderSettings* BuilderSettingManager::GetBuilderSetting(const PlatformName& platform)
|
||||
AZStd::vector<AZStd::string> BuilderSettingManager::GetFileMasksForPreset(const PresetName& presetName) const
|
||||
{
|
||||
if (m_builderSettings.find(platform) != m_builderSettings.end())
|
||||
AZStd::vector<AZStd::string> fileMasks;
|
||||
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
||||
for (const auto& mapping:m_presetFilterMap)
|
||||
{
|
||||
return &m_builderSettings[platform];
|
||||
for (const auto& preset : mapping.second)
|
||||
{
|
||||
if (preset == presetName)
|
||||
{
|
||||
fileMasks.push_back(mapping.first);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return fileMasks;
|
||||
}
|
||||
|
||||
const BuilderSettings* BuilderSettingManager::GetBuilderSetting(const PlatformName& platform) const
|
||||
{
|
||||
auto itr = m_builderSettings.find(platform);
|
||||
if (itr != m_builderSettings.end())
|
||||
{
|
||||
return &itr->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const PlatformNameList BuilderSettingManager::GetPlatformList()
|
||||
const PlatformNameList BuilderSettingManager::GetPlatformList() const
|
||||
{
|
||||
PlatformNameList platforms;
|
||||
|
||||
@@ -161,12 +190,19 @@ namespace ImageProcessingAtom
|
||||
return platforms;
|
||||
}
|
||||
|
||||
const AZStd::map <FileMask, AZStd::unordered_set<PresetName>>& BuilderSettingManager::GetPresetFilterMap()
|
||||
const AZStd::map <FileMask, AZStd::unordered_set<PresetName>>& BuilderSettingManager::GetPresetFilterMap() const
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
||||
return m_presetFilterMap;
|
||||
}
|
||||
|
||||
const AZStd::unordered_set<PresetName>& BuilderSettingManager::GetFullPresetList() const
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
||||
AZStd::string noFilter = AZStd::string();
|
||||
return m_presetFilterMap.find(noFilter)->second;
|
||||
}
|
||||
|
||||
const PresetName BuilderSettingManager::GetPresetNameFromId(const AZ::Uuid& presetId)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
||||
@@ -188,7 +224,6 @@ namespace ImageProcessingAtom
|
||||
m_presetFilterMap.clear();
|
||||
m_builderSettings.clear();
|
||||
m_presets.clear();
|
||||
m_defaultPresetByFileMask.clear();
|
||||
}
|
||||
|
||||
StringOutcome BuilderSettingManager::LoadConfig()
|
||||
@@ -198,44 +233,53 @@ namespace ImageProcessingAtom
|
||||
auto fileIoBase = AZ::IO::FileIOBase::GetInstance();
|
||||
if (fileIoBase == nullptr)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("File IO instance needs to be initialized to resolve ImageProcessing builder file aliases"));
|
||||
return AZ::Failure(
|
||||
AZStd::string("File IO instance needs to be initialized to resolve ImageProcessing builder file aliases"));
|
||||
}
|
||||
|
||||
// Construct the default setting path
|
||||
|
||||
AZ::IO::FixedMaxPath defaultConfigFolder;
|
||||
if (auto engineRoot = fileIoBase->ResolvePath("@engroot@"); engineRoot.has_value())
|
||||
{
|
||||
defaultConfigFolder = *engineRoot;
|
||||
defaultConfigFolder /= s_defaultConfigRelativeFolder;
|
||||
m_defaultConfigFolder = *engineRoot;
|
||||
m_defaultConfigFolder /= s_defaultConfigRelativeFolder;
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPath projectConfigFolder;
|
||||
if (auto sourceGameRoot = fileIoBase->ResolvePath("@projectroot@"); sourceGameRoot.has_value())
|
||||
{
|
||||
projectConfigFolder = *sourceGameRoot;
|
||||
projectConfigFolder /= s_projectConfigRelativeFolder;
|
||||
m_projectConfigFolder = *sourceGameRoot;
|
||||
m_projectConfigFolder /= s_projectConfigRelativeFolder;
|
||||
}
|
||||
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
||||
ClearSettings();
|
||||
|
||||
outcome = LoadSettings((projectConfigFolder / s_builderSettingFileName).Native());
|
||||
|
||||
if (!outcome.IsSuccess())
|
||||
{
|
||||
outcome = LoadSettings((defaultConfigFolder / s_builderSettingFileName).Native());
|
||||
}
|
||||
outcome = LoadSettings();
|
||||
|
||||
if (outcome.IsSuccess())
|
||||
{
|
||||
// Load presets in default folder first, then load from project folder.
|
||||
// The same presets which loaded last will overwrite previous loaded one.
|
||||
LoadPresets(defaultConfigFolder.Native());
|
||||
LoadPresets(projectConfigFolder.Native());
|
||||
LoadPresets(m_defaultConfigFolder.Native());
|
||||
LoadPresets(m_projectConfigFolder.Native());
|
||||
}
|
||||
|
||||
// Regenerate file mask mapping after all presets loaded
|
||||
RegenerateMappings();
|
||||
// Collect extra file masks from preset files
|
||||
CollectFileMasksFromPresets();
|
||||
|
||||
|
||||
if (QCoreApplication::instance())
|
||||
{
|
||||
m_fileWatcher.reset(new QFileSystemWatcher);
|
||||
// track preset files
|
||||
// Note, the QT signal would only works for AP but not AssetBuilder
|
||||
// We use file time stamp to track preset file change in builder's CreateJob
|
||||
for (auto& preset : m_presets)
|
||||
{
|
||||
m_fileWatcher.data()->addPath(QString(preset.second.m_presetFilePath.c_str()));
|
||||
}
|
||||
m_fileWatcher.data()->addPath(QString(m_defaultConfigFolder.c_str()));
|
||||
m_fileWatcher.data()->addPath(QString(m_projectConfigFolder.c_str()));
|
||||
QObject::connect(m_fileWatcher.data(), &QFileSystemWatcher::fileChanged, this, &BuilderSettingManager::OnFileChanged);
|
||||
QObject::connect(m_fileWatcher.data(), &QFileSystemWatcher::directoryChanged, this, &BuilderSettingManager::OnFolderChanged);
|
||||
}
|
||||
|
||||
return outcome;
|
||||
@@ -243,36 +287,84 @@ namespace ImageProcessingAtom
|
||||
|
||||
void BuilderSettingManager::LoadPresets(AZStd::string_view presetFolder)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
||||
|
||||
QDirIterator it(presetFolder.data(), QStringList() << "*.preset", QDir::Files, QDirIterator::NoIteratorFlags);
|
||||
while (it.hasNext())
|
||||
{
|
||||
QString filePath = it.next();
|
||||
QFileInfo fileInfo = it.fileInfo();
|
||||
LoadPreset(filePath.toUtf8().data());
|
||||
}
|
||||
}
|
||||
|
||||
MultiplatformPresetSettings preset;
|
||||
auto result = AZ::JsonSerializationUtils::LoadObjectFromFile(preset, filePath.toUtf8().data());
|
||||
if (!result.IsSuccess())
|
||||
bool BuilderSettingManager::LoadPreset(const AZStd::string& filePath)
|
||||
{
|
||||
QFileInfo fileInfo (filePath.c_str());
|
||||
|
||||
if (!fileInfo.exists())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MultiplatformPresetSettings preset;
|
||||
auto result = AZ::JsonSerializationUtils::LoadObjectFromFile(preset, filePath);
|
||||
if (!result.IsSuccess())
|
||||
{
|
||||
AZ_Warning(LogWindow, false, "Failed to load preset file %s. Error: %s",
|
||||
filePath.c_str(), result.GetError().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
PresetName presetName(fileInfo.baseName().toUtf8().data());
|
||||
|
||||
AZ_Warning(LogWindow, presetName == preset.GetPresetName(), "Preset file name '%s' is not"
|
||||
" same as preset name '%s'. Using preset file name as preset name",
|
||||
filePath.c_str(), preset.GetPresetName().GetCStr());
|
||||
|
||||
preset.SetPresetName(presetName);
|
||||
|
||||
m_presets[presetName] = PresetEntry{preset, filePath.c_str(), fileInfo.lastModified()};
|
||||
return true;
|
||||
}
|
||||
|
||||
void BuilderSettingManager::ReloadPreset(const PresetName& presetName)
|
||||
{
|
||||
// Find the preset file from project or default config folder
|
||||
AZStd::string presetFileName = AZStd::string::format("%s.%s", presetName.GetCStr(), s_presetFileExtension);
|
||||
AZ::IO::FixedMaxPath filePath = m_projectConfigFolder/presetFileName;
|
||||
QFileInfo fileInfo (filePath.c_str());
|
||||
if (!fileInfo.exists())
|
||||
{
|
||||
filePath = (m_defaultConfigFolder/presetFileName).c_str();
|
||||
fileInfo = QFileInfo(filePath.c_str());
|
||||
}
|
||||
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
||||
|
||||
//Skip the loading if the file wasn't chagned
|
||||
if (fileInfo.exists())
|
||||
{
|
||||
if (m_presets.find(presetName) != m_presets.end())
|
||||
{
|
||||
AZ_Warning("Image Processing", false, "Failed to load preset file %s. Error: %s",
|
||||
filePath.toUtf8().data(), result.GetError().c_str());
|
||||
if (m_presets[presetName].m_lastModifiedTime == fileInfo.lastModified()
|
||||
&& m_presets[presetName].m_presetFilePath == filePath.c_str())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PresetName presetName(fileInfo.baseName().toUtf8().data());
|
||||
// remove preset
|
||||
m_presets.erase(presetName);
|
||||
|
||||
AZ_Warning("Image Processing", presetName == preset.GetPresetName(), "Preset file name '%s' is not"
|
||||
" same as preset name '%s'. Using preset file name as preset name",
|
||||
filePath.toUtf8().data(), preset.GetPresetName().GetCStr());
|
||||
|
||||
preset.SetPresetName(presetName);
|
||||
|
||||
m_presets[presetName] = PresetEntry{preset, filePath.toUtf8().data()};
|
||||
if (fileInfo.exists())
|
||||
{
|
||||
LoadPreset(filePath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
StringOutcome BuilderSettingManager::LoadConfigFromFolder(AZStd::string_view configFolder)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
||||
|
||||
// Load builder settings
|
||||
AZStd::string settingFilePath = AZStd::string::format("%.*s%s", aznumeric_cast<int>(configFolder.size()),
|
||||
configFolder.data(), s_builderSettingFileName);
|
||||
@@ -282,12 +374,108 @@ namespace ImageProcessingAtom
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
LoadPresets(configFolder);
|
||||
RegenerateMappings();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void BuilderSettingManager::ReportDeprecatedSettings()
|
||||
{
|
||||
// reported deprecated attributes in image builder settings
|
||||
if (!m_analysisFingerprint.empty())
|
||||
{
|
||||
AZ_Warning(LogWindow, false, "'AnalysisFingerprint' is deprecated and it should be removed from file [%s]", s_builderSettingFileName);
|
||||
}
|
||||
if (!m_defaultPresetByFileMask.empty())
|
||||
{
|
||||
AZ_Warning(LogWindow, false, "'DefaultPresetsByFileMask' is deprecated and it should be removed from file [%s]. Use PresetsByFileMask instead", s_builderSettingFileName);
|
||||
}
|
||||
}
|
||||
|
||||
StringOutcome BuilderSettingManager::LoadSettings()
|
||||
{
|
||||
// If the project image build setting file exist, it will merge image builder settings from project folder to the settings from default config folder.
|
||||
bool needMerge = false;
|
||||
AZStd::string projectSettingFile{ (m_projectConfigFolder / s_builderSettingFileName).Native() };
|
||||
|
||||
if (AZ::IO::SystemFile::Exists(projectSettingFile.c_str()))
|
||||
{
|
||||
needMerge = true;
|
||||
}
|
||||
|
||||
AZ::Outcome<void, AZStd::string> outcome;
|
||||
AZStd::string defaultSettingFile{ (m_defaultConfigFolder / s_builderSettingFileName).Native() };
|
||||
if (needMerge)
|
||||
{
|
||||
auto outcome1 = AZ::JsonSerializationUtils::ReadJsonFile(defaultSettingFile);
|
||||
auto outcome2 = AZ::JsonSerializationUtils::ReadJsonFile(projectSettingFile);
|
||||
|
||||
// return error if it failed to load default settings
|
||||
if (!outcome1.IsSuccess())
|
||||
{
|
||||
return STRING_OUTCOME_ERROR(outcome1.GetError());
|
||||
}
|
||||
|
||||
// if project config was loaded successfully, apply merge patch
|
||||
rapidjson::Document& originDoc = outcome1.GetValue();
|
||||
if (outcome2.IsSuccess())
|
||||
{
|
||||
const rapidjson::Document& patchDoc = outcome2.GetValue();
|
||||
AZ::JsonSerializationResult::ResultCode result =
|
||||
AZ::JsonSerialization::ApplyPatch(originDoc, originDoc.GetAllocator(), patchDoc, AZ::JsonMergeApproach::JsonMergePatch);
|
||||
|
||||
if (result.GetProcessing() == AZ::JsonSerializationResult::Processing::Completed)
|
||||
{
|
||||
AZStd::vector<char> outBuffer;
|
||||
AZ::IO::ByteContainerStream<AZStd::vector<char>> outStream{ &outBuffer };
|
||||
AZ::JsonSerializationUtils::WriteJsonStream(originDoc, outStream);
|
||||
|
||||
outStream.Seek(0, AZ::IO::GenericStream::ST_SEEK_BEGIN);
|
||||
|
||||
outcome = AZ::JsonSerializationUtils::LoadObjectFromStream(*this, outStream);
|
||||
if (!outcome.IsSuccess())
|
||||
{
|
||||
return STRING_OUTCOME_ERROR(outcome.GetError());
|
||||
}
|
||||
|
||||
ReportDeprecatedSettings();
|
||||
|
||||
|
||||
// Generate config file fingerprint
|
||||
outStream.Seek(0, AZ::IO::GenericStream::ST_SEEK_BEGIN);
|
||||
AZ::u64 hash = AssetBuilderSDK::GetHashFromIOStream(outStream);
|
||||
m_analysisFingerprint = AZStd::string::format("%llX", hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
needMerge = false;
|
||||
AZ_Warning(LogWindow, false, "Failed to fully merge data into image builder settings. Skipping project build setting file [%s]", projectSettingFile.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning(LogWindow, false, "Failed to load project setting file [%s]. Skipping", projectSettingFile.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (!needMerge)
|
||||
{
|
||||
outcome = AZ::JsonSerializationUtils::LoadObjectFromFile(*this, defaultSettingFile);
|
||||
if (!outcome.IsSuccess())
|
||||
{
|
||||
return STRING_OUTCOME_ERROR(outcome.GetError());
|
||||
}
|
||||
|
||||
ReportDeprecatedSettings();
|
||||
|
||||
// Generate config file fingerprint
|
||||
AZ::u64 hash = AssetBuilderSDK::GetFileHash(defaultSettingFile.c_str());
|
||||
m_analysisFingerprint = AZStd::string::format("%llX", hash);
|
||||
}
|
||||
|
||||
return STRING_OUTCOME_SUCCESS;
|
||||
}
|
||||
|
||||
StringOutcome BuilderSettingManager::LoadSettings(AZStd::string_view filepath)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
||||
@@ -336,13 +524,13 @@ namespace ImageProcessingAtom
|
||||
return m_analysisFingerprint;
|
||||
}
|
||||
|
||||
void BuilderSettingManager::RegenerateMappings()
|
||||
void BuilderSettingManager::CollectFileMasksFromPresets()
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
||||
|
||||
AZStd::string noFilter = AZStd::string();
|
||||
|
||||
m_presetFilterMap.clear();
|
||||
|
||||
AZStd::string extraString;
|
||||
|
||||
for (const auto& presetIter : m_presets)
|
||||
{
|
||||
@@ -357,22 +545,31 @@ namespace ImageProcessingAtom
|
||||
{
|
||||
if (filemask.empty() || filemask[0] != FileMaskDelimiter)
|
||||
{
|
||||
AZ_Warning("Image Processing", false, "File mask '%s' is invalid. It must start with '%c'.", filemask.c_str(), FileMaskDelimiter);
|
||||
AZ_Warning(LogWindow, false, "File mask '%s' is invalid. It must start with '%c'.", filemask.c_str(), FileMaskDelimiter);
|
||||
continue;
|
||||
}
|
||||
else if (filemask.size() < 2)
|
||||
{
|
||||
AZ_Warning("Image Processing", false, "File mask '%s' is invalid. The '%c' must be followed by at least one other character.", filemask.c_str());
|
||||
AZ_Warning(LogWindow, false, "File mask '%s' is invalid. The '%c' must be followed by at least one other character.", filemask.c_str());
|
||||
continue;
|
||||
}
|
||||
else if (filemask.find(FileMaskDelimiter, 1) != AZStd::string::npos)
|
||||
{
|
||||
AZ_Warning("Image Processing", false, "File mask '%s' is invalid. It must contain only a single '%c' character.", filemask.c_str(), FileMaskDelimiter);
|
||||
AZ_Warning(LogWindow, false, "File mask '%s' is invalid. It must contain only a single '%c' character.", filemask.c_str(), FileMaskDelimiter);
|
||||
continue;
|
||||
}
|
||||
|
||||
extraString += (filemask + preset.m_name.GetCStr());
|
||||
|
||||
m_presetFilterMap[filemask].insert(preset.m_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!extraString.empty())
|
||||
{
|
||||
AZ::u64 hash = AZStd::hash<AZStd::string>{}(extraString);
|
||||
m_analysisFingerprint += AZStd::string::format("%llX", hash);
|
||||
}
|
||||
}
|
||||
|
||||
void BuilderSettingManager::MetafilePathFromImagePath(AZStd::string_view imagePath, AZStd::string& metafilePath)
|
||||
@@ -419,38 +616,15 @@ namespace ImageProcessingAtom
|
||||
return m_presets.find(presetName) != m_presets.end();
|
||||
}
|
||||
|
||||
PresetName BuilderSettingManager::GetSuggestedPreset(AZStd::string_view imageFilePath, IImageObjectPtr imageFromFile)
|
||||
PresetName BuilderSettingManager::GetSuggestedPreset(AZStd::string_view imageFilePath) const
|
||||
{
|
||||
PresetName emptyPreset;
|
||||
|
||||
//load the image to get its size for later use
|
||||
IImageObjectPtr image = imageFromFile;
|
||||
//if the input image is empty we will try to load it from the path
|
||||
if (imageFromFile == nullptr)
|
||||
{
|
||||
image = IImageObjectPtr(LoadImageFromFile(imageFilePath));
|
||||
}
|
||||
|
||||
if (image == nullptr)
|
||||
{
|
||||
return emptyPreset;
|
||||
}
|
||||
|
||||
//get file mask of this image file
|
||||
AZStd::string fileMask = GetFileMask(imageFilePath);
|
||||
|
||||
PresetName outPreset = emptyPreset;
|
||||
|
||||
//check default presets for some file masks
|
||||
if (m_defaultPresetByFileMask.find(fileMask) != m_defaultPresetByFileMask.end())
|
||||
{
|
||||
outPreset = m_defaultPresetByFileMask[fileMask];
|
||||
if (!IsValidPreset(outPreset))
|
||||
{
|
||||
outPreset = emptyPreset;
|
||||
}
|
||||
}
|
||||
|
||||
//use the preset filter map to find
|
||||
if (outPreset.IsEmpty() && !fileMask.empty())
|
||||
{
|
||||
@@ -461,54 +635,21 @@ namespace ImageProcessingAtom
|
||||
}
|
||||
}
|
||||
|
||||
const PresetSettings* presetInfo = nullptr;
|
||||
|
||||
if (!outPreset.IsEmpty())
|
||||
{
|
||||
presetInfo = GetPreset(outPreset);
|
||||
|
||||
//special case for cubemap
|
||||
if (presetInfo && presetInfo->m_cubemapSetting)
|
||||
{
|
||||
// If it's not a latitude-longitude map or it doesn't match any cubemap layouts then reset its preset
|
||||
if (!IsValidLatLongMap(image) && CubemapLayout::GetCubemapLayoutInfo(image) == nullptr)
|
||||
{
|
||||
outPreset = emptyPreset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (outPreset == emptyPreset)
|
||||
{
|
||||
if (image->GetAlphaContent() == EAlphaContent::eAlphaContent_Absent)
|
||||
{
|
||||
outPreset = m_defaultPreset;
|
||||
}
|
||||
else
|
||||
{
|
||||
outPreset = m_defaultPresetAlpha;
|
||||
}
|
||||
outPreset = m_defaultPreset;
|
||||
}
|
||||
|
||||
//get the pixel format for selected preset
|
||||
presetInfo = GetPreset(outPreset);
|
||||
return outPreset;
|
||||
}
|
||||
|
||||
if (presetInfo)
|
||||
{
|
||||
//valid whether image size work with pixel format
|
||||
if (CPixelFormats::GetInstance().IsImageSizeValid(presetInfo->m_pixelFormat,
|
||||
image->GetWidth(0), image->GetHeight(0), false))
|
||||
{
|
||||
return outPreset;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning("Image Processing", false, "Image dimensions are not compatible with preset '%s'. The default preset will be used.", presetInfo->m_name.GetCStr());
|
||||
}
|
||||
}
|
||||
|
||||
//uncompressed one which could be used for almost everything
|
||||
return m_defaultPresetNonePOT;
|
||||
AZStd::vector<AZStd::string> BuilderSettingManager::GetPossiblePresetPaths(const PresetName& presetName) const
|
||||
{
|
||||
AZStd::vector<AZStd::string> paths;
|
||||
AZStd::string presetFile = AZStd::string::format("%s.preset", presetName.GetCStr());
|
||||
paths.push_back((m_defaultConfigFolder / presetFile).c_str());
|
||||
paths.push_back((m_projectConfigFolder / presetFile).c_str());
|
||||
return paths;
|
||||
}
|
||||
|
||||
bool BuilderSettingManager::DoesSupportPlatform(AZStd::string_view platformId)
|
||||
@@ -526,18 +667,50 @@ namespace ImageProcessingAtom
|
||||
AZStd::string filePath;
|
||||
if (!AzFramework::StringFunc::Path::Join(outputFolder.data(), fileName.c_str(), filePath))
|
||||
{
|
||||
AZ_Warning("Image Processing", false, "Failed to construct path with folder '%.*s' and file: '%s' to save preset",
|
||||
AZ_Warning(LogWindow, false, "Failed to construct path with folder '%.*s' and file: '%s' to save preset",
|
||||
aznumeric_cast<int>(outputFolder.size()), outputFolder.data(), filePath.c_str());
|
||||
continue;
|
||||
}
|
||||
auto result = AZ::JsonSerializationUtils::SaveObjectToFile(&presetEntry.m_multiPreset, filePath);
|
||||
if (!result.IsSuccess())
|
||||
{
|
||||
AZ_Warning("Image Processing", false, "Failed to save preset '%s' to file '%s'. Error: %s",
|
||||
AZ_Warning(LogWindow, false, "Failed to save preset '%s' to file '%s'. Error: %s",
|
||||
presetEntry.m_multiPreset.GetDefaultPreset().m_name.GetCStr(), filePath.c_str(), result.GetError().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BuilderSettingManager::OnFileChanged(const QString &path)
|
||||
{
|
||||
// handles preset file change
|
||||
// Note: this signal only works with AP but not AssetBuilder
|
||||
AZ_TracePrintf(LogWindow, "File changed %s\n", path.toUtf8().data());
|
||||
QFileInfo info(path);
|
||||
|
||||
// skip if the file is not a preset file
|
||||
// Note: for .settings file change it's handled when restart AP.
|
||||
if (info.suffix() != s_presetFileExtension)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ReloadPreset(PresetName(info.baseName().toUtf8().data()));
|
||||
}
|
||||
|
||||
void BuilderSettingManager::OnFolderChanged([[maybe_unused]] const QString &path)
|
||||
{
|
||||
// handles new file added or removed
|
||||
// Note: this signal only works with AP but not AssetBuilder
|
||||
AZ_TracePrintf(LogWindow, "folder changed %s\n", path.toUtf8().data());
|
||||
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_presetMapLock);
|
||||
m_presets.clear();
|
||||
LoadPresets(m_defaultConfigFolder.Native());
|
||||
LoadPresets(m_projectConfigFolder.Native());
|
||||
|
||||
for (auto& preset : m_presets)
|
||||
{
|
||||
m_fileWatcher.data()->addPath(QString(preset.second.m_presetFilePath.c_str()));
|
||||
}
|
||||
}
|
||||
} // namespace ImageProcessingAtom
|
||||
|
||||
+56
-12
@@ -10,10 +10,15 @@
|
||||
|
||||
#include <BuilderSettings/ImageProcessingDefines.h>
|
||||
#include <BuilderSettings/BuilderSettings.h>
|
||||
#include <AzCore/std/containers/set.h>
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/std/containers/set.h>
|
||||
#include <Atom/ImageProcessing/ImageObject.h>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QScopedPointer>
|
||||
|
||||
class QSettings;
|
||||
class QString;
|
||||
|
||||
@@ -36,6 +41,7 @@ namespace ImageProcessingAtom
|
||||
* Each preset setting may have different values on different platform, but they are using same uuid.
|
||||
*/
|
||||
class BuilderSettingManager
|
||||
: public QObject // required for using QFileSystemWatcher
|
||||
{
|
||||
friend class ImageProcessingTest;
|
||||
|
||||
@@ -49,17 +55,21 @@ namespace ImageProcessingAtom
|
||||
static void DestroyInstance();
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
const PresetSettings* GetPreset(const PresetName& presetName, const PlatformName& platform = "", AZStd::string_view* settingsFilePathOut = nullptr);
|
||||
const PresetSettings* GetPreset(const PresetName& presetName, const PlatformName& platform = "", AZStd::string_view* settingsFilePathOut = nullptr) const;
|
||||
|
||||
const BuilderSettings* GetBuilderSetting(const PlatformName& platform);
|
||||
AZStd::vector<AZStd::string> GetFileMasksForPreset(const PresetName& presetName) const;
|
||||
|
||||
const BuilderSettings* GetBuilderSetting(const PlatformName& platform) const;
|
||||
|
||||
//! Return A list of platform supported
|
||||
const PlatformNameList GetPlatformList();
|
||||
const PlatformNameList GetPlatformList() const;
|
||||
|
||||
//! Return A map of preset settings based on their filemasks.
|
||||
//! @key filemask string, empty string means no filemask
|
||||
//! @value set of preset setting names supporting the specified filemask
|
||||
const AZStd::map<FileMask, AZStd::unordered_set<PresetName>>& GetPresetFilterMap();
|
||||
const AZStd::map<FileMask, AZStd::unordered_set<PresetName>>& GetPresetFilterMap() const;
|
||||
|
||||
const AZStd::unordered_set<PresetName>& GetFullPresetList() const;
|
||||
|
||||
//! Find preset name based on the preset id.
|
||||
const PresetName GetPresetNameFromId(const AZ::Uuid& presetId);
|
||||
@@ -68,7 +78,11 @@ namespace ImageProcessingAtom
|
||||
StringOutcome LoadConfig();
|
||||
|
||||
//! Load configurations files from a folder which includes builder settings and presets
|
||||
StringOutcome LoadConfigFromFolder(AZStd::string_view configFolder);
|
||||
//! Note: this is only used for unit test. Use LoadConfig() for editor or game launcher
|
||||
StringOutcome LoadConfigFromFolder(AZStd::string_view configFolder);
|
||||
|
||||
//! Reload preset from config folders
|
||||
void ReloadPreset(const PresetName& presetName);
|
||||
|
||||
const AZStd::string& GetAnalysisFingerprint() const;
|
||||
|
||||
@@ -81,7 +95,12 @@ namespace ImageProcessingAtom
|
||||
//! @param imageFilePath: Filepath string of the image file. The function may load the image from the path for better detection
|
||||
//! @param image: an optional image object which can be used for preset selection if there is no match based file mask.
|
||||
//! @return suggested preset name.
|
||||
PresetName GetSuggestedPreset(AZStd::string_view imageFilePath, IImageObjectPtr image = nullptr);
|
||||
PresetName GetSuggestedPreset(AZStd::string_view imageFilePath) const;
|
||||
|
||||
//! Get the possible preset config's full file paths
|
||||
//! This function is only used for setting up image's source dependency if a preset file is missing
|
||||
//! Otherwise, the preset's file path can be retrieved in GetPreset() function
|
||||
AZStd::vector<AZStd::string> GetPossiblePresetPaths(const PresetName& presetName) const;
|
||||
|
||||
bool IsValidPreset(PresetName presetName) const;
|
||||
|
||||
@@ -105,25 +124,41 @@ namespace ImageProcessingAtom
|
||||
private: // functions
|
||||
AZ_DISABLE_COPY_MOVE(BuilderSettingManager);
|
||||
|
||||
// Write image builder setting to the file specified by filepath
|
||||
StringOutcome WriteSettings(AZStd::string_view filepath);
|
||||
// Load image builder settings from the file specified by filepath
|
||||
StringOutcome LoadSettings(AZStd::string_view filepath);
|
||||
|
||||
// Load merge image builder settings (project and default)
|
||||
StringOutcome LoadSettings();
|
||||
|
||||
// report warnings for the deprecated properties in image builder setting data
|
||||
void ReportDeprecatedSettings();
|
||||
|
||||
// Clear Builder Settings and any cached maps/lists
|
||||
void ClearSettings();
|
||||
|
||||
// Regenerate Builder Settings and any cached maps/lists
|
||||
void RegenerateMappings();
|
||||
// collect file masks
|
||||
void CollectFileMasksFromPresets();
|
||||
|
||||
// Functions to save/load preset from a folder
|
||||
void SavePresets(AZStd::string_view outputFolder);
|
||||
void LoadPresets(AZStd::string_view presetFolder);
|
||||
|
||||
// Load a preset to m_presets and return true if success
|
||||
bool LoadPreset(const AZStd::string& filePath);
|
||||
|
||||
// handle preset files changes
|
||||
void OnFileChanged(const QString &path);
|
||||
void OnFolderChanged(const QString &path);
|
||||
|
||||
private: // variables
|
||||
|
||||
struct PresetEntry
|
||||
{
|
||||
MultiplatformPresetSettings m_multiPreset;
|
||||
AZStd::string m_presetFilePath; // Can be used for debug output
|
||||
QDateTime m_lastModifiedTime;
|
||||
};
|
||||
|
||||
// Builder settings for each platform
|
||||
@@ -131,13 +166,13 @@ namespace ImageProcessingAtom
|
||||
|
||||
AZStd::unordered_map<PresetName, PresetEntry> m_presets;
|
||||
|
||||
// Cached list of presets mapped by their file masks.
|
||||
// a list of presets mapped by their file masks.
|
||||
// @Key file mask, use empty string to indicate all presets without filtering
|
||||
// @Value set of preset names that matches the file mask
|
||||
AZStd::map <FileMask, AZStd::unordered_set<PresetName>> m_presetFilterMap;
|
||||
|
||||
// A mutex to protect when modifying any map in this manager
|
||||
AZStd::recursive_mutex m_presetMapLock;
|
||||
// A mutex to protect when modifying any map in this manager
|
||||
mutable AZStd::recursive_mutex m_presetMapLock;
|
||||
|
||||
// Default presets for certain file masks
|
||||
AZStd::map <FileMask, PresetName > m_defaultPresetByFileMask;
|
||||
@@ -153,5 +188,14 @@ namespace ImageProcessingAtom
|
||||
|
||||
// Image builder's version
|
||||
AZStd::string m_analysisFingerprint;
|
||||
|
||||
// default config folder
|
||||
AZ::IO::FixedMaxPath m_defaultConfigFolder;
|
||||
|
||||
// project config folder
|
||||
AZ::IO::FixedMaxPath m_projectConfigFolder;
|
||||
|
||||
// File system watcher to detect preset file changes
|
||||
QScopedPointer<QFileSystemWatcher> m_fileWatcher;
|
||||
};
|
||||
} // namespace ImageProcessingAtom
|
||||
|
||||
@@ -26,19 +26,19 @@ namespace ImageProcessingAtom
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
// "cm_ftype", cubemap angular filter type: gaussian, cone, disc, cosine, cosine_power, ggx
|
||||
CubemapFilterType m_filter;
|
||||
CubemapFilterType m_filter = CubemapFilterType::ggx;
|
||||
|
||||
// "cm_fangle", base filter angle for cubemap filtering(degrees), 0 - disabled
|
||||
float m_angle;
|
||||
float m_angle = 0;
|
||||
|
||||
// "cm_fmipangle", initial mip filter angle for cubemap filtering(degrees), 0 - disabled
|
||||
float m_mipAngle;
|
||||
float m_mipAngle = 0;
|
||||
|
||||
// "cm_fmipslope", mip filter angle multiplier for cubemap filtering, 1 - default"
|
||||
float m_mipSlope;
|
||||
float m_mipSlope = 1;
|
||||
|
||||
// "cm_edgefixup", cubemap edge fix-up width, 0 - disabled
|
||||
float m_edgeFixup;
|
||||
float m_edgeFixup = 0;
|
||||
|
||||
// generate an IBL specular cubemap
|
||||
bool m_generateIBLSpecular = false;
|
||||
|
||||
+2
-1
@@ -39,7 +39,8 @@ namespace ImageProcessingAtom
|
||||
#define STRING_OUTCOME_ERROR(error) AZ::Failure(AZStd::string(error))
|
||||
|
||||
// Common typedefs (with dependent forward-declarations)
|
||||
typedef AZStd::string PlatformName, FileMask;
|
||||
typedef AZStd::string PlatformName;
|
||||
typedef AZStd::string FileMask;
|
||||
typedef AZ::Name PresetName;
|
||||
typedef AZStd::vector<PlatformName> PlatformNameVector;
|
||||
typedef AZStd::list<PlatformName> PlatformNameList;
|
||||
|
||||
@@ -171,7 +171,7 @@ namespace ImageProcessingAtomEditor
|
||||
if (!preset)
|
||||
{
|
||||
AZ_Warning("Texture Editor", false, "Cannot find preset %s! Will assign a suggested one for the texture.", presetName.GetCStr());
|
||||
presetName = BuilderSettingManager::Instance()->GetSuggestedPreset(m_fullPath, m_img);
|
||||
presetName = BuilderSettingManager::Instance()->GetSuggestedPreset(m_fullPath);
|
||||
|
||||
for (auto& settingIter : m_settingsMap)
|
||||
{
|
||||
@@ -257,15 +257,22 @@ namespace ImageProcessingAtomEditor
|
||||
// Update input width and height if it's a cubemap
|
||||
if (presetSetting->m_cubemapSetting != nullptr)
|
||||
{
|
||||
CubemapLayout *srcCubemap = CubemapLayout::CreateCubemapLayout(m_img);
|
||||
if (srcCubemap == nullptr)
|
||||
if (IsValidLatLongMap(m_img))
|
||||
{
|
||||
return false;
|
||||
inputWidth = inputWidth/4;
|
||||
}
|
||||
else
|
||||
{
|
||||
CubemapLayout *srcCubemap = CubemapLayout::CreateCubemapLayout(m_img);
|
||||
if (srcCubemap == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
inputWidth = srcCubemap->GetFaceSize();
|
||||
delete srcCubemap;
|
||||
}
|
||||
inputWidth = srcCubemap->GetFaceSize();
|
||||
inputHeight = inputWidth;
|
||||
outResolutionInfo.arrayCount = 6;
|
||||
delete srcCubemap;
|
||||
}
|
||||
|
||||
GetOutputExtent(inputWidth, inputHeight, outResolutionInfo.width, outResolutionInfo.height, outResolutionInfo.reduce, &textureSetting, presetSetting);
|
||||
|
||||
+38
-18
@@ -18,6 +18,27 @@
|
||||
namespace ImageProcessingAtomEditor
|
||||
{
|
||||
using namespace ImageProcessingAtom;
|
||||
|
||||
AZStd::string GetImageFileMask(const AZStd::string& imageFilePath)
|
||||
{
|
||||
const char FileMaskDelimiter = '_';
|
||||
|
||||
//get file name
|
||||
AZStd::string fileName;
|
||||
QString lowerFileName = imageFilePath.data();
|
||||
lowerFileName = lowerFileName.toLower();
|
||||
AzFramework::StringFunc::Path::GetFileName(lowerFileName.toUtf8().constData(), fileName);
|
||||
|
||||
//get the substring from last '_'
|
||||
size_t lastUnderScore = fileName.find_last_of(FileMaskDelimiter);
|
||||
if (lastUnderScore != AZStd::string::npos)
|
||||
{
|
||||
return fileName.substr(lastUnderScore);
|
||||
}
|
||||
|
||||
return AZStd::string();
|
||||
}
|
||||
|
||||
TexturePresetSelectionWidget::TexturePresetSelectionWidget(EditorTextureSetting& textureSetting, QWidget* parent /*= nullptr*/)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::TexturePresetSelectionWidget)
|
||||
@@ -29,33 +50,31 @@ namespace ImageProcessingAtomEditor
|
||||
m_presetList.clear();
|
||||
auto& presetFilterMap = BuilderSettingManager::Instance()->GetPresetFilterMap();
|
||||
|
||||
AZStd::unordered_set<ImageProcessingAtom::PresetName> noFilterPresetList;
|
||||
|
||||
// Check if there is any filtered preset list first
|
||||
for(auto& presetFilter : presetFilterMap)
|
||||
if (m_listAllPresets)
|
||||
{
|
||||
if (presetFilter.first.empty())
|
||||
m_presetList = BuilderSettingManager::Instance()->GetFullPresetList();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto fileMask = GetImageFileMask(m_textureSetting->m_textureName);
|
||||
auto itr = presetFilterMap.find(fileMask);
|
||||
if (itr != presetFilterMap.end())
|
||||
{
|
||||
noFilterPresetList = presetFilter.second;
|
||||
m_presetList = itr->second;
|
||||
}
|
||||
else if (IsMatchingWithFileMask(m_textureSetting->m_textureName, presetFilter.first))
|
||||
else
|
||||
{
|
||||
for(const auto& presetName : presetFilter.second)
|
||||
{
|
||||
m_presetList.insert(presetName);
|
||||
}
|
||||
m_presetList = BuilderSettingManager::Instance()->GetFullPresetList();
|
||||
}
|
||||
}
|
||||
// If no filtered preset list available or should list all presets, use non-filter list
|
||||
if (m_presetList.size() == 0 || m_listAllPresets)
|
||||
{
|
||||
m_presetList = noFilterPresetList;
|
||||
}
|
||||
|
||||
QStringList stringList;
|
||||
foreach (const auto& presetName, m_presetList)
|
||||
{
|
||||
m_ui->presetComboBox->addItem(QString(presetName.GetCStr()));
|
||||
stringList.append(QString(presetName.GetCStr()));
|
||||
}
|
||||
stringList.sort();
|
||||
m_ui->presetComboBox->addItems(stringList);
|
||||
|
||||
// Set current preset
|
||||
const auto& currPreset = m_textureSetting->GetMultiplatformTextureSetting().m_preset;
|
||||
@@ -173,8 +192,9 @@ namespace ImageProcessingAtomEditor
|
||||
AZStd::string conventionText = "";
|
||||
if (presetSettings)
|
||||
{
|
||||
auto fileMasks = BuilderSettingManager::Instance()->GetFileMasksForPreset(presetSettings->m_name);
|
||||
int i = 0;
|
||||
for (const PlatformName& filemask : presetSettings->m_fileMasks)
|
||||
for (const auto& filemask : fileMasks)
|
||||
{
|
||||
conventionText += i > 0 ? " " + filemask : filemask;
|
||||
i++;
|
||||
|
||||
@@ -221,6 +221,58 @@ namespace ImageProcessingAtom
|
||||
m_isShuttingDown = true;
|
||||
}
|
||||
|
||||
PresetName GetImagePreset(const AZStd::string& filepath)
|
||||
{
|
||||
// first let preset from asset info
|
||||
TextureSettings textureSettings;
|
||||
StringOutcome output = TextureSettings::LoadTextureSetting(filepath, textureSettings);
|
||||
|
||||
if (!textureSettings.m_preset.IsEmpty())
|
||||
{
|
||||
return textureSettings.m_preset;
|
||||
}
|
||||
|
||||
return BuilderSettingManager::Instance()->GetSuggestedPreset(filepath);
|
||||
}
|
||||
|
||||
void HandlePresetDependency(PresetName presetName, AZStd::vector<AssetBuilderSDK::SourceFileDependency>& sourceDependencyList)
|
||||
{
|
||||
// Reload preset if it was changed
|
||||
ImageProcessingAtom::BuilderSettingManager::Instance()->ReloadPreset(presetName);
|
||||
|
||||
AZStd::string_view filePath;
|
||||
auto presetSettings = BuilderSettingManager::Instance()->GetPreset(presetName, /*default platform*/"", &filePath);
|
||||
|
||||
AssetBuilderSDK::SourceFileDependency sourceFileDependency;
|
||||
sourceFileDependency.m_sourceDependencyType = AssetBuilderSDK::SourceFileDependency::SourceFileDependencyType::Absolute;
|
||||
|
||||
// Need to watch any possibe preset paths
|
||||
AZStd::vector<AZStd::string> possiblePresetPaths = BuilderSettingManager::Instance()->GetPossiblePresetPaths(presetName);
|
||||
for (const auto& path:possiblePresetPaths)
|
||||
{
|
||||
sourceFileDependency.m_sourceFileDependencyPath = path;
|
||||
sourceDependencyList.push_back(sourceFileDependency);
|
||||
}
|
||||
|
||||
if (presetSettings)
|
||||
{
|
||||
// handle special case here
|
||||
// Cubemap setting may reference some other presets
|
||||
if (presetSettings->m_cubemapSetting)
|
||||
{
|
||||
if (presetSettings->m_cubemapSetting->m_generateIBLDiffuse && !presetSettings->m_cubemapSetting->m_iblDiffusePreset.IsEmpty())
|
||||
{
|
||||
HandlePresetDependency(presetSettings->m_cubemapSetting->m_iblDiffusePreset, sourceDependencyList);
|
||||
}
|
||||
|
||||
if (presetSettings->m_cubemapSetting->m_generateIBLSpecular && !presetSettings->m_cubemapSetting->m_iblSpecularPreset.IsEmpty())
|
||||
{
|
||||
HandlePresetDependency(presetSettings->m_cubemapSetting->m_iblSpecularPreset, sourceDependencyList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this happens early on in the file scanning pass
|
||||
// this function should consistently always create the same jobs, and should do no checking whether the job is up to date or not - just be consistent.
|
||||
void ImageBuilderWorker::CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response)
|
||||
@@ -242,13 +294,26 @@ namespace ImageProcessingAtom
|
||||
if (ImageProcessingAtom::BuilderSettingManager::Instance()->DoesSupportPlatform(platformInfo.m_identifier))
|
||||
{
|
||||
AssetBuilderSDK::JobDescriptor descriptor;
|
||||
descriptor.m_jobKey = ext + " Atom Compile";
|
||||
descriptor.m_jobKey = "Image Compile: " + ext;
|
||||
descriptor.SetPlatformIdentifier(platformInfo.m_identifier.c_str());
|
||||
descriptor.m_critical = false;
|
||||
descriptor.m_additionalFingerprintInfo = "";
|
||||
response.m_createJobOutputs.push_back(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
// add source dependency for .assetinfo file
|
||||
AssetBuilderSDK::SourceFileDependency sourceFileDependency;
|
||||
sourceFileDependency.m_sourceDependencyType = AssetBuilderSDK::SourceFileDependency::SourceFileDependencyType::Absolute;
|
||||
sourceFileDependency.m_sourceFileDependencyPath = request.m_sourceFile;
|
||||
AZ::StringFunc::Path::ReplaceExtension(sourceFileDependency.m_sourceFileDependencyPath, TextureSettings::ExtensionName);
|
||||
response.m_sourceFileDependencyList.push_back(sourceFileDependency);
|
||||
|
||||
// add source dependencies for .preset files
|
||||
// Get the preset for this file
|
||||
auto presetName = GetImagePreset(request.m_sourceFile);
|
||||
HandlePresetDependency(presetName, response.m_sourceFileDependencyList);
|
||||
|
||||
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <Processing/ImageConvert.h>
|
||||
#include <Processing/ImageAssetProducer.h>
|
||||
#include <Processing/ImageFlags.h>
|
||||
#include <Processing/Utils.h>
|
||||
#include <Converters/FIR-Weights.h>
|
||||
#include <Converters/Cubemap.h>
|
||||
#include <Converters/PixelOperation.h>
|
||||
@@ -229,12 +230,24 @@ namespace ImageProcessingAtom
|
||||
AZStd::unique_ptr<CubemapSettings>& cubemapSettings = m_input->m_presetSetting.m_cubemapSetting;
|
||||
if (cubemapSettings->m_generateIBLSpecular && !cubemapSettings->m_iblSpecularPreset.IsEmpty())
|
||||
{
|
||||
CreateIBLCubemap(cubemapSettings->m_iblSpecularPreset, SpecularCubemapSuffix, m_iblSpecularCubemapImage);
|
||||
bool success = CreateIBLCubemap(cubemapSettings->m_iblSpecularPreset, SpecularCubemapSuffix, m_iblSpecularCubemapImage);
|
||||
if (!success)
|
||||
{
|
||||
m_isSucceed = false;
|
||||
m_isFinished = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cubemapSettings->m_generateIBLDiffuse && !cubemapSettings->m_iblDiffusePreset.IsEmpty())
|
||||
{
|
||||
CreateIBLCubemap(cubemapSettings->m_iblDiffusePreset, DiffuseCubemapSuffix, m_iblDiffuseCubemapImage);
|
||||
bool success = CreateIBLCubemap(cubemapSettings->m_iblDiffusePreset, DiffuseCubemapSuffix, m_iblDiffuseCubemapImage);
|
||||
if (!success)
|
||||
{
|
||||
m_isSucceed = false;
|
||||
m_isFinished = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,7 +264,12 @@ namespace ImageProcessingAtom
|
||||
{
|
||||
if (m_input->m_presetSetting.m_cubemapSetting->m_requiresConvolve)
|
||||
{
|
||||
FillCubemapMipmaps();
|
||||
bool success = FillCubemapMipmaps();
|
||||
if (!success)
|
||||
{
|
||||
m_isSucceed = false;
|
||||
m_isFinished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -268,9 +286,7 @@ namespace ImageProcessingAtom
|
||||
// get gloss from normal for all mipmaps and save to alpha channel
|
||||
if (m_input->m_presetSetting.m_glossFromNormals)
|
||||
{
|
||||
bool hasAlpha = (m_alphaContent == EAlphaContent::eAlphaContent_OnlyBlack
|
||||
|| m_alphaContent == EAlphaContent::eAlphaContent_OnlyBlackAndWhite
|
||||
|| m_alphaContent == EAlphaContent::eAlphaContent_Greyscale);
|
||||
bool hasAlpha = Utils::NeedAlphaChannel(m_alphaContent);
|
||||
|
||||
m_image->Get()->GlossFromNormals(hasAlpha);
|
||||
// set alpha content so it won't be ignored later.
|
||||
@@ -347,7 +363,11 @@ namespace ImageProcessingAtom
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_TracePrintf("Image Processing", "Image converted with preset [%s] [%s] and saved to [%s] (%d bytes) taking %f seconds\n",
|
||||
|
||||
[[maybe_unused]] const PixelFormatInfo* formatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(m_image->Get()->GetPixelFormat());
|
||||
AZ_TracePrintf("Image Processing", "Image [%dx%d] [%s] converted with preset [%s] [%s] and saved to [%s] (%d bytes) taking %f seconds\n",
|
||||
m_image->Get()->GetWidth(0), m_image->Get()->GetHeight(0),
|
||||
formatInfo->szName,
|
||||
m_input->m_presetSetting.m_name.GetCStr(),
|
||||
m_input->m_filePath.c_str(),
|
||||
m_input->m_outputFolder.c_str(), sizeTotal, m_processTime);
|
||||
@@ -421,6 +441,17 @@ namespace ImageProcessingAtom
|
||||
outHeight >>= 1;
|
||||
outReduce++;
|
||||
}
|
||||
|
||||
// resize to min texture size if it's smaller
|
||||
if (outWidth < presetSettings->m_minTextureSize)
|
||||
{
|
||||
outWidth = presetSettings->m_minTextureSize;
|
||||
}
|
||||
|
||||
if (outHeight < presetSettings->m_minTextureSize)
|
||||
{
|
||||
outHeight = presetSettings->m_minTextureSize;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImageConvertProcess::ConvertToLinear()
|
||||
@@ -647,7 +678,7 @@ namespace ImageProcessingAtom
|
||||
}
|
||||
else if (!CPixelFormats::GetInstance().IsImageSizeValid(dstFmt, dwWidth, dwHeight, false))
|
||||
{
|
||||
AZ_Warning("Image Processing", false, "Image size will be scaled for pixel format %s", CPixelFormats::GetInstance().GetPixelFormatInfo(dstFmt)->szName);
|
||||
AZ_TracePrintf("Image processing", "Image size will be scaled for pixel format %s\n", CPixelFormats::GetInstance().GetPixelFormatInfo(dstFmt)->szName);
|
||||
}
|
||||
|
||||
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
|
||||
@@ -758,7 +789,7 @@ namespace ImageProcessingAtom
|
||||
// in very rare user case, an old texture setting file may not have a preset. We fix it over here too.
|
||||
if (textureSettings.m_preset.IsEmpty())
|
||||
{
|
||||
textureSettings.m_preset = BuilderSettingManager::Instance()->GetSuggestedPreset(imageFilePath, srcImage);
|
||||
textureSettings.m_preset = BuilderSettingManager::Instance()->GetSuggestedPreset(imageFilePath);
|
||||
}
|
||||
|
||||
// Get preset
|
||||
@@ -795,7 +826,7 @@ namespace ImageProcessingAtom
|
||||
return process;
|
||||
}
|
||||
|
||||
void ImageConvertProcess::CreateIBLCubemap(PresetName preset, const char* fileNameSuffix, IImageObjectPtr& cubemapImage)
|
||||
bool ImageConvertProcess::CreateIBLCubemap(PresetName preset, const char* fileNameSuffix, IImageObjectPtr& cubemapImage)
|
||||
{
|
||||
const AZStd::string& platformId = m_input->m_platform;
|
||||
AZStd::string_view filePath;
|
||||
@@ -803,7 +834,7 @@ namespace ImageProcessingAtom
|
||||
if (presetSettings == nullptr)
|
||||
{
|
||||
AZ_Error("Image Processing", false, "Couldn't find preset for IBL cubemap generation");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// generate export file name
|
||||
@@ -838,14 +869,14 @@ namespace ImageProcessingAtom
|
||||
if (!imageConvertProcess)
|
||||
{
|
||||
AZ_Error("Image Processing", false, "Failed to create image convert process for the IBL cubemap");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
imageConvertProcess->ProcessAll();
|
||||
if (!imageConvertProcess->IsSucceed())
|
||||
{
|
||||
AZ_Error("Image Processing", false, "Image convert process for the IBL cubemap failed");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// append the output products to the job's product list
|
||||
@@ -853,6 +884,7 @@ namespace ImageProcessingAtom
|
||||
|
||||
// store the output cubemap so it can be accessed by unit tests
|
||||
cubemapImage = imageConvertProcess->m_image->Get();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConvertImageFile(const AZStd::string& imageFilePath, const AZStd::string& exportDir,
|
||||
@@ -873,68 +905,6 @@ namespace ImageProcessingAtom
|
||||
return result;
|
||||
}
|
||||
|
||||
IImageObjectPtr MergeOutputImageForPreview(IImageObjectPtr image, IImageObjectPtr alphaImage)
|
||||
{
|
||||
if (!image)
|
||||
{
|
||||
return IImageObjectPtr();
|
||||
}
|
||||
|
||||
ImageToProcess imageToProcess(image);
|
||||
imageToProcess.ConvertFormat(ePixelFormat_R8G8B8A8);
|
||||
IImageObjectPtr previewImage = imageToProcess.Get();
|
||||
|
||||
// If there is separate Alpha image, combine it with output
|
||||
if (alphaImage)
|
||||
{
|
||||
// Create pixel operation function for rgb and alpha images
|
||||
IPixelOperationPtr imageOp = CreatePixelOperation(ePixelFormat_R8G8B8A8);
|
||||
IPixelOperationPtr alphaOp = CreatePixelOperation(ePixelFormat_A8);
|
||||
|
||||
// Convert the alpha image to A8 first
|
||||
ImageToProcess imageToProcess2(alphaImage);
|
||||
imageToProcess2.ConvertFormat(ePixelFormat_A8);
|
||||
IImageObjectPtr previewImageAlpha = imageToProcess2.Get();
|
||||
|
||||
const uint32 imageMips = previewImage->GetMipCount();
|
||||
[[maybe_unused]] const uint32 alphaMips = previewImageAlpha->GetMipCount();
|
||||
|
||||
// Get count of bytes per pixel for both rgb and alpha images
|
||||
uint32 imagePixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(ePixelFormat_R8G8B8A8)->bitsPerBlock / 8;
|
||||
uint32 alphaPixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(ePixelFormat_A8)->bitsPerBlock / 8;
|
||||
|
||||
AZ_Assert(imageMips <= alphaMips, "Mip level of alpha image is less than origin image!");
|
||||
|
||||
// For each mip level, set the alpha value to the image
|
||||
for (uint32 mipLevel = 0; mipLevel < imageMips; ++mipLevel)
|
||||
{
|
||||
const uint32 pixelCount = previewImage->GetPixelCount(mipLevel);
|
||||
[[maybe_unused]] const uint32 alphaPixelCount = previewImageAlpha->GetPixelCount(mipLevel);
|
||||
|
||||
AZ_Assert(pixelCount == alphaPixelCount, "Pixel count for image and alpha image at mip level %d is not equal!", mipLevel);
|
||||
|
||||
uint8* imageBuf;
|
||||
uint32 pitch;
|
||||
previewImage->GetImagePointer(mipLevel, imageBuf, pitch);
|
||||
|
||||
uint8* alphaBuf;
|
||||
uint32 alphaPitch;
|
||||
previewImageAlpha->GetImagePointer(mipLevel, alphaBuf, alphaPitch);
|
||||
|
||||
float rAlpha, gAlpha, bAlpha, aAlpha, rImage, gImage, bImage, aImage;
|
||||
|
||||
for (uint32 i = 0; i < pixelCount; ++i, imageBuf += imagePixelBytes, alphaBuf += alphaPixelBytes)
|
||||
{
|
||||
alphaOp->GetRGBA(alphaBuf, rAlpha, gAlpha, bAlpha, aAlpha);
|
||||
imageOp->GetRGBA(imageBuf, rImage, gImage, bImage, aImage);
|
||||
imageOp->SetRGBA(imageBuf, rImage, gImage, bImage, aAlpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return previewImage;
|
||||
}
|
||||
|
||||
IImageObjectPtr ConvertImageForPreview(IImageObjectPtr image)
|
||||
{
|
||||
if (!image)
|
||||
|
||||
@@ -51,9 +51,6 @@ namespace ImageProcessingAtom
|
||||
//Converts the image to a RGBA8 format that can be displayed in a preview UI.
|
||||
IImageObjectPtr ConvertImageForPreview(IImageObjectPtr image);
|
||||
|
||||
//Combine image with alpha image if any and output as RGBA8
|
||||
IImageObjectPtr MergeOutputImageForPreview(IImageObjectPtr image, IImageObjectPtr alphaImage);
|
||||
|
||||
//get output image size and mip count based on the texture setting and preset setting
|
||||
|
||||
//other helper functions
|
||||
@@ -160,7 +157,7 @@ namespace ImageProcessingAtom
|
||||
bool FillCubemapMipmaps();
|
||||
|
||||
//IBL cubemap generation, this creates a separate ImageConvertProcess
|
||||
void CreateIBLCubemap(PresetName preset, const char* fileNameSuffix, IImageObjectPtr& cubemapImage);
|
||||
bool CreateIBLCubemap(PresetName preset, const char* fileNameSuffix, IImageObjectPtr& cubemapImage);
|
||||
|
||||
//convert color space to linear with pixel format rgba32f
|
||||
bool ConvertToLinear();
|
||||
|
||||
@@ -16,28 +16,14 @@
|
||||
|
||||
namespace ImageProcessingAtom
|
||||
{
|
||||
IImageObjectPtr ImageConvertOutput::GetOutputImage(OutputImageType type) const
|
||||
IImageObjectPtr ImageConvertOutput::GetOutputImage() const
|
||||
{
|
||||
if (type < OutputImageType::Count)
|
||||
{
|
||||
return m_outputImage[static_cast<int>(type)];
|
||||
}
|
||||
else
|
||||
{
|
||||
return IImageObjectPtr();
|
||||
}
|
||||
return m_outputImage;
|
||||
}
|
||||
|
||||
void ImageConvertOutput::SetOutputImage(IImageObjectPtr image, OutputImageType type)
|
||||
void ImageConvertOutput::SetOutputImage(IImageObjectPtr image)
|
||||
{
|
||||
if (type < OutputImageType::Count)
|
||||
{
|
||||
m_outputImage[static_cast<int>(type)] = image;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("ImageProcess", false, "Cannot set output image to %d", type);
|
||||
}
|
||||
m_outputImage = image;
|
||||
}
|
||||
|
||||
void ImageConvertOutput::SetReady(bool ready)
|
||||
@@ -62,10 +48,7 @@ namespace ImageProcessingAtom
|
||||
|
||||
void ImageConvertOutput::Reset()
|
||||
{
|
||||
for (int i = 0; i < static_cast<int>(OutputImageType::Count); i++)
|
||||
{
|
||||
m_outputImage[i] = nullptr;
|
||||
}
|
||||
m_outputImage = nullptr;
|
||||
m_outputReady = false;
|
||||
m_progress = 0.0f;
|
||||
}
|
||||
@@ -109,13 +92,12 @@ namespace ImageProcessingAtom
|
||||
|
||||
IImageObjectPtr outputImage = m_process->GetOutputImage();
|
||||
|
||||
m_output->SetOutputImage(outputImage, ImageConvertOutput::Base);
|
||||
|
||||
if (!IsJobCancelled())
|
||||
{
|
||||
// For preview, combine image output with alpha if any
|
||||
// convert the output image to RGBA format for preview
|
||||
m_output->SetProgress(1.0f / static_cast<float>(m_previewProcessStep));
|
||||
m_output->SetOutputImage(outputImage, ImageConvertOutput::Preview);
|
||||
IImageObjectPtr uncompressedImage = ConvertImageForPreview(outputImage);
|
||||
m_output->SetOutputImage(uncompressedImage);
|
||||
}
|
||||
|
||||
m_output->SetReady(true);
|
||||
|
||||
@@ -21,16 +21,8 @@ namespace ImageProcessingAtom
|
||||
class ImageConvertOutput
|
||||
{
|
||||
public:
|
||||
enum OutputImageType
|
||||
{
|
||||
Base = 0, // Might contains alpha or not
|
||||
Alpha, // Separate alpha image
|
||||
Preview, // Combine base image with alpha if any, format RGBA8
|
||||
Count
|
||||
};
|
||||
|
||||
IImageObjectPtr GetOutputImage(OutputImageType type) const;
|
||||
void SetOutputImage(IImageObjectPtr image, OutputImageType type);
|
||||
IImageObjectPtr GetOutputImage() const;
|
||||
void SetOutputImage(IImageObjectPtr image);
|
||||
void SetReady(bool ready);
|
||||
bool IsReady() const;
|
||||
float GetProgress() const;
|
||||
@@ -38,7 +30,7 @@ namespace ImageProcessingAtom
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
IImageObjectPtr m_outputImage[OutputImageType::Count];
|
||||
IImageObjectPtr m_outputImage;
|
||||
bool m_outputReady = false;
|
||||
float m_progress = 0.0f;
|
||||
};
|
||||
|
||||
@@ -183,10 +183,9 @@ namespace ImageProcessingAtom
|
||||
return EAlphaContent::eAlphaContent_Absent;
|
||||
}
|
||||
|
||||
//if it's compressed format, return indeterminate. if user really want to know the content, they may convert the format to ARGB8 first
|
||||
if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat))
|
||||
{
|
||||
AZ_Assert(false, "the function only works right with uncompressed formats. convert to uncompressed format if you get accurate result");
|
||||
AZ_TracePrintf("Image processing", "GetAlphaContent() was called for compressed format\n");
|
||||
return EAlphaContent::eAlphaContent_Indeterminate;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace ImageProcessingAtom
|
||||
|
||||
IImageObjectPtr ImagePreview::GetOutputImage()
|
||||
{
|
||||
return m_output.GetOutputImage(ImageConvertOutput::Preview);
|
||||
return m_output.GetOutputImage();
|
||||
}
|
||||
|
||||
ImagePreview::~ImagePreview()
|
||||
|
||||
@@ -385,6 +385,13 @@ namespace ImageProcessingAtom
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NeedAlphaChannel(EAlphaContent alphaContent)
|
||||
{
|
||||
return (alphaContent == EAlphaContent::eAlphaContent_OnlyBlack
|
||||
|| alphaContent == EAlphaContent::eAlphaContent_OnlyBlackAndWhite
|
||||
|| alphaContent == EAlphaContent::eAlphaContent_Greyscale);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ImageProcessingAtom
|
||||
|
||||
@@ -26,5 +26,7 @@ namespace ImageProcessingAtom
|
||||
IImageObjectPtr LoadImageFromImageAsset(const AZ::Data::Asset<AZ::RPI::StreamingImageAsset>& asset);
|
||||
|
||||
bool SaveImageToDdsFile(IImageObjectPtr image, AZStd::string_view filePath);
|
||||
|
||||
bool NeedAlphaChannel(EAlphaContent alphaContent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ namespace UnitTest
|
||||
m_gemFolder = AZ::Test::GetEngineRootPath() + "/Gems/Atom/Asset/ImageProcessingAtom/";
|
||||
m_outputFolder = m_gemFolder + AZStd::string("Code/Tests/TestAssets/temp/");
|
||||
|
||||
m_defaultSettingFolder = m_gemFolder + AZStd::string("Config/");
|
||||
m_defaultSettingFolder = m_gemFolder + AZStd::string("Assets/Config/");
|
||||
m_testFileFolder = m_gemFolder + AZStd::string("Code/Tests/TestAssets/");
|
||||
|
||||
InitialImageFilenames();
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "BuilderSettingManager",
|
||||
"ClassData": {
|
||||
"AnalysisFingerprint": "2",
|
||||
"BuildSettings": {
|
||||
"android": {
|
||||
"GlossScale": 16.0,
|
||||
"GlossBias": 0.0,
|
||||
"Streaming": false,
|
||||
"Enable": true
|
||||
},
|
||||
"ios": {
|
||||
"GlossScale": 16.0,
|
||||
"GlossBias": 0.0,
|
||||
"Streaming": false,
|
||||
"Enable": true
|
||||
},
|
||||
"mac": {
|
||||
"GlossScale": 16.0,
|
||||
"GlossBias": 0.0,
|
||||
"Streaming": false,
|
||||
"Enable": true
|
||||
},
|
||||
"pc": {
|
||||
"GlossScale": 16.0,
|
||||
"GlossBias": 0.0,
|
||||
"Streaming": false,
|
||||
"Enable": true
|
||||
},
|
||||
"linux": {
|
||||
"GlossScale": 16.0,
|
||||
"GlossBias": 0.0,
|
||||
"Streaming": false,
|
||||
"Enable": true
|
||||
},
|
||||
"provo": {
|
||||
"GlossScale": 16.0,
|
||||
"GlossBias": 0.0,
|
||||
"Streaming": false,
|
||||
"Enable": false
|
||||
}
|
||||
},
|
||||
"DefaultPresetsByFileMask": {
|
||||
"_basecolor": "Albedo",
|
||||
"_diff": "Albedo",
|
||||
"_diffuse": "Albedo",
|
||||
"_ddn": "Normals",
|
||||
"_normal": "Normals",
|
||||
"_ddna": "NormalsWithSmoothness",
|
||||
"_glossness": "Reflectance",
|
||||
"_spec": "Reflectance",
|
||||
"_specular": "Reflectance",
|
||||
"_metallic": "Reflectance",
|
||||
"_refl": "Reflectance",
|
||||
"_roughness": "Reflectance",
|
||||
"_ibldiffusecm": "IBLDiffuse",
|
||||
"_iblskyboxcm": "IBLSkybox",
|
||||
"_iblspecularcm": "IBLSpecular",
|
||||
"_skyboxcm": "Skybox"
|
||||
},
|
||||
"DefaultPreset": "Albedo",
|
||||
"DefaultPresetAlpha": "AlbedoWithGenericAlpha",
|
||||
"DefaultPresetNonePOT": "ReferenceImage"
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "MultiplatformPresetSettings",
|
||||
"ClassData": {
|
||||
"DefaultPreset": {
|
||||
"UUID": "{7A3CC95E-0A0C-4CA1-8357-5712B028B77D}",
|
||||
"Name": "Reflectance",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_spec",
|
||||
"_refl",
|
||||
"_ref",
|
||||
"_rf",
|
||||
"_gloss",
|
||||
"_g",
|
||||
"_f0",
|
||||
"_specf0",
|
||||
"_specular",
|
||||
"_metal",
|
||||
"_mtl",
|
||||
"_m",
|
||||
"_mt",
|
||||
"_metalness",
|
||||
"_metallic",
|
||||
"_roughness",
|
||||
"_rough"
|
||||
],
|
||||
"PixelFormat": "BC1",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
},
|
||||
"PlatformsPresets": {
|
||||
"android": {
|
||||
"UUID": "{7A3CC95E-0A0C-4CA1-8357-5712B028B77D}",
|
||||
"Name": "Reflectance",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_spec",
|
||||
"_refl",
|
||||
"_ref",
|
||||
"_rf",
|
||||
"_gloss",
|
||||
"_g",
|
||||
"_f0",
|
||||
"_specf0",
|
||||
"_metal",
|
||||
"_mtl",
|
||||
"_m",
|
||||
"_mt",
|
||||
"_metalness",
|
||||
"_metallic",
|
||||
"_roughness",
|
||||
"_rough"
|
||||
],
|
||||
"PixelFormat": "ASTC_6x6",
|
||||
"MaxTextureSize": 2048,
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
},
|
||||
"ios": {
|
||||
"UUID": "{7A3CC95E-0A0C-4CA1-8357-5712B028B77D}",
|
||||
"Name": "Reflectance",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_spec",
|
||||
"_refl",
|
||||
"_ref",
|
||||
"_rf",
|
||||
"_gloss",
|
||||
"_g",
|
||||
"_f0",
|
||||
"_specf0",
|
||||
"_metal",
|
||||
"_mtl",
|
||||
"_m",
|
||||
"_mt",
|
||||
"_metalness",
|
||||
"_metallic",
|
||||
"_roughness",
|
||||
"_rough"
|
||||
],
|
||||
"PixelFormat": "ASTC_6x6",
|
||||
"MaxTextureSize": 2048,
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
},
|
||||
"mac": {
|
||||
"UUID": "{7A3CC95E-0A0C-4CA1-8357-5712B028B77D}",
|
||||
"Name": "Reflectance",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_spec",
|
||||
"_refl",
|
||||
"_ref",
|
||||
"_rf",
|
||||
"_gloss",
|
||||
"_g",
|
||||
"_f0",
|
||||
"_specf0",
|
||||
"_metal",
|
||||
"_mtl",
|
||||
"_m",
|
||||
"_mt",
|
||||
"_metalness",
|
||||
"_metallic",
|
||||
"_roughness",
|
||||
"_rough"
|
||||
],
|
||||
"PixelFormat": "BC1",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
},
|
||||
"provo": {
|
||||
"UUID": "{7A3CC95E-0A0C-4CA1-8357-5712B028B77D}",
|
||||
"Name": "Reflectance",
|
||||
"SourceColor": "Linear",
|
||||
"DestColor": "Linear",
|
||||
"FileMasks": [
|
||||
"_spec",
|
||||
"_refl",
|
||||
"_ref",
|
||||
"_rf",
|
||||
"_gloss",
|
||||
"_g",
|
||||
"_f0",
|
||||
"_specf0",
|
||||
"_metal",
|
||||
"_mtl",
|
||||
"_m",
|
||||
"_mt",
|
||||
"_metalness",
|
||||
"_metallic",
|
||||
"_roughness",
|
||||
"_rough"
|
||||
],
|
||||
"PixelFormat": "BC1",
|
||||
"IsPowerOf2": true,
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,10 +34,6 @@
|
||||
}
|
||||
],
|
||||
"PassRequests": [
|
||||
{
|
||||
"Name": "ReflectionScreenSpaceBlurPass",
|
||||
"TemplateName": "ReflectionScreenSpaceBlurPassTemplate"
|
||||
},
|
||||
{
|
||||
"Name": "ReflectionScreenSpaceTracePass",
|
||||
"TemplateName": "ReflectionScreenSpaceTracePassTemplate",
|
||||
@@ -56,42 +52,65 @@
|
||||
"Attachment": "NormalInput"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "DepthStencilInput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "Parent",
|
||||
"Attachment": "DepthStencilInput"
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "SpecularF0Input",
|
||||
"AttachmentRef": {
|
||||
"Pass": "Parent",
|
||||
"Attachment": "SpecularF0Input"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "ReflectionInputOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "Parent",
|
||||
"Attachment": "ReflectionInputOutput"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "ReflectionScreenSpaceBlurPass",
|
||||
"TemplateName": "ReflectionScreenSpaceBlurPassTemplate",
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "DepthInput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "Parent",
|
||||
"Attachment": "DepthStencilInput"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "ScreenSpaceReflectionInputOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "ReflectionScreenSpaceTracePass",
|
||||
"Attachment": "ScreenSpaceReflectionOutput"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "DownsampledDepthInputOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "ReflectionScreenSpaceTracePass",
|
||||
"Attachment": "DownsampledDepthOutput"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "ReflectionScreenSpaceCompositePass",
|
||||
"TemplateName": "ReflectionScreenSpaceCompositePassTemplate",
|
||||
"ExecuteAfter": [
|
||||
"ReflectionScreenSpaceBlurPass"
|
||||
],
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "TraceInput",
|
||||
"LocalSlot": "ReflectionInput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "ReflectionScreenSpaceTracePass",
|
||||
"Attachment": "Output"
|
||||
"Pass": "ReflectionScreenSpaceBlurPass",
|
||||
"Attachment": "ScreenSpaceReflectionInputOutput"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "PreviousFrameBufferInput",
|
||||
"LocalSlot": "DownsampledDepthInput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "ReflectionScreenSpaceBlurPass",
|
||||
"Attachment": "PreviousFrameInputOutput"
|
||||
"Attachment": "DownsampledDepthInputOutput"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -115,6 +134,13 @@
|
||||
"Attachment": "DepthStencilInput"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "PreviousFrameInputOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "ReflectionScreenSpaceTracePass",
|
||||
"Attachment": "PreviousFrameInputOutput"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "DepthStencilInput",
|
||||
"AttachmentRef": {
|
||||
|
||||
@@ -8,34 +8,19 @@
|
||||
"PassClass": "ReflectionScreenSpaceBlurPass",
|
||||
"Slots": [
|
||||
{
|
||||
"Name": "PreviousFrameInputOutput",
|
||||
"Name": "DepthInput",
|
||||
"SlotType": "Input",
|
||||
"ScopeAttachmentUsage": "Shader"
|
||||
},
|
||||
{
|
||||
"Name": "ScreenSpaceReflectionInputOutput",
|
||||
"SlotType": "InputOutput",
|
||||
"ScopeAttachmentUsage": "Shader"
|
||||
}
|
||||
],
|
||||
"ImageAttachments": [
|
||||
},
|
||||
{
|
||||
"Name": "PreviousFrameImage",
|
||||
"SizeSource": {
|
||||
"Source": {
|
||||
"Pass": "Parent",
|
||||
"Attachment": "SpecularInput"
|
||||
}
|
||||
},
|
||||
"ImageDescriptor": {
|
||||
"Format": "R16G16B16A16_FLOAT",
|
||||
"SharedQueueMask": "Graphics"
|
||||
},
|
||||
"GenerateFullMipChain": true
|
||||
}
|
||||
],
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "PreviousFrameInputOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "This",
|
||||
"Attachment": "PreviousFrameImage"
|
||||
}
|
||||
"Name": "DownsampledDepthInputOutput",
|
||||
"SlotType": "InputOutput",
|
||||
"ScopeAttachmentUsage": "DepthStencil"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
"Name": "ReflectionScreenSpaceBlurVerticalPassTemplate",
|
||||
"PassClass": "ReflectionScreenSpaceBlurChildPass",
|
||||
"Slots": [
|
||||
{
|
||||
"Name": "DepthInput",
|
||||
"SlotType": "Input",
|
||||
"ScopeAttachmentUsage": "Shader"
|
||||
},
|
||||
{
|
||||
"Name": "Input",
|
||||
"SlotType": "InputOutput",
|
||||
@@ -16,6 +21,20 @@
|
||||
"Name": "Output",
|
||||
"SlotType": "InputOutput",
|
||||
"ScopeAttachmentUsage": "RenderTarget"
|
||||
},
|
||||
{
|
||||
"Name": "DownsampledDepthOutput",
|
||||
"SlotType": "InputOutput",
|
||||
"ScopeAttachmentUsage": "DepthStencil"
|
||||
}
|
||||
],
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "DepthInput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "Parent",
|
||||
"Attachment": "DepthInput"
|
||||
}
|
||||
}
|
||||
],
|
||||
"PassData": {
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
"PassClass": "ReflectionScreenSpaceCompositePass",
|
||||
"Slots": [
|
||||
{
|
||||
"Name": "TraceInput",
|
||||
"Name": "ReflectionInput",
|
||||
"SlotType": "Input",
|
||||
"ScopeAttachmentUsage": "Shader"
|
||||
},
|
||||
{
|
||||
"Name": "PreviousFrameBufferInput",
|
||||
"Name": "DownsampledDepthInput",
|
||||
"SlotType": "Input",
|
||||
"ScopeAttachmentUsage": "Shader"
|
||||
},
|
||||
@@ -37,6 +37,11 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "PreviousFrameInputOutput",
|
||||
"SlotType": "InputOutput",
|
||||
"ScopeAttachmentUsage": "Shader"
|
||||
},
|
||||
{
|
||||
"Name": "DepthStencilInput",
|
||||
"SlotType": "Input",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"ClassData": {
|
||||
"PassTemplate": {
|
||||
"Name": "ReflectionScreenSpaceTracePassTemplate",
|
||||
"PassClass": "FullScreenTriangle",
|
||||
"PassClass": "ReflectionScreenSpaceTracePass",
|
||||
"Slots": [
|
||||
{
|
||||
"Name": "DepthStencilTextureInput",
|
||||
@@ -28,24 +28,52 @@
|
||||
"ScopeAttachmentUsage": "Shader"
|
||||
},
|
||||
{
|
||||
"Name": "DepthStencilInput",
|
||||
"Name": "ReflectionInputOutput",
|
||||
"SlotType": "Input",
|
||||
"ScopeAttachmentUsage": "DepthStencil",
|
||||
"ImageViewDesc": {
|
||||
"AspectFlags": [
|
||||
"Stencil"
|
||||
]
|
||||
"ScopeAttachmentUsage": "Shader"
|
||||
},
|
||||
{
|
||||
"Name": "PreviousFrameInputOutput",
|
||||
"SlotType": "Input",
|
||||
"ScopeAttachmentUsage": "Shader"
|
||||
},
|
||||
{
|
||||
"Name": "ScreenSpaceReflectionOutput",
|
||||
"SlotType": "Output",
|
||||
"ScopeAttachmentUsage": "RenderTarget",
|
||||
"LoadStoreAction": {
|
||||
"ClearValue": {
|
||||
"Value": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"LoadAction": "Clear"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "Output",
|
||||
"Name": "DownsampledDepthOutput",
|
||||
"SlotType": "Output",
|
||||
"ScopeAttachmentUsage": "RenderTarget"
|
||||
"ScopeAttachmentUsage": "DepthStencil",
|
||||
"LoadStoreAction": {
|
||||
"ClearValue": {
|
||||
"Type": "DepthStencil",
|
||||
"Value": [
|
||||
1.0,
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
]
|
||||
},
|
||||
"LoadAction": "Clear"
|
||||
}
|
||||
}
|
||||
],
|
||||
"ImageAttachments": [
|
||||
{
|
||||
"Name": "TraceImage",
|
||||
"Name": "ScreenSpaceReflectionImage",
|
||||
"SizeSource": {
|
||||
"Source": {
|
||||
"Pass": "This",
|
||||
@@ -56,9 +84,40 @@
|
||||
"HeightMultiplier": 0.5
|
||||
}
|
||||
},
|
||||
"MultisampleSource": {
|
||||
"Pass": "This",
|
||||
"Attachment": "SpecularF0Input"
|
||||
"ImageDescriptor": {
|
||||
"Format": "R16G16B16A16_FLOAT",
|
||||
"MipLevels": "5",
|
||||
"SharedQueueMask": "Graphics"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "DownsampledDepthImage",
|
||||
"SizeSource": {
|
||||
"Source": {
|
||||
"Pass": "Parent",
|
||||
"Attachment": "DepthStencilInput"
|
||||
},
|
||||
"Multipliers": {
|
||||
"WidthMultiplier": 0.5,
|
||||
"HeightMultiplier": 0.5
|
||||
}
|
||||
},
|
||||
"FormatSource": {
|
||||
"Pass": "Parent",
|
||||
"Attachment": "DepthStencilInput"
|
||||
},
|
||||
"ImageDescriptor": {
|
||||
"MipLevels": "5",
|
||||
"SharedQueueMask": "Graphics"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "PreviousFrameImage",
|
||||
"SizeSource": {
|
||||
"Source": {
|
||||
"Pass": "Parent",
|
||||
"Attachment": "SpecularInput"
|
||||
}
|
||||
},
|
||||
"ImageDescriptor": {
|
||||
"Format": "R16G16B16A16_FLOAT",
|
||||
@@ -68,15 +127,28 @@
|
||||
],
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "Output",
|
||||
"LocalSlot": "ScreenSpaceReflectionOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "This",
|
||||
"Attachment": "TraceImage"
|
||||
"Attachment": "ScreenSpaceReflectionImage"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "DownsampledDepthOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "This",
|
||||
"Attachment": "DownsampledDepthImage"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "PreviousFrameInputOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "This",
|
||||
"Attachment": "PreviousFrameImage"
|
||||
}
|
||||
}
|
||||
],
|
||||
"PassData":
|
||||
{
|
||||
"PassData": {
|
||||
"$type": "FullscreenTrianglePassData",
|
||||
"ShaderAsset": {
|
||||
"FilePath": "Shaders/Reflections/ReflectionScreenSpaceTrace.shader"
|
||||
|
||||
+8
-1
@@ -14,6 +14,7 @@
|
||||
#include <Atom/RPI/Math.azsli>
|
||||
#include "BicubicPcfFilters.azsli"
|
||||
#include "Shadow.azsli"
|
||||
#include "NormalOffsetShadows.azsli"
|
||||
|
||||
// ProjectedShadow calculates shadowed area projected from a light.
|
||||
class ProjectedShadow
|
||||
@@ -123,6 +124,7 @@ float ProjectedShadow::GetThickness(uint shadowIndex, float3 worldPosition)
|
||||
|
||||
ProjectedShadow shadow;
|
||||
shadow.m_worldPosition = worldPosition;
|
||||
shadow.m_normalVector = 0; // The normal vector is used to reduce acne, this is not an issue when using the shadowmap to determine thickness.
|
||||
shadow.m_shadowIndex = shadowIndex;
|
||||
shadow.SetShadowPosition();
|
||||
return shadow.GetThickness();
|
||||
@@ -317,8 +319,13 @@ bool ProjectedShadow::IsShadowed(float3 shadowPosition)
|
||||
|
||||
void ProjectedShadow::SetShadowPosition()
|
||||
{
|
||||
const float normalBias = ViewSrg::m_projectedShadows[m_shadowIndex].m_normalShadowBias;
|
||||
const float shadowmapSize = ViewSrg::m_projectedFilterParams[m_shadowIndex].m_shadowmapSize;
|
||||
const float3 shadowOffset = ComputeNormalShadowOffset(normalBias, m_normalVector, shadowmapSize);
|
||||
const float4x4 depthBiasMatrix = ViewSrg::m_projectedShadows[m_shadowIndex].m_depthBiasMatrix;
|
||||
float4 shadowPositionHomogeneous = mul(depthBiasMatrix, float4(m_worldPosition, 1));
|
||||
|
||||
float4 shadowPositionHomogeneous = mul(depthBiasMatrix, float4(m_worldPosition + shadowOffset, 1));
|
||||
|
||||
m_shadowPosition = shadowPositionHomogeneous.xyz / shadowPositionHomogeneous.w;
|
||||
|
||||
m_bias = ViewSrg::m_projectedShadows[m_shadowIndex].m_bias / shadowPositionHomogeneous.w;
|
||||
|
||||
+25
-5
@@ -6,11 +6,31 @@
|
||||
*
|
||||
*/
|
||||
|
||||
// 7-tap Gaussian Kernel (Sigma 1.1)
|
||||
static const uint GaussianKernelSize = 7;
|
||||
static const int2 TexelOffsetsV[GaussianKernelSize] = {{0, -3}, {0, -2}, {0, -1}, {0, 0}, {0, 1}, {0, 2}, {0, 3}};
|
||||
static const int2 TexelOffsetsH[GaussianKernelSize] = {{-3, 0}, {-2, 0}, {-1, 0}, {0, 0}, {1, 0}, {2, 0}, {3, 0}};
|
||||
static const float TexelWeights[GaussianKernelSize] = {0.010805f, 0.074929f, 0.238727f, 0.351078f, 0.238727f, 0.074929f, 0.010805f};
|
||||
// Gaussian Kernel Radius 9, Sigma 1.8
|
||||
static const uint GaussianKernelSize = 19;
|
||||
static const int2 TexelOffsetsV[GaussianKernelSize] = {{0, -9}, {0, -8}, {0, -7}, {0, -6}, {0, -5}, {0, -4}, {0, -3}, {0, -2}, {0, -1}, {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {0, 9}};
|
||||
static const int2 TexelOffsetsH[GaussianKernelSize] = {{-9, 0}, {-8, 0}, {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0}, {0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}};
|
||||
static const float TexelWeights[GaussianKernelSize] = {
|
||||
0.0000011022801820635918f,
|
||||
0.000014295732881160677f,
|
||||
0.0001370168487067367f,
|
||||
0.0009708086495991633f,
|
||||
0.005086391900047703f,
|
||||
0.019711193240183777f,
|
||||
0.056512463228943335f,
|
||||
0.11989501853796679f,
|
||||
0.18826323520204147f,
|
||||
0.21881694875889543f,
|
||||
0.18826323520204147f,
|
||||
0.11989501853796679f,
|
||||
0.056512463228943335f,
|
||||
0.019711193240183777f,
|
||||
0.005086391900047703f,
|
||||
0.0009708086495991633f,
|
||||
0.0001370168487067367f,
|
||||
0.000014295732881160677f,
|
||||
0.0000011022801820635918f
|
||||
};
|
||||
|
||||
float3 GaussianFilter(uint2 screenCoords, int2 texelOffsets[GaussianKernelSize], RWTexture2D<float4> inputImage)
|
||||
{
|
||||
|
||||
+30
-3
@@ -10,12 +10,13 @@
|
||||
#include <viewsrg.srgi>
|
||||
|
||||
#include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
|
||||
#include <Atom/Features/PostProcessing/FullscreenPixelInfo.azsli>
|
||||
#include <Atom/Features/SrgSemantics.azsli>
|
||||
#include <Atom/RPI/Math.azsli>
|
||||
#include "ReflectionScreenSpaceBlurCommon.azsli"
|
||||
|
||||
ShaderResourceGroup PassSrg : SRG_PerPass
|
||||
{
|
||||
Texture2DMS<float> m_depth;
|
||||
RWTexture2D<float4> m_input;
|
||||
RWTexture2D<float4> m_output;
|
||||
uint m_imageWidth;
|
||||
@@ -26,13 +27,39 @@ ShaderResourceGroup PassSrg : SRG_PerPass
|
||||
#include <Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli>
|
||||
|
||||
// Pixel Shader
|
||||
struct PSOutput
|
||||
{
|
||||
float4 m_color : SV_Target0;
|
||||
float m_depth : SV_Depth;
|
||||
};
|
||||
|
||||
PSOutput MainPS(VSOutput IN)
|
||||
{
|
||||
// vertical blur uses coordinates from the mip0 input image
|
||||
uint2 coords = IN.m_position.xy * PassSrg::m_outputScale;
|
||||
float3 result = GaussianFilter(coords, TexelOffsetsV, PassSrg::m_input);
|
||||
uint2 halfResCoords = IN.m_position.xy * PassSrg::m_outputScale;
|
||||
float3 result = GaussianFilter(halfResCoords, TexelOffsetsV, PassSrg::m_input);
|
||||
|
||||
// downsample depth, using fullscreen image coordinates
|
||||
float downsampledDepth = 0;
|
||||
if (PassSrg::m_input[halfResCoords].w > 0.0f)
|
||||
{
|
||||
uint2 fullScreenCoords = halfResCoords * 2;
|
||||
|
||||
for (int y = -2; y < 2; ++y)
|
||||
{
|
||||
for (int x = -2; x < 2; ++x)
|
||||
{
|
||||
float depth = PassSrg::m_depth.Load(fullScreenCoords + int2(x, y), 0).r;
|
||||
if (depth > downsampledDepth)
|
||||
{
|
||||
downsampledDepth = depth;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PSOutput OUT;
|
||||
OUT.m_color = float4(result, 1.0f);
|
||||
OUT.m_depth = downsampledDepth;
|
||||
return OUT;
|
||||
}
|
||||
|
||||
+2
-1
@@ -10,7 +10,8 @@
|
||||
{
|
||||
"Depth" :
|
||||
{
|
||||
"Enable" : false
|
||||
"Enable" : true, // required to bind the depth buffer SRV
|
||||
"CompareFunc" : "Always"
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
+69
-39
@@ -12,17 +12,19 @@
|
||||
#include <Atom/RPI/Math.azsli>
|
||||
#include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
|
||||
#include <Atom/Features/PostProcessing/FullscreenPixelInfo.azsli>
|
||||
#include <Atom/Features/PostProcessing/PostProcessUtil.azsli>
|
||||
#include <Atom/Features/MatrixUtility.azsli>
|
||||
#include <Atom/Features/PBR/LightingUtils.azsli>
|
||||
#include <Atom/Features/PBR/Microfacet/Fresnel.azsli>
|
||||
|
||||
ShaderResourceGroup PassSrg : SRG_PerPass
|
||||
{
|
||||
Texture2DMS<float4> m_trace;
|
||||
Texture2D<float4> m_previousFrame;
|
||||
Texture2D<float4> m_reflection;
|
||||
Texture2D<float> m_downsampledDepth;
|
||||
Texture2DMS<float4> m_normal; // RGB10 = Normal (Encoded), A2 = Flags
|
||||
Texture2DMS<float4> m_specularF0; // RGB8 = SpecularF0, A8 = Roughness
|
||||
Texture2DMS<float> m_depth;
|
||||
Texture2D<float4> m_previousFrame;
|
||||
|
||||
Sampler LinearSampler
|
||||
{
|
||||
@@ -40,6 +42,49 @@ ShaderResourceGroup PassSrg : SRG_PerPass
|
||||
|
||||
#include <Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli>
|
||||
|
||||
float3 SampleReflection(float2 reflectionUV, float mip, float depth, float3 normal, uint2 invDimensions)
|
||||
{
|
||||
const float DepthTolerance = 0.001f;
|
||||
|
||||
// attempt to trivially accept the downsampled reflection texel
|
||||
float downsampledDepth = PassSrg::m_downsampledDepth.SampleLevel(PassSrg::LinearSampler, reflectionUV, floor(mip)).r;
|
||||
if (abs(depth - downsampledDepth) <= DepthTolerance)
|
||||
{
|
||||
// use this reflection sample
|
||||
float3 reflection = PassSrg::m_reflection.SampleLevel(PassSrg::LinearSampler, reflectionUV, mip).rgb;
|
||||
return reflection;
|
||||
}
|
||||
|
||||
// neighborhood search surrounding the downsampled texel, searching for the closest matching depth
|
||||
float closestDepthDelta = 1.0f;
|
||||
int2 closestOffsetUV = float2(0.0f, 0.0f);
|
||||
for (int y = -4; y <= 4; ++y)
|
||||
{
|
||||
for (int x = -4; x <= 4; ++x)
|
||||
{
|
||||
float2 offsetUV = float2(x * invDimensions.x, y * invDimensions.y);
|
||||
float downsampledDepth = PassSrg::m_downsampledDepth.SampleLevel(PassSrg::LinearSampler, reflectionUV + offsetUV, floor(mip)).r;
|
||||
float depthDelta = abs(depth - downsampledDepth);
|
||||
|
||||
if (depthDelta <= DepthTolerance)
|
||||
{
|
||||
// depth is within tolerance, use this texel
|
||||
float3 reflection = PassSrg::m_reflection.SampleLevel(PassSrg::LinearSampler, reflectionUV + offsetUV, mip).rgb;
|
||||
return reflection;
|
||||
}
|
||||
|
||||
if (closestDepthDelta > depthDelta)
|
||||
{
|
||||
closestDepthDelta = depthDelta;
|
||||
closestOffsetUV = offsetUV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float3 reflection = PassSrg::m_reflection.SampleLevel(PassSrg::LinearSampler, reflectionUV + closestOffsetUV, mip).rgb;
|
||||
return reflection;
|
||||
}
|
||||
|
||||
// Pixel Shader
|
||||
PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
|
||||
{
|
||||
@@ -52,11 +97,21 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
|
||||
// compute trace image coordinates for the half-res image
|
||||
float2 traceCoords = screenCoords * 0.5f;
|
||||
|
||||
// load trace data and check w-component to see if there was a hit
|
||||
float4 traceData = PassSrg::m_trace.Load(traceCoords, sampleIndex);
|
||||
if (traceData.w <= 0.0f)
|
||||
// check reflection data mip0 to see if there was a hit
|
||||
float4 reflectionData = PassSrg::m_reflection.Load(uint3(traceCoords, 0));
|
||||
if (reflectionData.w <= 0.0f)
|
||||
{
|
||||
// no hit, fallback to the cubemap reflections currently in the reflection buffer
|
||||
// fallback to the cubemap reflections currently in the reflection buffer
|
||||
discard;
|
||||
}
|
||||
|
||||
// load specular and roughness
|
||||
float4 specularF0 = PassSrg::m_specularF0.Load(screenCoords, sampleIndex);
|
||||
float roughness = specularF0.a;
|
||||
const float MaxRoughness = 0.5f;
|
||||
if (roughness > MaxRoughness)
|
||||
{
|
||||
// fallback to the cubemap reflections currently in the reflection buffer
|
||||
discard;
|
||||
}
|
||||
|
||||
@@ -65,8 +120,9 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
|
||||
float depth = PassSrg::m_depth.Load(screenCoords, sampleIndex).r;
|
||||
float2 ndcPos = float2(UV.x, 1.0f - UV.y) * 2.0f - 1.0f;
|
||||
float4 projectedPos = float4(ndcPos, depth, 1.0f);
|
||||
float4 positionWS = mul(ViewSrg::m_viewProjectionInverseMatrix, projectedPos);
|
||||
positionWS /= positionWS.w;
|
||||
float4 positionVS = mul(ViewSrg::m_projectionMatrixInverse, projectedPos);
|
||||
positionVS /= positionVS.w;
|
||||
float3 positionWS = mul(ViewSrg::m_viewMatrixInverse, positionVS).xyz;
|
||||
|
||||
// compute ray from camera to surface position
|
||||
float3 cameraToPositionWS = normalize(positionWS.xyz - ViewSrg::m_worldPosition);
|
||||
@@ -74,42 +130,16 @@ PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
|
||||
// retrieve surface normal
|
||||
float4 encodedNormal = PassSrg::m_normal.Load(screenCoords, sampleIndex);
|
||||
float3 normalWS = DecodeNormalSignedOctahedron(encodedNormal.rgb);
|
||||
|
||||
// compute surface specular
|
||||
float4 specularF0 = PassSrg::m_specularF0.Load(screenCoords, sampleIndex);
|
||||
float roughness = specularF0.a;
|
||||
float NdotV = dot(normalWS, -cameraToPositionWS);
|
||||
float3 specular = FresnelSchlickWithRoughness(NdotV, specularF0.rgb, roughness);
|
||||
|
||||
// reconstruct the world space position of the trace coordinates
|
||||
float2 traceUV = saturate(traceData.xy / dimensions);
|
||||
float traceDepth = PassSrg::m_depth.Load(traceData.xy, sampleIndex).r;
|
||||
float2 traceNDC = float2(traceUV.x, 1.0f - traceUV.y) * 2.0f - 1.0f;
|
||||
float4 traceProjectedPos = float4(traceNDC, traceDepth, 1.0f);
|
||||
float4 tracePositionVS = mul(ViewSrg::m_projectionMatrixInverse, traceProjectedPos);
|
||||
tracePositionVS /= tracePositionVS.w;
|
||||
float4 tracePositionWS = mul(ViewSrg::m_viewMatrixInverse, tracePositionVS);
|
||||
|
||||
// reproject to the previous frame image coordinates
|
||||
float4 tracePrevNDC = mul(ViewSrg::m_viewProjectionPrevMatrix, tracePositionWS);
|
||||
tracePrevNDC /= tracePrevNDC.w;
|
||||
float2 tracePrevUV = float2(tracePrevNDC.x, -1.0f * tracePrevNDC.y) * 0.5f + 0.5f;
|
||||
|
||||
// compute the roughness mip to use in the previous frame image
|
||||
// compute the roughness mip to use in the reflection image
|
||||
// remap the roughness mip into a lower range to more closely match the material roughness values
|
||||
const float MaxRoughness = 0.5f;
|
||||
float mip = saturate(roughness / MaxRoughness) * PassSrg::m_maxMipLevel;
|
||||
|
||||
// sample reflection value from the roughness mip
|
||||
float4 reflectionColor = float4(PassSrg::m_previousFrame.SampleLevel(PassSrg::LinearSampler, tracePrevUV, mip).rgb, 1.0f);
|
||||
|
||||
// fade rays close to screen edge
|
||||
const float ScreenFadeDistance = 0.95f;
|
||||
float2 fadeAmount = max(max(0.0f, traceUV - ScreenFadeDistance), max(0.0f, 1.0f - traceUV - ScreenFadeDistance));
|
||||
fadeAmount /= (1.0f - ScreenFadeDistance);
|
||||
float alpha = 1.0f - max(fadeAmount.x, fadeAmount.y);
|
||||
|
||||
// sample reflection color from the mip chain
|
||||
float3 reflectionColor = SampleReflection(IN.m_texCoord, mip, depth, normalWS, 1.0f / dimensions);
|
||||
|
||||
PSOutput OUT;
|
||||
OUT.m_color = float4(reflectionColor.rgb * specular, alpha);
|
||||
OUT.m_color = float4(reflectionColor, reflectionData.w);
|
||||
return OUT;
|
||||
}
|
||||
|
||||
+88
-3
@@ -10,7 +10,7 @@
|
||||
#include <viewsrg.srgi>
|
||||
|
||||
#include <Atom/Features/PostProcessing/FullscreenVertexUtil.azsli>
|
||||
#include <Atom/Features/PostProcessing/FullscreenPixelInfo.azsli>
|
||||
#include <Atom/Features/PostProcessing/PostProcessUtil.azsli>
|
||||
#include <Atom/Features/MatrixUtility.azsli>
|
||||
#include <Atom/Features/PBR/LightingUtils.azsli>
|
||||
#include <Atom/Features/PBR/Microfacet/Fresnel.azsli>
|
||||
@@ -20,6 +20,18 @@ ShaderResourceGroup PassSrg : SRG_PerPass
|
||||
Texture2DMS<float> m_depth;
|
||||
Texture2DMS<float4> m_normal; // RGB10 = Normal (Encoded), A2 = Flags
|
||||
Texture2DMS<float4> m_specularF0; // RGB8 = SpecularF0, A8 = Roughness
|
||||
Texture2DMS<float4> m_reflection;
|
||||
Texture2D<float4> m_previousFrame;
|
||||
|
||||
Sampler LinearSampler
|
||||
{
|
||||
MinFilter = Linear;
|
||||
MagFilter = Linear;
|
||||
MipFilter = Linear;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
AddressW = Clamp;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli>
|
||||
@@ -49,6 +61,12 @@ VSOutput MainVS(VSInput input)
|
||||
}
|
||||
|
||||
// Pixel Shader
|
||||
struct PSOutput
|
||||
{
|
||||
float4 m_color : SV_Target0;
|
||||
float m_depth : SV_Depth;
|
||||
};
|
||||
|
||||
PSOutput MainPS(VSOutput IN)
|
||||
{
|
||||
// compute screen coords based on a half-res render target
|
||||
@@ -83,16 +101,83 @@ PSOutput MainPS(VSOutput IN)
|
||||
// reflect view ray around surface normal
|
||||
float3 reflectDirVS = normalize(reflect(cameraToPositionVS, normalVS));
|
||||
|
||||
// check to see if the reflected direction is approaching the camera
|
||||
float rdotv = dot(reflectDirVS, -cameraToPositionVS);
|
||||
bool fallbackEdge = false;
|
||||
if (rdotv >= -0.05f)
|
||||
{
|
||||
if (rdotv >= 0.0f)
|
||||
{
|
||||
// ray points back to camera, fallback to cubemaps
|
||||
discard;
|
||||
}
|
||||
|
||||
// ray is approaching the camera direction, but not there yet - trace the reflection and set this
|
||||
// as a non-reflected pixel, which will prevent artifacts at the boundary
|
||||
fallbackEdge = true;
|
||||
}
|
||||
|
||||
// trace screenspace rays against the depth buffer to find the screenspace intersection coordinates
|
||||
float4 result = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
float2 hitCoords = float2(0.0f, 0.0f);
|
||||
if (TraceRayScreenSpace(positionVS, reflectDirVS, dimensions, hitCoords))
|
||||
{
|
||||
float rdotv = dot(reflectDirVS, cameraToPositionVS);
|
||||
result = float4(hitCoords, 0.0f, rdotv);
|
||||
// reconstruct the world space position of the trace coordinates
|
||||
float2 traceUV = saturate(hitCoords / dimensions);
|
||||
float traceDepth = PassSrg::m_depth.Load(hitCoords, 0).r;
|
||||
float2 traceNDC = float2(traceUV.x, 1.0f - traceUV.y) * 2.0f - 1.0f;
|
||||
float4 traceProjectedPos = float4(traceNDC, traceDepth, 1.0f);
|
||||
float4 tracePositionVS = mul(ViewSrg::m_projectionMatrixInverse, traceProjectedPos);
|
||||
tracePositionVS /= tracePositionVS.w;
|
||||
float4 tracePositionWS = mul(ViewSrg::m_viewMatrixInverse, tracePositionVS);
|
||||
|
||||
// reproject to the previous frame image coordinates
|
||||
float4 tracePrevNDC = mul(ViewSrg::m_viewProjectionPrevMatrix, tracePositionWS);
|
||||
tracePrevNDC /= tracePrevNDC.w;
|
||||
float2 tracePrevUV = float2(tracePrevNDC.x, -1.0f * tracePrevNDC.y) * 0.5f + 0.5f;
|
||||
|
||||
// sample the previous frame image
|
||||
result.rgb = PassSrg::m_previousFrame.SampleLevel(PassSrg::LinearSampler, tracePrevUV, 0).rgb;
|
||||
|
||||
// apply surface specular
|
||||
float3 specularF0 = PassSrg::m_specularF0.Load(screenCoords, 0).rgb;
|
||||
result.rgb *= specularF0;
|
||||
|
||||
// fade rays close to screen edge
|
||||
const float ScreenFadeDistance = 0.95f;
|
||||
float2 fadeAmount = max(max(0.0f, traceUV - ScreenFadeDistance), max(0.0f, 1.0f - traceUV - ScreenFadeDistance));
|
||||
fadeAmount /= (1.0f - ScreenFadeDistance);
|
||||
result.a = fallbackEdge ? 0.0f : 1.0f - max(fadeAmount.x, fadeAmount.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ray miss, add in the IBL/probe reflections from the specular pass
|
||||
float4 positionWS = mul(ViewSrg::m_viewMatrixInverse, positionVS);
|
||||
float3 cameraToPositionWS = normalize(positionWS - ViewSrg::m_worldPosition);
|
||||
float3 reflectDirWS = normalize(reflect(cameraToPositionWS, normalWS));
|
||||
|
||||
result.rgb += PassSrg::m_reflection.Load(screenCoords, 0).rgb;
|
||||
result.a = fallbackEdge ? 0.0f : 1.0f;
|
||||
}
|
||||
|
||||
// downsample depth
|
||||
float downsampledDepth = 0.0f;
|
||||
for (int y = -2; y < 2; ++y)
|
||||
{
|
||||
for (int x = -2; x < 2; ++x)
|
||||
{
|
||||
float depth = PassSrg::m_depth.Load(screenCoords + int2(x, y), 0).r;
|
||||
|
||||
// take the closest depth sample (larger depth value due to reverse depth)
|
||||
if (depth > downsampledDepth)
|
||||
{
|
||||
downsampledDepth = depth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PSOutput OUT;
|
||||
OUT.m_color = result;
|
||||
OUT.m_depth = downsampledDepth;
|
||||
return OUT;
|
||||
}
|
||||
|
||||
+2
-1
@@ -10,7 +10,8 @@
|
||||
{
|
||||
"Depth" :
|
||||
{
|
||||
"Enable" : false
|
||||
"Enable" : true, // required to bind the depth buffer SRV
|
||||
"CompareFunc" : "Always"
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
+2
@@ -86,6 +86,8 @@ namespace AZ
|
||||
virtual void SetShadowsEnabled(LightHandle handle, bool enabled) = 0;
|
||||
//! Sets the shadow bias
|
||||
virtual void SetShadowBias(LightHandle handle, float bias) = 0;
|
||||
//! Sets the normal shadow bias
|
||||
virtual void SetNormalShadowBias(LightHandle handle, float bias) = 0;
|
||||
//! Sets the shadowmap size (width and height) of the light.
|
||||
virtual void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) = 0;
|
||||
//! Specifies filter method of shadows.
|
||||
|
||||
+2
@@ -74,6 +74,8 @@ namespace AZ
|
||||
virtual void SetFilteringSampleCount(LightHandle handle, uint16_t count) = 0;
|
||||
//! Sets the Esm exponent to use. Higher values produce a steeper falloff in the border areas between light and shadow.
|
||||
virtual void SetEsmExponent(LightHandle handle, float exponent) = 0;
|
||||
//! Sets the normal shadow bias. Reduces acne by biasing the shadowmap lookup along the geometric normal.
|
||||
virtual void SetNormalShadowBias(LightHandle handle, float bias) = 0;
|
||||
//! Sets all of the the point data for the provided LightHandle.
|
||||
virtual void SetPointData(LightHandle handle, const PointLightData& data) = 0;
|
||||
};
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace AZ
|
||||
|
||||
AZStd::string m_displayName;
|
||||
AZ::Data::Asset<AZ::RPI::ModelAsset> m_modelAsset;
|
||||
AZ::Data::Asset<AZ::RPI::StreamingImageAsset> m_previewImageAsset;
|
||||
};
|
||||
|
||||
using ModelPresetPtr = AZStd::shared_ptr<ModelPreset>;
|
||||
|
||||
@@ -155,8 +155,10 @@ namespace AZ
|
||||
enum AuxGeomShapeType
|
||||
{
|
||||
ShapeType_Sphere,
|
||||
ShapeType_Hemisphere,
|
||||
ShapeType_Cone,
|
||||
ShapeType_Cylinder,
|
||||
ShapeType_CylinderNoEnds, // Cylinder without disks on either end
|
||||
ShapeType_Disk,
|
||||
ShapeType_Quad,
|
||||
|
||||
|
||||
@@ -314,15 +314,40 @@ namespace AZ
|
||||
AddShape(style, shape);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawSphere(
|
||||
const AZ::Vector3& center,
|
||||
Matrix3x3 CreateMatrix3x3FromDirection(const AZ::Vector3& direction)
|
||||
{
|
||||
Vector3 unitDirection(direction.GetNormalized());
|
||||
Vector3 unitOrthogonal(direction.GetOrthogonalVector().GetNormalized());
|
||||
Vector3 unitCross(unitOrthogonal.Cross(unitDirection));
|
||||
return Matrix3x3::CreateFromColumns(unitOrthogonal, unitDirection, unitCross);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawSphere(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex)
|
||||
{
|
||||
DrawSphereCommon(center, direction, radius, color, style, depthTest, depthWrite, faceCull, viewProjOverrideIndex, false);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawSphere(const AZ::Vector3& center, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex)
|
||||
{
|
||||
DrawSphereCommon(center, AZ::Vector3::CreateAxisZ(), radius, color, style, depthTest, depthWrite, faceCull, viewProjOverrideIndex, false);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawHemisphere(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex)
|
||||
{
|
||||
DrawSphereCommon(center, direction, radius, color, style, depthTest, depthWrite, faceCull, viewProjOverrideIndex, true);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawSphereCommon(
|
||||
const AZ::Vector3& center,
|
||||
const AZ::Vector3& direction,
|
||||
float radius,
|
||||
const AZ::Color& color,
|
||||
DrawStyle style,
|
||||
DepthTest depthTest,
|
||||
DepthWrite depthWrite,
|
||||
FaceCullMode faceCull,
|
||||
int32_t viewProjOverrideIndex)
|
||||
int32_t viewProjOverrideIndex,
|
||||
bool isHemisphere)
|
||||
{
|
||||
if (radius <= 0.0f)
|
||||
{
|
||||
@@ -330,12 +355,12 @@ namespace AZ
|
||||
}
|
||||
|
||||
ShapeBufferEntry shape;
|
||||
shape.m_shapeType = ShapeType_Sphere;
|
||||
shape.m_shapeType = isHemisphere ? ShapeType_Hemisphere : ShapeType_Sphere;
|
||||
shape.m_depthRead = ConvertRPIDepthTestFlag(depthTest);
|
||||
shape.m_depthWrite = ConvertRPIDepthWriteFlag(depthWrite);
|
||||
shape.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull);
|
||||
shape.m_color = color;
|
||||
shape.m_rotationMatrix = Matrix3x3::CreateIdentity();
|
||||
shape.m_rotationMatrix = CreateMatrix3x3FromDirection(direction);
|
||||
shape.m_position = center;
|
||||
shape.m_scale = AZ::Vector3(radius, radius, radius);
|
||||
shape.m_pointSize = m_pointSize;
|
||||
@@ -362,13 +387,9 @@ namespace AZ
|
||||
shape.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull);
|
||||
shape.m_color = color;
|
||||
|
||||
Vector3 unitDirection(direction.GetNormalized());
|
||||
Vector3 unitOrthogonal(direction.GetOrthogonalVector().GetNormalized());
|
||||
Vector3 unitCross(unitOrthogonal.Cross(unitDirection));
|
||||
|
||||
// The disk mesh is created with the top of the disk pointing along the positive Y axis. This creates a
|
||||
// rotation so that the top of the disk will point along the given direction vector.
|
||||
shape.m_rotationMatrix = Matrix3x3::CreateFromColumns(unitOrthogonal, unitDirection, unitCross);
|
||||
shape.m_rotationMatrix = CreateMatrix3x3FromDirection(direction);
|
||||
shape.m_position = center;
|
||||
shape.m_scale = AZ::Vector3(radius, 1.0f, radius);
|
||||
shape.m_pointSize = m_pointSize;
|
||||
@@ -401,13 +422,7 @@ namespace AZ
|
||||
shape.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull);
|
||||
shape.m_color = color;
|
||||
|
||||
Vector3 unitDirection(direction.GetNormalized());
|
||||
Vector3 unitOrthogonal(direction.GetOrthogonalVector().GetNormalized());
|
||||
Vector3 unitCross(unitOrthogonal.Cross(unitDirection));
|
||||
|
||||
// The cone mesh is created with the tip of the cone pointing along the positive Y axis. This creates a
|
||||
// rotation so that the tip of the cone will point along the given direction vector.
|
||||
shape.m_rotationMatrix = Matrix3x3::CreateFromColumns(unitOrthogonal, unitDirection, unitCross);
|
||||
shape.m_rotationMatrix = CreateMatrix3x3FromDirection(direction);
|
||||
shape.m_position = center;
|
||||
shape.m_scale = AZ::Vector3(radius, height, radius);
|
||||
shape.m_pointSize = m_pointSize;
|
||||
@@ -416,17 +431,30 @@ namespace AZ
|
||||
AddShape(style, shape);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawCylinder(
|
||||
const AZ::Vector3& center,
|
||||
const AZ::Vector3& direction,
|
||||
float radius,
|
||||
float height,
|
||||
const AZ::Color& color,
|
||||
DrawStyle style,
|
||||
DepthTest depthTest,
|
||||
DepthWrite depthWrite,
|
||||
FaceCullMode faceCull,
|
||||
int32_t viewProjOverrideIndex)
|
||||
void AuxGeomDrawQueue::DrawCylinder(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color,
|
||||
DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex)
|
||||
{
|
||||
DrawCylinderCommon(center, direction, radius, height, color, style, depthTest, depthWrite, faceCull, viewProjOverrideIndex, true);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawCylinderNoEnds(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color,
|
||||
DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex)
|
||||
{
|
||||
DrawCylinderCommon(center, direction, radius, height, color, style, depthTest, depthWrite, faceCull, viewProjOverrideIndex, false);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawCylinderCommon(
|
||||
const AZ::Vector3& center,
|
||||
const AZ::Vector3& direction,
|
||||
float radius,
|
||||
float height,
|
||||
const AZ::Color& color,
|
||||
DrawStyle style,
|
||||
DepthTest depthTest,
|
||||
DepthWrite depthWrite,
|
||||
FaceCullMode faceCull,
|
||||
int32_t viewProjOverrideIndex,
|
||||
bool drawEnds)
|
||||
{
|
||||
if (radius <= 0.0f || height <= 0.0f)
|
||||
{
|
||||
@@ -434,19 +462,15 @@ namespace AZ
|
||||
}
|
||||
|
||||
ShapeBufferEntry shape;
|
||||
shape.m_shapeType = ShapeType_Cylinder;
|
||||
shape.m_depthRead = ConvertRPIDepthTestFlag(depthTest);
|
||||
shape.m_shapeType = drawEnds ? ShapeType_Cylinder : ShapeType_CylinderNoEnds;
|
||||
shape.m_depthRead = ConvertRPIDepthTestFlag(depthTest);
|
||||
shape.m_depthWrite = ConvertRPIDepthWriteFlag(depthWrite);
|
||||
shape.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull);
|
||||
shape.m_color = color;
|
||||
|
||||
Vector3 unitDirection(direction.GetNormalized());
|
||||
Vector3 unitOrthogonal(direction.GetOrthogonalVector().GetNormalized());
|
||||
Vector3 unitCross(unitOrthogonal.Cross(unitDirection));
|
||||
|
||||
// The cylinder mesh is created with the top end cap of the cylinder facing along the positive Y axis. This creates a
|
||||
// rotation so that the top face of the cylinder will face along the given direction vector.
|
||||
shape.m_rotationMatrix = Matrix3x3::CreateFromColumns(unitOrthogonal, unitDirection, unitCross);
|
||||
shape.m_rotationMatrix = CreateMatrix3x3FromDirection(direction);
|
||||
shape.m_position = center;
|
||||
shape.m_scale = AZ::Vector3(radius, height, radius);
|
||||
shape.m_pointSize = m_pointSize;
|
||||
|
||||
@@ -60,9 +60,12 @@ namespace AZ
|
||||
// Fixed shape draws
|
||||
void DrawQuad(float width, float height, const AZ::Matrix3x4& transform, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawSphere(const AZ::Vector3& center, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawSphere(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawHemisphere(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawDisk(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawCone(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawCylinder(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawCylinderNoEnds(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawAabb(const AZ::Aabb& aabb, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawAabb(const AZ::Aabb& aabb, const AZ::Matrix3x4& transform, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawObb(const AZ::Obb& obb, const AZ::Vector3& position, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
@@ -73,6 +76,9 @@ namespace AZ
|
||||
|
||||
private: // functions
|
||||
|
||||
void DrawCylinderCommon(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex, bool drawEnds);
|
||||
void DrawSphereCommon(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex, bool isHemisphere);
|
||||
|
||||
//! Clear the current buffers
|
||||
void ClearCurrentBufferData();
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "AuxGeomDrawProcessorShared.h"
|
||||
|
||||
#include <AzCore/Debug/EventTrace.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/containers/array.h>
|
||||
|
||||
#include <Atom/RHI/Factory.h>
|
||||
@@ -69,11 +70,13 @@ namespace AZ
|
||||
SetupInputStreamLayout(m_objectStreamLayout[DrawStyle_Solid], RHI::PrimitiveTopology::TriangleList, false);
|
||||
SetupInputStreamLayout(m_objectStreamLayout[DrawStyle_Shaded], RHI::PrimitiveTopology::TriangleList, true);
|
||||
|
||||
CreateSphereBuffersAndViews();
|
||||
CreateSphereBuffersAndViews(AuxGeomShapeType::ShapeType_Sphere);
|
||||
CreateSphereBuffersAndViews(AuxGeomShapeType::ShapeType_Hemisphere);
|
||||
CreateQuadBuffersAndViews();
|
||||
CreateDiskBuffersAndViews();
|
||||
CreateConeBuffersAndViews();
|
||||
CreateCylinderBuffersAndViews();
|
||||
CreateCylinderBuffersAndViews(AuxGeomShapeType::ShapeType_Cylinder);
|
||||
CreateCylinderBuffersAndViews(AuxGeomShapeType::ShapeType_CylinderNoEnds);
|
||||
CreateBoxBuffersAndViews();
|
||||
|
||||
// cache scene pointer for RHI::PipelineState creation.
|
||||
@@ -293,8 +296,11 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
bool FixedShapeProcessor::CreateSphereBuffersAndViews()
|
||||
bool FixedShapeProcessor::CreateSphereBuffersAndViews(AuxGeomShapeType sphereShapeType)
|
||||
{
|
||||
AZ_Assert(sphereShapeType == ShapeType_Sphere || sphereShapeType == ShapeType_Hemisphere,
|
||||
"Trying to create sphere buffers and views with a non-sphere shape type!");
|
||||
|
||||
const uint32_t numSphereLods = 5;
|
||||
struct LodInfo
|
||||
{
|
||||
@@ -311,13 +317,13 @@ namespace AZ
|
||||
{ 9, 9, 0.0000f}
|
||||
}};
|
||||
|
||||
auto& m_shape = m_shapes[ShapeType_Sphere];
|
||||
auto& m_shape = m_shapes[sphereShapeType];
|
||||
m_shape.m_numLods = numSphereLods;
|
||||
|
||||
for (uint32_t lodIndex = 0; lodIndex < numSphereLods; ++lodIndex)
|
||||
{
|
||||
MeshData meshData;
|
||||
CreateSphereMeshData(meshData, lodInfo[lodIndex].numRings, lodInfo[lodIndex].numSections);
|
||||
CreateSphereMeshData(meshData, lodInfo[lodIndex].numRings, lodInfo[lodIndex].numSections, sphereShapeType);
|
||||
|
||||
ObjectBuffers objectBuffers;
|
||||
|
||||
@@ -334,12 +340,25 @@ namespace AZ
|
||||
return true;
|
||||
}
|
||||
|
||||
void FixedShapeProcessor::CreateSphereMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections)
|
||||
void FixedShapeProcessor::CreateSphereMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections, AuxGeomShapeType sphereShapeType)
|
||||
{
|
||||
const float radius = 1.0f;
|
||||
|
||||
// calculate "inner" vertices
|
||||
float sectionAngle(DegToRad(360.0f / static_cast<float>(numSections)));
|
||||
float ringSlice(DegToRad(180.0f / static_cast<float>(numRings)));
|
||||
|
||||
uint32_t numberOfPoles = 2;
|
||||
|
||||
if (sphereShapeType == ShapeType_Hemisphere)
|
||||
{
|
||||
numberOfPoles = 1;
|
||||
numRings = (numRings + 1) / 2;
|
||||
ringSlice = DegToRad(90.0f / static_cast<float>(numRings));
|
||||
}
|
||||
|
||||
// calc required number of vertices/indices/triangles to build a sphere for the given parameters
|
||||
uint32_t numVertices = (numRings - 1) * numSections + 2;
|
||||
uint32_t numVertices = (numRings - 1) * numSections + numberOfPoles;
|
||||
|
||||
// setup buffers
|
||||
auto& positions = meshData.m_positions;
|
||||
@@ -354,30 +373,29 @@ namespace AZ
|
||||
using NormalType = AuxGeomNormal;
|
||||
|
||||
// 1st pole vertex
|
||||
positions.push_back(PosType(0.0f, 0.0f, radius));
|
||||
normals.push_back(NormalType(0.0f, 0.0f, 1.0f));
|
||||
positions.push_back(PosType(0.0f, radius, 0.0f));
|
||||
normals.push_back(NormalType(0.0f, 1.0f, 0.0f));
|
||||
|
||||
// calculate "inner" vertices
|
||||
float sectionAngle(DegToRad(360.0f / static_cast<float>(numSections)));
|
||||
float ringSlice(DegToRad(180.0f / static_cast<float>(numRings)));
|
||||
|
||||
for (uint32_t ring = 1; ring < numRings; ++ring)
|
||||
for (uint32_t ring = 1; ring < numRings - numberOfPoles + 2; ++ring)
|
||||
{
|
||||
float w(sinf(ring * ringSlice));
|
||||
for (uint32_t section = 0; section < numSections; ++section)
|
||||
{
|
||||
float x = radius * cosf(section * sectionAngle) * w;
|
||||
float y = radius * sinf(section * sectionAngle) * w;
|
||||
float z = radius * cosf(ring * ringSlice);
|
||||
float y = radius * cosf(ring * ringSlice);
|
||||
float z = radius * sinf(section * sectionAngle) * w;
|
||||
Vector3 radialVector(x, y, z);
|
||||
positions.push_back(radialVector);
|
||||
normals.push_back(radialVector.GetNormalized());
|
||||
}
|
||||
}
|
||||
|
||||
// 2nd vertex of pole (for end cap)
|
||||
positions.push_back(PosType(0.0f, 0.0f, -radius));
|
||||
normals.push_back(NormalType(0.0f, 0.0f, -1.0f));
|
||||
if (sphereShapeType == ShapeType_Sphere)
|
||||
{
|
||||
// 2nd vertex of pole (for end cap)
|
||||
positions.push_back(PosType(0.0f, -radius, 0.0f));
|
||||
normals.push_back(NormalType(0.0f, -1.0f, 0.0f));
|
||||
}
|
||||
|
||||
// point indices
|
||||
{
|
||||
@@ -393,7 +411,8 @@ namespace AZ
|
||||
|
||||
// line indices
|
||||
{
|
||||
const uint32_t numEdges = (numRings - 2) * numSections * 2 + 2 * numSections * 2;
|
||||
// NumEdges = NumRingEdges + NumSectionEdges = (numRings * numSections) + (numRings * numSections)
|
||||
const uint32_t numEdges = numRings * numSections * 2;
|
||||
const uint32_t numLineIndices = numEdges * 2;
|
||||
|
||||
// build "inner" faces
|
||||
@@ -401,10 +420,9 @@ namespace AZ
|
||||
indices.clear();
|
||||
indices.reserve(numLineIndices);
|
||||
|
||||
for (uint16_t ring = 0; ring < numRings - 2; ++ring)
|
||||
for (uint16_t ring = 0; ring < numRings - numberOfPoles + 1; ++ring)
|
||||
{
|
||||
uint16_t firstVertOfThisRing = static_cast<uint16_t>(1 + ring * numSections);
|
||||
uint16_t firstVertOfNextRing = static_cast<uint16_t>(1 + (ring + 1) * numSections);
|
||||
for (uint16_t section = 0; section < numSections; ++section)
|
||||
{
|
||||
uint32_t nextSection = (section + 1) % numSections;
|
||||
@@ -414,32 +432,33 @@ namespace AZ
|
||||
indices.push_back(static_cast<uint16_t>(firstVertOfThisRing + nextSection));
|
||||
|
||||
// line around section
|
||||
indices.push_back(firstVertOfThisRing + section);
|
||||
indices.push_back(firstVertOfNextRing + section);
|
||||
int currentVertexIndex = firstVertOfThisRing + section;
|
||||
// max 0 will implicitly handle the top pole
|
||||
int previousVertexIndex = AZStd::max(currentVertexIndex - (int)numSections, 0);
|
||||
indices.push_back(static_cast<uint16_t>(currentVertexIndex));
|
||||
indices.push_back(static_cast<uint16_t>(previousVertexIndex));
|
||||
}
|
||||
}
|
||||
|
||||
// build faces for end caps (to connect "inner" vertices with poles)
|
||||
uint16_t firstPoleVert = 0;
|
||||
uint16_t firstVertOfFirstRing = static_cast<uint16_t>(1 + (0) * numSections);
|
||||
for (uint16_t section = 0; section < numSections; ++section)
|
||||
if (sphereShapeType == ShapeType_Sphere)
|
||||
{
|
||||
indices.push_back(firstPoleVert);
|
||||
indices.push_back(firstVertOfFirstRing + section);
|
||||
}
|
||||
|
||||
uint16_t lastPoleVert = static_cast<uint16_t>((numRings - 1) * numSections + 1);
|
||||
uint16_t firstVertOfLastRing = static_cast<uint16_t>(1 + (numRings - 2) * numSections);
|
||||
for (uint16_t section = 0; section < numSections; ++section)
|
||||
{
|
||||
indices.push_back(firstVertOfLastRing + section);
|
||||
indices.push_back(lastPoleVert);
|
||||
// build faces for bottom pole (to connect "inner" vertices with poles)
|
||||
uint16_t lastPoleVert = static_cast<uint16_t>((numRings - 1) * numSections + 1);
|
||||
uint16_t firstVertOfLastRing = static_cast<uint16_t>(1 + (numRings - 2) * numSections);
|
||||
for (uint16_t section = 0; section < numSections; ++section)
|
||||
{
|
||||
indices.push_back(firstVertOfLastRing + section);
|
||||
indices.push_back(lastPoleVert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// triangle indices
|
||||
{
|
||||
const uint32_t numTriangles = (numRings - 2) * numSections * 2 + 2 * numSections;
|
||||
// NumTriangles = NumTrianglesAtPoles + NumQuads * 2
|
||||
// = (numSections * 2) + ((numRings - 2) * numSections * 2)
|
||||
// = (numSections * 2) * (numRings - 2 + 1)
|
||||
const uint32_t numTriangles = (numRings - 1) * numSections * 2;
|
||||
const uint32_t numTriangleIndices = numTriangles * 3;
|
||||
|
||||
// build "inner" faces
|
||||
@@ -447,10 +466,10 @@ namespace AZ
|
||||
indices.clear();
|
||||
indices.reserve(numTriangleIndices);
|
||||
|
||||
for (uint32_t ring = 0; ring < numRings - 2; ++ring)
|
||||
for (uint32_t ring = 0; ring < numRings - numberOfPoles; ++ring)
|
||||
{
|
||||
uint32_t firstVertOfThisRing = 1 + ring * numSections;
|
||||
uint32_t firstVertOfNextRing = 1 + (ring + 1) * numSections;
|
||||
uint32_t firstVertOfNextRing = firstVertOfThisRing + numSections;
|
||||
|
||||
for (uint32_t section = 0; section < numSections; ++section)
|
||||
{
|
||||
@@ -476,14 +495,17 @@ namespace AZ
|
||||
indices.push_back(static_cast<uint16_t>(firstPoleVert));
|
||||
}
|
||||
|
||||
uint32_t lastPoleVert = (numRings - 1) * numSections + 1;
|
||||
uint32_t firstVertOfLastRing = 1 + (numRings - 2) * numSections;
|
||||
for (uint32_t section = 0; section < numSections; ++section)
|
||||
if (sphereShapeType == ShapeType_Sphere)
|
||||
{
|
||||
uint32_t nextSection = (section + 1) % numSections;
|
||||
indices.push_back(static_cast<uint16_t>(firstVertOfLastRing + nextSection));
|
||||
indices.push_back(static_cast<uint16_t>(firstVertOfLastRing + section));
|
||||
indices.push_back(static_cast<uint16_t>(lastPoleVert));
|
||||
uint32_t lastPoleVert = (numRings - 1) * numSections + 1;
|
||||
uint32_t firstVertOfLastRing = 1 + (numRings - 2) * numSections;
|
||||
for (uint32_t section = 0; section < numSections; ++section)
|
||||
{
|
||||
uint32_t nextSection = (section + 1) % numSections;
|
||||
indices.push_back(static_cast<uint16_t>(firstVertOfLastRing + nextSection));
|
||||
indices.push_back(static_cast<uint16_t>(firstVertOfLastRing + section));
|
||||
indices.push_back(static_cast<uint16_t>(lastPoleVert));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -827,8 +849,11 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
bool FixedShapeProcessor::CreateCylinderBuffersAndViews()
|
||||
bool FixedShapeProcessor::CreateCylinderBuffersAndViews(AuxGeomShapeType cylinderShapeType)
|
||||
{
|
||||
AZ_Assert(cylinderShapeType == ShapeType_Cylinder || cylinderShapeType == ShapeType_CylinderNoEnds,
|
||||
"Trying to create cylinder buffers and views with a non-cylinder shape type!");
|
||||
|
||||
const uint32_t numCylinderLods = 5;
|
||||
struct LodInfo
|
||||
{
|
||||
@@ -836,21 +861,21 @@ namespace AZ
|
||||
float screenPercentage;
|
||||
};
|
||||
const AZStd::array<LodInfo, numCylinderLods> lodInfo =
|
||||
{{
|
||||
{ {
|
||||
{ 38, 0.1000f},
|
||||
{ 22, 0.0100f},
|
||||
{ 14, 0.0010f},
|
||||
{ 10, 0.0001f},
|
||||
{ 8, 0.0000f}
|
||||
}};
|
||||
} };
|
||||
|
||||
auto& m_shape = m_shapes[ShapeType_Cylinder];
|
||||
auto& m_shape = m_shapes[cylinderShapeType];
|
||||
m_shape.m_numLods = numCylinderLods;
|
||||
|
||||
for (uint32_t lodIndex = 0; lodIndex < numCylinderLods; ++lodIndex)
|
||||
{
|
||||
MeshData meshData;
|
||||
CreateCylinderMeshData(meshData, lodInfo[lodIndex].numSections);
|
||||
CreateCylinderMeshData(meshData, lodInfo[lodIndex].numSections, cylinderShapeType);
|
||||
|
||||
ObjectBuffers objectBuffers;
|
||||
|
||||
@@ -867,13 +892,25 @@ namespace AZ
|
||||
return true;
|
||||
}
|
||||
|
||||
void FixedShapeProcessor::CreateCylinderMeshData(MeshData& meshData, uint32_t numSections)
|
||||
void FixedShapeProcessor::CreateCylinderMeshData(MeshData& meshData, uint32_t numSections, AuxGeomShapeType cylinderShapeType)
|
||||
{
|
||||
const float radius = 1.0f;
|
||||
const float height = 1.0f;
|
||||
|
||||
//uint16_t indexOfBottomCenter = 0;
|
||||
//uint16_t indexOfBottomStart = 1;
|
||||
//uint16_t indexOfTopCenter = numSections + 1;
|
||||
//uint16_t indexOfTopStart = numSections + 2;
|
||||
uint16_t indexOfSidesStart = static_cast<uint16_t>(2 * numSections + 2);
|
||||
|
||||
if (cylinderShapeType == ShapeType_CylinderNoEnds)
|
||||
{
|
||||
// We won't draw disks at the ends of the cylinder, so no need to offset side indices
|
||||
indexOfSidesStart = 0;
|
||||
}
|
||||
|
||||
// calc required number of vertices to build a cylinder for the given parameters
|
||||
uint32_t numVertices = 4 * numSections + 2;
|
||||
uint32_t numVertices = indexOfSidesStart + 2 * numSections;
|
||||
|
||||
// setup buffers
|
||||
auto& positions = meshData.m_positions;
|
||||
@@ -888,8 +925,11 @@ namespace AZ
|
||||
float topHeight = height * 0.5f;
|
||||
|
||||
// Create caps
|
||||
CreateDiskMeshData(meshData, numSections, Facing::Down, bottomHeight);
|
||||
CreateDiskMeshData(meshData, numSections, Facing::Up, topHeight);
|
||||
if (cylinderShapeType == ShapeType_Cylinder)
|
||||
{
|
||||
CreateDiskMeshData(meshData, numSections, Facing::Down, bottomHeight);
|
||||
CreateDiskMeshData(meshData, numSections, Facing::Up, topHeight);
|
||||
}
|
||||
|
||||
// create vertices for side (so normal points out correctly)
|
||||
float sectionAngle(DegToRad(360.0f / (float)numSections));
|
||||
@@ -906,12 +946,6 @@ namespace AZ
|
||||
normals.push_back(normal);
|
||||
}
|
||||
|
||||
//uint16_t indexOfBottomCenter = 0;
|
||||
//uint16_t indexOfBottomStart = 1;
|
||||
//uint16_t indexOfTopCenter = numSections + 1;
|
||||
//uint16_t indexOfTopStart = numSections + 2;
|
||||
uint16_t indexOfSidesStart = static_cast<uint16_t>(2 * numSections + 2);
|
||||
|
||||
// build point indices
|
||||
{
|
||||
auto& indices = meshData.m_pointIndices;
|
||||
@@ -930,6 +964,24 @@ namespace AZ
|
||||
indices.push_back(indexOfSidesStart + 2 * section);
|
||||
indices.push_back(indexOfSidesStart + 2 * section + 1);
|
||||
}
|
||||
|
||||
// If we're not drawing the disks at the ends of the cylinder, we still want to
|
||||
// draw a ring around the end to join the tips of lines we created just above
|
||||
if (cylinderShapeType == ShapeType_CylinderNoEnds)
|
||||
{
|
||||
for (uint16_t section = 0; section < numSections; ++section)
|
||||
{
|
||||
uint16_t nextSection = (section + 1) % numSections;
|
||||
|
||||
// line around the bottom cap
|
||||
indices.push_back(section * 2);
|
||||
indices.push_back(nextSection * 2);
|
||||
|
||||
// line around the top cap
|
||||
indices.push_back(section * 2 + 1);
|
||||
indices.push_back(nextSection * 2 + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// indices for triangles
|
||||
|
||||
@@ -138,8 +138,8 @@ namespace AZ
|
||||
Both,
|
||||
};
|
||||
|
||||
bool CreateSphereBuffersAndViews();
|
||||
void CreateSphereMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections);
|
||||
bool CreateSphereBuffersAndViews(AuxGeomShapeType sphereShapeType);
|
||||
void CreateSphereMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections, AuxGeomShapeType sphereShapeType);
|
||||
|
||||
bool CreateQuadBuffersAndViews();
|
||||
void CreateQuadMeshDataSide(MeshData& meshData, bool isUp, bool drawLines);
|
||||
@@ -152,8 +152,8 @@ namespace AZ
|
||||
bool CreateConeBuffersAndViews();
|
||||
void CreateConeMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections);
|
||||
|
||||
bool CreateCylinderBuffersAndViews();
|
||||
void CreateCylinderMeshData(MeshData& meshData, uint32_t numSections);
|
||||
bool CreateCylinderBuffersAndViews(AuxGeomShapeType cylinderShapeType);
|
||||
void CreateCylinderMeshData(MeshData& meshData, uint32_t numSections, AuxGeomShapeType cylinderShapeType);
|
||||
|
||||
bool CreateBoxBuffersAndViews();
|
||||
void CreateBoxMeshData(MeshData& meshData);
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
#include <DiffuseGlobalIllumination/DiffuseProbeGridRenderPass.h>
|
||||
#include <DiffuseGlobalIllumination/DiffuseProbeGridFeatureProcessor.h>
|
||||
#include <DiffuseGlobalIllumination/DiffuseGlobalIlluminationFeatureProcessor.h>
|
||||
#include <ReflectionScreenSpace/ReflectionScreenSpaceTracePass.h>
|
||||
#include <ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.h>
|
||||
#include <ReflectionScreenSpace/ReflectionScreenSpaceBlurChildPass.h>
|
||||
#include <ReflectionScreenSpace/ReflectionScreenSpaceCompositePass.h>
|
||||
@@ -292,6 +293,7 @@ namespace AZ
|
||||
passSystem->AddPassCreator(Name("DeferredFogPass"), &DeferredFogPass::Create);
|
||||
|
||||
// Add Reflection passes
|
||||
passSystem->AddPassCreator(Name("ReflectionScreenSpaceTracePass"), &Render::ReflectionScreenSpaceTracePass::Create);
|
||||
passSystem->AddPassCreator(Name("ReflectionScreenSpaceBlurPass"), &Render::ReflectionScreenSpaceBlurPass::Create);
|
||||
passSystem->AddPassCreator(Name("ReflectionScreenSpaceBlurChildPass"), &Render::ReflectionScreenSpaceBlurChildPass::Create);
|
||||
passSystem->AddPassCreator(Name("ReflectionScreenSpaceCompositePass"), &Render::ReflectionScreenSpaceCompositePass::Create);
|
||||
|
||||
+8
-29
@@ -343,7 +343,6 @@ namespace AZ
|
||||
m_shadowBufferNeedsUpdate = true;
|
||||
|
||||
m_shadowProperties.GetData(index).m_cameraConfigurations[nullptr] = {};
|
||||
m_shadowProperties.GetData(index).m_cameraTransforms[nullptr] = Transform::CreateIdentity();
|
||||
|
||||
const LightHandle handle(index);
|
||||
m_shadowingLightHandle = handle; // only the recent light has shadows.
|
||||
@@ -495,20 +494,10 @@ namespace AZ
|
||||
|
||||
void DirectionalLightFeatureProcessor::SetCameraTransform(
|
||||
LightHandle handle,
|
||||
const Transform& cameraTransform,
|
||||
const RPI::RenderPipelineId& renderPipelineId)
|
||||
const Transform&,
|
||||
const RPI::RenderPipelineId&)
|
||||
{
|
||||
ShadowProperty& property = m_shadowProperties.GetData(handle.GetIndex());
|
||||
|
||||
if (RPI::RenderPipeline* renderPipeline = GetParentScene()->GetRenderPipeline(renderPipelineId).get())
|
||||
{
|
||||
const RPI::View* cameraView = renderPipeline->GetDefaultView().get();
|
||||
property.m_cameraTransforms[cameraView] = cameraTransform;
|
||||
}
|
||||
else
|
||||
{
|
||||
property.m_cameraTransforms[nullptr] = cameraTransform;
|
||||
}
|
||||
property.m_shadowmapViewNeedsUpdate = true;
|
||||
}
|
||||
|
||||
@@ -934,17 +923,6 @@ namespace AZ
|
||||
return property.m_cameraConfigurations.at(nullptr);
|
||||
}
|
||||
|
||||
const Transform& DirectionalLightFeatureProcessor::GetCameraTransform(LightHandle handle, const RPI::View* cameraView) const
|
||||
{
|
||||
const ShadowProperty& property = m_shadowProperties.GetData(handle.GetIndex());
|
||||
const auto findIt = property.m_cameraTransforms.find(cameraView);
|
||||
if (findIt != property.m_cameraTransforms.end())
|
||||
{
|
||||
return findIt->second;
|
||||
}
|
||||
return property.m_cameraTransforms.at(nullptr);
|
||||
}
|
||||
|
||||
void DirectionalLightFeatureProcessor::UpdateFrustums(
|
||||
LightHandle handle)
|
||||
{
|
||||
@@ -1365,10 +1343,11 @@ namespace AZ
|
||||
// If we used an AABB whose Y-direction range is from a segment,
|
||||
// the depth value on the shadowmap saturated to 0 or 1,
|
||||
// and we could not draw shadow correctly.
|
||||
const Transform cameraTransform = cameraView->GetCameraTransform();
|
||||
const Vector3 entireFrustumCenterLight =
|
||||
lightTransform.GetInverseFast() * (GetCameraTransform(handle, cameraView).TransformPoint(property.m_entireFrustumCenterLocal));
|
||||
lightTransform.GetInverseFast() * (cameraTransform.TransformPoint(property.m_entireFrustumCenterLocal));
|
||||
const float entireCenterY = entireFrustumCenterLight.GetElement(1);
|
||||
const Vector3 cameraLocationWorld = GetCameraTransform(handle, cameraView).GetTranslation();
|
||||
const Vector3 cameraLocationWorld = cameraTransform.GetTranslation();
|
||||
const Vector3 cameraLocationLight = lightTransformInverse * cameraLocationWorld;
|
||||
// Extend light view frustum by camera depth far in order to avoid shadow lacking behind camera.
|
||||
const float cameraBehindMinY = cameraLocationLight.GetElement(1) - GetCameraConfiguration(handle, cameraView).GetDepthFar();
|
||||
@@ -1428,8 +1407,8 @@ namespace AZ
|
||||
GetCameraConfiguration(handle, cameraView).GetDepthCenter(depthNear, depthFar),
|
||||
depthFar);
|
||||
|
||||
const Vector3 localCenter{ 0.f, depthCenter, 0.f };
|
||||
return GetCameraTransform(handle, cameraView).TransformPoint(localCenter);
|
||||
const Vector3 localCenter{ 0.f, depthCenter, 0.f };
|
||||
return cameraView->GetCameraTransform().TransformPoint(localCenter);
|
||||
}
|
||||
|
||||
float DirectionalLightFeatureProcessor::GetRadius(
|
||||
@@ -1483,7 +1462,7 @@ namespace AZ
|
||||
const ShadowProperty& property = m_shadowProperties.GetData(handle.GetIndex());
|
||||
const Vector3& boundaryCenter = GetWorldCenterPosition(handle, cameraView, depthNear, depthFar);
|
||||
const CascadeShadowCameraConfiguration& cameraConfiguration = GetCameraConfiguration(handle, cameraView);
|
||||
const Transform& cameraTransform = GetCameraTransform(handle, cameraView);
|
||||
const Transform cameraTransform = cameraView->GetCameraTransform();
|
||||
const Vector3& cameraFwd = cameraTransform.GetBasis(1);
|
||||
const Vector3& cameraUp = cameraTransform.GetBasis(2);
|
||||
const Vector3 cameraToBoundaryCenter = boundaryCenter - cameraTransform.GetTranslation();
|
||||
|
||||
@@ -134,9 +134,6 @@ namespace AZ
|
||||
// Default far depth of each cascade.
|
||||
AZStd::array<float, Shadow::MaxNumberOfCascades> m_defaultFarDepths;
|
||||
|
||||
// Transforms of camera who offers view frustum for each camera view.
|
||||
AZStd::unordered_map<const RPI::View*, Transform> m_cameraTransforms;
|
||||
|
||||
// Configuration offers shape of the camera view frustum for each camera view.
|
||||
AZStd::unordered_map<const RPI::View*, CascadeShadowCameraConfiguration> m_cameraConfigurations;
|
||||
|
||||
@@ -259,11 +256,6 @@ namespace AZ
|
||||
//! it returns one of the fallback render pipeline ID.
|
||||
const CascadeShadowCameraConfiguration& GetCameraConfiguration(LightHandle handle, const RPI::View* cameraView) const;
|
||||
|
||||
//! This returns the camera transform.
|
||||
//! If it has not been registered for the given camera view.
|
||||
//! it returns one of the fallback render pipeline ID.
|
||||
const Transform& GetCameraTransform(LightHandle handle, const RPI::View* cameraView) const;
|
||||
|
||||
//! This update view frustum of camera.
|
||||
void UpdateFrustums(LightHandle handle);
|
||||
|
||||
|
||||
@@ -313,6 +313,11 @@ namespace AZ
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowBias, bias);
|
||||
}
|
||||
|
||||
void DiskLightFeatureProcessor::SetNormalShadowBias(LightHandle handle, float bias)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetNormalShadowBias, bias);
|
||||
}
|
||||
|
||||
void DiskLightFeatureProcessor::SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowmapMaxResolution, shadowmapSize);
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace AZ
|
||||
void SetConeAngles(LightHandle handle, float innerDegrees, float outerDegrees) override;
|
||||
void SetShadowsEnabled(LightHandle handle, bool enabled) override;
|
||||
void SetShadowBias(LightHandle handle, float bias) override;
|
||||
void SetNormalShadowBias(LightHandle handle, float bias) override;
|
||||
void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) override;
|
||||
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
|
||||
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
|
||||
|
||||
@@ -302,5 +302,10 @@ namespace AZ
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetEsmExponent, esmExponent);
|
||||
}
|
||||
|
||||
void PointLightFeatureProcessor::SetNormalShadowBias(LightHandle handle, float bias)
|
||||
{
|
||||
SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetNormalShadowBias, bias);
|
||||
}
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -52,6 +52,7 @@ namespace AZ
|
||||
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
|
||||
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
|
||||
void SetEsmExponent(LightHandle handle, float esmExponent) override;
|
||||
void SetNormalShadowBias(LightHandle handle, float bias) override;
|
||||
void SetPointData(LightHandle handle, const PointLightData& data) override;
|
||||
|
||||
const Data::Instance<RPI::Buffer> GetLightBuffer() const;
|
||||
|
||||
+5
-5
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
#include "ReflectionCopyFrameBufferPass.h"
|
||||
#include "ReflectionScreenSpaceBlurPass.h"
|
||||
#include "ReflectionScreenSpaceTracePass.h"
|
||||
#include <Atom/RPI.Public/Pass/PassSystemInterface.h>
|
||||
#include <Atom/RPI.Public/Pass/PassFilter.h>
|
||||
|
||||
@@ -28,16 +28,16 @@ namespace AZ
|
||||
|
||||
void ReflectionCopyFrameBufferPass::BuildInternal()
|
||||
{
|
||||
RPI::PassFilter passFilter = RPI::PassFilter::CreateWithPassName(AZ::Name("ReflectionScreenSpaceBlurPass"), GetRenderPipeline());
|
||||
RPI::PassFilter passFilter = RPI::PassFilter::CreateWithPassName(AZ::Name("ReflectionScreenSpaceTracePass"), GetRenderPipeline());
|
||||
RPI::PassSystemInterface::Get()->ForEachPass(passFilter, [this](RPI::Pass* pass) -> RPI::PassFilterExecutionFlow
|
||||
{
|
||||
Render::ReflectionScreenSpaceBlurPass* blurPass = azrtti_cast<ReflectionScreenSpaceBlurPass*>(pass);
|
||||
Data::Instance<RPI::AttachmentImage>& frameBufferAttachment = blurPass->GetFrameBufferImageAttachment();
|
||||
Render::ReflectionScreenSpaceTracePass* tracePass = azrtti_cast<ReflectionScreenSpaceTracePass*>(pass);
|
||||
Data::Instance<RPI::AttachmentImage>& frameBufferAttachment = tracePass->GetPreviousFrameImageAttachment();
|
||||
|
||||
RPI::PassAttachmentBinding& outputBinding = GetOutputBinding(0);
|
||||
AttachImageToSlot(outputBinding.m_name, frameBufferAttachment);
|
||||
|
||||
return RPI::PassFilterExecutionFlow::StopVisitingPasses;
|
||||
return RPI::PassFilterExecutionFlow::StopVisitingPasses;
|
||||
});
|
||||
|
||||
FullscreenTrianglePass::BuildInternal();
|
||||
|
||||
+21
-28
@@ -12,6 +12,7 @@
|
||||
#include <Atom/RHI/FrameGraphAttachmentInterface.h>
|
||||
#include <Atom/RHI.Reflect/ImageViewDescriptor.h>
|
||||
#include <Atom/RPI.Reflect/Pass/FullscreenTrianglePassData.h>
|
||||
#include <Atom/RPI.Reflect/Pass/PassName.h>
|
||||
#include <Atom/RPI.Public/Pass/PassDefines.h>
|
||||
#include <Atom/RPI.Public/Pass/PassFactory.h>
|
||||
#include <Atom/RPI.Public/Pass/PassSystemInterface.h>
|
||||
@@ -79,7 +80,7 @@ namespace AZ
|
||||
horizontalBlurChildDesc.m_passTemplate = blurHorizontalPassTemplate;
|
||||
|
||||
// add child passes to perform the vertical and horizontal Gaussian blur for each roughness mip level
|
||||
for (uint32_t mip = 0; mip < m_numBlurMips; ++mip)
|
||||
for (uint32_t mip = 0; mip < NumMipLevels - 1; ++mip)
|
||||
{
|
||||
// create Vertical blur child passes
|
||||
{
|
||||
@@ -114,35 +115,15 @@ namespace AZ
|
||||
RemoveChildren();
|
||||
m_flags.m_createChildren = true;
|
||||
|
||||
Data::Instance<RPI::AttachmentImagePool> pool = RPI::ImageSystemInterface::Get()->GetSystemAttachmentPool();
|
||||
|
||||
// retrieve the image attachment from the pass
|
||||
AZ_Assert(m_ownedAttachments.size() == 1, "ReflectionScreenSpaceBlurPass must have exactly one ImageAttachment defined");
|
||||
RPI::Ptr<RPI::PassAttachment> reflectionImageAttachment = m_ownedAttachments[0];
|
||||
|
||||
// update the image attachment descriptor to sync up size and format
|
||||
reflectionImageAttachment->Update();
|
||||
|
||||
// change the lifetime since we want it to live between frames
|
||||
reflectionImageAttachment->m_lifetime = RHI::AttachmentLifetimeType::Imported;
|
||||
|
||||
// set the bind flags
|
||||
RHI::ImageDescriptor& imageDesc = reflectionImageAttachment->m_descriptor.m_image;
|
||||
imageDesc.m_bindFlags |= RHI::ImageBindFlags::Color | RHI::ImageBindFlags::ShaderReadWrite;
|
||||
|
||||
// create the image attachment
|
||||
RHI::ClearValue clearValue = RHI::ClearValue::CreateVector4Float(0, 0, 0, 0);
|
||||
m_frameBufferImageAttachment = RPI::AttachmentImage::Create(*pool.get(), imageDesc, Name(reflectionImageAttachment->m_path.GetCStr()), &clearValue, nullptr);
|
||||
|
||||
reflectionImageAttachment->m_path = m_frameBufferImageAttachment->GetAttachmentId();
|
||||
reflectionImageAttachment->m_importedResource = m_frameBufferImageAttachment;
|
||||
|
||||
uint32_t mipLevels = reflectionImageAttachment->m_descriptor.m_image.m_mipLevels;
|
||||
// retrieve the reflection, downsampled normal, and downsampled depth attachments
|
||||
RPI::PassAttachment* reflectionImageAttachment = GetInputOutputBinding(0).m_attachment.get();
|
||||
RHI::Size imageSize = reflectionImageAttachment->m_descriptor.m_image.m_size;
|
||||
|
||||
RPI::PassAttachment* downsampledDepthImageAttachment = GetInputOutputBinding(1).m_attachment.get();
|
||||
|
||||
// create transient attachments, one for each blur mip level
|
||||
AZStd::vector<RPI::PassAttachment*> transientPassAttachments;
|
||||
for (uint32_t mip = 1; mip <= mipLevels - 1; ++mip)
|
||||
for (uint32_t mip = 1; mip <= NumMipLevels - 1; ++mip)
|
||||
{
|
||||
RHI::Size mipSize = imageSize.GetReducedMip(mip);
|
||||
|
||||
@@ -160,8 +141,6 @@ namespace AZ
|
||||
m_ownedAttachments.push_back(transientPassAttachment);
|
||||
}
|
||||
|
||||
m_numBlurMips = mipLevels - 1;
|
||||
|
||||
// call ParentPass::BuildInternal() first to configure the slots and auto-add the empty bindings,
|
||||
// then we will assign attachments to the bindings
|
||||
ParentPass::BuildInternal();
|
||||
@@ -170,13 +149,27 @@ namespace AZ
|
||||
uint32_t attachmentIndex = 0;
|
||||
for (auto& verticalBlurChildPass : m_verticalBlurChildPasses)
|
||||
{
|
||||
// mip0 source input
|
||||
RPI::PassAttachmentBinding& inputAttachmentBinding = verticalBlurChildPass->GetInputOutputBinding(0);
|
||||
inputAttachmentBinding.SetAttachment(reflectionImageAttachment);
|
||||
inputAttachmentBinding.m_connectedBinding = &GetInputOutputBinding(0);
|
||||
|
||||
// mipN transient output
|
||||
RPI::PassAttachmentBinding& outputAttachmentBinding = verticalBlurChildPass->GetInputOutputBinding(1);
|
||||
outputAttachmentBinding.SetAttachment(transientPassAttachments[attachmentIndex]);
|
||||
|
||||
// setup downsampled depth output
|
||||
// Note: this is a vertical pass output only, and each vertical child pass writes a specific mip level
|
||||
uint32_t mipLevel = attachmentIndex + 1;
|
||||
|
||||
// downsampled depth output
|
||||
RPI::PassAttachmentBinding& downsampledDepthAttachmentBinding = verticalBlurChildPass->GetInputOutputBinding(2);
|
||||
RHI::ImageViewDescriptor downsampledDepthOutputViewDesc;
|
||||
downsampledDepthOutputViewDesc.m_mipSliceMin = static_cast<int16_t>(mipLevel);
|
||||
downsampledDepthOutputViewDesc.m_mipSliceMax = static_cast<int16_t>(mipLevel);
|
||||
downsampledDepthAttachmentBinding.m_unifiedScopeDesc.SetAsImage(downsampledDepthOutputViewDesc);
|
||||
downsampledDepthAttachmentBinding.SetAttachment(downsampledDepthImageAttachment);
|
||||
|
||||
attachmentIndex++;
|
||||
}
|
||||
|
||||
|
||||
+2
-9
@@ -29,12 +29,8 @@ namespace AZ
|
||||
//! Creates a new pass without a PassTemplate
|
||||
static RPI::Ptr<ReflectionScreenSpaceBlurPass> Create(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
//! Returns the frame buffer image attachment used by the ReflectionFrameBufferCopy pass
|
||||
//! to store the previous frame image
|
||||
Data::Instance<RPI::AttachmentImage>& GetFrameBufferImageAttachment() { return m_frameBufferImageAttachment; }
|
||||
|
||||
//! Returns the number of mip levels in the blur
|
||||
uint32_t GetNumBlurMips() const { return m_numBlurMips; }
|
||||
//! The total number of mip levels in the blur (including mip0)
|
||||
static const uint32_t NumMipLevels = 5;
|
||||
|
||||
private:
|
||||
explicit ReflectionScreenSpaceBlurPass(const RPI::PassDescriptor& descriptor);
|
||||
@@ -47,9 +43,6 @@ namespace AZ
|
||||
|
||||
AZStd::vector<RPI::Ptr<RPI::FullscreenTrianglePass>> m_verticalBlurChildPasses;
|
||||
AZStd::vector<RPI::Ptr<RPI::FullscreenTrianglePass>> m_horizontalBlurChildPasses;
|
||||
|
||||
Data::Instance<RPI::AttachmentImage> m_frameBufferImageAttachment;
|
||||
uint32_t m_numBlurMips = 0;
|
||||
};
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
|
||||
+15
-16
@@ -26,6 +26,19 @@ namespace AZ
|
||||
{
|
||||
}
|
||||
|
||||
bool ReflectionScreenSpaceCompositePass::IsEnabled() const
|
||||
{
|
||||
// delay for a few frames to ensure that the previous frame texture is populated
|
||||
static const uint32_t FrameDelay = 10;
|
||||
if (m_frameDelayCount < FrameDelay)
|
||||
{
|
||||
m_frameDelayCount++;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReflectionScreenSpaceCompositePass::CompileResources([[maybe_unused]] const RHI::FrameGraphCompileContext& context)
|
||||
{
|
||||
if (!m_shaderResourceGroup)
|
||||
@@ -33,22 +46,8 @@ namespace AZ
|
||||
return;
|
||||
}
|
||||
|
||||
RPI::PassFilter passFilter = RPI::PassFilter::CreateWithPassName(AZ::Name("ReflectionScreenSpaceBlurPass"), GetRenderPipeline());
|
||||
|
||||
RPI::PassSystemInterface::Get()->ForEachPass(passFilter, [this](RPI::Pass* pass) -> RPI::PassFilterExecutionFlow
|
||||
{
|
||||
Render::ReflectionScreenSpaceBlurPass* blurPass = azrtti_cast<ReflectionScreenSpaceBlurPass*>(pass);
|
||||
|
||||
// compute the max mip level based on the available mips in the previous frame image, and capping it
|
||||
// to stay within a range that has reasonable data
|
||||
const uint32_t MaxNumRoughnessMips = 8;
|
||||
uint32_t maxMipLevel = AZStd::min(MaxNumRoughnessMips, blurPass->GetNumBlurMips()) - 1;
|
||||
|
||||
auto constantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_maxMipLevel"));
|
||||
m_shaderResourceGroup->SetConstant(constantIndex, maxMipLevel);
|
||||
|
||||
return RPI::PassFilterExecutionFlow::StopVisitingPasses;
|
||||
});
|
||||
auto constantIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name("m_maxMipLevel"));
|
||||
m_shaderResourceGroup->SetConstant(constantIndex, ReflectionScreenSpaceBlurPass::NumMipLevels - 1);
|
||||
|
||||
FullscreenTrianglePass::CompileResources(context);
|
||||
}
|
||||
|
||||
+3
@@ -34,6 +34,9 @@ namespace AZ
|
||||
|
||||
// Pass Overrides...
|
||||
void CompileResources(const RHI::FrameGraphCompileContext& context) override;
|
||||
bool IsEnabled() const override;
|
||||
|
||||
mutable uint32_t m_frameDelayCount = 0;
|
||||
};
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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 "ReflectionScreenSpaceTracePass.h"
|
||||
#include <Atom/RPI.Public/Pass/PassSystemInterface.h>
|
||||
#include <Atom/RPI.Public/Pass/PassFilter.h>
|
||||
#include <Atom/RPI.Public/RenderPipeline.h>
|
||||
#include <Atom/RPI.Public/Image/ImageSystemInterface.h>
|
||||
#include <Atom/RPI.Public/Image/AttachmentImagePool.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
RPI::Ptr<ReflectionScreenSpaceTracePass> ReflectionScreenSpaceTracePass::Create(const RPI::PassDescriptor& descriptor)
|
||||
{
|
||||
RPI::Ptr<ReflectionScreenSpaceTracePass> pass = aznew ReflectionScreenSpaceTracePass(descriptor);
|
||||
return AZStd::move(pass);
|
||||
}
|
||||
|
||||
ReflectionScreenSpaceTracePass::ReflectionScreenSpaceTracePass(const RPI::PassDescriptor& descriptor)
|
||||
: RPI::FullscreenTrianglePass(descriptor)
|
||||
{
|
||||
}
|
||||
|
||||
void ReflectionScreenSpaceTracePass::BuildInternal()
|
||||
{
|
||||
Data::Instance<RPI::AttachmentImagePool> pool = RPI::ImageSystemInterface::Get()->GetSystemAttachmentPool();
|
||||
|
||||
// retrieve the previous frame image attachment from the pass
|
||||
AZ_Assert(m_ownedAttachments.size() == 3, "ReflectionScreenSpaceTracePass must have the following attachment images defined: ReflectionImage, DownSampledDepthImage, and PreviousFrameImage");
|
||||
RPI::Ptr<RPI::PassAttachment> previousFrameImageAttachment = m_ownedAttachments[2];
|
||||
|
||||
// update the image attachment descriptor to sync up size and format
|
||||
previousFrameImageAttachment->Update();
|
||||
|
||||
// change the lifetime since we want it to live between frames
|
||||
previousFrameImageAttachment->m_lifetime = RHI::AttachmentLifetimeType::Imported;
|
||||
|
||||
// set the bind flags
|
||||
RHI::ImageDescriptor& imageDesc = previousFrameImageAttachment->m_descriptor.m_image;
|
||||
imageDesc.m_bindFlags |= RHI::ImageBindFlags::Color | RHI::ImageBindFlags::ShaderReadWrite;
|
||||
|
||||
// create the image attachment
|
||||
RHI::ClearValue clearValue = RHI::ClearValue::CreateVector4Float(0, 0, 0, 0);
|
||||
m_previousFrameImageAttachment = RPI::AttachmentImage::Create(*pool.get(), imageDesc, Name(previousFrameImageAttachment->m_path.GetCStr()), &clearValue, nullptr);
|
||||
|
||||
previousFrameImageAttachment->m_path = m_previousFrameImageAttachment->GetAttachmentId();
|
||||
previousFrameImageAttachment->m_importedResource = m_previousFrameImageAttachment;
|
||||
}
|
||||
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Atom/RPI.Public/Pass/Pass.h>
|
||||
#include <Atom/RPI.Public/Pass/FullscreenTrianglePass.h>
|
||||
#include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
|
||||
#include <Atom/RPI.Public/Shader/Shader.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
//! This pass traces screenspace reflections from the previous frame image.
|
||||
class ReflectionScreenSpaceTracePass
|
||||
: public RPI::FullscreenTrianglePass
|
||||
{
|
||||
AZ_RPI_PASS(DiffuseProbeGridDownsamplePass);
|
||||
|
||||
public:
|
||||
AZ_RTTI(Render::ReflectionScreenSpaceTracePass, "{70FD45E9-8363-4AA1-A514-3C24AC975E53}", FullscreenTrianglePass);
|
||||
AZ_CLASS_ALLOCATOR(Render::ReflectionScreenSpaceTracePass, SystemAllocator, 0);
|
||||
|
||||
//! Creates a new pass without a PassTemplate
|
||||
static RPI::Ptr<ReflectionScreenSpaceTracePass> Create(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
Data::Instance<RPI::AttachmentImage>& GetPreviousFrameImageAttachment() { return m_previousFrameImageAttachment; }
|
||||
|
||||
private:
|
||||
explicit ReflectionScreenSpaceTracePass(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
// Pass behavior overrides...
|
||||
virtual void BuildInternal() override;
|
||||
|
||||
Data::Instance<RPI::AttachmentImage> m_previousFrameImageAttachment;
|
||||
};
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
@@ -155,8 +155,9 @@ namespace AZ::Render
|
||||
{
|
||||
AZ_Assert(id.IsValid(), "Invalid ShadowId passed to ProjectedShadowFeatureProcessor::SetNormalShadowBias().");
|
||||
|
||||
ShadowProperty& shadowProperty = GetShadowPropertyFromShadowId(id);
|
||||
shadowProperty.m_normalShadowBias = normalShadowBias;
|
||||
ShadowData& shadowData = m_shadowData.GetElement<ShadowDataIndex>(id.GetIndex());
|
||||
shadowData.m_normalShadowBias = normalShadowBias;
|
||||
m_deviceBufferNeedsUpdate = true;
|
||||
}
|
||||
|
||||
void ProjectedShadowFeatureProcessor::SetShadowmapMaxResolution(ShadowId id, ShadowmapSize size)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user