a few libibl optimizations
This commit is contained in:
committed by
Mathias Agopian
parent
a5addd2257
commit
6ea8ed07ed
@@ -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.
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user