Add mipmap scaling according to alphatest coverage.
This commit is contained in:
parent
77bfabca3b
commit
8cbd2c9ec6
|
@ -194,10 +194,16 @@ void FloatImage::scaleBias(uint base_component, uint num, float scale, float bia
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clamp the elements of the image.
|
/// Clamp the elements of the image.
|
||||||
void FloatImage::clamp(float low, float high)
|
void FloatImage::clamp(uint base_component, uint num, float low, float high)
|
||||||
{
|
{
|
||||||
for(uint i = 0; i < m_count; i++) {
|
const uint size = m_width * m_height;
|
||||||
m_mem[i] = nv::clamp(m_mem[i], low, high);
|
|
||||||
|
for(uint c = 0; c < num; c++) {
|
||||||
|
float * ptr = this->channel(base_component + c);
|
||||||
|
|
||||||
|
for(uint i = 0; i < size; i++) {
|
||||||
|
ptr[i] = nv::clamp(ptr[i], low, high);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -945,6 +951,54 @@ void FloatImage::flip()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float FloatImage::alphaTestCoverage(float alphaRef, int alphaChannel) const
|
||||||
|
{
|
||||||
|
const uint w = m_width;
|
||||||
|
const uint h = m_height;
|
||||||
|
|
||||||
|
float coverage = 0.0f;
|
||||||
|
|
||||||
|
for (uint y = 0; y < h; y++) {
|
||||||
|
const float * alpha = scanline(y, alphaChannel);
|
||||||
|
for (uint x = 0; x < w; x++) {
|
||||||
|
if (alpha[x] > alphaRef) coverage += 1.0f; // @@ gt or lt?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return coverage / float(w * h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FloatImage::scaleAlphaToCoverage(float desiredCoverage, float alphaRef, int alphaChannel)
|
||||||
|
{
|
||||||
|
float minAlphaRef = 0.0f;
|
||||||
|
float maxAlphaRef = 1.0f;
|
||||||
|
float midAlphaRef = 0.5f;
|
||||||
|
|
||||||
|
// Determine desired scale using a binary search. Hardcoded to 8 steps max.
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
float currentCoverage = alphaTestCoverage(midAlphaRef, alphaChannel);
|
||||||
|
|
||||||
|
if (currentCoverage > desiredCoverage) {
|
||||||
|
maxAlphaRef = midAlphaRef;
|
||||||
|
}
|
||||||
|
else if (currentCoverage < desiredCoverage) {
|
||||||
|
minAlphaRef = midAlphaRef;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
midAlphaRef = (minAlphaRef + maxAlphaRef) * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float alphaScale = alphaRef / midAlphaRef;
|
||||||
|
|
||||||
|
// Scale alpha channel.
|
||||||
|
scaleBias(alphaChannel, 1, alphaScale, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FloatImage* FloatImage::clone() const
|
FloatImage* FloatImage::clone() const
|
||||||
{
|
{
|
||||||
FloatImage* copy = new FloatImage();
|
FloatImage* copy = new FloatImage();
|
||||||
|
|
|
@ -59,10 +59,9 @@ public:
|
||||||
|
|
||||||
NVIMAGE_API void packNormals(uint base_component);
|
NVIMAGE_API void packNormals(uint base_component);
|
||||||
NVIMAGE_API void expandNormals(uint base_component);
|
NVIMAGE_API void expandNormals(uint base_component);
|
||||||
NVIMAGE_API void scaleBias(uint base_component, uint num, float scale, float add);
|
NVIMAGE_API void scaleBias(uint base_component, uint num, float scale, float bias);
|
||||||
|
|
||||||
//NVIMAGE_API void clamp(uint base_component, uint num);
|
NVIMAGE_API void clamp(uint base_component, uint num, float low, float high);
|
||||||
NVIMAGE_API void clamp(float low, float high);
|
|
||||||
|
|
||||||
NVIMAGE_API void toLinear(uint base_component, uint num, float gamma = 2.2f);
|
NVIMAGE_API void toLinear(uint base_component, uint num, float gamma = 2.2f);
|
||||||
NVIMAGE_API void toGamma(uint base_component, uint num, float gamma = 2.2f);
|
NVIMAGE_API void toGamma(uint base_component, uint num, float gamma = 2.2f);
|
||||||
|
@ -87,6 +86,9 @@ public:
|
||||||
NVIMAGE_API void applyKernelHorizontal(const PolyphaseKernel & k, int y, uint c, uint a, WrapMode wm, float * output) const;
|
NVIMAGE_API void applyKernelHorizontal(const PolyphaseKernel & k, int y, uint c, uint a, WrapMode wm, float * output) const;
|
||||||
|
|
||||||
NVIMAGE_API void flip();
|
NVIMAGE_API void flip();
|
||||||
|
|
||||||
|
NVIMAGE_API float alphaTestCoverage(float alphaRef, int alphaChannel) const;
|
||||||
|
NVIMAGE_API void scaleAlphaToCoverage(float coverage, float alphaRef, int alphaChannel);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
uint width() const { return m_width; }
|
uint width() const { return m_width; }
|
||||||
|
|
|
@ -112,7 +112,7 @@ void OutputOptions::Private::beginImage(int size, int width, int height, int dep
|
||||||
|
|
||||||
bool OutputOptions::Private::writeData(const void * data, int size) const
|
bool OutputOptions::Private::writeData(const void * data, int size) const
|
||||||
{
|
{
|
||||||
if (outputHandler != NULL) return outputHandler->writeData(data, size);
|
return outputHandler == NULL || outputHandler->writeData(data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutputOptions::Private::error(Error e) const
|
void OutputOptions::Private::error(Error e) const
|
||||||
|
|
|
@ -244,6 +244,29 @@ int TexImage::countMipmaps() const
|
||||||
return ::countMipmaps(width(), height(), depth());
|
return ::countMipmaps(width(), height(), depth());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float TexImage::alphaTestCoverage(float alphaRef/*= 0.5*/) const
|
||||||
|
{
|
||||||
|
int imageCount = 0.0f;
|
||||||
|
float coverage = 0.0f;
|
||||||
|
|
||||||
|
foreach (i, m->imageArray)
|
||||||
|
{
|
||||||
|
FloatImage * img = m->imageArray[i];
|
||||||
|
|
||||||
|
if (img == NULL) continue;
|
||||||
|
|
||||||
|
imageCount++;
|
||||||
|
coverage += img->alphaTestCoverage(alphaRef, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imageCount > 0) {
|
||||||
|
return coverage / imageCount;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool TexImage::load(const char * fileName)
|
bool TexImage::load(const char * fileName)
|
||||||
{
|
{
|
||||||
|
@ -937,6 +960,21 @@ void TexImage::fill(float red, float green, float blue, float alpha)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TexImage::scaleAlphaToCoverage(float coverage, float alphaRef/*= 0.5f*/)
|
||||||
|
{
|
||||||
|
detach();
|
||||||
|
|
||||||
|
foreach (i, m->imageArray)
|
||||||
|
{
|
||||||
|
FloatImage * img = m->imageArray[i];
|
||||||
|
if (img == NULL) continue;
|
||||||
|
|
||||||
|
img->scaleAlphaToCoverage(coverage, alphaRef, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set normal map options.
|
// Set normal map options.
|
||||||
void TexImage::toNormalMap(float sm, float medium, float big, float large)
|
void TexImage::toNormalMap(float sm, float medium, float big, float large)
|
||||||
{
|
{
|
||||||
|
|
|
@ -412,6 +412,7 @@ namespace nvtt
|
||||||
NVTT_API AlphaMode alphaMode() const;
|
NVTT_API AlphaMode alphaMode() const;
|
||||||
NVTT_API bool isNormalMap() const;
|
NVTT_API bool isNormalMap() const;
|
||||||
NVTT_API int countMipmaps() const;
|
NVTT_API int countMipmaps() const;
|
||||||
|
NVTT_API float alphaTestCoverage(float alphaRef = 0.5) const;
|
||||||
|
|
||||||
// Texture data.
|
// Texture data.
|
||||||
NVTT_API bool load(const char * fileName);
|
NVTT_API bool load(const char * fileName);
|
||||||
|
@ -424,7 +425,7 @@ namespace nvtt
|
||||||
NVTT_API void resize(int w, int h, ResizeFilter filter);
|
NVTT_API void resize(int w, int h, ResizeFilter filter);
|
||||||
NVTT_API void resize(int maxExtent, RoundMode mode, ResizeFilter filter);
|
NVTT_API void resize(int maxExtent, RoundMode mode, ResizeFilter filter);
|
||||||
NVTT_API bool buildNextMipmap(MipmapFilter filter);
|
NVTT_API bool buildNextMipmap(MipmapFilter filter);
|
||||||
|
|
||||||
// Color transforms.
|
// Color transforms.
|
||||||
NVTT_API void toLinear(float gamma);
|
NVTT_API void toLinear(float gamma);
|
||||||
NVTT_API void toGamma(float gamma);
|
NVTT_API void toGamma(float gamma);
|
||||||
|
@ -438,6 +439,7 @@ namespace nvtt
|
||||||
NVTT_API void toGreyScale(float redScale, float greenScale, float blueScale, float alphaScale);
|
NVTT_API void toGreyScale(float redScale, float greenScale, float blueScale, float alphaScale);
|
||||||
NVTT_API void setBorder(float r, float g, float b, float a);
|
NVTT_API void setBorder(float r, float g, float b, float a);
|
||||||
NVTT_API void fill(float r, float g, float b, float a);
|
NVTT_API void fill(float r, float g, float b, float a);
|
||||||
|
NVTT_API void scaleAlphaToCoverage(float coverage, float alphaRef = 0.5f);
|
||||||
|
|
||||||
// Set normal map options.
|
// Set normal map options.
|
||||||
NVTT_API void toNormalMap(float sm, float medium, float big, float large);
|
NVTT_API void toNormalMap(float sm, float medium, float big, float large);
|
||||||
|
|
|
@ -386,7 +386,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (nv::strCaseCmp(input.extension(), ".exr") == 0)
|
if (nv::strCaseCmp(input.extension(), ".exr") == 0 || nv::strCaseCmp(input.extension(), ".hdr") == 0)
|
||||||
{
|
{
|
||||||
loadAsFloat = true;
|
loadAsFloat = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user