Moved GetValueFromImageAsset from ImageAsset to ImageGradientComponent
Signed-off-by: Chris Galvan <chgalvan@amazon.com>
This commit is contained in:
@@ -99,6 +99,7 @@ namespace GradientSignal
|
||||
void SetupDependencies();
|
||||
|
||||
void GetSubImageData();
|
||||
float GetValueFromImageData(const AZ::Vector3& uvw, float tilingX, float tilingY, float defaultValue) const;
|
||||
|
||||
// ImageGradientRequestBus overrides...
|
||||
AZStd::string GetImageAssetPath() const override;
|
||||
|
||||
@@ -62,6 +62,4 @@ namespace GradientSignal
|
||||
}
|
||||
};
|
||||
|
||||
float GetValueFromImageAsset(AZStd::span<const uint8_t> imageData, const AZ::RHI::ImageDescriptor& imageDescriptor, const AZ::Vector3& uvw, float tilingX, float tilingY, float defaultValue);
|
||||
|
||||
} // namespace GradientSignal
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <GradientSignal/Components/ImageGradientComponent.h>
|
||||
#include <Atom/ImageProcessing/ImageProcessingDefines.h>
|
||||
#include <Atom/RPI.Public/RPIUtils.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
@@ -226,6 +227,60 @@ namespace GradientSignal
|
||||
m_imageData = m_configuration.m_imageAsset->GetSubImageData(0, 0);
|
||||
}
|
||||
|
||||
float ImageGradientComponent::GetValueFromImageData(const AZ::Vector3& uvw, float tilingX, float tilingY, float defaultValue) const
|
||||
{
|
||||
if (!m_imageData.empty())
|
||||
{
|
||||
const AZ::RHI::ImageDescriptor& imageDescriptor = m_configuration.m_imageAsset->GetImageDescriptor();
|
||||
auto width = imageDescriptor.m_size.m_width;
|
||||
auto height = imageDescriptor.m_size.m_height;
|
||||
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
// When "rasterizing" from uvs, a range of 0-1 has slightly different meanings depending on the sampler state.
|
||||
// For repeating states (Unbounded/None, Repeat), a uv value of 1 should wrap around back to our 0th pixel.
|
||||
// For clamping states (Clamp to Zero, Clamp to Edge), a uv value of 1 should point to the last pixel.
|
||||
|
||||
// We assume here that the code handling sampler states has handled this for us in the clamping cases
|
||||
// by reducing our uv by a small delta value such that anything that wants the last pixel has a value
|
||||
// just slightly less than 1.
|
||||
|
||||
// Keeping that in mind, we scale our uv from 0-1 to 0-image size inclusive. So a 4-pixel image will scale
|
||||
// uv values of 0-1 to 0-4, not 0-3 as you might expect. This is because we want the following range mappings:
|
||||
// [0 - 1/4) = pixel 0
|
||||
// [1/4 - 1/2) = pixel 1
|
||||
// [1/2 - 3/4) = pixel 2
|
||||
// [3/4 - 1) = pixel 3
|
||||
// [1 - 1 1/4) = pixel 0
|
||||
// ...
|
||||
|
||||
// Also, based on our tiling settings, we extend the size of our image virtually by a factor of tilingX and tilingY.
|
||||
// A 16x16 pixel image and tilingX = tilingY = 1 maps the uv range of 0-1 to 0-16 pixels.
|
||||
// A 16x16 pixel image and tilingX = tilingY = 1.5 maps the uv range of 0-1 to 0-24 pixels.
|
||||
|
||||
const AZ::Vector3 tiledDimensions((width * tilingX),
|
||||
(height * tilingY),
|
||||
0.0f);
|
||||
|
||||
// Convert from uv space back to pixel space
|
||||
AZ::Vector3 pixelLookup = (uvw * tiledDimensions);
|
||||
|
||||
// UVs outside the 0-1 range are treated as infinitely tiling, so that we behave the same as the
|
||||
// other gradient generators. As mentioned above, if clamping is desired, we expect it to be applied
|
||||
// outside of this function.
|
||||
auto x = aznumeric_cast<AZ::u32>(pixelLookup.GetX()) % width;
|
||||
auto y = aznumeric_cast<AZ::u32>(pixelLookup.GetY()) % height;
|
||||
|
||||
// Flip the y because images are stored in reverse of our world axes
|
||||
y = (height - 1) - y;
|
||||
|
||||
return AZ::RPI::GetImageDataPixelValue<float>(m_imageData, imageDescriptor, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
void ImageGradientComponent::Activate()
|
||||
{
|
||||
// This will immediately call OnGradientTransformChanged and initialize m_gradientTransform.
|
||||
@@ -325,8 +380,8 @@ namespace GradientSignal
|
||||
|
||||
if (!wasPointRejected)
|
||||
{
|
||||
return GetValueFromImageAsset(
|
||||
m_imageData, m_configuration.m_imageAsset->GetImageDescriptor(), uvw, m_configuration.m_tilingX, m_configuration.m_tilingY, 0.0f);
|
||||
return GetValueFromImageData(
|
||||
uvw, m_configuration.m_tilingX, m_configuration.m_tilingY, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,8 +413,8 @@ namespace GradientSignal
|
||||
|
||||
if (!wasPointRejected)
|
||||
{
|
||||
outValues[index] = GetValueFromImageAsset(
|
||||
m_imageData, m_configuration.m_imageAsset->GetImageDescriptor(), uvw, m_configuration.m_tilingX, m_configuration.m_tilingY, 0.0f);
|
||||
outValues[index] = GetValueFromImageData(
|
||||
uvw, m_configuration.m_tilingX, m_configuration.m_tilingY, 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
|
||||
#include <Atom/ImageProcessing/PixelFormats.h>
|
||||
#include <Atom/RPI.Public/RPIUtils.h>
|
||||
#include <GradientSignal/Util.h>
|
||||
#include <numeric>
|
||||
|
||||
@@ -77,57 +76,4 @@ namespace GradientSignal
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
float GetValueFromImageAsset(AZStd::span<const uint8_t> imageData, const AZ::RHI::ImageDescriptor& imageDescriptor, const AZ::Vector3& uvw, float tilingX, float tilingY, float defaultValue)
|
||||
{
|
||||
if (!imageData.empty())
|
||||
{
|
||||
auto width = imageDescriptor.m_size.m_width;
|
||||
auto height = imageDescriptor.m_size.m_height;
|
||||
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
// When "rasterizing" from uvs, a range of 0-1 has slightly different meanings depending on the sampler state.
|
||||
// For repeating states (Unbounded/None, Repeat), a uv value of 1 should wrap around back to our 0th pixel.
|
||||
// For clamping states (Clamp to Zero, Clamp to Edge), a uv value of 1 should point to the last pixel.
|
||||
|
||||
// We assume here that the code handling sampler states has handled this for us in the clamping cases
|
||||
// by reducing our uv by a small delta value such that anything that wants the last pixel has a value
|
||||
// just slightly less than 1.
|
||||
|
||||
// Keeping that in mind, we scale our uv from 0-1 to 0-image size inclusive. So a 4-pixel image will scale
|
||||
// uv values of 0-1 to 0-4, not 0-3 as you might expect. This is because we want the following range mappings:
|
||||
// [0 - 1/4) = pixel 0
|
||||
// [1/4 - 1/2) = pixel 1
|
||||
// [1/2 - 3/4) = pixel 2
|
||||
// [3/4 - 1) = pixel 3
|
||||
// [1 - 1 1/4) = pixel 0
|
||||
// ...
|
||||
|
||||
// Also, based on our tiling settings, we extend the size of our image virtually by a factor of tilingX and tilingY.
|
||||
// A 16x16 pixel image and tilingX = tilingY = 1 maps the uv range of 0-1 to 0-16 pixels.
|
||||
// A 16x16 pixel image and tilingX = tilingY = 1.5 maps the uv range of 0-1 to 0-24 pixels.
|
||||
|
||||
const AZ::Vector3 tiledDimensions((width * tilingX),
|
||||
(height * tilingY),
|
||||
0.0f);
|
||||
|
||||
// Convert from uv space back to pixel space
|
||||
AZ::Vector3 pixelLookup = (uvw * tiledDimensions);
|
||||
|
||||
// UVs outside the 0-1 range are treated as infinitely tiling, so that we behave the same as the
|
||||
// other gradient generators. As mentioned above, if clamping is desired, we expect it to be applied
|
||||
// outside of this function.
|
||||
auto x = aznumeric_cast<AZ::u32>(pixelLookup.GetX()) % width;
|
||||
auto y = aznumeric_cast<AZ::u32>(pixelLookup.GetY()) % height;
|
||||
|
||||
// Flip the y because images are stored in reverse of our world axes
|
||||
y = (height - 1) - y;
|
||||
|
||||
return AZ::RPI::GetImageDataPixelValue<float>(imageData, imageDescriptor, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user