Merge branch 'main' into Atom/dmcdiar/ATOM-15555

This commit is contained in:
Doug McDiarmid
2021-05-27 19:24:16 -07:00
342 changed files with 4335 additions and 5205 deletions
@@ -0,0 +1,45 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "MultiplatformPresetSettings",
"ClassData": {
"DefaultPreset": {
"UUID": "{10D4D7D8-23E2-4FC5-BE6A-DA9949D2C603}",
"Name": "LUT_R32F",
"FileMasks": ["_lutr32f"],
"SourceColor": "Linear",
"DestColor": "Linear",
"PixelFormat": "R32F"
},
"PlatformsPresets": {
"es3": {
"UUID": "{10D4D7D8-23E2-4FC5-BE6A-DA9949D2C603}",
"Name": "LUT_R32F",
"SourceColor": "Linear",
"DestColor": "Linear",
"PixelFormat": "R32F"
},
"ios": {
"UUID": "{10D4D7D8-23E2-4FC5-BE6A-DA9949D2C603}",
"Name": "LUT_R32F",
"SourceColor": "Linear",
"DestColor": "Linear",
"PixelFormat": "R32F"
},
"osx_gl": {
"UUID": "{10D4D7D8-23E2-4FC5-BE6A-DA9949D2C603}",
"Name": "LUT_R32F",
"SourceColor": "Linear",
"DestColor": "Linear",
"PixelFormat": "R32F"
},
"provo": {
"UUID": "{10D4D7D8-23E2-4FC5-BE6A-DA9949D2C603}",
"Name": "LUT_R32F",
"SourceColor": "Linear",
"DestColor": "Linear",
"PixelFormat": "R32F"
}
}
}
}
@@ -0,0 +1,59 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "MultiplatformPresetSettings",
"ClassData": {
"DefaultPreset": {
"UUID": "{ABDFCED1-0565-4B7B-9BC1-82C473BCEEA2}",
"Name": "LUT_RGBA16",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16"
],
"PixelFormat": "R16G16B16A16"
},
"PlatformsPresets": {
"es3": {
"UUID": "{ABDFCED1-0565-4B7B-9BC1-82C473BCEEA2}",
"Name": "LUT_RGBA16",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16"
],
"PixelFormat": "R16G16B16A16"
},
"ios": {
"UUID": "{ABDFCED1-0565-4B7B-9BC1-82C473BCEEA2}",
"Name": "LUT_RGBA16",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16"
],
"PixelFormat": "R16G16B16A16"
},
"osx_gl": {
"UUID": "{ABDFCED1-0565-4B7B-9BC1-82C473BCEEA2}",
"Name": "LUT_RGBA16",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16"
],
"PixelFormat": "R16G16B16A16"
},
"provo": {
"UUID": "{ABDFCED1-0565-4B7B-9BC1-82C473BCEEA2}",
"Name": "LUT_RGBA16",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16"
],
"PixelFormat": "R16G16B16A16"
}
}
}
}
@@ -0,0 +1,59 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "MultiplatformPresetSettings",
"ClassData": {
"DefaultPreset": {
"UUID": "{6D75F093-C826-437A-AD94-8631A5A4E8A2}",
"Name": "LUT_RGBA16F",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16f"
],
"PixelFormat": "R16G16B16A16F"
},
"PlatformsPresets": {
"es3": {
"UUID": "{6D75F093-C826-437A-AD94-8631A5A4E8A2}",
"Name": "LUT_RGBA16F",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16f"
],
"PixelFormat": "R16G16B16A16F"
},
"ios": {
"UUID": "{6D75F093-C826-437A-AD94-8631A5A4E8A2}",
"Name": "LUT_RGBA16F",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16f"
],
"PixelFormat": "R16G16B16A16F"
},
"osx_gl": {
"UUID": "{6D75F093-C826-437A-AD94-8631A5A4E8A2}",
"Name": "LUT_RGBA16F",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16f"
],
"PixelFormat": "R16G16B16A16F"
},
"provo": {
"UUID": "{6D75F093-C826-437A-AD94-8631A5A4E8A2}",
"Name": "LUT_RGBA16F",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16f"
],
"PixelFormat": "R16G16B16A16F"
}
}
}
}
@@ -738,7 +738,7 @@ namespace AZ
}
else if (platformIdentifier == "mac")
{
platformId = AzFramework::PlatformId::MAC;
platformId = AzFramework::PlatformId::MAC_ID;
}
else if (platformIdentifier == "android")
{
@@ -790,7 +790,7 @@ namespace AZ
}
else if (platform == "mac")
{
platformId = AzFramework::PlatformId::MAC;
platformId = AzFramework::PlatformId::MAC_ID;
}
else if (platform == "android")
{
File diff suppressed because it is too large Load Diff
@@ -267,16 +267,16 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// Directional light shadow coordinates
lightingData.shadowCoords = IN.m_shadowCoords;
// ------- Occlusion -------
lightingData.diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture);
lightingData.specularOcclusion = GetOcclusionInput(MaterialSrg::m_specularOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_specularOcclusionMapUvIndex], MaterialSrg::m_specularOcclusionFactor, o_specularOcclusion_useTexture);
// ------- Emissive -------
float2 emissiveUv = IN.m_uv[MaterialSrg::m_emissiveMapUvIndex];
lightingData.emissiveLighting = GetEmissiveInput(MaterialSrg::m_emissiveMap, MaterialSrg::m_sampler, emissiveUv, MaterialSrg::m_emissiveIntensity, MaterialSrg::m_emissiveColor.rgb, o_emissiveEnabled, o_emissive_useTexture);
// ------- Occlusion -------
lightingData.diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture);
lightingData.specularOcclusion = GetOcclusionInput(MaterialSrg::m_specularOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_specularOcclusionMapUvIndex], MaterialSrg::m_specularOcclusionFactor, o_specularOcclusion_useTexture);
// ------- Clearcoat -------
// [GFX TODO][ATOM-14603]: Clean up the double uses of these clear coat flags
@@ -287,6 +287,13 @@
"id": "m_specularF0Map"
}
},
{
"id": "useTexture",
"displayName": "Use Texture",
"description": "Whether to use the texture map, or just default to the Factor value.",
"type": "Bool",
"defaultValue": true
},
{
"id": "textureMapUv",
"displayName": "UV",
@@ -299,13 +306,7 @@
"id": "m_specularF0MapUvIndex"
}
},
{
"id": "useTexture",
"displayName": "Use Texture",
"description": "Whether to use the texture map, or just default to the Factor value.",
"type": "Bool",
"defaultValue": true
},
// Consider moving this to the "general" group to be consistent with StandardMultilayerPBR
{
"id": "enableMultiScatterCompensation",
"displayName": "Multiscattering Compensation",
@@ -616,7 +617,7 @@
"type": "float",
"defaultValue": 6.0,
"min": 0.0,
"softMax": 20.0
"softMax": 20.0
},
{
"id": "transmissionDistortion",
@@ -909,7 +910,7 @@
"description": "Center point for scaling and rotation transformations.",
"type": "vector2",
"vectorLabels": [ "U", "V" ],
"defaultValue": [ 0.0, 0.0 ]
"defaultValue": [ 0.5, 0.5 ]
},
{
"id": "tileU",
@@ -1011,18 +1012,18 @@
"type": "HandleSubsurfaceScatteringParameters",
"args": {
"mode": "subsurfaceScattering.transmissionMode",
"scale" : "subsurfaceScattering.transmissionScale",
"power" : "subsurfaceScattering.transmissionPower",
"distortion" : "subsurfaceScattering.transmissionDistortion",
"attenuation" : "subsurfaceScattering.transmissionAttenuation",
"tintColor" : "subsurfaceScattering.transmissionTint",
"thickness" : "subsurfaceScattering.thickness",
"scale": "subsurfaceScattering.transmissionScale",
"power": "subsurfaceScattering.transmissionPower",
"distortion": "subsurfaceScattering.transmissionDistortion",
"attenuation": "subsurfaceScattering.transmissionAttenuation",
"tintColor": "subsurfaceScattering.transmissionTint",
"thickness": "subsurfaceScattering.thickness",
"enabled": "subsurfaceScattering.enableSubsurfaceScattering",
"scatterDistanceColor" : "subsurfaceScattering.scatterColor",
"scatterDistanceIntensity" : "subsurfaceScattering.scatterDistance",
"scatterDistanceShaderInput" : "m_scatterDistance",
"parametersShaderInput" : "m_transmissionParams",
"tintThickenssShaderInput" : "m_transmissionTintThickness"
"scatterDistanceColor": "subsurfaceScattering.scatterColor",
"scatterDistanceIntensity": "subsurfaceScattering.scatterDistance",
"scatterDistanceShaderInput": "m_scatterDistance",
"parametersShaderInput": "m_transmissionParams",
"tintThickenssShaderInput": "m_transmissionTintThickness"
}
},
{
@@ -1038,8 +1039,8 @@
"type": "UseTexture",
"args": {
"textureProperty": "specularF0.textureMap",
"dependentProperties": ["specularF0.textureMapUv"],
"useTextureProperty": "specularF0.useTexture",
"dependentProperties": ["specularF0.textureMapUv"],
"shaderOption": "o_specularF0_useTexture"
}
},
@@ -369,15 +369,14 @@
],
"parallax": [
{
// Note parallax is enabled by default so that as soon as a user hooks up displacement settings they will see some parallax applied.
// The functor that controls parallax will set o_parallax_feature_enabled=false when all the individual layers have no displacement, so
// a default value of true here will not have any initial impact on performance.
"id": "enable",
"displayName": "Enable",
"description": "Whether to enable the parallax feature for this material.",
"type": "Bool",
"defaultValue": false,
"connection": {
"type": "ShaderOption",
"id": "o_parallax_feature_enabled"
}
"defaultValue": true
},
{
"id": "parallaxUv",
@@ -409,7 +408,7 @@
"description": "Quality of parallax mapping.",
"type": "Enum",
"enumValues": [ "Low", "Medium", "High", "Ultra" ],
"defaultValue": "Medium",
"defaultValue": "Low",
"connection": {
"type": "ShaderOption",
"id": "o_parallax_quality"
@@ -445,7 +444,7 @@
"description": "Center point for scaling and rotation transformations.",
"type": "vector2",
"vectorLabels": [ "U", "V" ],
"defaultValue": [ 0.0, 0.0 ]
"defaultValue": [ 0.5, 0.5 ]
},
{
"id": "tileU",
@@ -1141,7 +1140,7 @@
"displayName": "Scale",
"description": "The total height of the displacement texture map in local model units.",
"type": "Float",
"defaultValue": 0.0,
"defaultValue": 0.05,
"min": 0.0,
"softMax": 0.1,
"connection": {
@@ -1170,7 +1169,7 @@
"description": "Center point for scaling and rotation transformations.",
"type": "vector2",
"vectorLabels": [ "U", "V" ],
"defaultValue": [ 0.0, 0.0 ]
"defaultValue": [ 0.5, 0.5 ]
},
{
"id": "tileU",
@@ -1847,7 +1846,7 @@
"displayName": "Scale",
"description": "The total height of the displacement texture map in local model units.",
"type": "Float",
"defaultValue": 0.0,
"defaultValue": 0.05,
"min": 0.0,
"softMax": 0.1,
"connection": {
@@ -1876,7 +1875,7 @@
"description": "Center point for scaling and rotation transformations.",
"type": "vector2",
"vectorLabels": [ "U", "V" ],
"defaultValue": [ 0.0, 0.0 ]
"defaultValue": [ 0.5, 0.5 ]
},
{
"id": "tileU",
@@ -2553,7 +2552,7 @@
"displayName": "Scale",
"description": "The total height of the displacement texture map in local model units.",
"type": "Float",
"defaultValue": 0.0,
"defaultValue": 0.05,
"min": 0.0,
"softMax": 0.1,
"connection": {
@@ -2582,7 +2581,7 @@
"description": "Center point for scaling and rotation transformations.",
"type": "vector2",
"vectorLabels": [ "U", "V" ],
"defaultValue": [ 0.0, 0.0 ]
"defaultValue": [ 0.5, 0.5 ]
},
{
"id": "tileU",
@@ -35,6 +35,10 @@ function GetMaterialPropertyDependencies()
}
end
function GetShaderOptionDependencies()
return {"o_parallax_feature_enabled"}
end
-- These values must align with LayerBlendSource in StandardMultilayerPBR_Common.azsli.
LayerBlendSource_BlendMaskTexture = 0
LayerBlendSource_BlendMaskVertexColors = 1
@@ -50,6 +54,39 @@ function BlendSourceUsesDisplacement(context)
return blendSourceIncludesDisplacement
end
function IsParallaxNeededForLayer(context, layerNumber)
local enableLayer = true
if(layerNumber > 1) then -- layer 1 is always enabled, it is the implicit base layer
enableLayer = context:GetMaterialPropertyValue_bool("blend.enableLayer" .. layerNumber)
end
if not enableLayer then
return false
end
local parallaxGroupName = "layer" .. layerNumber .. "_parallax."
local factor = context:GetMaterialPropertyValue_float(parallaxGroupName .. "factor")
local offset = context:GetMaterialPropertyValue_float(parallaxGroupName .. "offset")
if factor == 0.0 and offset == 0.0 then
return false
end
local hasTexture = nil ~= context:GetMaterialPropertyValue_Image(parallaxGroupName .. "textureMap")
local useTexture = context:GetMaterialPropertyValue_bool(parallaxGroupName .. "useTexture")
if not hasTexture or not useTexture then
factorLayer = 0.0
end
if factor == 0.0 and offset == 0.0 then
return false
end
return true
end
-- Calculates the min and max displacement height values encompassing all enabled layers.
-- @return a table with two values {min,max}. Negative values are below the surface and positive values are above the surface.
function CalcOverallHeightRange(context)
@@ -114,21 +151,32 @@ function Process(context)
local heightMinMax = CalcOverallHeightRange(context)
context:SetShaderConstant_float("m_displacementMin", heightMinMax[0])
context:SetShaderConstant_float("m_displacementMax", heightMinMax[1])
local parallaxFeatureEnabled = context:GetMaterialPropertyValue_bool("parallax.enable")
if parallaxFeatureEnabled then
if not IsParallaxNeededForLayer(context, 1) and
not IsParallaxNeededForLayer(context, 2) and
not IsParallaxNeededForLayer(context, 3) then
parallaxFeatureEnabled = false
end
end
context:SetShaderOptionValue_bool("o_parallax_feature_enabled", parallaxFeatureEnabled)
end
function ProcessEditor(context)
local enable = context:GetMaterialPropertyValue_bool("parallax.enable")
local enableParallaxSettings = context:GetMaterialPropertyValue_bool("parallax.enable")
local visibility = MaterialPropertyVisibility_Enabled
if(not enable) then
visibility = MaterialPropertyVisibility_Hidden
local parallaxSettingVisibility = MaterialPropertyVisibility_Enabled
if(not enableParallaxSettings) then
parallaxSettingVisibility = MaterialPropertyVisibility_Hidden
end
context:SetMaterialPropertyVisibility("parallax.parallaxUv", visibility)
context:SetMaterialPropertyVisibility("parallax.algorithm", visibility)
context:SetMaterialPropertyVisibility("parallax.quality", visibility)
context:SetMaterialPropertyVisibility("parallax.pdo", visibility)
context:SetMaterialPropertyVisibility("parallax.showClipping", visibility)
context:SetMaterialPropertyVisibility("parallax.parallaxUv", parallaxSettingVisibility)
context:SetMaterialPropertyVisibility("parallax.algorithm", parallaxSettingVisibility)
context:SetMaterialPropertyVisibility("parallax.quality", parallaxSettingVisibility)
context:SetMaterialPropertyVisibility("parallax.pdo", parallaxSettingVisibility)
context:SetMaterialPropertyVisibility("parallax.showClipping", parallaxSettingVisibility)
if BlendSourceUsesDisplacement(context) then
context:SetMaterialPropertyVisibility("blend.displacementBlendDistance", MaterialPropertyVisibility_Enabled)
@@ -601,7 +601,7 @@
"displayName": "Opacity Mode",
"description": "Opacity mode for this texture.",
"type": "Enum",
"enumValues": [ "Opaque", "Cutout", "Blended" ],
"enumValues": [ "Opaque", "Cutout", "Blended", "TintedTransparent" ],
"defaultValue": "Opaque",
"connection": {
"type": "ShaderOption",
@@ -669,12 +669,12 @@
"description": "Center point for scaling and rotation transformations.",
"type": "vector2",
"vectorLabels": [ "U", "V" ],
"defaultValue": [ 0.0, 0.0 ]
"defaultValue": [ 0.5, 0.5 ]
},
{
"id": "tileU",
"displayName": "Tile U",
"description": "Scales texture coordinates in V.",
"description": "Scales texture coordinates in U.",
"type": "float",
"defaultValue": 1.0,
"step": 0.1
@@ -879,13 +879,6 @@
}
],
"parallax": [
{
"id": "enable",
"displayName": "Enable",
"description": "Whether to enable the parallax feature.",
"type": "Bool",
"defaultValue": false
},
{
"id": "textureMap",
"displayName": "Texture Map",
@@ -896,6 +889,13 @@
"id": "m_depthMap"
}
},
{
"id": "useTexture",
"displayName": "Use Texture",
"description": "Whether to use the texture map.",
"type": "Bool",
"defaultValue": true
},
{
"id": "textureMapUv",
"displayName": "UV",
@@ -913,7 +913,7 @@
"displayName": "Heightmap Scale",
"description": "The total height of the heightmap in local model units.",
"type": "Float",
"defaultValue": 0.0,
"defaultValue": 0.05,
"min": 0.0,
"softMax": 0.1,
"connection": {
@@ -951,7 +951,7 @@
"description": "Select the algorithm to use for parallax mapping.",
"type": "Enum",
"enumValues": [ "Basic", "Steep", "POM", "Relief", "ContactRefinement" ],
"defaultValue": "Basic",
"defaultValue": "POM",
"connection": {
"type": "ShaderOption",
"id": "o_parallax_algorithm"
@@ -1139,7 +1139,7 @@
"type": "float",
"defaultValue": 6.0,
"min": 0.0,
"softMax": 20.0
"softMax": 20.0
},
{
"id": "transmissionDistortion",
@@ -1170,7 +1170,7 @@
}
],
"irradiance": [
// Note: this property group is used in the DiffuseGlobalIllumination pass, it is not read by the StandardPBR shader
// Note: this property group is used in the DiffuseGlobalIllumination pass and not by the main forward shader
{
"id": "color",
"displayName": "Color",
@@ -1277,18 +1277,18 @@
"type": "HandleSubsurfaceScatteringParameters",
"args": {
"mode": "subsurfaceScattering.transmissionMode",
"scale" : "subsurfaceScattering.transmissionScale",
"power" : "subsurfaceScattering.transmissionPower",
"distortion" : "subsurfaceScattering.transmissionDistortion",
"attenuation" : "subsurfaceScattering.transmissionAttenuation",
"tintColor" : "subsurfaceScattering.transmissionTint",
"thickness" : "subsurfaceScattering.thickness",
"scale": "subsurfaceScattering.transmissionScale",
"power": "subsurfaceScattering.transmissionPower",
"distortion": "subsurfaceScattering.transmissionDistortion",
"attenuation": "subsurfaceScattering.transmissionAttenuation",
"tintColor": "subsurfaceScattering.transmissionTint",
"thickness": "subsurfaceScattering.thickness",
"enabled": "subsurfaceScattering.enableSubsurfaceScattering",
"scatterDistanceColor" : "subsurfaceScattering.scatterColor",
"scatterDistanceIntensity" : "subsurfaceScattering.scatterDistance",
"scatterDistanceShaderInput" : "m_scatterDistance",
"parametersShaderInput" : "m_transmissionParams",
"tintThickenssShaderInput" : "m_transmissionTintThickness"
"scatterDistanceColor": "subsurfaceScattering.scatterColor",
"scatterDistanceIntensity": "subsurfaceScattering.scatterDistance",
"scatterDistanceShaderInput": "m_scatterDistance",
"parametersShaderInput": "m_transmissionParams",
"tintThickenssShaderInput": "m_transmissionTintThickness"
}
},
{
@@ -1387,15 +1387,6 @@
"file": "StandardPBR_HandleOpacityDoubleSided.lua"
}
},
{
"type": "OverrideDrawList",
"args": {
"triggerProperty": "opacity.mode",
"triggerValue": "Blended",
"shaderIndex": 1,
"drawList": "transparent"
}
},
{
"type": "Lua",
"args": {
@@ -294,6 +294,24 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse
lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular
}
else if (o_opacity_mode == OpacityMode::TintedTransparent)
{
// See OpacityMode::Blended above for the basic method. TintedTransparent adds onto the above concept by supporting
// colored alpha. This is currently a very basic calculation that uses the baseColor as a multiplier with strength
// determined by the alpha. We'll modify this later to be more physically accurate and allow surface depth,
// absorption, and interior color to be specified.
//
// The technique uses dual source blending to allow two separate sources to be part of the blending equation
// even though ultimately only a single render target is being written to. m_diffuseColor is render target 0 and
// m_specularColor render target 1, and the blend mode is (dest * source1color) + (source * 1.0).
//
// This means that m_specularColor.rgb (source 1) is multiplied against the destination, then
// m_diffuseColor.rgb (source) is added to that, and the final result is stored in render target 0.
lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse
lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular
lightingOutput.m_specularColor.rgb = baseColor * (1.0 - lightingOutput.m_diffuseColor.w);
}
else
{
// Pack factor and quality, drawback: because of precision limit of float16 cannot represent exact 1, maximum representable value is 0.9961
@@ -60,10 +60,13 @@ function Process(context)
if(opacityMode == OpacityMode_Blended) then
ConfigureAlphaBlending(context:GetShader(ForwardPassIndex))
context:GetShader(ForwardPassIndex):SetDrawListTagOverride("transparent")
elseif(opacityMode == OpacityMode_TintedTransparent) then
ConfigureDualSourceBlending(context:GetShader(ForwardPassIndex))
context:GetShader(ForwardPassIndex):SetDrawListTagOverride("transparent")
else
ResetAlphaBlending(context:GetShader(ForwardPassIndex))
context:GetShader(ForwardPassIndex):SetDrawListTagOverride("") -- reset to default draw list
end
end
@@ -13,7 +13,7 @@
----------------------------------------------------------------------------------------------------
function GetMaterialPropertyDependencies()
return {"parallax.enable", "parallax.textureMap"}
return {"parallax.textureMap", "parallax.useTexture"}
end
function GetShaderOptionDependencies()
@@ -21,27 +21,31 @@ function GetShaderOptionDependencies()
end
function Process(context)
local enable = context:GetMaterialPropertyValue_bool("parallax.enable")
local textureMap = context:GetMaterialPropertyValue_Image("parallax.textureMap")
local useTexture = context:GetMaterialPropertyValue_bool("parallax.useTexture")
local enable = textureMap ~= nil and useTexture
context:SetShaderOptionValue_bool("o_parallax_feature_enabled", enable)
context:SetShaderOptionValue_bool("o_useDepthMap", enable and textureMap ~= nil)
context:SetShaderOptionValue_bool("o_useDepthMap", enable)
end
function ProcessEditor(context)
local enable = context:GetMaterialPropertyValue_bool("parallax.enable")
if enable then
context:SetMaterialPropertyVisibility("parallax.textureMap", MaterialPropertyVisibility_Enabled)
else
context:SetMaterialPropertyVisibility("parallax.textureMap", MaterialPropertyVisibility_Hidden)
end
local textureMap = context:GetMaterialPropertyValue_Image("parallax.textureMap")
local visibility = MaterialPropertyVisibility_Enabled
if(not enable or textureMap == nil) then
visibility = MaterialPropertyVisibility_Hidden
if textureMap ~= nil then
context:SetMaterialPropertyVisibility("parallax.useTexture", MaterialPropertyVisibility_Enabled)
else
context:SetMaterialPropertyVisibility("parallax.useTexture", MaterialPropertyVisibility_Hidden)
end
local useTexture = context:GetMaterialPropertyValue_bool("parallax.useTexture")
local visibility = MaterialPropertyVisibility_Enabled
if(textureMap == nil) then
visibility = MaterialPropertyVisibility_Hidden
elseif not useTexture then
visibility = MaterialPropertyVisibility_Disabled
end
context:SetMaterialPropertyVisibility("parallax.factor", visibility)
context:SetMaterialPropertyVisibility("parallax.offset", visibility)
context:SetMaterialPropertyVisibility("parallax.showClipping", visibility)
@@ -13,7 +13,7 @@
----------------------------------------------------------------------------------------------------
function GetMaterialPropertyDependencies()
return {"opacity.mode", "parallax.enable", "parallax.pdo"}
return {"opacity.mode", "parallax.textureMap", "parallax.useTexture", "parallax.pdo"}
end
OpacityMode_Opaque = 0
@@ -21,41 +21,61 @@ OpacityMode_Cutout = 1
OpacityMode_Blended = 2
OpacityMode_TintedTransparent = 3
function TryGetShaderByTag(context, shaderTag)
if context:HasShaderWithTag(shaderTag) then
return context:GetShaderByTag(shaderTag)
else
return nil
end
end
function TrySetShaderEnabled(shader, enabled)
if shader then
shader:SetEnabled(enabled)
end
end
function Process(context)
local opacityMode = context:GetMaterialPropertyValue_enum("opacity.mode")
local parallaxEnabled = context:GetMaterialPropertyValue_bool("parallax.enable")
local displacementMap = context:GetMaterialPropertyValue_Image("parallax.textureMap")
local useDisplacementMap = context:GetMaterialPropertyValue_bool("parallax.useTexture")
local parallaxEnabled = displacementMap ~= nil and useDisplacementMap
local parallaxPdoEnabled = context:GetMaterialPropertyValue_bool("parallax.pdo")
local depthPass = context:GetShaderByTag("DepthPass")
local shadowMap = context:GetShaderByTag("Shadowmap")
local forwardPassEDS = context:GetShaderByTag("ForwardPass_EDS")
local lowEndForwardEDS = context:GetShaderByTag("LowEndForward_EDS")
local depthPassWithPS = context:GetShaderByTag("DepthPass_WithPS")
local shadowMapWithPS = context:GetShaderByTag("Shadowmap_WithPS")
local forwardPass = context:GetShaderByTag("ForwardPass")
local lowEndForward = context:GetShaderByTag("LowEndForward")
-- Use TryGetShaderByTag because these shaders only exist in StandardPBR but this script is also used for EnhancedPBR
local lowEndForwardEDS = TryGetShaderByTag(context, "LowEndForward_EDS")
local lowEndForward = TryGetShaderByTag(context, "LowEndForward")
if parallaxEnabled and parallaxPdoEnabled then
depthPass:SetEnabled(false)
shadowMap:SetEnabled(false)
forwardPassEDS:SetEnabled(false)
lowEndForwardEDS:SetEnabled(false)
depthPassWithPS:SetEnabled(true)
shadowMapWithPS:SetEnabled(true)
forwardPass:SetEnabled(true)
lowEndForward:SetEnabled(true)
TrySetShaderEnabled(lowEndForwardEDS, false)
TrySetShaderEnabled(lowEndForward, true)
else
depthPass:SetEnabled(opacityMode == OpacityMode_Opaque)
shadowMap:SetEnabled(opacityMode == OpacityMode_Opaque)
forwardPassEDS:SetEnabled((opacityMode == OpacityMode_Opaque) or (opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent))
lowEndForwardEDS:SetEnabled((opacityMode == OpacityMode_Opaque) or (opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent))
depthPassWithPS:SetEnabled(opacityMode == OpacityMode_Cutout)
shadowMapWithPS:SetEnabled(opacityMode == OpacityMode_Cutout)
forwardPass:SetEnabled(opacityMode == OpacityMode_Cutout)
lowEndForward:SetEnabled(opacityMode == OpacityMode_Cutout)
TrySetShaderEnabled(lowEndForwardEDS, (opacityMode == OpacityMode_Opaque) or (opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent))
TrySetShaderEnabled(lowEndForward, opacityMode == OpacityMode_Cutout)
end
context:GetShaderByTag("DepthPassTransparentMin"):SetEnabled((opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent))
@@ -14,6 +14,9 @@
#include <AzCore/base.h>
#include <Atom/RPI.Public/FeatureProcessor.h>
#include <Atom/RHI.Reflect/Size.h>
#include <Atom/RPI.Reflect/Image/StreamingImageAsset.h>
#include <Atom/RPI.Reflect/Image/Image.h>
namespace AZ
{
@@ -23,6 +26,57 @@ namespace AZ
using DiffuseProbeGridHandle = AZStd::shared_ptr<DiffuseProbeGrid>;
enum class DiffuseProbeGridMode : uint8_t
{
RealTime,
Baked,
AutoSelect
};
enum class DiffuseProbeGridTextureNotificationType
{
None,
Ready,
Error
};
struct DiffuseProbeGridTexture
{
const AZStd::shared_ptr<AZStd::vector<uint8_t>> m_data;
RHI::Format m_format;
RHI::Size m_size;
};
static const char* DiffuseProbeGridIrradianceFileName = "Irradiance_lutrgba16.dds";
static const char* DiffuseProbeGridDistanceFileName = "Distance_lutrg32f.dds";
static const char* DiffuseProbeGridRelocationFileName = "Relocation_lutrgba16f.dds";
static const char* DiffuseProbeGridClassificationFileName = "Classification_lutr32f.dds";
using DiffuseProbeGridBakeTexturesCallback = AZStd::function<void(
DiffuseProbeGridTexture irradianceTexture,
DiffuseProbeGridTexture distanceTexture,
DiffuseProbeGridTexture relocationTexture,
DiffuseProbeGridTexture classificationTexture)>;
struct DiffuseProbeGridBakedTextures
{
// irradiance and distance images can be used directly
Data::Instance<RPI::Image> m_irradianceImage;
AZStd::string m_irradianceImageRelativePath;
Data::Instance<RPI::Image> m_distanceImage;
AZStd::string m_distanceImageRelativePath;
// relocation and classification images need to be recreated as RW textures
RHI::ImageDescriptor m_relocationImageDescriptor;
AZStd::array_view<uint8_t> m_relocationImageData;
AZStd::string m_relocationImageRelativePath;
RHI::ImageDescriptor m_classificationImageDescriptor;
AZStd::array_view<uint8_t> m_classificationImageData;
AZStd::string m_classificationImageRelativePath;
};
// DiffuseProbeGridFeatureProcessorInterface provides an interface to the feature processor for code outside of Atom
class DiffuseProbeGridFeatureProcessorInterface
: public RPI::FeatureProcessor
@@ -44,6 +98,29 @@ namespace AZ
virtual void Enable(const DiffuseProbeGridHandle& probeGrid, bool enable) = 0;
virtual void SetGIShadows(const DiffuseProbeGridHandle& probeGrid, bool giShadows) = 0;
virtual void SetUseDiffuseIbl(const DiffuseProbeGridHandle& probeGrid, bool useDiffuseIbl) = 0;
virtual void SetMode(const DiffuseProbeGridHandle& probeGrid, DiffuseProbeGridMode mode) = 0;
virtual void SetBakedTextures(const DiffuseProbeGridHandle& probeGrid, const DiffuseProbeGridBakedTextures& bakedTextures) = 0;
virtual void BakeTextures(
const DiffuseProbeGridHandle& probeGrid,
DiffuseProbeGridBakeTexturesCallback callback,
const AZStd::string& irradianceTextureRelativePath,
const AZStd::string& distanceTextureRelativePath,
const AZStd::string& relocationTextureRelativePath,
const AZStd::string& classificationTextureRelativePath) = 0;
// check for and retrieve a new baked texture asset (does not apply to hot-reloaded assets, only initial bakes)
virtual bool CheckTextureAssetNotification(
const AZStd::string& relativePath,
Data::Asset<RPI::StreamingImageAsset>& outTextureAsset,
DiffuseProbeGridTextureNotificationType& outNotificationType) = 0;
virtual bool AreBakedTexturesReferenced(
const AZStd::string& irradianceTextureRelativePath,
const AZStd::string& distanceTextureRelativePath,
const AZStd::string& relocationTextureRelativePath,
const AZStd::string& classificationTextureRelativePath) = 0;
};
} // namespace Render
} // namespace AZ
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -26,14 +26,15 @@ namespace AZ
, public AzToolsFramework::EditorEntityVisibilityNotificationBus::Handler
{
public:
using BaseClass = AzToolsFramework::Components::EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>;
AZ_RTTI((EditorRenderComponentAdapter, "{AAF38BE4-EA2F-408B-9C44-63C7FBAC6B33}", TController, TRuntimeComponent, TConfiguration), BaseClass);
AZ_RTTI(
(EditorRenderComponentAdapter, "{AAF38BE4-EA2F-408B-9C44-63C7FBAC6B33}", TController, TRuntimeComponent, TConfiguration),
BaseClass);
static void Reflect(AZ::ReflectContext* context);
EditorRenderComponentAdapter() = default;
EditorRenderComponentAdapter(const TConfiguration& config);
explicit EditorRenderComponentAdapter(const TConfiguration& config);
// AzToolsFramework::Components::EditorComponentAdapter overrides
void Activate() override;
@@ -50,7 +51,8 @@ namespace AZ
// Convert pre-existing EditorCompnentAdapter based serialized data to EditorRenderComponentAdapter
template<int TVersion>
static bool ConvertToEditorRenderComponentAdapter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
static bool ConvertToEditorRenderComponentAdapter(
AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
};
} // namespace Render
} // namespace AZ
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Atom/Feature/Utils/EditorRenderComponentAdapter.h>
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
@@ -19,11 +19,12 @@ namespace AZ
{
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
template<int TVersion>
bool EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration>::ConvertToEditorRenderComponentAdapter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
bool EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration>::ConvertToEditorRenderComponentAdapter(
AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
{
if (classElement.GetVersion() < TVersion)
{
// Get the and remove the EditorComponentAdapter base class data that was previpously serialized
// Get the and remove the EditorComponentAdapter base class data that was previously serialized
AzToolsFramework::Components::EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration> oldBaseClassData;
if (!classElement.FindSubElementAndGetData(AZ_CRC("BaseClass1", 0xd4925735), oldBaseClassData))
@@ -41,8 +42,8 @@ namespace AZ
// Replace the old base class data with EditorRenderComponentAdapter
EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration> newBaseClassData;
AZ::SerializeContext::DataElementNode& newBaseClassElement = classElement.GetSubElement(
classElement.AddElementWithData(context, "BaseClass1", newBaseClassData));
AZ::SerializeContext::DataElementNode& newBaseClassElement =
classElement.GetSubElement(classElement.AddElementWithData(context, "BaseClass1", newBaseClassData));
// Overwrite EditorRenderComponentAdapter base class data with retrieved EditorComponentAdapter base class data
if (!newBaseClassElement.RemoveElementByName(AZ_CRC("BaseClass1", 0xd4925735)))
@@ -62,25 +63,24 @@ namespace AZ
{
BaseClass::Reflect(context);
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<EditorRenderComponentAdapter, BaseClass>()
->Version(0)
;
serializeContext->Class<EditorRenderComponentAdapter, BaseClass>()->Version(0);
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<EditorRenderComponentAdapter>(
"EditorRenderComponentAdapter", "")
// clang-format off
editContext->Class<EditorRenderComponentAdapter>("EditorRenderComponentAdapter", "")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
;
->Attribute(AZ::Edit::Attributes::AutoExpand, true);
// clang-format on
}
}
}
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration>::EditorRenderComponentAdapter(const TConfiguration& config)
EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration>::EditorRenderComponentAdapter(
const TConfiguration& config)
: BaseClass(config)
{
}
@@ -103,7 +103,8 @@ namespace AZ
bool EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration>::IsVisible() const
{
bool visible = true;
AzToolsFramework::EditorEntityInfoRequestBus::EventResult(visible, this->GetEntityId(), &AzToolsFramework::EditorEntityInfoRequestBus::Events::IsVisible);
AzToolsFramework::EditorEntityInfoRequestBus::EventResult(
visible, this->GetEntityId(), &AzToolsFramework::EditorEntityInfoRequestBus::Events::IsVisible);
return visible;
}
@@ -114,15 +115,16 @@ namespace AZ
}
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
void EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration>::OnEntityVisibilityChanged([[maybe_unused]] bool visibility)
void EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration>::OnEntityVisibilityChanged(
[[maybe_unused]] bool visibility)
{
this->m_controller.Deactivate();
if (this->ShouldActivateController())
{
this->m_controller.Activate(this->GetEntityId());
AzFramework::Components::ComponentActivateHelper<TController>::Activate(
this->m_controller, AZ::EntityComponentIdPair(this->GetEntityId(), this->GetId()));
}
}
} // namespace Render
} // namespace AZ
@@ -14,8 +14,6 @@
#include <Source/Material/UseTextureFunctor.h>
#include <Source/Material/SubsurfaceTransmissionParameterFunctor.h>
#include <Source/Material/Transform2DFunctor.h>
#include <Source/Material/ShaderEnableFunctor.h>
#include <Source/Material/PropertyVisibilityFunctor.h>
#include <Source/Material/DrawListFunctor.h>
#include <Source/Material/ConvertEmissiveUnitFunctor.h>
@@ -116,7 +114,6 @@ namespace AZ
ProjectedShadowFeatureProcessor::Reflect(context);
SkyBoxFeatureProcessor::Reflect(context);
UseTextureFunctor::Reflect(context);
PropertyVisibilityFunctor::Reflect(context);
DrawListFunctor::Reflect(context);
SubsurfaceTransmissionParameterFunctor::Reflect(context);
Transform2DFunctor::Reflect(context);
@@ -128,7 +125,6 @@ namespace AZ
DisplayMapperPassData::Reflect(context);
ConvertEmissiveUnitFunctor::Reflect(context);
LookupTableAsset::Reflect(context);
ShaderEnableFunctor::Reflect(context);
ReflectionProbeFeatureProcessor::Reflect(context);
DecalTextureArrayFeatureProcessor::Reflect(context);
SMAAFeatureProcessor::Reflect(context);
@@ -279,7 +279,7 @@ namespace AZ
if (handle.IsValid())
{
Quaternion orientation = world.GetRotation();
Vector3 scale = world.GetScale() * nonUniformScale;
Vector3 scale = world.GetUniformScale() * nonUniformScale;
SetDecalHalfSize(handle, scale);
SetDecalPosition(handle, world.GetTranslation());
@@ -285,7 +285,7 @@ namespace AZ
{
if (handle.IsValid())
{
SetDecalHalfSize(handle, nonUniformScale * world.GetScale());
SetDecalHalfSize(handle, nonUniformScale * world.GetUniformScale());
SetDecalPosition(handle, world.GetTranslation());
SetDecalOrientation(handle, world.GetRotation());
@@ -13,6 +13,7 @@
#include <Atom/RHI.Reflect/ShaderResourceGroupLayoutDescriptor.h>
#include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
#include <DiffuseProbeGrid/DiffuseProbeGrid.h>
#include <Atom/RPI.Public/Image/StreamingImage.h>
#include <Atom/RPI.Public/View.h>
#include <Atom/RHI/RHISystemInterface.h>
#include <Atom/RHI/Factory.h>
@@ -23,6 +24,11 @@ namespace AZ
{
namespace Render
{
DiffuseProbeGrid::DiffuseProbeGrid()
: m_textureReadback(this)
{
}
DiffuseProbeGrid::~DiffuseProbeGrid()
{
m_scene->GetCullingScene()->UnregisterCullable(m_cullable);
@@ -166,6 +172,84 @@ namespace AZ
m_updateRenderObjectSrg = true;
}
void DiffuseProbeGrid::SetMode(DiffuseProbeGridMode mode)
{
// handle auto-select
if (mode == DiffuseProbeGridMode::AutoSelect)
{
RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
m_mode = (device->GetFeatures().m_rayTracing) ? DiffuseProbeGridMode::RealTime : DiffuseProbeGridMode::Baked;
}
else
{
m_mode = mode;
}
m_updateTextures = true;
}
void DiffuseProbeGrid::SetBakedTextures(const DiffuseProbeGridBakedTextures& bakedTextures)
{
AZ_Assert(bakedTextures.m_irradianceImage.get(), "Invalid Irradiance image passed to SetBakedTextures");
AZ_Assert(bakedTextures.m_distanceImage.get(), "Invalid Distance image passed to SetBakedTextures");
AZ_Assert(bakedTextures.m_relocationImageData.size() > 0, "Invalid Relocation image data passed to SetBakedTextures");
AZ_Assert(bakedTextures.m_classificationImageData.size() > 0, "Invalid Classification image data passed to SetBakedTextures");
m_bakedIrradianceImage = bakedTextures.m_irradianceImage;
m_bakedDistanceImage = bakedTextures.m_distanceImage;
m_bakedIrradianceRelativePath = bakedTextures.m_irradianceImageRelativePath;
m_bakedDistanceRelativePath = bakedTextures.m_distanceImageRelativePath;
m_bakedRelocationRelativePath = bakedTextures.m_relocationImageRelativePath;
m_bakedClassificationRelativePath = bakedTextures.m_classificationImageRelativePath;
m_bakedRelocationImageData.resize(bakedTextures.m_relocationImageData.size());
memcpy(m_bakedRelocationImageData.data(), bakedTextures.m_relocationImageData.data(), bakedTextures.m_relocationImageData.size());
m_bakedClassificationImageData.resize(bakedTextures.m_classificationImageData.size());
memcpy(m_bakedClassificationImageData.data(), bakedTextures.m_classificationImageData.data(), bakedTextures.m_classificationImageData.size());
// create the relocation and distance RW textures now, these are needed for shader compatibility
// (image data is copied in UpdateTextures)
{
m_bakedRelocationImage = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest initRequest;
initRequest.m_image = m_bakedRelocationImage.get();
initRequest.m_descriptor = RHI::ImageDescriptor::Create2D(
RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead,
bakedTextures.m_relocationImageDescriptor.m_size.m_width,
bakedTextures.m_relocationImageDescriptor.m_size.m_height,
bakedTextures.m_relocationImageDescriptor.m_format);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(initRequest);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize Relocation image");
}
{
m_bakedClassificationImage = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest initRequest;
initRequest.m_image = m_bakedClassificationImage.get();
initRequest.m_descriptor = RHI::ImageDescriptor::Create2D(
RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead,
bakedTextures.m_classificationImageDescriptor.m_size.m_width,
bakedTextures.m_classificationImageDescriptor.m_size.m_height,
bakedTextures.m_classificationImageDescriptor.m_format);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(initRequest);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize Classification image");
}
m_updateTextures = true;
}
bool DiffuseProbeGrid::HasValidBakedTextures() const
{
return m_bakedIrradianceImage.get() &&
m_bakedDistanceImage.get() &&
m_bakedRelocationImage.get() &&
m_bakedClassificationImage.get();
}
uint32_t DiffuseProbeGrid::GetTotalProbeCount() const
{
return m_probeCountX * m_probeCountY * m_probeCountZ;
@@ -188,83 +272,117 @@ namespace AZ
RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
// advance to the next image in the frame image array
m_currentImageIndex = (m_currentImageIndex + 1) % ImageFrameCount;
// probe raytrace
{
uint32_t width = m_numRaysPerProbe;
uint32_t height = GetTotalProbeCount();
m_rayTraceImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_rayTraceImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite, width, height, DiffuseProbeGridRenderData::RayTraceImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeRayTraceImage image");
}
uint32_t probeCountX;
uint32_t probeCountY;
GetTexture2DProbeCount(probeCountX, probeCountY);
// probe irradiance
if (m_mode == DiffuseProbeGridMode::RealTime)
{
uint32_t width = probeCountX * (DefaultNumIrradianceTexels + 2);
uint32_t height = probeCountY * (DefaultNumIrradianceTexels + 2);
// advance to the next image in the frame image array
m_currentImageIndex = (m_currentImageIndex + 1) % ImageFrameCount;
m_irradianceImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
// probe raytrace
{
uint32_t width = m_numRaysPerProbe;
uint32_t height = GetTotalProbeCount();
RHI::ImageInitRequest request;
request.m_image = m_irradianceImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite, width, height, DiffuseProbeGridRenderData::IrradianceImageFormat);
RHI::ClearValue clearValue = RHI::ClearValue::CreateVector4Float(0.0f, 0.0f, 0.0f, 0.0f);
request.m_optimizedClearValue = &clearValue;
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeIrradianceImage image");
m_rayTraceImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_rayTraceImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead, width, height, DiffuseProbeGridRenderData::RayTraceImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeRayTraceImage image");
}
// probe irradiance
{
uint32_t width = probeCountX * (DefaultNumIrradianceTexels + 2);
uint32_t height = probeCountY * (DefaultNumIrradianceTexels + 2);
m_irradianceImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_irradianceImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead, width, height, DiffuseProbeGridRenderData::IrradianceImageFormat);
RHI::ClearValue clearValue = RHI::ClearValue::CreateVector4Float(0.0f, 0.0f, 0.0f, 0.0f);
request.m_optimizedClearValue = &clearValue;
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeIrradianceImage image");
}
// probe distance
{
uint32_t width = probeCountX * (DefaultNumDistanceTexels + 2);
uint32_t height = probeCountY * (DefaultNumDistanceTexels + 2);
m_distanceImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_distanceImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead, width, height, DiffuseProbeGridRenderData::DistanceImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeDistanceImage image");
}
// probe relocation
{
uint32_t width = probeCountX;
uint32_t height = probeCountY;
m_relocationImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_relocationImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead, width, height, DiffuseProbeGridRenderData::RelocationImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeRelocationImage image");
}
// probe classification
{
uint32_t width = probeCountX;
uint32_t height = probeCountY;
m_classificationImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_classificationImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead, width, height, DiffuseProbeGridRenderData::ClassificationImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeClassificationImage image");
}
}
// probe distance
else if (m_mode == DiffuseProbeGridMode::Baked && HasValidBakedTextures())
{
uint32_t width = probeCountX * (DefaultNumDistanceTexels + 2);
uint32_t height = probeCountY * (DefaultNumDistanceTexels + 2);
// copy the baked relocation and classification texture data to the RW textures
// (these need to be RW for shader compatibility)
RHI::ImageSubresourceRange range{ 0, 0, 0 ,0 };
RHI::ImageSubresourceLayoutPlaced layout;
m_distanceImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
// relocation
{
m_bakedRelocationImage->GetSubresourceLayouts(range, &layout, nullptr);
RHI::ImageInitRequest request;
request.m_image = m_distanceImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite, width, height, DiffuseProbeGridRenderData::DistanceImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeDistanceImage image");
}
RHI::ImageUpdateRequest updateRequest;
updateRequest.m_image = m_bakedRelocationImage.get();
updateRequest.m_sourceSubresourceLayout = layout;
updateRequest.m_sourceData = m_bakedRelocationImageData.data();
updateRequest.m_imageSubresourcePixelOffset = RHI::Origin(0, 0, 0);
m_renderData->m_imagePool->UpdateImageContents(updateRequest);
}
// probe relocation
{
uint32_t width = probeCountX;
uint32_t height = probeCountY;
// classification
{
m_bakedClassificationImage->GetSubresourceLayouts(range, &layout, nullptr);
m_relocationImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_relocationImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite, width, height, DiffuseProbeGridRenderData::RelocationImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeRelocationImage image");
}
// probe classification
{
uint32_t width = probeCountX;
uint32_t height = probeCountY;
m_classificationImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_classificationImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite, width, height, DiffuseProbeGridRenderData::ClassificationImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeClassificationImage image");
RHI::ImageUpdateRequest updateRequest;
updateRequest.m_image = m_bakedClassificationImage.get();
updateRequest.m_sourceSubresourceLayout = layout;
updateRequest.m_sourceData = m_bakedClassificationImageData.data();
updateRequest.m_imageSubresourcePixelOffset = RHI::Origin(0, 0, 0);
m_renderData->m_imagePool->UpdateImageContents(updateRequest);
}
}
m_updateTextures = false;
@@ -639,16 +757,16 @@ namespace AZ
m_renderObjectSrg->SetConstant(constantIndex, m_ambientMultiplier);
imageIndex = srgLayout->FindShaderInputImageIndex(Name("m_probeIrradiance"));
m_renderObjectSrg->SetImageView(imageIndex, m_irradianceImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeIrradianceImageViewDescriptor).get());
m_renderObjectSrg->SetImageView(imageIndex, GetIrradianceImage()->GetImageView(m_renderData->m_probeIrradianceImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(Name("m_probeDistance"));
m_renderObjectSrg->SetImageView(imageIndex, m_distanceImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeDistanceImageViewDescriptor).get());
m_renderObjectSrg->SetImageView(imageIndex, GetDistanceImage()->GetImageView(m_renderData->m_probeDistanceImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(Name("m_probeOffsets"));
m_renderObjectSrg->SetImageView(imageIndex, m_relocationImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeRelocationImageViewDescriptor).get());
m_renderObjectSrg->SetImageView(imageIndex, GetRelocationImage()->GetImageView(m_renderData->m_probeRelocationImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(Name("m_probeStates"));
m_renderObjectSrg->SetImageView(imageIndex, m_classificationImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeClassificationImageViewDescriptor).get());
m_renderObjectSrg->SetImageView(imageIndex, GetClassificationImage()->GetImageView(m_renderData->m_probeClassificationImageViewDescriptor).get());
SetGridConstants(m_renderObjectSrg);
@@ -17,6 +17,7 @@
#include <Atom/RPI.Public/Scene.h>
#include <AzCore/Math/Random.h>
#include <AzCore/Math/Aabb.h>
#include <DiffuseProbeGrid/DiffuseProbeGridTextureReadback.h>
namespace AZ
{
@@ -26,11 +27,12 @@ namespace AZ
struct DiffuseProbeGridRenderData
{
// [GFX TODO][ATOM-15650] Change DiffuseProbeGrid Classification texture to R8_UINT
static const RHI::Format RayTraceImageFormat = RHI::Format::R32G32B32A32_FLOAT;
static const RHI::Format IrradianceImageFormat = RHI::Format::R16G16B16A16_UNORM;
static const RHI::Format DistanceImageFormat = RHI::Format::R32G32_FLOAT;
static const RHI::Format RelocationImageFormat = RHI::Format::R16G16B16A16_FLOAT;
static const RHI::Format ClassificationImageFormat = RHI::Format::R8_UINT;
static const RHI::Format ClassificationImageFormat = RHI::Format::R32_FLOAT;
// image pool
RHI::Ptr<RHI::ImagePool> m_imagePool;
@@ -61,7 +63,7 @@ namespace AZ
class DiffuseProbeGrid final
{
public:
DiffuseProbeGrid() = default;
DiffuseProbeGrid();
~DiffuseProbeGrid();
void Init(RPI::Scene* scene, DiffuseProbeGridRenderData* diffuseProbeGridRenderData);
@@ -96,6 +98,9 @@ namespace AZ
bool GetUseDiffuseIbl() const { return m_useDiffuseIbl; }
void SetUseDiffuseIbl(bool useDiffuseIbl) { m_useDiffuseIbl = useDiffuseIbl; }
DiffuseProbeGridMode GetMode() const { return m_mode; }
void SetMode(DiffuseProbeGridMode mode);
uint32_t GetNumRaysPerProbe() const { return m_numRaysPerProbe; }
uint32_t GetRemainingRelocationIterations() const { return aznumeric_cast<uint32_t>(m_remainingRelocationIterations); }
@@ -133,11 +138,16 @@ namespace AZ
void UpdateRenderObjectSrg();
// textures
const RHI::Ptr<RHI::Image>& GetRayTraceImage() { return m_rayTraceImage[m_currentImageIndex]; }
const RHI::Ptr<RHI::Image>& GetIrradianceImage() { return m_irradianceImage[m_currentImageIndex]; }
const RHI::Ptr<RHI::Image>& GetDistanceImage() { return m_distanceImage[m_currentImageIndex]; }
const RHI::Ptr<RHI::Image>& GetRelocationImage() { return m_relocationImage[m_currentImageIndex]; }
const RHI::Ptr<RHI::Image>& GetClassificationImage() { return m_classificationImage[m_currentImageIndex]; }
const RHI::Ptr<RHI::Image> GetRayTraceImage() { return m_rayTraceImage[m_currentImageIndex]; }
const RHI::Ptr<RHI::Image> GetIrradianceImage() { return m_mode == DiffuseProbeGridMode::RealTime ? m_irradianceImage[m_currentImageIndex] : m_bakedIrradianceImage->GetRHIImage(); }
const RHI::Ptr<RHI::Image> GetDistanceImage() { return m_mode == DiffuseProbeGridMode::RealTime ? m_distanceImage[m_currentImageIndex] : m_bakedDistanceImage->GetRHIImage(); }
const RHI::Ptr<RHI::Image> GetRelocationImage() { return m_mode == DiffuseProbeGridMode::RealTime ? m_relocationImage[m_currentImageIndex] : m_bakedRelocationImage; }
const RHI::Ptr<RHI::Image> GetClassificationImage() { return m_mode == DiffuseProbeGridMode::RealTime ? m_classificationImage[m_currentImageIndex] : m_bakedClassificationImage; }
const AZStd::string& GetBakedIrradianceRelativePath() const { return m_bakedIrradianceRelativePath; }
const AZStd::string& GetBakedDistanceRelativePath() const { return m_bakedDistanceRelativePath; }
const AZStd::string& GetBakedRelocationRelativePath() const { return m_bakedRelocationRelativePath; }
const AZStd::string& GetBakedClassificationRelativePath() const { return m_bakedClassificationRelativePath; }
// attachment Ids
const RHI::AttachmentId GetRayTraceImageAttachmentId() const { return m_rayTraceImageAttachmentId; }
@@ -152,6 +162,12 @@ namespace AZ
bool GetIrradianceClearRequired() const { return m_irradianceClearRequired; }
void ResetIrradianceClearRequired() { m_irradianceClearRequired = false; }
// texture readback
DiffuseProbeGridTextureReadback& GetTextureReadback() { return m_textureReadback; }
void SetBakedTextures(const DiffuseProbeGridBakedTextures& bakedTextures);
bool HasValidBakedTextures() const;
static constexpr uint32_t DefaultNumIrradianceTexels = 6;
static constexpr uint32_t DefaultNumDistanceTexels = 14;
static constexpr int32_t DefaultNumRelocationIterations = 100;
@@ -221,7 +237,10 @@ namespace AZ
// culling
RPI::Cullable m_cullable;
// textures
// grid mode (RealTime or Baked)
DiffuseProbeGridMode m_mode = DiffuseProbeGridMode::RealTime;
// real-time textures
static const uint32_t MaxTextureDimension = 8192;
static const uint32_t ImageFrameCount = 3;
RHI::Ptr<RHI::Image> m_rayTraceImage[ImageFrameCount];
@@ -233,6 +252,25 @@ namespace AZ
bool m_updateTextures = false;
bool m_irradianceClearRequired = true;
// baked textures
Data::Instance<RPI::Image> m_bakedIrradianceImage;
Data::Instance<RPI::Image> m_bakedDistanceImage;
RHI::Ptr<RHI::Image> m_bakedRelocationImage;
RHI::Ptr<RHI::Image> m_bakedClassificationImage;
// baked texture relative paths
AZStd::string m_bakedIrradianceRelativePath;
AZStd::string m_bakedDistanceRelativePath;
AZStd::string m_bakedRelocationRelativePath;
AZStd::string m_bakedClassificationRelativePath;
// baked texture data (only needed for the relocation and classification textures)
AZStd::vector<uint8_t> m_bakedRelocationImageData;
AZStd::vector<uint8_t> m_bakedClassificationImageData;
// texture readback
DiffuseProbeGridTextureReadback m_textureReadback;
// Srgs
Data::Instance<RPI::ShaderResourceGroup> m_rayTraceSrg;
Data::Instance<RPI::ShaderResourceGroup> m_blendIrradianceSrg;
@@ -87,7 +87,7 @@ namespace AZ
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetProbeGrids().empty())
if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty())
{
// no diffuse probe grids
return;
@@ -111,7 +111,7 @@ namespace AZ
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
// probe raytrace image
{
@@ -150,7 +150,7 @@ namespace AZ
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
// the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs
// (see ValidateSetImageView() in ShaderResourceGroupData.cpp)
@@ -167,7 +167,7 @@ namespace AZ
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
// submit the DispatchItem for each DiffuseProbeGrid
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
const RHI::ShaderResourceGroup* shaderResourceGroup = diffuseProbeGrid->GetBlendDistanceSrg()->GetRHIShaderResourceGroup();
commandList->SetShaderResourceGroupForDispatch(*shaderResourceGroup);
@@ -87,7 +87,7 @@ namespace AZ
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetProbeGrids().empty())
if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty())
{
// no diffuse probe grids
return;
@@ -111,7 +111,7 @@ namespace AZ
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
// probe raytrace image
{
@@ -150,7 +150,7 @@ namespace AZ
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
// the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs
// (see ValidateSetImageView() in ShaderResourceGroupData.cpp)
@@ -167,7 +167,7 @@ namespace AZ
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
// submit the DispatchItem for each DiffuseProbeGrid
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
const RHI::ShaderResourceGroup* shaderResourceGroup = diffuseProbeGrid->GetBlendIrradianceSrg()->GetRHIShaderResourceGroup();
commandList->SetShaderResourceGroupForDispatch(*shaderResourceGroup);
@@ -100,7 +100,7 @@ namespace AZ
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetProbeGrids().empty())
if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty())
{
// no diffuse probe grids
return;
@@ -124,7 +124,7 @@ namespace AZ
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
// probe irradiance image
{
@@ -153,7 +153,7 @@ namespace AZ
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
// the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs
// (see line ValidateSetImageView() in ShaderResourceGroupData.cpp)
@@ -173,7 +173,7 @@ namespace AZ
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
// submit the DispatchItems for each DiffuseProbeGrid
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
uint32_t probeCountX;
uint32_t probeCountY;
@@ -91,7 +91,7 @@ namespace AZ
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetProbeGrids().empty())
if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty())
{
// no diffuse probe grids
return;
@@ -115,7 +115,7 @@ namespace AZ
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
// probe raytrace image
{
@@ -143,7 +143,7 @@ namespace AZ
{
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
// the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs
// (see ValidateSetImageView() in ShaderResourceGroupData.cpp)
@@ -159,7 +159,7 @@ namespace AZ
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
// submit the DispatchItems for each DiffuseProbeGrid
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
const RHI::ShaderResourceGroup* shaderResourceGroup = diffuseProbeGrid->GetClassificationSrg()->GetRHIShaderResourceGroup();
commandList->SetShaderResourceGroupForDispatch(*shaderResourceGroup);
@@ -45,6 +45,7 @@ namespace AZ
RHI::RHISystemInterface* rhiSystem = RHI::RHISystemInterface::Get();
m_diffuseProbeGrids.reserve(InitialProbeGridAllocationSize);
m_realTimeDiffuseProbeGrids.reserve(InitialProbeGridAllocationSize);
RHI::BufferPoolDescriptor desc;
desc.m_heapMemoryLevel = RHI::HeapMemoryLevel::Device;
@@ -61,7 +62,7 @@ namespace AZ
// image pool
{
RHI::ImagePoolDescriptor imagePoolDesc;
imagePoolDesc.m_bindFlags = RHI::ImageBindFlags::ShaderReadWrite;
imagePoolDesc.m_bindFlags = RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead;
m_probeGridRenderData.m_imagePool = RHI::Factory::Get().CreateImagePool();
[[maybe_unused]] RHI::ResultCode result = m_probeGridRenderData.m_imagePool->Init(*rhiSystem->GetDevice(), imagePoolDesc);
@@ -123,6 +124,32 @@ namespace AZ
m_needUpdatePipelineStates = false;
}
// check pending textures and connect bus for notifications
for (auto& notificationEntry : m_notifyTextureAssets)
{
if (notificationEntry.m_assetId.IsValid())
{
// asset already has an assetId
continue;
}
// query for the assetId
AZ::Data::AssetId assetId;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
assetId,
&AZ::Data::AssetCatalogRequests::GetAssetIdByPath,
notificationEntry.m_relativePath.c_str(),
azrtti_typeid<AZ::RPI::StreamingImageAsset>(),
false);
if (assetId.IsValid())
{
notificationEntry.m_assetId = assetId;
notificationEntry.m_asset.Create(assetId, true);
Data::AssetBus::MultiHandler::BusConnect(assetId);
}
}
// if the volumes changed we need to re-sort the probe list
if (m_probeGridSortRequired)
{
@@ -139,6 +166,7 @@ namespace AZ
};
AZStd::sort(m_diffuseProbeGrids.begin(), m_diffuseProbeGrids.end(), sortFn);
AZStd::sort(m_realTimeDiffuseProbeGrids.begin(), m_realTimeDiffuseProbeGrids.end(), sortFn);
m_probeGridSortRequired = false;
}
@@ -160,6 +188,9 @@ namespace AZ
diffuseProbeGrid->SetExtents(extents);
diffuseProbeGrid->SetProbeSpacing(probeSpacing);
m_diffuseProbeGrids.push_back(diffuseProbeGrid);
UpdateRealTimeList(diffuseProbeGrid);
m_probeGridSortRequired = true;
return diffuseProbeGrid;
@@ -169,6 +200,7 @@ namespace AZ
{
AZ_Assert(probeGrid.get(), "RemoveProbeGrid called with an invalid handle");
// remove from main list
auto itEntry = AZStd::find_if(m_diffuseProbeGrids.begin(), m_diffuseProbeGrids.end(), [&](AZStd::shared_ptr<DiffuseProbeGrid> const& entry)
{
return (entry == probeGrid);
@@ -176,6 +208,18 @@ namespace AZ
AZ_Assert(itEntry != m_diffuseProbeGrids.end(), "RemoveProbeGrid called with a probe grid that is not in the probe list");
m_diffuseProbeGrids.erase(itEntry);
// remove from side list of real-time grids
itEntry = AZStd::find_if(m_realTimeDiffuseProbeGrids.begin(), m_realTimeDiffuseProbeGrids.end(), [&](AZStd::shared_ptr<DiffuseProbeGrid> const& entry)
{
return (entry == probeGrid);
});
if (itEntry != m_realTimeDiffuseProbeGrids.end())
{
m_realTimeDiffuseProbeGrids.erase(itEntry);
}
probeGrid = nullptr;
}
@@ -247,6 +291,134 @@ namespace AZ
probeGrid->SetUseDiffuseIbl(useDiffuseIbl);
}
void DiffuseProbeGridFeatureProcessor::BakeTextures(
const DiffuseProbeGridHandle& probeGrid,
DiffuseProbeGridBakeTexturesCallback callback,
const AZStd::string& irradianceTextureRelativePath,
const AZStd::string& distanceTextureRelativePath,
const AZStd::string& relocationTextureRelativePath,
const AZStd::string& classificationTextureRelativePath)
{
AZ_Assert(probeGrid.get(), "BakeTextures called with an invalid handle");
AddNotificationEntry(irradianceTextureRelativePath);
AddNotificationEntry(distanceTextureRelativePath);
AddNotificationEntry(relocationTextureRelativePath);
AddNotificationEntry(classificationTextureRelativePath);
probeGrid->GetTextureReadback().BeginTextureReadback(callback);
}
void DiffuseProbeGridFeatureProcessor::UpdateRealTimeList(const DiffuseProbeGridHandle& diffuseProbeGrid)
{
if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::RealTime)
{
// add to side list of real-time grids
auto itEntry = AZStd::find_if(m_realTimeDiffuseProbeGrids.begin(), m_realTimeDiffuseProbeGrids.end(), [&](AZStd::shared_ptr<DiffuseProbeGrid> const& entry)
{
return (entry == diffuseProbeGrid);
});
if (itEntry == m_realTimeDiffuseProbeGrids.end())
{
m_realTimeDiffuseProbeGrids.push_back(diffuseProbeGrid);
}
}
else
{
// remove from side list of real-time grids
auto itEntry = AZStd::find_if(m_realTimeDiffuseProbeGrids.begin(), m_realTimeDiffuseProbeGrids.end(), [&](AZStd::shared_ptr<DiffuseProbeGrid> const& entry)
{
return (entry == diffuseProbeGrid);
});
if (itEntry != m_realTimeDiffuseProbeGrids.end())
{
m_realTimeDiffuseProbeGrids.erase(itEntry);
}
}
}
void DiffuseProbeGridFeatureProcessor::AddNotificationEntry(const AZStd::string& relativePath)
{
AZStd::string assetPath = relativePath + ".streamingimage";
// check to see if this is an existing asset
AZ::Data::AssetId assetId;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
assetId,
&AZ::Data::AssetCatalogRequests::GetAssetIdByPath,
assetPath.c_str(),
azrtti_typeid<AZ::RPI::StreamingImageAsset>(),
false);
// We only track notifications for new texture assets, meaning assets that are created the first time a DiffuseProbeGrid is baked.
// On subsequent bakes the existing assets are automatically reloaded by the RPI since they are already known by the asset system.
if (!assetId.IsValid())
{
m_notifyTextureAssets.push_back({ assetPath, assetId });
}
}
bool DiffuseProbeGridFeatureProcessor::CheckTextureAssetNotification(
const AZStd::string& relativePath,
Data::Asset<RPI::StreamingImageAsset>& outTextureAsset,
DiffuseProbeGridTextureNotificationType& outNotificationType)
{
for (NotifyTextureAssetVector::iterator itNotification = m_notifyTextureAssets.begin(); itNotification != m_notifyTextureAssets.end(); ++itNotification)
{
if (itNotification->m_relativePath == relativePath)
{
outNotificationType = itNotification->m_notificationType;
if (outNotificationType != DiffuseProbeGridTextureNotificationType::None)
{
outTextureAsset = itNotification->m_asset;
m_notifyTextureAssets.erase(itNotification);
}
return true;
}
}
return false;
}
bool DiffuseProbeGridFeatureProcessor::AreBakedTexturesReferenced(
const AZStd::string& irradianceTextureRelativePath,
const AZStd::string& distanceTextureRelativePath,
const AZStd::string& relocationTextureRelativePath,
const AZStd::string& classificationTextureRelativePath)
{
for (auto& diffuseProbeGrid : m_diffuseProbeGrids)
{
if ((diffuseProbeGrid->GetBakedIrradianceRelativePath() == irradianceTextureRelativePath) ||
(diffuseProbeGrid->GetBakedDistanceRelativePath() == distanceTextureRelativePath) ||
(diffuseProbeGrid->GetBakedRelocationRelativePath() == relocationTextureRelativePath) ||
(diffuseProbeGrid->GetBakedClassificationRelativePath() == classificationTextureRelativePath))
{
return true;
}
}
return false;
}
void DiffuseProbeGridFeatureProcessor::SetMode(const DiffuseProbeGridHandle& probeGrid, DiffuseProbeGridMode mode)
{
AZ_Assert(probeGrid.get(), "SetMode called with an invalid handle");
probeGrid->SetMode(mode);
UpdateRealTimeList(probeGrid);
m_probeGridSortRequired = true;
}
void DiffuseProbeGridFeatureProcessor::SetBakedTextures(const DiffuseProbeGridHandle& probeGrid, const DiffuseProbeGridBakedTextures& bakedTextures)
{
AZ_Assert(probeGrid.get(), "SetBakedTextures called with an invalid handle");
probeGrid->SetBakedTextures(bakedTextures);
}
void DiffuseProbeGridFeatureProcessor::CreateBoxMesh()
{
// vertex positions
@@ -418,5 +590,34 @@ namespace AZ
}
}
void DiffuseProbeGridFeatureProcessor::HandleAssetNotification(Data::Asset<Data::AssetData> asset, DiffuseProbeGridTextureNotificationType notificationType)
{
for (NotifyTextureAssetVector::iterator itNotification = m_notifyTextureAssets.begin(); itNotification != m_notifyTextureAssets.end(); ++itNotification)
{
if (itNotification->m_assetId == asset.GetId())
{
// store the texture asset
itNotification->m_asset = Data::static_pointer_cast<RPI::StreamingImageAsset>(asset);
itNotification->m_notificationType = notificationType;
// stop notifications on this asset
Data::AssetBus::MultiHandler::BusDisconnect(itNotification->m_assetId);
break;
}
}
}
void DiffuseProbeGridFeatureProcessor::OnAssetReady(Data::Asset<Data::AssetData> asset)
{
HandleAssetNotification(asset, DiffuseProbeGridTextureNotificationType::Ready);
}
void DiffuseProbeGridFeatureProcessor::OnAssetError(Data::Asset<Data::AssetData> asset)
{
AZ_Error("ReflectionProbeFeatureProcessor", false, "Failed to load cubemap [%s]", asset.GetHint().c_str());
HandleAssetNotification(asset, DiffuseProbeGridTextureNotificationType::Error);
}
} // namespace Render
} // namespace AZ
@@ -22,6 +22,7 @@ namespace AZ
//! This class manages DiffuseProbeGrids which generate diffuse global illumination
class DiffuseProbeGridFeatureProcessor final
: public DiffuseProbeGridFeatureProcessorInterface
, private Data::AssetBus::MultiHandler
{
public:
AZ_RTTI(AZ::Render::DiffuseProbeGridFeatureProcessor, "{BCD232F9-1EBF-4D0D-A5F4-84AEC933A93C}", DiffuseProbeGridFeatureProcessorInterface);
@@ -46,6 +47,27 @@ namespace AZ
void Enable(const DiffuseProbeGridHandle& probeGrid, bool enable) override;
void SetGIShadows(const DiffuseProbeGridHandle& probeGrid, bool giShadows) override;
void SetUseDiffuseIbl(const DiffuseProbeGridHandle& probeGrid, bool useDiffuseIbl) override;
void SetMode(const DiffuseProbeGridHandle& probeGrid, DiffuseProbeGridMode mode) override;
void SetBakedTextures(const DiffuseProbeGridHandle& probeGrid, const DiffuseProbeGridBakedTextures& bakedTextures) override;
void BakeTextures(
const DiffuseProbeGridHandle& probeGrid,
DiffuseProbeGridBakeTexturesCallback callback,
const AZStd::string& irradianceTextureRelativePath,
const AZStd::string& distanceTextureRelativePath,
const AZStd::string& relocationTextureRelativePath,
const AZStd::string& classificationTextureRelativePath) override;
bool CheckTextureAssetNotification(
const AZStd::string& relativePath,
Data::Asset<RPI::StreamingImageAsset>& outTextureAsset,
DiffuseProbeGridTextureNotificationType& outNotificationType) override;
bool AreBakedTexturesReferenced(
const AZStd::string& irradianceTextureRelativePath,
const AZStd::string& distanceTextureRelativePath,
const AZStd::string& relocationTextureRelativePath,
const AZStd::string& classificationTextureRelativePath) override;
// FeatureProcessor overrides
void Activate() override;
@@ -56,12 +78,28 @@ namespace AZ
using DiffuseProbeGridVector = AZStd::vector<AZStd::shared_ptr<DiffuseProbeGrid>>;
DiffuseProbeGridVector& GetProbeGrids() { return m_diffuseProbeGrids; }
// retrieve the side list of probe grids that are using real-time (raytraced) mode
DiffuseProbeGridVector& GetRealTimeProbeGrids() { return m_realTimeDiffuseProbeGrids; }
private:
AZ_DISABLE_COPY_MOVE(DiffuseProbeGridFeatureProcessor);
// create the box vertex and index streams, which are used to render the probe volumes
void CreateBoxMesh();
// AssetBus::MultiHandler overrides...
void OnAssetReady(Data::Asset<Data::AssetData> asset) override;
void OnAssetError(Data::Asset<Data::AssetData> asset) override;
// updates the real-time list for a specific probe grid
void UpdateRealTimeList(const DiffuseProbeGridHandle& diffuseProbeGrid);
// adds a notification entry for a new asset
void AddNotificationEntry(const AZStd::string& relativePath);
// notifies and removes the notification entry
void HandleAssetNotification(Data::Asset<Data::AssetData> asset, DiffuseProbeGridTextureNotificationType notificationType);
// RPI::SceneNotificationBus::Handler overrides
void OnRenderPipelinePassesChanged(RPI::RenderPipeline* renderPipeline) override;
void OnRenderPipelineAdded(RPI::RenderPipelinePtr pipeline) override;
@@ -70,10 +108,13 @@ namespace AZ
void UpdatePipelineStates();
void UpdatePasses();
// list of diffuse probe grids
// list of all diffuse probe grids
const size_t InitialProbeGridAllocationSize = 64;
DiffuseProbeGridVector m_diffuseProbeGrids;
// side list of diffuse probe grids that are in real-time mode (subset of m_diffuseProbeGrids)
DiffuseProbeGridVector m_realTimeDiffuseProbeGrids;
// position structure for the box vertices
struct Position
{
@@ -102,6 +143,17 @@ namespace AZ
// indicates the the diffuse probe grid render pipeline state needs to be updated
bool m_needUpdatePipelineStates = false;
// list of texture assets that we need to check during Simulate() to see if they are ready
struct NotifyTextureAssetEntry
{
AZStd::string m_relativePath;
AZ::Data::AssetId m_assetId;
Data::Asset<RPI::StreamingImageAsset> m_asset;
DiffuseProbeGridTextureNotificationType m_notificationType = DiffuseProbeGridTextureNotificationType::None;
};
typedef AZStd::vector<NotifyTextureAssetEntry> NotifyTextureAssetVector;
NotifyTextureAssetVector m_notifyTextureAssets;
};
} // namespace Render
} // namespace AZ
@@ -136,7 +136,7 @@ namespace AZ
}
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetProbeGrids().empty())
if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty())
{
// no diffuse probe grids
return;
@@ -153,9 +153,9 @@ namespace AZ
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
RayTracingFeatureProcessor* rayTracingFeatureProcessor = scene->GetFeatureProcessor<RayTracingFeatureProcessor>();
frameGraph.SetEstimatedItemCount(aznumeric_cast<uint32_t>(diffuseProbeGridFeatureProcessor->GetProbeGrids().size()));
frameGraph.SetEstimatedItemCount(aznumeric_cast<uint32_t>(diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().size()));
for (const auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (const auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
// TLAS
{
@@ -260,7 +260,7 @@ namespace AZ
rayTracingFeatureProcessor->GetMeshInfoBuffer() &&
rayTracingFeatureProcessor->GetSubMeshCount())
{
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
// the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader
// inputs (see line ValidateSetImageView() in ShaderResourceGroupData.cpp)
@@ -308,7 +308,7 @@ namespace AZ
m_rayTracingShaderTable)
{
// submit the DispatchRaysItem for each DiffuseProbeGrid
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
const RHI::ShaderResourceGroup* shaderResourceGroups[] = {
diffuseProbeGrid->GetRayTraceSrg()->GetRHIShaderResourceGroup(),
@@ -91,7 +91,7 @@ namespace AZ
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetProbeGrids().empty())
if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids().empty())
{
// no diffuse probe grids
return;
@@ -108,7 +108,7 @@ namespace AZ
// create the Relocation Srgs for each DiffuseProbeGrid, and check to see if any grids need relocation
bool needRelocation = false;
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
uint32_t rayTracingDataRevision = rayTracingFeatureProcessor->GetRevision();
if (rayTracingDataRevision != m_rayTracingDataRevision)
@@ -139,7 +139,7 @@ namespace AZ
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
// probe raytrace image
{
@@ -167,7 +167,7 @@ namespace AZ
{
RPI::Scene* scene = m_pipeline->GetScene();
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
// the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs
// (see ValidateSetImageView() in ShaderResourceGroupData.cpp)
@@ -187,7 +187,7 @@ namespace AZ
DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
// submit the DispatchItems for each DiffuseProbeGrid
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
const RHI::ShaderResourceGroup* shaderResourceGroup = diffuseProbeGrid->GetRelocationSrg()->GetRHIShaderResourceGroup();
commandList->SetShaderResourceGroupForDispatch(*shaderResourceGroup);
@@ -79,6 +79,12 @@ namespace AZ
params.m_scissorState = scissor;
Base::FrameBeginInternal(params);
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
{
// process attachment readback
diffuseProbeGrid->GetTextureReadback().FrameBegin(params);
}
}
void DiffuseProbeGridRenderPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)
@@ -88,8 +94,21 @@ namespace AZ
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
{
if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::Baked &&
!diffuseProbeGrid->HasValidBakedTextures())
{
continue;
}
// probe irradiance image
{
if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::Baked)
{
// import the irradiance image now, since it is baked and therefore was not imported during the raytracing pass
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(diffuseProbeGrid->GetIrradianceImageAttachmentId(), diffuseProbeGrid->GetIrradianceImage());
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import probeIrradianceImage");
}
RHI::ImageScopeAttachmentDescriptor desc;
desc.m_attachmentId = diffuseProbeGrid->GetIrradianceImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeIrradianceImageViewDescriptor;
@@ -100,6 +119,13 @@ namespace AZ
// probe distance image
{
if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::Baked)
{
// import the distance image now, since it is baked and therefore was not imported during the raytracing pass
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(diffuseProbeGrid->GetDistanceImageAttachmentId(), diffuseProbeGrid->GetDistanceImage());
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import probeDistanceImage");
}
RHI::ImageScopeAttachmentDescriptor desc;
desc.m_attachmentId = diffuseProbeGrid->GetDistanceImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeDistanceImageViewDescriptor;
@@ -110,6 +136,13 @@ namespace AZ
// probe relocation image
{
if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::Baked)
{
// import the relocation image now, since it is baked and therefore was not imported during the raytracing pass
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(diffuseProbeGrid->GetRelocationImageAttachmentId(), diffuseProbeGrid->GetRelocationImage());
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import probeRelocationImage");
}
RHI::ImageScopeAttachmentDescriptor desc;
desc.m_attachmentId = diffuseProbeGrid->GetRelocationImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeRelocationImageViewDescriptor;
@@ -120,6 +153,13 @@ namespace AZ
// probe classification image
{
if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::Baked)
{
// import the classification image now, since it is baked and therefore was not imported during the raytracing pass
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(diffuseProbeGrid->GetClassificationImageAttachmentId(), diffuseProbeGrid->GetClassificationImage());
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import probeClassificationImage");
}
RHI::ImageScopeAttachmentDescriptor desc;
desc.m_attachmentId = diffuseProbeGrid->GetClassificationImageAttachmentId();
desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeClassificationImageViewDescriptor;
@@ -127,6 +167,8 @@ namespace AZ
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
}
diffuseProbeGrid->GetTextureReadback().Update(GetName());
}
Base::SetupFrameGraphDependencies(frameGraph);
@@ -139,6 +181,12 @@ namespace AZ
for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
{
if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::Baked &&
!diffuseProbeGrid->HasValidBakedTextures())
{
continue;
}
// the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs
// (see ValidateSetImageView() of ShaderResourceGroupData.cpp)
diffuseProbeGrid->UpdateRenderObjectSrg();
@@ -0,0 +1,134 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <DiffuseProbeGrid/DiffuseProbeGridTextureReadback.h>
#include <DiffuseProbeGrid/DiffuseProbeGrid.h>
namespace AZ
{
namespace Render
{
DiffuseProbeGridTextureReadback::DiffuseProbeGridTextureReadback(DiffuseProbeGrid* diffuseProbeGrid)
: m_diffuseProbeGrid(diffuseProbeGrid)
{
}
void DiffuseProbeGridTextureReadback::BeginTextureReadback(DiffuseProbeGridBakeTexturesCallback callback)
{
AZ_Assert(m_readbackState == DiffuseProbeGridReadbackState::Idle, "DiffuseProbeGridTextureReadback is already processing a readback request");
m_callback = callback;
m_readbackState = DiffuseProbeGridReadbackState::Irradiance;
}
void DiffuseProbeGridTextureReadback::Update(const AZ::Name& passName)
{
if (m_readbackState == DiffuseProbeGridReadbackState::Idle || m_readbackState == DiffuseProbeGridReadbackState::Complete)
{
return;
}
if (m_attachmentReadback.get() && m_attachmentReadback->GetReadbackState() > RPI::AttachmentReadback::ReadbackState::Idle)
{
// still processing previous request
return;
}
AZStd::string readbackName = AZStd::string::format("DiffuseProbeGridReadback_%s", passName.GetCStr());
RHI::ImageDescriptor descriptor;
RHI::AttachmentId attachmentId;
RPI::AttachmentReadback::CallbackFunction callbackFunction;
switch (m_readbackState)
{
case DiffuseProbeGridReadbackState::Irradiance:
descriptor = m_diffuseProbeGrid->GetIrradianceImage()->GetDescriptor();
attachmentId = m_diffuseProbeGrid->GetIrradianceImageAttachmentId();
callbackFunction = [this](const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
{
m_irradianceReadbackResult = readbackResult;
m_readbackState = DiffuseProbeGridReadbackState::Distance;
};
break;
case DiffuseProbeGridReadbackState::Distance:
descriptor = m_diffuseProbeGrid->GetDistanceImage()->GetDescriptor();
attachmentId = m_diffuseProbeGrid->GetDistanceImageAttachmentId();
callbackFunction = [this](const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
{
m_distanceReadbackResult = readbackResult;
m_readbackState = DiffuseProbeGridReadbackState::Relocation;
};
break;
case DiffuseProbeGridReadbackState::Relocation:
descriptor = m_diffuseProbeGrid->GetRelocationImage()->GetDescriptor();
attachmentId = m_diffuseProbeGrid->GetRelocationImageAttachmentId();
callbackFunction = [this](const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
{
m_relocationReadbackResult = readbackResult;
m_readbackState = DiffuseProbeGridReadbackState::Classification;
};
break;
case DiffuseProbeGridReadbackState::Classification:
descriptor = m_diffuseProbeGrid->GetClassificationImage()->GetDescriptor();
attachmentId = m_diffuseProbeGrid->GetClassificationImageAttachmentId();
callbackFunction = [this](const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
{
m_classificationReadbackResult = readbackResult;
m_readbackState = DiffuseProbeGridReadbackState::Complete;
};
break;
default:
AZ_Assert(false, "Unknown readback state");
}
m_attachmentReadback = AZStd::make_shared<AZ::RPI::AttachmentReadback>(AZ::RHI::ScopeId{ "DiffuseProbeGridTextureReadBack" });
m_attachmentReadback->SetCallback(callbackFunction);
AZ::RPI::PassAttachment passAttachment;
passAttachment.m_descriptor = descriptor;
passAttachment.m_path = attachmentId;
passAttachment.m_name = readbackName;
passAttachment.m_lifetime = RHI::AttachmentLifetimeType::Imported;
m_attachmentReadback->ReadPassAttachment(&passAttachment, AZ::Name(readbackName));
}
void DiffuseProbeGridTextureReadback::FrameBegin(AZ::RPI::Pass::FramePrepareParams& params)
{
if (m_readbackState == DiffuseProbeGridReadbackState::Idle)
{
return;
}
if (!m_attachmentReadback.get())
{
return;
}
if (m_readbackState == DiffuseProbeGridReadbackState::Complete)
{
// readback of all textures is complete, invoke callback and return to Idle state
m_callback(
{ m_irradianceReadbackResult.m_dataBuffer, m_irradianceReadbackResult.m_imageDescriptor.m_format, m_irradianceReadbackResult.m_imageDescriptor.m_size },
{ m_distanceReadbackResult.m_dataBuffer, m_distanceReadbackResult.m_imageDescriptor.m_format, m_distanceReadbackResult.m_imageDescriptor.m_size },
{ m_relocationReadbackResult.m_dataBuffer, m_relocationReadbackResult.m_imageDescriptor.m_format, m_relocationReadbackResult.m_imageDescriptor.m_size },
{ m_classificationReadbackResult.m_dataBuffer, m_classificationReadbackResult.m_imageDescriptor.m_format, m_classificationReadbackResult.m_imageDescriptor.m_size });
m_readbackState = DiffuseProbeGridReadbackState::Idle;
m_attachmentReadback.reset();
return;
}
m_attachmentReadback->FrameBegin(params);
}
} // namespace Render
} // namespace AZ
@@ -0,0 +1,60 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Atom/RHI/ScopeProducer.h>
#include <Atom/RPI.Public/Pass/AttachmentReadback.h>
#include <Atom/RPI.Public/Pass/Pass.h>
#include <Atom/Feature/DiffuseProbeGrid/DiffuseProbeGridFeatureProcessorInterface.h>
namespace AZ
{
namespace Render
{
class DiffuseProbeGrid;
enum class DiffuseProbeGridReadbackState
{
Idle,
Irradiance,
Distance,
Relocation,
Classification,
Complete
};
//! This class contains functionality necessary to read back the DiffuseProbeGrid textures, which
//! allows them to be saved as assets to run the DiffuseProbeGrid in non-realtime mode.
class DiffuseProbeGridTextureReadback final
{
public:
DiffuseProbeGridTextureReadback(DiffuseProbeGrid* diffuseProbeGrid);
~DiffuseProbeGridTextureReadback() = default;
void BeginTextureReadback(DiffuseProbeGridBakeTexturesCallback callback);
void Update(const AZ::Name& passName);
void FrameBegin(AZ::RPI::Pass::FramePrepareParams& params);
private:
DiffuseProbeGrid* m_diffuseProbeGrid = nullptr;
DiffuseProbeGridReadbackState m_readbackState = DiffuseProbeGridReadbackState::Idle;
AZStd::shared_ptr<AZ::RPI::AttachmentReadback> m_attachmentReadback;
DiffuseProbeGridBakeTexturesCallback m_callback;
AZ::RPI::AttachmentReadback::ReadbackResult m_irradianceReadbackResult;
AZ::RPI::AttachmentReadback::ReadbackResult m_distanceReadbackResult;
AZ::RPI::AttachmentReadback::ReadbackResult m_relocationReadbackResult;
AZ::RPI::AttachmentReadback::ReadbackResult m_classificationReadbackResult;
};
} // namespace Render
} // namespace AZ
@@ -12,11 +12,9 @@
#include <EditorCommonSystemComponent.h>
#include <Source/Material/UseTextureFunctorSourceData.h>
#include <Source/Material/PropertyVisibilityFunctorSourceData.h>
#include <Source/Material/DrawListFunctorSourceData.h>
#include <Source/Material/SubsurfaceTransmissionParameterFunctorSourceData.h>
#include <Source/Material/Transform2DFunctorSourceData.h>
#include <Source/Material/ShaderEnableFunctorSourceData.h>
#include <Source/Material/ConvertEmissiveUnitFunctorSourceData.h>
#include <Atom/Feature/Utils/EditorLightingPreset.h>
@@ -58,11 +56,9 @@ namespace AZ
}
AZ::Render::UseTextureFunctorSourceData::Reflect(context);
AZ::Render::PropertyVisibilityFunctorSourceData::Reflect(context);
AZ::Render::DrawListFunctorSourceData::Reflect(context);
AZ::Render::Transform2DFunctorSourceData::Reflect(context);
AZ::Render::ConvertEmissiveUnitFunctorSourceData::Reflect(context);
AZ::Render::ShaderEnableFunctorSourceData::Reflect(context);
AZ::Render::SubsurfaceTransmissionParameterFunctorSourceData::Reflect(context);
AZ::Render::EditorLightingPreset::Reflect(context);
@@ -104,11 +100,9 @@ namespace AZ
}
materialFunctorRegistration->RegisterMaterialFunctor("UseTexture", azrtti_typeid<UseTextureFunctorSourceData>());
materialFunctorRegistration->RegisterMaterialFunctor("UpdatePropertyVisibility", azrtti_typeid<PropertyVisibilityFunctorSourceData>());
materialFunctorRegistration->RegisterMaterialFunctor("OverrideDrawList", azrtti_typeid<DrawListFunctorSourceData>());
materialFunctorRegistration->RegisterMaterialFunctor("Transform2D", azrtti_typeid<Transform2DFunctorSourceData>());
materialFunctorRegistration->RegisterMaterialFunctor("ConvertEmissiveUnit", azrtti_typeid<ConvertEmissiveUnitFunctorSourceData>());
materialFunctorRegistration->RegisterMaterialFunctor("ShaderEnable", azrtti_typeid<ShaderEnableFunctorSourceData>());
materialFunctorRegistration->RegisterMaterialFunctor("HandleSubsurfaceScatteringParameters", azrtti_typeid<SubsurfaceTransmissionParameterFunctorSourceData>());
materialFunctorRegistration->RegisterMaterialFunctor("Lua", azrtti_typeid<RPI::LuaMaterialFunctorSourceData>());
@@ -1,77 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "PropertyVisibilityFunctor.h"
namespace AZ
{
namespace Render
{
void PropertyVisibilityFunctor::Reflect(ReflectContext* context)
{
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
{
serializeContext->Class<Action>()
->Version(1)
->Field("triggerProperty", &Action::m_triggerPropertyIndex)
->Field("triggerValue", &Action::m_triggerValue)
->Field("visibility", &Action::m_visibility)
;
serializeContext->Class<PropertyVisibilityFunctor, RPI::MaterialFunctor>()
->Version(1)
->Field("actions", &PropertyVisibilityFunctor::m_actions)
->Field("affectedProperties", &PropertyVisibilityFunctor::m_affectedProperties)
;
}
}
void PropertyVisibilityFunctor::Process(EditorContext& context)
{
bool visibilityApplied = false;
RPI::MaterialPropertyVisibility lastAppliedVisibility;
for (const auto& action : m_actions)
{
bool willSetVisibility = false;
if (action.m_triggerValue.Is<bool>() || action.m_triggerValue.Is<int32_t>() || action.m_triggerValue.Is<uint32_t>())
{
willSetVisibility = action.m_triggerValue == context.GetMaterialPropertyValue(action.m_triggerPropertyIndex);
}
else if (action.m_triggerValue.Is<float>())
{
willSetVisibility = AZ::IsClose(action.m_triggerValue.GetValue<float>(),
context.GetMaterialPropertyValue<float>(action.m_triggerPropertyIndex),
std::numeric_limits<float>::epsilon());
}
else // for types Vector2, Vector3, Vector4, Color, Image
{
AZ_Error("PropertyVisibilityFunctor", false, "Unsupported property data type as an enable property.");
}
if (willSetVisibility)
{
visibilityApplied = true;
lastAppliedVisibility = action.m_visibility;
}
}
if (visibilityApplied)
{
for (const auto& propertyIndex : m_affectedProperties)
{
context.SetMaterialPropertyVisibility(propertyIndex, lastAppliedVisibility);
}
}
}
} // namespace Render
} // namespace AZ
@@ -1,49 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Atom/RPI.Reflect/Material/MaterialFunctor.h>
#include <Atom/RPI.Reflect/Material/MaterialPropertyDescriptor.h>
namespace AZ
{
namespace Render
{
//! Materials can use this functor to control when and how to set the visibility of a group of properties.
class PropertyVisibilityFunctor final
: public RPI::MaterialFunctor
{
friend class PropertyVisibilityFunctorSourceData;
public:
AZ_RTTI(AZ::Render::PropertyVisibilityFunctor, "{2582B36F-FA7C-450F-B46A-39AAE18356A0}", RPI::MaterialFunctor);
static void Reflect(ReflectContext* context);
void Process(EditorContext& context) override;
private:
struct Action
{
AZ_TYPE_INFO(AZ::Render::PropertyVisibilityFunctor::Action, "{5DF4D981-9D0C-4040-A6C5-52E1D0BD876B}");
RPI::MaterialPropertyIndex m_triggerPropertyIndex; //! The control property for affected properties.
RPI::MaterialPropertyValue m_triggerValue; //! The trigger value of the control property.
RPI::MaterialPropertyVisibility m_visibility; //! The visibility of affected properties when the trigger value is hit.
};
// Material property inputs...
AZStd::vector<Action> m_actions; //! The actions that describes when and what to do with visibilities.
AZStd::vector<RPI::MaterialPropertyIndex> m_affectedProperties; //! The properties that are affected by actions.
};
} // namespace Render
} // namespace AZ
@@ -1,100 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "PropertyVisibilityFunctorSourceData.h"
#include <Atom/RPI.Reflect/Shader/ShaderOptionGroupLayout.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <Atom/RPI.Edit/Material/MaterialUtils.h>
namespace AZ
{
namespace Render
{
void PropertyVisibilityFunctorSourceData::Reflect(ReflectContext* context)
{
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
{
serializeContext->Class<ActionSourceData>()
->Version(1)
->Field("triggerProperty", &ActionSourceData::m_triggerPropertyName)
->Field("triggerValue", &ActionSourceData::m_triggerValue)
->Field("visibility", &ActionSourceData::m_visibility)
;
serializeContext->Class<PropertyVisibilityFunctorSourceData>()
->Version(2)
->Field("actions", &PropertyVisibilityFunctorSourceData::m_actions)
->Field("affectedProperties", &PropertyVisibilityFunctorSourceData::m_affectedPropertyNames)
;
}
}
RPI::MaterialFunctorSourceData::FunctorResult PropertyVisibilityFunctorSourceData::CreateFunctor(const EditorContext& context) const
{
using namespace RPI;
RPI::Ptr<PropertyVisibilityFunctor> functor = aznew PropertyVisibilityFunctor;
functor->m_actions.reserve(m_actions.size());
for (const auto& actionSource : m_actions)
{
functor->m_actions.emplace_back();
PropertyVisibilityFunctor::Action& action = functor->m_actions.back();
action.m_triggerPropertyIndex = context.FindMaterialPropertyIndex(AZ::Name{ actionSource.m_triggerPropertyName });
if (action.m_triggerPropertyIndex.IsNull())
{
return Failure();
}
AddMaterialPropertyDependency(functor, action.m_triggerPropertyIndex);
if (!actionSource.m_triggerValue.Resolve(*context.GetMaterialPropertiesLayout(), Name{ actionSource.m_triggerPropertyName }))
{
// Error is reported in Resolve().
return Failure();
}
const MaterialPropertyDescriptor* propertyDescriptor = context.GetMaterialPropertiesLayout()->GetPropertyDescriptor(action.m_triggerPropertyIndex);
// Enum type should resolve further to a unit32_t from the string source.
if (propertyDescriptor->GetDataType() == RPI::MaterialPropertyDataType::Enum)
{
if (!RPI::MaterialUtils::ResolveMaterialPropertyEnumValue(
propertyDescriptor,
Name(actionSource.m_triggerValue.GetValue().GetValue<AZStd::string>()),
action.m_triggerValue))
{
return Failure();
}
}
else
{
action.m_triggerValue = actionSource.m_triggerValue.GetValue();
}
action.m_visibility = actionSource.m_visibility;
}
functor->m_affectedProperties.reserve(m_affectedPropertyNames.size());
for (const AZStd::string& name : m_affectedPropertyNames)
{
RPI::MaterialPropertyIndex index = context.FindMaterialPropertyIndex(AZ::Name{ name });
if (index.IsNull())
{
return Failure();
}
functor->m_affectedProperties.push_back(index);
}
return Success(RPI::Ptr<MaterialFunctor>(functor));
}
} // namespace Render
} // namespace AZ
@@ -1,48 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include "PropertyVisibilityFunctor.h"
#include <Atom/RPI.Edit/Material/MaterialFunctorSourceData.h>
#include <Atom/RPI.Edit/Material/MaterialPropertyValueSourceData.h>
namespace AZ
{
namespace Render
{
//! Builds a PropertyVisibilityFunctor.
//! Materials can use this functor to control whether a specific property group will be enabled.
class PropertyVisibilityFunctorSourceData final
: public RPI::MaterialFunctorSourceData
{
public:
AZ_RTTI(AZ::Render::PropertyVisibilityFunctorSourceData, "{B44E6929-8FFF-405F-9056-B9B811F97676}", RPI::MaterialFunctorSourceData);
static void Reflect(ReflectContext* context);
FunctorResult CreateFunctor(const EditorContext& context) const override;
private:
struct ActionSourceData
{
AZ_TYPE_INFO(AZ::Render::PropertyVisibilityFunctorSourceData::ActionSourceData, "{70E01DA6-0B42-4CCB-AAD0-51980DB43F62}");
AZStd::string m_triggerPropertyName; //! The control property for affected properties.
RPI::MaterialPropertyValueSourceData m_triggerValue; //! The trigger value of the control property.
RPI::MaterialPropertyVisibility m_visibility; //! The visibility of affected properties when the trigger value is hit.
};
// Material property inputs...
AZStd::vector<ActionSourceData> m_actions; //! The actions that describes when and what to do with visibilities.
AZStd::vector<AZStd::string> m_affectedPropertyNames; //! The properties that are affected by actions.
};
} // namespace Render
} // namespace AZ
@@ -1,74 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "./ShaderEnableFunctor.h"
#include <Atom/RPI.Public/Material/Material.h>
#include <Atom/RPI.Reflect/Image/Image.h>
#include <Atom/RPI.Reflect/Shader/ShaderOptionGroup.h>
namespace AZ
{
namespace Render
{
void ShaderEnableFunctor::Reflect(ReflectContext* context)
{
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
{
serializeContext->Class<ShaderEnableFunctor, RPI::MaterialFunctor>()
->Version(4)
->Field("opacityModeIndex", &ShaderEnableFunctor::m_opacityModeIndex)
->Field("parallaxEnableIndex", &ShaderEnableFunctor::m_parallaxEnableIndex)
->Field("parallaxPdoEnableIndex", &ShaderEnableFunctor::m_parallaxPdoEnableIndex)
->Field("shadowShaderNoPSIndex", &ShaderEnableFunctor::m_shadowShaderNoPSIndex)
->Field("shadowShaderWithPSIndex", &ShaderEnableFunctor::m_shadowShaderWithPSIndex)
->Field("depthShaderNoPSIndex", &ShaderEnableFunctor::m_depthShaderNoPSIndex)
->Field("depthShaderWithPSIndex", &ShaderEnableFunctor::m_depthShaderWithPSIndex)
->Field("pbrShaderNoEdsIndex", &ShaderEnableFunctor::m_pbrShaderNoEdsIndex)
->Field("pbrShaderWithEdsIndex", &ShaderEnableFunctor::m_pbrShaderWithEdsIndex)
->Field("depthShaderTransparentMin", &ShaderEnableFunctor::m_depthShaderTransparentMin)
->Field("depthShaderTransparentMax", &ShaderEnableFunctor::m_depthShaderTransparentMax)
;
}
}
void ShaderEnableFunctor::Process(RuntimeContext& context)
{
unsigned int opacityMode = context.GetMaterialPropertyValue<uint32_t>(m_opacityModeIndex);
bool parallaxEnabled = context.GetMaterialPropertyValue<bool>(m_parallaxEnableIndex);
bool parallaxPdoEnabled = context.GetMaterialPropertyValue<bool>(m_parallaxPdoEnableIndex);
if (parallaxEnabled && parallaxPdoEnabled)
{
context.SetShaderEnabled(m_depthShaderNoPSIndex, false);
context.SetShaderEnabled(m_shadowShaderNoPSIndex, false);
context.SetShaderEnabled(m_pbrShaderWithEdsIndex, false);
context.SetShaderEnabled(m_depthShaderWithPSIndex, true);
context.SetShaderEnabled(m_shadowShaderWithPSIndex, true);
context.SetShaderEnabled(m_pbrShaderNoEdsIndex, true);
}
else
{
context.SetShaderEnabled(m_depthShaderNoPSIndex, opacityMode == OpacityMode::Opaque );
context.SetShaderEnabled(m_shadowShaderNoPSIndex, opacityMode == OpacityMode::Opaque);
context.SetShaderEnabled(m_pbrShaderWithEdsIndex, opacityMode == OpacityMode::Opaque || opacityMode == OpacityMode::Blended || opacityMode == OpacityMode::TintedTransparent);
context.SetShaderEnabled(m_depthShaderWithPSIndex, opacityMode == OpacityMode::Cutout);
context.SetShaderEnabled(m_shadowShaderWithPSIndex, opacityMode == OpacityMode::Cutout);
context.SetShaderEnabled(m_pbrShaderNoEdsIndex, opacityMode == OpacityMode::Cutout);
}
context.SetShaderEnabled(m_depthShaderTransparentMin, opacityMode == OpacityMode::Blended || opacityMode == OpacityMode::TintedTransparent);
context.SetShaderEnabled(m_depthShaderTransparentMax, opacityMode == OpacityMode::Blended || opacityMode == OpacityMode::TintedTransparent);
}
}
}
@@ -1,63 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Atom/RPI.Reflect/Material/MaterialFunctor.h>
#include <Atom/RPI.Reflect/Material/MaterialPropertyDescriptor.h>
#include <Atom/RHI.Reflect/Limits.h>
namespace AZ
{
namespace Render
{
enum OpacityMode
{
Opaque = 0,
Cutout,
Blended,
TintedTransparent,
};
//! Select shadow and depth shader based on opacity mode and parallax state
//! Opaque: Enable shader without PS
//! Cutout or Parallax enable: Enable shader with PS
//! Blended: Disable both
//! TintedTransparent: Disable both
class ShaderEnableFunctor final
: public RPI::MaterialFunctor
{
friend class ShaderEnableFunctorSourceData;
public:
AZ_RTTI(ShaderEnableFunctor, "{2079A693-FE4F-46A7-95C0-09D88AC156D0}", RPI::MaterialFunctor);
static void Reflect(ReflectContext* context);
void Process(RuntimeContext& context) override;
private:
RPI::MaterialPropertyIndex m_opacityModeIndex;
RPI::MaterialPropertyIndex m_parallaxEnableIndex;
RPI::MaterialPropertyIndex m_parallaxPdoEnableIndex;
uint32_t m_shadowShaderNoPSIndex = -1;
uint32_t m_shadowShaderWithPSIndex = -1;
uint32_t m_depthShaderNoPSIndex = -1;
uint32_t m_depthShaderWithPSIndex = -1;
uint32_t m_pbrShaderWithEdsIndex = -1;
uint32_t m_pbrShaderNoEdsIndex = -1;
// The following are used by the light culling system to produce min/max depth bounds
uint32_t m_depthShaderTransparentMin = -1;
uint32_t m_depthShaderTransparentMax = -1;
};
}
}
@@ -1,116 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "./ShaderEnableFunctorSourceData.h"
#include <Atom/RPI.Reflect/Shader/ShaderOptionGroupLayout.h>
#include <AzCore/Serialization/SerializeContext.h>
namespace AZ
{
namespace Render
{
void ShaderEnableFunctorSourceData::Reflect(ReflectContext* context)
{
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
{
serializeContext->Class<ShaderEnableFunctorSourceData>()
->Version(5)
->Field("opacityMode", &ShaderEnableFunctorSourceData::m_opacityMode)
->Field("parallaxEnable", &ShaderEnableFunctorSourceData::m_parallaxEnable)
->Field("parallaxPdoEnable", &ShaderEnableFunctorSourceData::m_parallaxPdoEnable)
->Field("shadowShaderNoPSIndex", &ShaderEnableFunctorSourceData::m_shadowShaderNoPSIndex)
->Field("shadowShaderWithPSIndex", &ShaderEnableFunctorSourceData::m_shadowShaderWithPSIndex)
->Field("depthShaderNoPSIndex", &ShaderEnableFunctorSourceData::m_depthShaderNoPSIndex)
->Field("depthShaderWithPSIndex", &ShaderEnableFunctorSourceData::m_depthShaderWithPSIndex)
->Field("pbrShaderNoEdsIndex", &ShaderEnableFunctorSourceData::m_pbrShaderNoEdsIndex)
->Field("pbrShaderWithEdsIndex", &ShaderEnableFunctorSourceData::m_pbrShaderWithEdsIndex)
->Field("depthShaderTransparentMin", &ShaderEnableFunctorSourceData::m_depthShaderTransparentMin)
->Field("depthShaderTransparentMax", &ShaderEnableFunctorSourceData::m_depthShaderTransparentMax)
;
}
}
RPI::MaterialFunctorSourceData::FunctorResult ShaderEnableFunctorSourceData::CreateFunctor(const RuntimeContext& context) const
{
RPI::Ptr<ShaderEnableFunctor> functor = aznew ShaderEnableFunctor;
functor->m_opacityModeIndex = context.FindMaterialPropertyIndex(Name{ m_opacityMode });
if (functor->m_opacityModeIndex.IsNull())
{
return Failure();
}
AddMaterialPropertyDependency(functor, functor->m_opacityModeIndex);
functor->m_parallaxEnableIndex = context.FindMaterialPropertyIndex(Name{ m_parallaxEnable });
if (functor->m_parallaxEnableIndex.IsNull())
{
return Failure();
}
AddMaterialPropertyDependency(functor, functor->m_parallaxEnableIndex);
functor->m_parallaxPdoEnableIndex = context.FindMaterialPropertyIndex(Name{ m_parallaxPdoEnable });
if (functor->m_parallaxPdoEnableIndex.IsNull())
{
return Failure();
}
AddMaterialPropertyDependency(functor, functor->m_parallaxPdoEnableIndex);
if (!context.CheckShaderIndexValid(m_shadowShaderWithPSIndex))
{
return Failure();
}
functor->m_shadowShaderWithPSIndex = m_shadowShaderWithPSIndex;
if (!context.CheckShaderIndexValid(m_shadowShaderNoPSIndex))
{
return Failure();
}
functor->m_shadowShaderNoPSIndex = m_shadowShaderNoPSIndex;
if (!context.CheckShaderIndexValid(m_depthShaderWithPSIndex))
{
return Failure();
}
functor->m_depthShaderWithPSIndex = m_depthShaderWithPSIndex;
if (!context.CheckShaderIndexValid(m_depthShaderNoPSIndex))
{
return Failure();
}
functor->m_depthShaderNoPSIndex = m_depthShaderNoPSIndex;
if (!context.CheckShaderIndexValid(m_pbrShaderNoEdsIndex))
{
return Failure();
}
functor->m_pbrShaderNoEdsIndex = m_pbrShaderNoEdsIndex;
if (!context.CheckShaderIndexValid(m_pbrShaderWithEdsIndex))
{
return Failure();
}
functor->m_pbrShaderWithEdsIndex = m_pbrShaderWithEdsIndex;
if (!context.CheckShaderIndexValid(m_depthShaderTransparentMin))
{
return Failure();
}
functor->m_depthShaderTransparentMin = m_depthShaderTransparentMin;
if (!context.CheckShaderIndexValid(m_depthShaderTransparentMax))
{
return Failure();
}
functor->m_depthShaderTransparentMax = m_depthShaderTransparentMax;
return Success(RPI::Ptr<RPI::MaterialFunctor>(functor));
}
}
}
@@ -1,52 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include "./ShaderEnableFunctor.h"
#include <Atom/RPI.Edit/Material/MaterialFunctorSourceData.h>
namespace AZ
{
namespace Render
{
class ShaderEnableFunctor;
//! Builds a ShaderEnableFunctor
class ShaderEnableFunctorSourceData final
: public RPI::MaterialFunctorSourceData
{
public:
AZ_RTTI(ShaderEnableFunctorSourceData, "{63775ECB-5C3E-44D3-B175-4537BF76C3A7}", RPI::MaterialFunctorSourceData);
static void Reflect(ReflectContext* context);
FunctorResult CreateFunctor(const RuntimeContext& context) const override;
private:
AZStd::string m_opacityMode;
AZStd::string m_parallaxEnable;
AZStd::string m_parallaxPdoEnable;
uint32_t m_shadowShaderNoPSIndex = -1;
uint32_t m_shadowShaderWithPSIndex = -1;
uint32_t m_depthShaderNoPSIndex = -1;
uint32_t m_depthShaderWithPSIndex = -1;
uint32_t m_pbrShaderWithEdsIndex = -1;
uint32_t m_pbrShaderNoEdsIndex = -1;
// The following are used by the light culling system to produce min/max depth bounds
uint32_t m_depthShaderTransparentMin = -1;
uint32_t m_depthShaderTransparentMax = -1;
};
}
}
@@ -209,7 +209,7 @@ namespace AZ
void ReflectionProbe::SetTransform(const AZ::Transform& transform)
{
// retrieve previous scale and revert the scale on the inner/outer extents
AZ::Vector3 previousScale = m_transform.GetScale();
float previousScale = m_transform.GetUniformScale();
m_outerExtents /= previousScale;
m_innerExtents /= previousScale;
@@ -218,12 +218,12 @@ namespace AZ
// avoid scaling the visualization sphere
AZ::Transform visualizationTransform = m_transform;
visualizationTransform.ExtractScale();
visualizationTransform.ExtractUniformScale();
m_meshFeatureProcessor->SetTransform(m_visualizationMeshHandle, visualizationTransform);
// update the inner/outer extents with the new scale
m_outerExtents *= m_transform.GetScale();
m_innerExtents *= m_transform.GetScale();
m_outerExtents *= m_transform.GetUniformScale();
m_innerExtents *= m_transform.GetUniformScale();
m_outerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_outerExtents / 2.0f);
m_innerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_innerExtents / 2.0f);
@@ -232,14 +232,14 @@ namespace AZ
void ReflectionProbe::SetOuterExtents(const AZ::Vector3& outerExtents)
{
m_outerExtents = outerExtents * m_transform.GetScale();
m_outerExtents = outerExtents * m_transform.GetUniformScale();
m_outerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_outerExtents / 2.0f);
m_updateSrg = true;
}
void ReflectionProbe::SetInnerExtents(const AZ::Vector3& innerExtents)
{
m_innerExtents = innerExtents * m_transform.GetScale();
m_innerExtents = innerExtents * m_transform.GetUniformScale();
m_innerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_innerExtents / 2.0f);
m_updateSrg = true;
}
@@ -24,16 +24,12 @@ set(FILES
Source/Material/ConvertEmissiveUnitFunctorSourceData.h
Source/Material/MaterialConverterSystemComponent.cpp
Source/Material/MaterialConverterSystemComponent.h
Source/Material/ShaderEnableFunctorSourceData.cpp
Source/Material/ShaderEnableFunctorSourceData.h
Source/Material/SubsurfaceTransmissionParameterFunctorSourceData.cpp
Source/Material/SubsurfaceTransmissionParameterFunctorSourceData.h
Source/Material/Transform2DFunctorSourceData.cpp
Source/Material/Transform2DFunctorSourceData.h
Source/Material/UseTextureFunctorSourceData.cpp
Source/Material/UseTextureFunctorSourceData.h
Source/Material/PropertyVisibilityFunctorSourceData.cpp
Source/Material/PropertyVisibilityFunctorSourceData.h
Source/Material/DrawListFunctorSourceData.cpp
Source/Material/DrawListFunctorSourceData.h
)
@@ -135,6 +135,8 @@ set(FILES
Source/DiffuseProbeGrid/DiffuseProbeGridRenderPass.h
Source/DiffuseProbeGrid/DiffuseProbeGrid.cpp
Source/DiffuseProbeGrid/DiffuseProbeGrid.h
Source/DiffuseProbeGrid/DiffuseProbeGridTextureReadback.cpp
Source/DiffuseProbeGrid/DiffuseProbeGridTextureReadback.h
Source/DiffuseProbeGrid/DiffuseProbeGridFeatureProcessor.h
Source/DiffuseProbeGrid/DiffuseProbeGridFeatureProcessor.cpp
Source/DisplayMapper/AcesOutputTransformPass.cpp
@@ -153,16 +155,12 @@ set(FILES
Source/LookupTable/LookupTableAsset.cpp
Source/Material/ConvertEmissiveUnitFunctor.cpp
Source/Material/ConvertEmissiveUnitFunctor.h
Source/Material/ShaderEnableFunctor.cpp
Source/Material/ShaderEnableFunctor.h
Source/Material/SubsurfaceTransmissionParameterFunctor.cpp
Source/Material/SubsurfaceTransmissionParameterFunctor.h
Source/Material/Transform2DFunctor.cpp
Source/Material/Transform2DFunctor.h
Source/Material/UseTextureFunctor.cpp
Source/Material/UseTextureFunctor.h
Source/Material/PropertyVisibilityFunctor.cpp
Source/Material/PropertyVisibilityFunctor.h
Source/Material/DrawListFunctor.cpp
Source/Material/DrawListFunctor.h
Source/Math/GaussianMathFilter.h
@@ -164,7 +164,7 @@ namespace AZ
arguments += " -Zi"; // Generate debug information
arguments += " -Zss"; // Compute Shader Hash considering source information
}
arguments += m_dxcAdditionalFreeArguments;
arguments += " " + m_dxcAdditionalFreeArguments;
return arguments;
}
}
@@ -180,6 +180,7 @@ namespace AZ
for (uint32_t imageIndex = static_cast<uint32_t>(NullDescriptorManager::ImageTypes::General2D); imageIndex < static_cast<uint32_t>(NullDescriptorManager::ImageTypes::Count); imageIndex++)
{
// different options for the images
imageCreateInfo.imageType = (imageIndex >= static_cast<uint32_t>(NullDescriptorManager::ImageTypes::General3D)) ? VK_IMAGE_TYPE_3D : VK_IMAGE_TYPE_2D;
imageCreateInfo.extent = { m_imageNullDescriptor.m_images[imageIndex].m_dimension, m_imageNullDescriptor.m_images[imageIndex].m_dimension, 1 };
imageCreateInfo.samples = m_imageNullDescriptor.m_images[imageIndex].m_sampleCountFlag;
imageCreateInfo.format = m_imageNullDescriptor.m_images[imageIndex].m_format;
@@ -288,6 +288,7 @@ namespace AZ
AZStd::size_t GetShaderCount() const;
LuaMaterialFunctorShaderItem GetShader(AZStd::size_t index);
LuaMaterialFunctorShaderItem GetShaderByTag(const char* shaderTag);
bool HasShaderWithTag(const char* shaderTag);
private:
@@ -96,12 +96,6 @@ namespace AZ
return QueryResultCode::Fail;
}
// Limit calling BeginQuery() to the first CommandList in the array.
if (context.GetCommandListIndex() != 0)
{
return QueryResultCode::Success;
}
const auto rhiQueryIndices = GetRhiQueryIndicesFromCurrentFrame();
if (!rhiQueryIndices)
{
@@ -124,12 +118,6 @@ namespace AZ
return QueryResultCode::Fail;
}
// Limit calling EndQuery() to the last CommandList in the array.
if (context.GetCommandListIndex() != context.GetCommandListCount() - 1)
{
return QueryResultCode::Success;
}
// Validate that the queries are recorded for the same scope.
if (m_cachedScopeId != context.GetScopeId())
{
@@ -522,8 +522,11 @@ namespace AZ
}
};
ExecuteOnTimestampQuery(beginQuery);
ExecuteOnPipelineStatisticsQuery(beginQuery);
if (context.GetCommandListIndex() == 0)
{
ExecuteOnTimestampQuery(beginQuery);
ExecuteOnPipelineStatisticsQuery(beginQuery);
}
}
void RenderPass::EndScopeQuery(const RHI::FrameGraphExecuteContext& context)
@@ -533,8 +536,23 @@ namespace AZ
query->EndQuery(context);
};
ExecuteOnTimestampQuery(endQuery);
ExecuteOnPipelineStatisticsQuery(endQuery);
// This scopy query implmentation should be replaced by
// [ATOM-5407] [RHI][Core] - Add GPU timestamp and pipeline statistic support for scopes
// For timestamp query, it's okay to execute across different command lists
if (context.GetCommandListIndex() == context.GetCommandListCount() - 1)
{
ExecuteOnTimestampQuery(endQuery);
}
// For all the other types of queries except timestamp, the query start and end has to be in the same command list
// Here only tracks the PipelineStatistics for the first command list due to that we don't know how many queries are
// needed when AddScopeQueryToFrameGraph is called.
// This implementation leads to an issue that we may not get accurate pipeline statistic data
// for passes which were executed with more than one command list
if (context.GetCommandListIndex() == 0)
{
ExecuteOnPipelineStatisticsQuery(endQuery);
}
}
void RenderPass::ReadbackScopeQueryResults()
@@ -296,6 +296,7 @@ namespace AZ
->Method("GetShaderCount", &LuaMaterialFunctorRuntimeContext::GetShaderCount)
->Method("GetShader", &LuaMaterialFunctorRuntimeContext::GetShader)
->Method("GetShaderByTag", &LuaMaterialFunctorRuntimeContext::GetShaderByTag)
->Method("HasShaderWithTag", &LuaMaterialFunctorRuntimeContext::HasShaderWithTag)
;
}
@@ -424,6 +425,11 @@ namespace AZ
return LuaMaterialFunctorShaderItem{nullptr};
}
}
bool LuaMaterialFunctorRuntimeContext::HasShaderWithTag(const char* shaderTag)
{
return m_runtimeContextImpl->m_shaderCollection->HasShaderTag(AZ::Name{shaderTag});
}
void LuaMaterialFunctorEditorContext::LuaMaterialFunctorEditorContext::Reflect(BehaviorContext* behaviorContext)
{
@@ -159,7 +159,9 @@ namespace UnitTest
const uint32_t ResultSize = sizeof(uint64_t);
uint64_t mockData;
const RHI::FrameGraphExecuteContext::Descriptor desc = {};
RHI::FrameGraphExecuteContext::Descriptor desc = {};
uint64_t dummyCommandList;
desc.m_commandList = reinterpret_cast<RHI::CommandList*>(&dummyCommandList);
RHI::FrameGraphExecuteContext context(desc);
RHI::Scope scope;
@@ -209,7 +211,9 @@ namespace UnitTest
const uint32_t ResultSize = sizeof(uint64_t) * 4u;
uint64_t mockData;
const RHI::FrameGraphExecuteContext::Descriptor desc = {};
RHI::FrameGraphExecuteContext::Descriptor desc = {};
uint64_t dummyCommandList;
desc.m_commandList = reinterpret_cast<RHI::CommandList*>(&dummyCommandList);
RHI::FrameGraphExecuteContext context(desc);
RHI::Scope scope;
@@ -273,7 +277,9 @@ namespace UnitTest
const uint32_t ResultSize = sizeof(uint64_t) * 2u;
uint64_t mockData;
const RHI::FrameGraphExecuteContext::Descriptor desc = {};
RHI::FrameGraphExecuteContext::Descriptor desc = {};
uint64_t dummyCommandList;
desc.m_commandList = reinterpret_cast<RHI::CommandList*>(&dummyCommandList);
RHI::FrameGraphExecuteContext context(desc);
RHI::Scope scope;
@@ -17,7 +17,6 @@
"textureMap": "TestData/Textures/cc0/Rock030_2K_Normal.jpg"
},
"parallax": {
"enable": true,
"algorithm": "POM",
"factor": 0.03,
"quality": "High",
@@ -86,6 +86,10 @@
"textureMap": "TestData/Textures/cc0/Lava004_1K_Roughness.jpg"
},
"layer2_uv": {
"center": [
0.0,
0.0
],
"offsetU": 0.5,
"offsetV": 0.25
},
@@ -128,11 +132,15 @@
"factor": 0.47474750876426699
},
"layer3_uv": {
"center": [
0.0,
0.0
],
"offsetU": 0.11999999731779099,
"rotateDegrees": -57.599998474121097
},
"parallax": {
"enable": true
"quality": "Medium"
},
"uv": {
"center": [
@@ -48,8 +48,8 @@
"textureMap": "TestData/Textures/cc0/Concrete019_1K_Color.jpg"
},
"parallax": {
"enable": true,
"pdo": true
"pdo": true,
"quality": "Medium"
}
}
}
@@ -6,6 +6,9 @@
"properties": {
"blend": {
"blendSource": "BlendMaskVertexColors"
},
"parallax": {
"quality": "Medium"
}
}
}
}
@@ -46,8 +46,8 @@
},
"layer2_uv": {
"center": [
0.5,
0.5
0.0,
0.0
],
"offsetU": 0.1599999964237213,
"offsetV": 0.07999999821186066,
@@ -67,13 +67,15 @@
"textureMap": "TestData/Textures/cc0/Rocks002_1K_Roughness.jpg"
},
"layer3_uv": {
"center": [
0.0,
0.0
],
"scale": 3.4999988079071047
},
"parallax": {
"algorithm": "Relief",
"enable": true,
"pdo": true,
"quality": "Low"
"pdo": true
}
}
}
@@ -0,0 +1,23 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"color": [
0.5906767249107361,
1.0,
0.11703670024871826,
1.0
],
"textureMap": "Textures/Default/default_basecolor.tif"
},
"opacity": {
"alphaSource": "Split",
"factor": 0.75,
"mode": "TintedTransparent",
"textureMap": "TestData/Textures/checker8x8_gray_512.png"
}
}
}
@@ -8,7 +8,6 @@
},
"parallax": {
"algorithm": "POM",
"enable": true,
"factor": 0.02500000037252903,
"quality": "High",
"textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_disp.png"
@@ -13,13 +13,15 @@
"textureMap": "TestData/Textures/checker8x8_512.png"
},
"parallax": {
"algorithm": "POM",
"enable": true,
"factor": 0.10000000149011612,
"quality": "High",
"textureMap": "TestData/Textures/TextureHaven/4k_castle_brick_02_red/4k_castle_brick_02_red_disp.png"
},
"uv": {
"center": [
0.0,
0.0
],
"scale": 0.5
}
}
@@ -6,7 +6,6 @@
"properties": {
"subsurfaceScattering": {
"enableSubsurfaceScattering": true,
"enableTransmission": true,
"scatterDistance": 64.6464614868164,
"subsurfaceScatterFactor": 1.0,
"thicknessMap": "TestData/Textures/checker8x8_512.png",
@@ -13,7 +13,6 @@
},
"parallax": {
"algorithm": "POM",
"enable": true,
"factor": 0.10000000149011612,
"quality": "High",
"textureMap": "TestData/Objects/cube/cube_diff.tif"
@@ -13,7 +13,6 @@
},
"parallax": {
"algorithm": "POM",
"enable": true,
"factor": 0.05000000074505806,
"quality": "High",
"textureMap": "TestData/Objects/cube/cube_diff.tif"
@@ -8,18 +8,24 @@
"textureMap": "Objects/Lucy/Lucy_bronze_BaseColor.png",
"textureMapUv": "Unwrapped"
},
"detailUV": {
"center": [
0.0,
0.0
]
},
"metallic": {
"textureMap": "Objects/Lucy/Lucy_bronze_metallic.png",
"textureMap": "Objects/Lucy/Lucy_bronze_Metallic.png",
"textureMapUv": "Unwrapped"
},
"normal": {
"flipY": true,
"textureMap": "Objects/Lucy/Lucy_normal.png",
"textureMap": "Objects/Lucy/Lucy_Normal.png",
"textureMapUv": "Unwrapped"
},
"roughness": {
"textureMap": "Objects/Lucy/Lucy_bronze_roughness.png",
"textureMap": "Objects/Lucy/Lucy_bronze_Roughness.png",
"textureMapUv": "Unwrapped"
}
}
}
}
@@ -5,7 +5,7 @@
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"textureMap": "Objects/Lucy/Lucy_bronze_baseColor.png",
"textureMap": "Objects/Lucy/Lucy_bronze_BaseColor.png",
"textureMapUv": "Unwrapped"
},
"detailLayerGroup": {
@@ -19,20 +19,24 @@
"normalDetailStrength": 1.5
},
"detailUV": {
"center": [
0.0,
0.0
],
"scale": 10.0
},
"metallic": {
"textureMap": "Objects/Lucy/Lucy_bronze_metallic.png",
"textureMap": "Objects/Lucy/Lucy_bronze_Metallic.png",
"textureMapUv": "Unwrapped"
},
"normal": {
"flipY": true,
"textureMap": "Objects/Lucy/Lucy_normal.png",
"textureMap": "Objects/Lucy/Lucy_Normal.png",
"textureMapUv": "Unwrapped"
},
"roughness": {
"textureMap": "Objects/Lucy/Lucy_bronze_roughness.png",
"textureMap": "Objects/Lucy/Lucy_bronze_Roughness.png",
"textureMapUv": "Unwrapped"
}
}
}
}
@@ -5,7 +5,7 @@
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"textureMap": "Objects/Lucy/Lucy_bronze_baseColor.png",
"textureMap": "Objects/Lucy/Lucy_bronze_BaseColor.png",
"textureMapUv": "Unwrapped"
},
"detailLayerGroup": {
@@ -18,20 +18,24 @@
"normalDetailStrength": 1.5
},
"detailUV": {
"center": [
0.0,
0.0
],
"scale": 10.0
},
"metallic": {
"textureMap": "Objects/Lucy/Lucy_bronze_metallic.png",
"textureMap": "Objects/Lucy/Lucy_bronze_Metallic.png",
"textureMapUv": "Unwrapped"
},
"normal": {
"flipY": true,
"textureMap": "Objects/Lucy/Lucy_normal.png",
"textureMap": "Objects/Lucy/Lucy_Normal.png",
"textureMapUv": "Unwrapped"
},
"roughness": {
"textureMap": "Objects/Lucy/Lucy_bronze_roughness.png",
"textureMap": "Objects/Lucy/Lucy_bronze_Roughness.png",
"textureMapUv": "Unwrapped"
}
}
}
}
@@ -98,6 +98,7 @@ namespace AtomToolsFramework
AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition, float depth) override;
AZStd::optional<AzToolsFramework::ViewportInteraction::ProjectedViewportRay> ViewportScreenToWorldRay(
const AzFramework::ScreenPoint& screenPosition) override;
float DeviceScalingFactor() override;
//! Set interface for providing viewport specific settings (e.g. snapping properties).
void SetViewportSettings(const AzToolsFramework::ViewportInteraction::ViewportSettings* viewportSettings);
@@ -313,8 +313,7 @@ namespace AtomToolsFramework
// Scale the size by the DPI of the platform to
// get the proper size in pixels.
const QSize uiWindowSize = size();
const qreal deficePixelRatio = devicePixelRatioF();
const QSize windowSize = uiWindowSize * deficePixelRatio;
const QSize windowSize = uiWindowSize * devicePixelRatioF();
const AzFramework::NativeWindowHandle windowId = reinterpret_cast<AzFramework::NativeWindowHandle>(winId());
AzFramework::WindowNotificationBus::Event(windowId, &AzFramework::WindowNotifications::OnWindowResized, windowSize.width(), windowSize.height());
@@ -465,6 +464,11 @@ namespace AtomToolsFramework
return AzToolsFramework::ViewportInteraction::ProjectedViewportRay{rayOrigin, rayDirection};
}
float RenderViewportWidget::DeviceScalingFactor()
{
return aznumeric_cast<float>(devicePixelRatioF());
}
AzFramework::ScreenPoint RenderViewportWidget::ViewportCursorScreenPosition()
{
return AzToolsFramework::ViewportInteraction::ScreenPointFromQPoint(m_mousePosition.toPoint());