Compute spherical harmonics from cube maps. Work in progress.
This commit is contained in:
@ -529,6 +529,24 @@ void CubeSurface::clamp(int channel, float low/*= 0.0f*/, float high/*= 1.0f*/)
|
||||
|
||||
CubeSurface CubeSurface::irradianceFilter(int size, EdgeFixup fixupMethod) const
|
||||
{
|
||||
// Evaluate spherical harmonic for each output texel.
|
||||
CubeSurface output;
|
||||
output.m->allocate(size);
|
||||
|
||||
Sh2 shr, shg, shb;
|
||||
|
||||
computeIrradianceSH3(0, shr.coef);
|
||||
computeIrradianceSH3(1, shg.coef);
|
||||
computeIrradianceSH3(2, shb.coef);
|
||||
|
||||
// @@ Sample spherical harmonic from every direction.
|
||||
|
||||
return CubeSurface();
|
||||
}
|
||||
|
||||
|
||||
void CubeSurface::computeLuminanceIrradianceSH3(float coef[9]) const{
|
||||
|
||||
m->allocateTexelTable();
|
||||
|
||||
// Transform this cube to spherical harmonic basis
|
||||
@ -537,6 +555,10 @@ CubeSurface CubeSurface::irradianceFilter(int size, EdgeFixup fixupMethod) const
|
||||
// For each texel of the input cube.
|
||||
const uint edgeLength = m->edgeLength;
|
||||
for (uint f = 0; f < 6; f++) {
|
||||
|
||||
const Surface & inputFace = m->face[f];
|
||||
const FloatImage * inputImage = inputFace.m->image;
|
||||
|
||||
for (uint y = 0; y < edgeLength; y++) {
|
||||
for (uint x = 0; x < edgeLength; x++) {
|
||||
|
||||
@ -546,24 +568,56 @@ CubeSurface CubeSurface::irradianceFilter(int size, EdgeFixup fixupMethod) const
|
||||
Sh2 shDir;
|
||||
shDir.eval(dir);
|
||||
|
||||
sh.addScaled(sh, solidAngle);
|
||||
float r = inputImage->pixel(0, x, y, 0);
|
||||
float g = inputImage->pixel(1, x, y, 0);
|
||||
float b = inputImage->pixel(2, x, y, 0);
|
||||
float lum = 0.333f * (r + g + b); // @@ use the proper luminance formula.
|
||||
|
||||
sh.addScaled(shDir, lum * solidAngle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Evaluate spherical harmonic for each output texel.
|
||||
CubeSurface output;
|
||||
output.m->allocate(size);
|
||||
|
||||
|
||||
|
||||
|
||||
// @@ TODO
|
||||
return CubeSurface();
|
||||
for (int i = 0; i < 9; i++) {
|
||||
coef[i] = sh.coef[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CubeSurface::computeIrradianceSH3(int channel, float coef[9]) const {
|
||||
|
||||
m->allocateTexelTable();
|
||||
|
||||
// Transform this cube to spherical harmonic basis
|
||||
Sh2 sh;
|
||||
|
||||
// For each texel of the input cube.
|
||||
const uint edgeLength = m->edgeLength;
|
||||
for (uint f = 0; f < 6; f++) {
|
||||
|
||||
const Surface & inputFace = m->face[f];
|
||||
const FloatImage * inputImage = inputFace.m->image;
|
||||
|
||||
for (uint y = 0; y < edgeLength; y++) {
|
||||
for (uint x = 0; x < edgeLength; x++) {
|
||||
|
||||
Vector3 dir = m->texelTable->direction(f, x, y);
|
||||
float solidAngle = m->texelTable->solidAngle(f, x, y);
|
||||
|
||||
Sh2 shDir;
|
||||
shDir.eval(dir);
|
||||
|
||||
float c = inputImage->pixel(channel, x, y, 0);
|
||||
|
||||
sh.addScaled(shDir, c * solidAngle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
coef[i] = sh.elemAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Convolve filter against this cube.
|
||||
@ -832,7 +886,7 @@ CubeSurface CubeSurface::cosinePowerFilter(int size, float cosinePower, EdgeFixu
|
||||
CubeSurface filteredCube;
|
||||
filteredCube.m->allocate(size);
|
||||
|
||||
// Texel table is stored along with the surface so that it's compute only once.
|
||||
// Texel table is stored along with the surface so that it's computed only once.
|
||||
m->allocateTexelTable();
|
||||
|
||||
const float threshold = 0.001f;
|
||||
|
@ -88,6 +88,9 @@ namespace nvtt
|
||||
|
||||
void allocateTexelTable()
|
||||
{
|
||||
if (edgeLength == 0) {
|
||||
edgeLength = face[0].width();
|
||||
}
|
||||
if (texelTable == NULL) {
|
||||
texelTable = new TexelTable(edgeLength);
|
||||
}
|
||||
|
@ -665,6 +665,10 @@ namespace nvtt
|
||||
NVTT_API CubeSurface fastResample(int size, EdgeFixup fixupMethod) const;
|
||||
|
||||
|
||||
// Spherical Harmonics:
|
||||
NVTT_API void computeLuminanceIrradianceSH3(float sh[9]) const;
|
||||
NVTT_API void computeIrradianceSH3(int channel, float sh[9]) const;
|
||||
|
||||
/*
|
||||
NVTT_API void resize(int w, int h, ResizeFilter filter);
|
||||
NVTT_API void resize(int w, int h, ResizeFilter filter, float filterWidth, const float * params = 0);
|
||||
|
Reference in New Issue
Block a user