a few libibl optimizations

This commit is contained in:
Mathias Agopian
2019-06-25 18:26:02 -07:00
committed by Mathias Agopian
parent a5addd2257
commit 6ea8ed07ed
4 changed files with 27 additions and 28 deletions

View File

@@ -390,7 +390,8 @@ public:
*
* The reflections cubemap's dimension must be a power-of-two.
*
* @warning This operation is computationally intensive, especially with large environments.
* @warning This operation is computationally intensive, especially with large environments and
* is currently synchronous. Expect about 1ms for a 16x16 cubemap.
*
* @param engine Reference to the filament::Engine to associate this IndirectLight with.
* @param buffer Client-side buffer containing the images to set.

View File

@@ -84,7 +84,7 @@ public:
inline Image& getImageForFace(Face face);
//! computes the center of a pixel at coordinate x, y
inline filament::math::float2 center(size_t x, size_t y) const;
static inline filament::math::float2 center(size_t x, size_t y);
//! computes a direction vector from a face and a location of the center of pixel in an Image
inline filament::math::float3 getDirectionFor(Face face, size_t x, size_t y) const;
@@ -153,7 +153,7 @@ inline Image& Cubemap::getImageForFace(Face face) {
return mFaces[int(face)];
}
inline filament::math::float2 Cubemap::center(size_t x, size_t y) const {
inline filament::math::float2 Cubemap::center(size_t x, size_t y) {
return { x + 0.5f, y + 0.5f };
}

View File

@@ -52,7 +52,7 @@ Cubemap::Address Cubemap::getAddressFor(const float3& r) {
const float ry = std::abs(r.y);
const float rz = std::abs(r.z);
if (rx >= ry && rx >= rz) {
ma = rx;
ma = 1.0f / rx;
if (r.x >= 0) {
addr.face = Face::PX;
sc = -r.z;
@@ -63,7 +63,7 @@ Cubemap::Address Cubemap::getAddressFor(const float3& r) {
tc = -r.y;
}
} else if (ry >= rx && ry >= rz) {
ma = ry;
ma = 1.0f / ry;
if (r.y >= 0) {
addr.face = Face::PY;
sc = r.x;
@@ -74,7 +74,7 @@ Cubemap::Address Cubemap::getAddressFor(const float3& r) {
tc = -r.z;
}
} else {
ma = rz;
ma = 1.0f / rz;
if (r.z >= 0) {
addr.face = Face::PZ;
sc = r.x;
@@ -86,8 +86,8 @@ Cubemap::Address Cubemap::getAddressFor(const float3& r) {
}
}
// ma is guaranteed to be >= sc and tc
addr.s = (sc / ma + 1) * 0.5f;
addr.t = (tc / ma + 1) * 0.5f;
addr.s = (sc * ma + 1.0f) * 0.5f;
addr.t = (tc * ma + 1.0f) * 0.5f;
return addr;
}
@@ -205,15 +205,13 @@ Cubemap::Texel Cubemap::trilinearFilterAt(const Cubemap& l0, const Cubemap& l1,
{
Cubemap::Address addr(getAddressFor(L));
const Image& i0 = l0.getImageForFace(addr.face);
const Image& i1 = l1.getImageForFace(addr.face);
float x0 = std::min(addr.s * l0.mDimensions, l0.mUpperBound);
float y0 = std::min(addr.t * l0.mDimensions, l0.mUpperBound);
float3 c0(filterAt(i0, x0, y0));
if (&l0 != &l1) {
const Image& i1 = l1.getImageForFace(addr.face);
float x1 = std::min(addr.s * l1.mDimensions, l1.mUpperBound);
float y1 = std::min(addr.t * l1.mDimensions, l1.mUpperBound);
c0 += lerp * (filterAt(i1, x1, y1) - c0);
}
float x1 = std::min(addr.s * l1.mDimensions, l1.mUpperBound);
float y1 = std::min(addr.t * l1.mDimensions, l1.mUpperBound);
float3 c0 = filterAt(i0, x0, y0);
c0 += lerp * (filterAt(i1, x1, y1) - c0);
return c0;
}

View File

@@ -300,13 +300,13 @@ void CubemapIBL::roughnessFilter(JobSystem& js, Cubemap& dst, const std::vector<
if (linearRoughness == 0) {
CubemapUtils::process<CubemapUtils::EmptyState>(dst, js, [&]
(CubemapUtils::EmptyState&, size_t y, Cubemap::Face f, Cubemap::Texel* data, size_t dim) {
if (updater) {
if (UTILS_UNLIKELY(updater)) {
size_t p = progress.fetch_add(1, std::memory_order_relaxed) + 1;
updater(0, (float)p / (dim * 6));
}
const Cubemap& cm = levels[0];
for (size_t x = 0; x < dim; ++x, ++data) {
const float2 p(dst.center(x, y));
const float2 p(Cubemap::center(x, y));
const float3 N(dst.getDirectionFor(f, p.x, p.y) * mirror);
// FIXME: we should pick the proper LOD here and do trilinear filtering
Cubemap::writeAt(data, cm.sampleAt(N));
@@ -356,9 +356,9 @@ void CubemapIBL::roughnessFilter(JobSystem& js, Cubemap& dst, const std::vector<
#else
const float NoV = 1;
const float NoH = H.z;
const float NoH2 = H.z*H.z;
const float NoL = 2*NoH2 - 1;
const float3 L(2*NoH*H.x, 2*NoH*H.y, NoL);
const float NoH2 = H.z * H.z;
const float NoL = 2 * NoH2 - 1;
const float3 L(2 * NoH * H.x, 2 * NoH * H.y, NoL);
#endif
if (NoL > 0) {
@@ -382,12 +382,12 @@ void CubemapIBL::roughnessFilter(JobSystem& js, Cubemap& dst, const std::vector<
}
}
std::for_each(cache.begin(), cache.end(), [weight](CacheEntry& entry){
entry.brdf_NoL /= weight;
});
for (auto& entry : cache) {
entry.brdf_NoL *= 1.0f / weight;
}
// we can sample the cubemap in any order, sort by the weight, it could improve fp precision
std::sort(cache.begin(), cache.end(), [](CacheEntry const& lhs, CacheEntry const& rhs){
std::sort(cache.begin(), cache.end(), [](CacheEntry const& lhs, CacheEntry const& rhs) {
return lhs.brdf_NoL < rhs.brdf_NoL;
});
@@ -395,7 +395,7 @@ void CubemapIBL::roughnessFilter(JobSystem& js, Cubemap& dst, const std::vector<
[&](CubemapUtils::EmptyState&, size_t y,
Cubemap::Face f, Cubemap::Texel* data, size_t dim) {
if (updater) {
if (UTILS_UNLIKELY(updater)) {
size_t p = progress.fetch_add(1, std::memory_order_relaxed) + 1;
updater(0, (float)p / (dim * 6));
}
@@ -403,7 +403,7 @@ void CubemapIBL::roughnessFilter(JobSystem& js, Cubemap& dst, const std::vector<
mat3 R;
const size_t numSamples = cache.size();
for (size_t x = 0; x < dim; ++x, ++data) {
const float2 p(dst.center(x, y));
const float2 p(Cubemap::center(x, y));
const float3 N(dst.getDirectionFor(f, p.x, p.y) * mirror);
// center the cone around the normal (handle case of normal close to up)
@@ -571,7 +571,7 @@ void CubemapIBL::diffuseIrradiance(JobSystem& js, Cubemap& dst, const std::vecto
mat3 R;
const size_t numSamples = cache.size();
for (size_t x = 0; x < dim; ++x, ++data) {
const float2 p(dst.center(x, y));
const float2 p(Cubemap::center(x, y));
const float3 N(dst.getDirectionFor(f, p.x, p.y));
// center the cone around the normal (handle case of normal close to up)
@@ -924,7 +924,7 @@ void CubemapIBL::brdf(utils::JobSystem& js, Cubemap& dst, float linearRoughness)
[ & ](CubemapUtils::EmptyState&, size_t y,
Cubemap::Face f, Cubemap::Texel* data, size_t dim) {
for (size_t x=0 ; x<dim ; ++x, ++data) {
const float2 p(dst.center(x, y));
const float2 p(Cubemap::center(x, y));
const float3 H(dst.getDirectionFor(f, p.x, p.y));
const float3 N = { 0, 0, 1 };
const float3 V = N;