Add new Shadows uniform buffer (#2194)

This commit is contained in:
Ben Doherty
2020-03-03 14:25:04 -08:00
committed by GitHub
parent 6878d0d6e6
commit 94b1ad52fa
8 changed files with 39 additions and 3 deletions

View File

@@ -24,7 +24,6 @@ namespace metal {
MetalBuffer::MetalBuffer(MetalContext& context, size_t size, bool forceGpuBuffer)
: mBufferSize(size), mContext(context) {
assert(size > 0);
// If the buffer is less than 4K in size, we don't use an explicit buffer and instead use
// immediate command encoder methods like setVertexBytes:length:atIndex:.
// TODO: we shouldn't do this if the data persists for multiple uses.

View File

@@ -332,6 +332,7 @@ backend::Handle<backend::HwProgram> FMaterial::getSurfaceProgramSlow(uint8_t var
pb
.setUniformBlock(BindingPoints::PER_VIEW, UibGenerator::getPerViewUib().getName())
.setUniformBlock(BindingPoints::LIGHTS, UibGenerator::getLightsUib().getName())
.setUniformBlock(BindingPoints::SHADOW, UibGenerator::getShadowUib().getName())
.setUniformBlock(BindingPoints::PER_RENDERABLE, UibGenerator::getPerRenderableUib().getName())
.setUniformBlock(BindingPoints::PER_MATERIAL_INSTANCE, mUniformInterfaceBlock.getName());

View File

@@ -56,6 +56,7 @@ namespace details {
FView::FView(FEngine& engine)
: mFroxelizer(engine),
mPerViewUb(PerViewUib::getUib().getSize()),
mShadowUb(ShadowUib::getUib().getSize()),
mPerViewSb(PerViewSib::SAMPLER_COUNT),
mDirectionalShadowMap(engine) {
DriverApi& driver = engine.getDriverApi();
@@ -77,6 +78,7 @@ FView::FView(FEngine& engine)
// allocate ubos
mPerViewUbh = driver.createUniformBuffer(mPerViewUb.getSize(), backend::BufferUsage::DYNAMIC);
mLightUbh = driver.createUniformBuffer(CONFIG_MAX_LIGHT_COUNT * sizeof(LightsUib), backend::BufferUsage::DYNAMIC);
mShadowUbh = driver.createUniformBuffer(mShadowUb.getSize(), backend::BufferUsage::DYNAMIC);
mIsDynamicResolutionSupported = driver.isFrameTimeSupported();
}
@@ -88,6 +90,7 @@ void FView::terminate(FEngine& engine) {
DriverApi& driver = engine.getDriverApi();
driver.destroyUniformBuffer(mPerViewUbh);
driver.destroyUniformBuffer(mLightUbh);
driver.destroyUniformBuffer(mShadowUbh);
driver.destroySamplerGroup(mPerViewSbh);
driver.destroyUniformBuffer(mRenderableUbh);
mDirectionalShadowMap.terminate(driver);
@@ -691,6 +694,10 @@ void FView::commitUniforms(backend::DriverApi& driver) const noexcept {
driver.loadUniformBuffer(mPerViewUbh, mPerViewUb.toBufferDescriptor(driver));
}
if (mShadowUb.isDirty()) {
driver.loadUniformBuffer(mShadowUbh, mShadowUb.toBufferDescriptor(driver));
}
if (mPerViewSb.isDirty()) {
driver.updateSamplerGroup(mPerViewSbh, std::move(mPerViewSb.toCommandStream()));
}

View File

@@ -338,6 +338,7 @@ private:
void bindPerViewUniformsAndSamplers(FEngine::DriverApi& driver) const noexcept {
driver.bindUniformBuffer(BindingPoints::PER_VIEW, mPerViewUbh);
driver.bindUniformBuffer(BindingPoints::LIGHTS, mLightUbh);
driver.bindUniformBuffer(BindingPoints::SHADOW, mShadowUbh);
driver.bindSamplers(BindingPoints::PER_VIEW, mPerViewSbh);
}
@@ -350,6 +351,7 @@ private:
backend::Handle<backend::HwSamplerGroup> mPerViewSbh;
backend::Handle<backend::HwUniformBuffer> mPerViewUbh;
backend::Handle<backend::HwUniformBuffer> mLightUbh;
backend::Handle<backend::HwUniformBuffer> mShadowUbh;
backend::Handle<backend::HwUniformBuffer> mRenderableUbh;
backend::Handle<backend::HwSamplerGroup> getUsh() const noexcept { return mPerViewSbh; }
@@ -399,6 +401,7 @@ private:
RenderQuality mRenderQuality;
mutable UniformBuffer mPerViewUb;
mutable UniformBuffer mShadowUb;
mutable backend::SamplerGroup mPerViewSb;
utils::CString mName;

View File

@@ -35,7 +35,7 @@ namespace BindingPoints {
constexpr uint8_t PER_RENDERABLE = 1; // uniforms/samplers updated per renderable
constexpr uint8_t PER_RENDERABLE_BONES = 2; // bones data, per renderable
constexpr uint8_t LIGHTS = 3; // lights data array
constexpr uint8_t POST_PROCESS_DEPRECATED = 4; // deprecated
constexpr uint8_t SHADOW = 4; // punctual shadow data
constexpr uint8_t PER_MATERIAL_INSTANCE = 5; // uniforms/samplers updates per material
constexpr uint8_t COUNT = 6;
// These are limited by Program::UNIFORM_BINDING_COUNT (currently 6)
@@ -53,7 +53,7 @@ constexpr size_t CONFIG_MAX_LIGHT_INDEX = CONFIG_MAX_LIGHT_COUNT - 1;
// Light space coordinates are computed in the vertex shader and interpolated across fragments.
// Thus, each additional shadow-casting spot light adds 4 additional varying components. Higher
// values may cause the number of varyings to exceed the driver limit.
constexpr size_t CONFIG_MAX_SHADOW_CASTING_SPOTS = 0;
constexpr size_t CONFIG_MAX_SHADOW_CASTING_SPOTS = 2;
// This value is also limited by UBO size, ES3.0 only guarantees 16 KiB.
// We store 64 bytes per bone.

View File

@@ -21,6 +21,8 @@
#include <math/mat4.h>
#include <math/vec4.h>
#include <private/filament/EngineEnums.h>
namespace filament {
class UniformInterfaceBlock;
@@ -30,6 +32,7 @@ public:
static UniformInterfaceBlock const& getPerViewUib() noexcept;
static UniformInterfaceBlock const& getPerRenderableUib() noexcept;
static UniformInterfaceBlock const& getLightsUib() noexcept;
static UniformInterfaceBlock const& getShadowUib() noexcept;
static UniformInterfaceBlock const& getPerRenderableBonesUib() noexcept;
};
@@ -112,6 +115,16 @@ struct LightsUib {
filament::math::float4 spotScaleOffset; // { scale, offset, unused, unused }
};
// UBO for punctual (spot light) shadows.
struct ShadowUib {
static const UniformInterfaceBlock& getUib() noexcept {
return UibGenerator::getShadowUib();
}
filament::math::mat4f spotLightFromWorldMatrix[CONFIG_MAX_SHADOW_CASTING_SPOTS];
filament::math::float4 directionShadowBias[CONFIG_MAX_SHADOW_CASTING_SPOTS]; // light direction, normal bias
};
// This is not the UBO proper, but just an element of a bone array.
struct PerRenderableUibBone {
filament::math::quatf q = { 1, 0, 0, 0 };

View File

@@ -107,6 +107,15 @@ UniformInterfaceBlock const& UibGenerator::getLightsUib() noexcept {
return uib;
}
UniformInterfaceBlock const& UibGenerator::getShadowUib() noexcept {
static UniformInterfaceBlock uib = UniformInterfaceBlock::Builder()
.name("ShadowUniforms")
.add("spotLightFromWorldMatrix", CONFIG_MAX_SHADOW_CASTING_SPOTS, UniformInterfaceBlock::Type::MAT4, Precision::HIGH)
.add("directionShadowBias", CONFIG_MAX_SHADOW_CASTING_SPOTS, UniformInterfaceBlock::Type::FLOAT4, Precision::HIGH)
.build();
return uib;
}
UniformInterfaceBlock const& UibGenerator::getPerRenderableBonesUib() noexcept {
static UniformInterfaceBlock uib = UniformInterfaceBlock::Builder()
.name("BonesUniforms")

View File

@@ -205,6 +205,10 @@ const std::string ShaderGenerator::createVertexProgram(filament::backend::Shader
BindingPoints::PER_VIEW, UibGenerator::getPerViewUib());
cg.generateUniforms(vs, ShaderType::VERTEX,
BindingPoints::PER_RENDERABLE, UibGenerator::getPerRenderableUib());
if (litVariants && variant.hasShadowReceiver()) {
cg.generateUniforms(vs, ShaderType::VERTEX,
BindingPoints::SHADOW, UibGenerator::getShadowUib());
}
if (variant.hasSkinningOrMorphing()) {
cg.generateUniforms(vs, ShaderType::VERTEX,
BindingPoints::PER_RENDERABLE_BONES,