Add new Shadows uniform buffer (#2194)
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user