Implement normal map generation for floating point images.
This commit is contained in:
parent
a52d3b7cdc
commit
a088ae5789
|
@ -36,9 +36,9 @@ using namespace nv;
|
||||||
// Create normal map using the given kernels.
|
// Create normal map using the given kernels.
|
||||||
static FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, const Kernel2 * kdu, const Kernel2 * kdv)
|
static FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, const Kernel2 * kdu, const Kernel2 * kdv)
|
||||||
{
|
{
|
||||||
nvCheck(kdu != NULL);
|
nvDebugCheck(kdu != NULL);
|
||||||
nvCheck(kdv != NULL);
|
nvDebugCheck(kdv != NULL);
|
||||||
nvCheck(img != NULL);
|
nvDebugCheck(img != NULL);
|
||||||
|
|
||||||
const uint w = img->width();
|
const uint w = img->width();
|
||||||
const uint h = img->height();
|
const uint h = img->height();
|
||||||
|
@ -75,10 +75,54 @@ static FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create normal map using the given kernels.
|
||||||
|
static FloatImage * createNormalMap(const FloatImage * img, FloatImage::WrapMode wm, const Kernel2 * kdu, const Kernel2 * kdv)
|
||||||
|
{
|
||||||
|
nvDebugCheck(kdu != NULL);
|
||||||
|
nvDebugCheck(kdv != NULL);
|
||||||
|
nvDebugCheck(img != NULL);
|
||||||
|
|
||||||
|
#pragma message(NV_FILE_LINE "Height scale parameter should go away. It should be a sensible value that produces good results when the heightmap is in the [0, 1] range.")
|
||||||
|
const float heightScale = 1.0f / 16.0f;
|
||||||
|
|
||||||
|
const uint w = img->width();
|
||||||
|
const uint h = img->height();
|
||||||
|
|
||||||
|
AutoPtr<FloatImage> img_out(new FloatImage());
|
||||||
|
img_out->allocate(4, w, h);
|
||||||
|
|
||||||
|
for (uint y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
for (uint x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
const float du = img->applyKernel(kdu, x, y, 3, wm);
|
||||||
|
const float dv = img->applyKernel(kdv, x, y, 3, wm);
|
||||||
|
|
||||||
|
Vector3 n = normalize(Vector3(du, dv, heightScale));
|
||||||
|
|
||||||
|
img_out->setPixel(n.x(), x, y, 0);
|
||||||
|
img_out->setPixel(n.y(), x, y, 1);
|
||||||
|
img_out->setPixel(n.z(), x, y, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy alpha channel.
|
||||||
|
for (uint y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
for (uint x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
img_out->setPixel(img->pixel(x, y, 3), x, y, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return img_out.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Create normal map using the given filter.
|
/// Create normal map using the given filter.
|
||||||
FloatImage * nv::createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, NormalMapFilter filter /*= Sobel3x3*/)
|
FloatImage * nv::createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, NormalMapFilter filter /*= Sobel3x3*/)
|
||||||
{
|
{
|
||||||
nvCheck(img != NULL);
|
nvDebugCheck(img != NULL);
|
||||||
|
|
||||||
// Init the kernels.
|
// Init the kernels.
|
||||||
Kernel2 * kdu = NULL;
|
Kernel2 * kdu = NULL;
|
||||||
|
@ -115,7 +159,7 @@ FloatImage * nv::createNormalMap(const Image * img, FloatImage::WrapMode wm, Vec
|
||||||
/// Create normal map combining multiple sobel filters.
|
/// Create normal map combining multiple sobel filters.
|
||||||
FloatImage * nv::createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, Vector4::Arg filterWeights)
|
FloatImage * nv::createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, Vector4::Arg filterWeights)
|
||||||
{
|
{
|
||||||
nvCheck(img != NULL);
|
nvDebugCheck(img != NULL);
|
||||||
|
|
||||||
Kernel2 * kdu = NULL;
|
Kernel2 * kdu = NULL;
|
||||||
Kernel2 * kdv = NULL;
|
Kernel2 * kdv = NULL;
|
||||||
|
@ -130,10 +174,32 @@ FloatImage * nv::createNormalMap(const Image * img, FloatImage::WrapMode wm, Vec
|
||||||
return ::createNormalMap(img, wm, heightWeights, kdu, kdv);
|
return ::createNormalMap(img, wm, heightWeights, kdu, kdv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FloatImage * nv::createNormalMap(const FloatImage * img, FloatImage::WrapMode wm, Vector4::Arg filterWeights)
|
||||||
|
{
|
||||||
|
nvDebugCheck(img != NULL);
|
||||||
|
|
||||||
|
Kernel2 * kdu = NULL;
|
||||||
|
Kernel2 * kdv = NULL;
|
||||||
|
|
||||||
|
kdu = new Kernel2(9);
|
||||||
|
kdu->initBlendedSobel(filterWeights);
|
||||||
|
kdu->normalize();
|
||||||
|
|
||||||
|
kdv = new Kernel2(*kdu);
|
||||||
|
kdv->transpose();
|
||||||
|
|
||||||
|
return ::createNormalMap(img, wm, kdu, kdv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Normalize the given image in place.
|
/// Normalize the given image in place.
|
||||||
void nv::normalizeNormalMap(FloatImage * img)
|
void nv::normalizeNormalMap(FloatImage * img)
|
||||||
{
|
{
|
||||||
nvCheck(img != NULL);
|
nvDebugCheck(img != NULL);
|
||||||
|
|
||||||
|
#pragma messsage(NV_FILE_LINE "Pack and expand normals explicitly")
|
||||||
|
|
||||||
img->expandNormals(0);
|
img->expandNormals(0);
|
||||||
img->normalize(0);
|
img->normalize(0);
|
||||||
img->packNormals(0);
|
img->packNormals(0);
|
||||||
|
|
|
@ -41,10 +41,12 @@ namespace nv
|
||||||
NormalMapFilter_Sobel9x9, // very large
|
NormalMapFilter_Sobel9x9, // very large
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// @@ These two functions should be deprecated:
|
||||||
FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, NormalMapFilter filter = NormalMapFilter_Sobel3x3);
|
FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, NormalMapFilter filter = NormalMapFilter_Sobel3x3);
|
||||||
|
|
||||||
FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, Vector4::Arg filterWeights);
|
FloatImage * createNormalMap(const Image * img, FloatImage::WrapMode wm, Vector4::Arg heightWeights, Vector4::Arg filterWeights);
|
||||||
|
|
||||||
|
FloatImage * createNormalMap(const FloatImage * img, FloatImage::WrapMode wm, Vector4::Arg filterWeights);
|
||||||
|
|
||||||
void normalizeNormalMap(FloatImage * img);
|
void normalizeNormalMap(FloatImage * img);
|
||||||
|
|
||||||
// @@ Add generation of DU/DV maps.
|
// @@ Add generation of DU/DV maps.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user