CMFT WIP.

This commit is contained in:
Branimir Karadžić
2018-06-21 19:10:14 -07:00
parent ba82899651
commit c3a55957f2
4 changed files with 248 additions and 28 deletions

View File

@@ -334,6 +334,16 @@ namespace bimg
, const void* _src
);
///
void imageRgba32fDownsample2x2(
void* _dst
, uint32_t _width
, uint32_t _height
, uint32_t _depth
, uint32_t _srcPitch
, const void* _src
);
///
void imageRgba32fDownsample2x2NormalMap(
void* _dst

View File

@@ -709,6 +709,136 @@ namespace bimg
imageRgba32fLinearDownsample2x2Ref(_dst, _width, _height, _depth, _srcPitch, _src);
}
void imageRgba32fDownsample2x2Ref(void* _dst, uint32_t _width, uint32_t _height, uint32_t _depth, uint32_t _srcPitch, const void* _src)
{
const uint32_t dstWidth = _width/2;
const uint32_t dstHeight = _height/2;
const uint32_t dstDepth = _depth/2;
if (0 == dstWidth
|| 0 == dstHeight)
{
return;
}
const uint8_t* src = (const uint8_t*)_src;
uint8_t* dst = (uint8_t*)_dst;
if (0 == dstDepth)
{
for (uint32_t yy = 0, ystep = _srcPitch*2; yy < dstHeight; ++yy, src += ystep)
{
const float* rgba0 = (const float*)&src[0];
const float* rgba1 = (const float*)&src[_srcPitch];
for (uint32_t xx = 0; xx < dstWidth; ++xx, rgba0 += 8, rgba1 += 8, dst += 16)
{
float xyz[4];
xyz[0] = bx::toLinear(rgba0[0]);
xyz[1] = bx::toLinear(rgba0[1]);
xyz[2] = bx::toLinear(rgba0[2]);
xyz[3] = rgba0[3];
xyz[0] += bx::toLinear(rgba0[4]);
xyz[1] += bx::toLinear(rgba0[5]);
xyz[2] += bx::toLinear(rgba0[6]);
xyz[3] += rgba0[7];
xyz[0] += bx::toLinear(rgba1[0]);
xyz[1] += bx::toLinear(rgba1[1]);
xyz[2] += bx::toLinear(rgba1[2]);
xyz[3] += rgba1[3];
xyz[0] += bx::toLinear(rgba1[4]);
xyz[1] += bx::toLinear(rgba1[5]);
xyz[2] += bx::toLinear(rgba1[6]);
xyz[3] += rgba1[7];
xyz[0] = bx::toGamma(xyz[0]/4.0f);
xyz[1] = bx::toGamma(xyz[1]/4.0f);
xyz[2] = bx::toGamma(xyz[2]/4.0f);
xyz[3] = xyz[3]/4.0f;
bx::packRgba32F(dst, xyz);
}
}
}
else
{
const uint32_t slicePitch = _srcPitch*_height;
for (uint32_t zz = 0; zz < dstDepth; ++zz, src += slicePitch)
{
for (uint32_t yy = 0, ystep = _srcPitch*2; yy < dstHeight; ++yy, src += ystep)
{
const float* rgba0 = (const float*)&src[0];
const float* rgba1 = (const float*)&src[_srcPitch];
const float* rgba2 = (const float*)&src[slicePitch];
const float* rgba3 = (const float*)&src[slicePitch+_srcPitch];
for (uint32_t xx = 0
; xx < dstWidth
; ++xx, rgba0 += 8, rgba1 += 8, rgba2 += 8, rgba3 += 8, dst += 16
)
{
float xyz[4];
xyz[0] = bx::toLinear(rgba0[0]);
xyz[1] = bx::toLinear(rgba0[1]);
xyz[2] = bx::toLinear(rgba0[2]);
xyz[3] = rgba0[3];
xyz[0] += bx::toLinear(rgba0[4]);
xyz[1] += bx::toLinear(rgba0[5]);
xyz[2] += bx::toLinear(rgba0[6]);
xyz[3] += rgba0[7];
xyz[0] += bx::toLinear(rgba1[0]);
xyz[1] += bx::toLinear(rgba1[1]);
xyz[2] += bx::toLinear(rgba1[2]);
xyz[3] += rgba1[3];
xyz[0] += bx::toLinear(rgba1[4]);
xyz[1] += bx::toLinear(rgba1[5]);
xyz[2] += bx::toLinear(rgba1[6]);
xyz[3] += rgba1[7];
xyz[0] += bx::toLinear(rgba2[0]);
xyz[1] += bx::toLinear(rgba2[1]);
xyz[2] += bx::toLinear(rgba2[2]);
xyz[3] += rgba2[3];
xyz[0] += bx::toLinear(rgba2[4]);
xyz[1] += bx::toLinear(rgba2[5]);
xyz[2] += bx::toLinear(rgba2[6]);
xyz[3] += rgba2[7];
xyz[0] += bx::toLinear(rgba3[0]);
xyz[1] += bx::toLinear(rgba3[1]);
xyz[2] += bx::toLinear(rgba3[2]);
xyz[3] += rgba3[3];
xyz[0] += bx::toLinear(rgba3[4]);
xyz[1] += bx::toLinear(rgba3[5]);
xyz[2] += bx::toLinear(rgba3[6]);
xyz[3] += rgba3[7];
xyz[0] = bx::toGamma(xyz[0]/8.0f);
xyz[1] = bx::toGamma(xyz[1]/8.0f);
xyz[2] = bx::toGamma(xyz[2]/8.0f);
xyz[3] = xyz[3]/8.0f;
bx::packRgba32F(dst, xyz);
}
}
}
}
}
void imageRgba32fDownsample2x2(void* _dst, uint32_t _width, uint32_t _height, uint32_t _depth, uint32_t _srcPitch, const void* _src)
{
imageRgba32fDownsample2x2Ref(_dst, _width, _height, _depth, _srcPitch, _src);
}
void imageRgba32fDownsample2x2NormalMapRef(void* _dst, uint32_t _width, uint32_t _height, uint32_t _srcPitch, uint32_t _dstPitch, const void* _src)
{
const uint32_t dstWidth = _width/2;
@@ -1037,7 +1167,7 @@ namespace bimg
if (_dstFormat == _srcFormat)
{
bx::memCopy(_dst, _src, _width*_height*_depth*srcBpp/8);
bx::memCopy(_dst, _src, _width*_height*_depth*(srcBpp/8) );
return true;
}

View File

@@ -623,6 +623,7 @@ namespace bimg
void processFilterArea(
float* _result
, const ImageContainer& _image
, uint8_t _lod
, const Aabb* _aabb
, const float* _dir
, float _specularPower
@@ -633,9 +634,6 @@ namespace bimg
float totalWeight = 0.0f;
const uint32_t bpp = getBitsPerPixel(_image.m_format);
const uint32_t pitch = _image.m_width*bpp/8;
const float widthMinusOne = float(_image.m_width-1);
const float invWidth = 1.0f/float(_image.m_width);
UnpackFn unpack = getUnpack(_image.m_format);
@@ -646,14 +644,18 @@ namespace bimg
continue;
}
ImageMip mip;
if (imageGetRawData(_image, side, _lod, _image.m_data, _image.m_size, mip) )
{
const uint32_t pitch = mip.m_width*bpp/8;
const float widthMinusOne = float(mip.m_width-1);
const float invWidth = 1.0f/float(mip.m_width);
const uint32_t minX = uint32_t(_aabb[side].m_min[0] * widthMinusOne);
const uint32_t maxX = uint32_t(_aabb[side].m_max[0] * widthMinusOne);
const uint32_t minY = uint32_t(_aabb[side].m_min[1] * widthMinusOne);
const uint32_t maxY = uint32_t(_aabb[side].m_max[1] * widthMinusOne);
ImageMip mip;
if (imageGetRawData(_image, side, 0, _image.m_data, _image.m_size, mip) )
{
for (uint32_t yy = minY; yy <= maxY; ++yy)
{
const uint8_t* row = mip.m_data + yy*pitch;
@@ -713,18 +715,95 @@ namespace bimg
}
}
ImageContainer* imageGenerateMips(bx::AllocatorI* _allocator, const ImageContainer& _image)
{
if (_image.m_format != TextureFormat::RGBA8
&& _image.m_format != TextureFormat::RGBA32F)
{
return NULL;
}
ImageContainer* output = imageAlloc(_allocator, _image.m_format, uint16_t(_image.m_width), uint16_t(_image.m_height), uint16_t(_image.m_depth), _image.m_numLayers, _image.m_cubeMap, true);
const uint32_t numMips = output->m_numMips;
const uint32_t numLayers = output->m_numLayers;
const uint32_t numSides = output->m_cubeMap ? 6 : 1;
for (uint32_t layer = 0; layer < numLayers; ++layer)
{
for (uint8_t side = 0; side < numSides; ++side)
{
ImageMip mip;
if (imageGetRawData(_image, uint16_t(layer*numSides + side), 0, _image.m_data, _image.m_size, mip) )
{
for (uint8_t lod = 0; lod < numMips; ++lod)
{
ImageMip srcMip;
imageGetRawData(*output, uint16_t(layer*numSides + side), lod == 0 ? 0 : lod-1, output->m_data, output->m_size, srcMip);
ImageMip dstMip;
imageGetRawData(*output, uint16_t(layer*numSides + side), lod, output->m_data, output->m_size, dstMip);
uint8_t* dstData = const_cast<uint8_t*>(dstMip.m_data);
if (0 == lod)
{
bx::memCopy(dstData, mip.m_data, mip.m_size);
}
else if (output->m_format == TextureFormat::RGBA8)
{
imageRgba8Downsample2x2(
dstData
, srcMip.m_width
, srcMip.m_height
, srcMip.m_depth
, srcMip.m_width*4
, dstMip.m_width*4
, srcMip.m_data
);
}
else if (output->m_format == TextureFormat::RGBA32F)
{
imageRgba32fDownsample2x2(
dstData
, srcMip.m_width
, srcMip.m_height
, srcMip.m_depth
, srcMip.m_width*16
, srcMip.m_data
);
}
}
}
}
}
return output;
}
ImageContainer* imageCubemapRadianceFilter(bx::AllocatorI* _allocator, const ImageContainer& _image, float _filterSize)
{
const uint32_t dstWidth = _image.m_width;
const uint32_t dstPitch = dstWidth*16;
const float invDstWidth = 1.0f / float(dstWidth);
ImageContainer* output = imageConvert(_allocator, TextureFormat::RGBA32F, _image, true);
ImageContainer* output = imageAlloc(_allocator, TextureFormat::RGBA32F, uint16_t(dstWidth), uint16_t(dstWidth), 1, 1, true, true);
if (1 >= output->m_numMips)
{
ImageContainer* temp = imageGenerateMips(_allocator, *output);
imageFree(output);
output = temp;
}
const uint32_t numMips = output->m_numMips;
for (uint8_t side = 0; side < 6; ++side)
{
for (uint8_t lod = 0; lod < numMips; ++lod)
{
ImageMip mip;
imageGetRawData(*output, side, 0, output->m_data, output->m_size, mip);
imageGetRawData(*output, side, lod, output->m_data, output->m_size, mip);
const uint32_t dstWidth = mip.m_width;
const uint32_t dstPitch = dstWidth*16;
const float invDstWidth = 1.0f / float(dstWidth);
for (uint32_t yy = 0; yy < dstWidth; ++yy)
{
@@ -741,7 +820,8 @@ namespace bimg
Aabb aabb[6];
calcFilterArea(aabb, dir, _filterSize);
processFilterArea(dstData, _image, aabb, dir, 10.0f, 0.2f);
processFilterArea(dstData, *output, lod, aabb, dir, 10.0f, 0.2f);
}
}
}
}

View File

@@ -1069,7 +1069,7 @@ int main(int _argc, const char* _argv[])
bimg::imageWriteHdr(&writer
, mip.m_width
, mip.m_height
, mip.m_width*8
, mip.m_width*getBitsPerPixel(mip.m_format)/8
, mip.m_data
, output->m_format
, false