You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
3.7 KiB
C++
101 lines
3.7 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
|
|
#include <Processing/ImageObjectImpl.h>
|
|
#include <Processing/ImageToProcess.h>
|
|
#include <Processing/ImageConvert.h>
|
|
#include <Processing/PixelFormatInfo.h>
|
|
#include <Converters/FIR-Windows.h>
|
|
#include <Converters/PixelOperation.h>
|
|
|
|
namespace ImageProcessingAtom
|
|
{
|
|
// higher mip level is subtracted by lower mip level when applying the [cheap] high pass filter
|
|
void ImageToProcess::CreateHighPass(AZ::u32 dwMipDown)
|
|
{
|
|
//no need to convert if mip go down 0
|
|
if (dwMipDown == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const EPixelFormat ePixelFormat = m_img->GetPixelFormat();
|
|
|
|
if (ePixelFormat != ePixelFormat_R32G32B32A32F)
|
|
{
|
|
AZ_Assert(false, "You need convert the orginal image to ePixelFormat_R32G32B32A32F before call this function");
|
|
return;
|
|
}
|
|
|
|
|
|
AZ::u32 dwWidth, dwHeight, dwMips;
|
|
dwWidth = m_img->GetWidth(0);
|
|
dwHeight = m_img->GetHeight(0);
|
|
dwMips = m_img->GetMipCount();
|
|
|
|
if (dwMipDown >= dwMips)
|
|
{
|
|
AZ_Warning("Image Processing", false, "CreateHighPass can't go down %i MIP levels for high pass as there are not\
|
|
enough MIP levels available, going down by %i instead", dwMipDown, dwMips - 1);
|
|
dwMipDown = dwMips - 1;
|
|
}
|
|
|
|
IImageObjectPtr newImage(IImageObject::CreateImage(dwWidth, dwHeight, dwMips, ePixelFormat));
|
|
newImage->CopyPropertiesFrom(m_img);
|
|
|
|
IPixelOperationPtr pixelOp = CreatePixelOperation(ePixelFormat);
|
|
AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(ePixelFormat)->bitsPerBlock / 8;
|
|
|
|
AZ::u32 dstMips = newImage->GetMipCount();
|
|
for (AZ::u32 dstMip = 0; dstMip < dwMipDown; ++dstMip)
|
|
{
|
|
// linear interpolation
|
|
FilterImage(MipGenType::triangle, MipGenEvalType::sum, 0.0f, 0.0f, m_img, dwMipDown, newImage, dstMip, NULL, NULL);
|
|
|
|
//substraction
|
|
AZ::u8* srcPixelBuf;
|
|
AZ::u32 srcPitch;
|
|
m_img->GetImagePointer(dstMip, srcPixelBuf, srcPitch);
|
|
AZ::u8* dstPixelBuf;
|
|
AZ::u32 dstPitch;
|
|
newImage->GetImagePointer(dstMip, dstPixelBuf, dstPitch);
|
|
const AZ::u32 pixelCount = newImage->GetPixelCount(dstMip);
|
|
|
|
for (AZ::u32 i = 0; i < pixelCount; ++i, srcPixelBuf += pixelBytes, dstPixelBuf += pixelBytes)
|
|
{
|
|
float r1, g1, b1, a1, r2, g2, b2, a2;
|
|
pixelOp->GetRGBA(srcPixelBuf, r1, g1, b1, a1);
|
|
pixelOp->GetRGBA(dstPixelBuf, r2, g2, b2, a2);
|
|
|
|
r2 = AZ::GetClamp<float>(r1 - r2 + 0.5f, 0.0f, 1.0f);
|
|
g2 = AZ::GetClamp<float>(g1 - g2 + 0.5f, 0.0f, 1.0f);
|
|
b2 = AZ::GetClamp<float>(b1 - b2 + 0.5f, 0.0f, 1.0f);
|
|
a2 = AZ::GetClamp<float>(a1 - a2 + 0.5f, 0.0f, 1.0f);
|
|
pixelOp->SetRGBA(dstPixelBuf, r2, g2, b2, a2);
|
|
}
|
|
}
|
|
|
|
// mips below the chosen highpass mip are grey
|
|
for (AZ::u32 dstMip = dwMipDown; dstMip < dstMips; ++dstMip)
|
|
{
|
|
AZ::u8* dstPixelBuf;
|
|
AZ::u32 dstPitch;
|
|
newImage->GetImagePointer(dstMip, dstPixelBuf, dstPitch);
|
|
const AZ::u32 pixelCount = newImage->GetPixelCount(dstMip);
|
|
|
|
for (AZ::u32 i = 0; i < pixelCount; ++i, dstPixelBuf += pixelBytes)
|
|
{
|
|
pixelOp->SetRGBA(dstPixelBuf, 0.5f, 0.5f, 0.5f, 1.0f);
|
|
}
|
|
}
|
|
|
|
m_img = newImage;
|
|
}
|
|
} // namespace ImageProcessingAtom
|