|
|
|
|
@ -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
|
|
|
|
|
{
|
|
|
|
|
|