mirror of
https://github.com/bkaradzic/bimg.git
synced 2026-02-17 20:52:38 +01:00
CMFT WIP.
This commit is contained in:
@@ -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
|
||||
|
||||
132
src/image.cpp
132
src/image.cpp
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,24 +715,101 @@ 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)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < dstWidth; ++xx)
|
||||
{
|
||||
float* dstData = (float*)&mip. m_data[yy*dstPitch+xx*16];
|
||||
float* dstData = (float*)&mip.m_data[yy*dstPitch+xx*16];
|
||||
|
||||
const float uu = float(xx)*invDstWidth*2.0f - 1.0f;
|
||||
const float vv = float(yy)*invDstWidth*2.0f - 1.0f;
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user