Merge branch 'main' into ma/descriptor-sets

This commit is contained in:
Mathias Agopian
2024-08-19 17:13:44 -07:00
committed by GitHub
30 changed files with 214 additions and 90 deletions
@@ -1150,7 +1150,7 @@ struct RasterState {
bool inverseFrontFaces : 1; // 31
//! padding, must be 0
uint8_t padding : 1; // 32
bool depthClamp : 1; // 32
};
uint32_t u = 0;
};
@@ -354,6 +354,7 @@ DECL_DRIVER_API_SYNCHRONOUS_0(bool, isParallelShaderCompileSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isDepthStencilResolveSupported)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isDepthStencilBlitSupported, backend::TextureFormat, format)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isProtectedTexturesSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isDepthClampSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(uint8_t, getMaxDrawBuffers)
DECL_DRIVER_API_SYNCHRONOUS_0(size_t, getMaxUniformBufferSize)
DECL_DRIVER_API_SYNCHRONOUS_0(math::float2, getClipSpaceParams)
@@ -166,6 +166,7 @@ struct MetalContext {
std::array<BufferState, MAX_SSBO_COUNT> ssboState;
CullModeStateTracker cullModeState;
WindingStateTracker windingState;
DepthClampStateTracker depthClampState;
Handle<HwRenderPrimitive> currentRenderPrimitive;
// State caches.
+11
View File
@@ -1061,6 +1061,10 @@ bool MetalDriver::isProtectedTexturesSupported() {
return false;
}
bool MetalDriver::isDepthClampSupported() {
return true;
}
bool MetalDriver::isWorkaroundNeeded(Workaround workaround) {
switch (workaround) {
case Workaround::SPLIT_EASU:
@@ -1957,6 +1961,13 @@ void MetalDriver::bindPipeline(PipelineState const& ps) {
[mContext->currentRenderPassEncoder setFrontFacingWinding:winding];
}
// depth clip mode
MTLDepthClipMode depthClipMode = rs.depthClamp ? MTLDepthClipModeClamp : MTLDepthClipModeClip;
mContext->depthClampState.updateState(depthClipMode);
if (mContext->depthClampState.stateChanged()) {
[mContext->currentRenderPassEncoder setDepthClipMode:depthClipMode];
}
// Set the depth-stencil state, if a state change is needed.
DepthStencilState depthState;
if (depthAttachment) {
+1
View File
@@ -379,6 +379,7 @@ using SamplerStateCache = StateCache<SamplerState, id<MTLSamplerState>, SamplerS
using CullModeStateTracker = StateTracker<MTLCullMode>;
using WindingStateTracker = StateTracker<MTLWinding>;
using DepthClampStateTracker = StateTracker<MTLDepthClipMode>;
// Argument encoder
+4
View File
@@ -208,6 +208,10 @@ bool NoopDriver::isProtectedTexturesSupported() {
return true;
}
bool NoopDriver::isDepthClampSupported() {
return false;
}
bool NoopDriver::isWorkaroundNeeded(Workaround) {
return false;
}
@@ -679,6 +679,7 @@ void OpenGLContext::initExtensionsGLES(Extensions* ext, GLint major, GLint minor
#ifndef __EMSCRIPTEN__
ext->EXT_debug_marker = exts.has("GL_EXT_debug_marker"sv);
#endif
ext->EXT_depth_clamp = exts.has("GL_EXT_depth_clamp"sv);
ext->EXT_discard_framebuffer = exts.has("GL_EXT_discard_framebuffer"sv);
#ifndef __EMSCRIPTEN__
ext->EXT_disjoint_timer_query = exts.has("GL_EXT_disjoint_timer_query"sv);
@@ -749,6 +750,7 @@ void OpenGLContext::initExtensionsGL(Extensions* ext, GLint major, GLint minor)
ext->EXT_color_buffer_half_float = true; // Assumes core profile.
ext->EXT_clip_cull_distance = true;
ext->EXT_debug_marker = exts.has("GL_EXT_debug_marker"sv);
ext->EXT_depth_clamp = true;
ext->EXT_discard_framebuffer = false;
ext->EXT_disjoint_timer_query = true;
ext->EXT_multisampled_render_to_texture = false;
+6 -4
View File
@@ -224,8 +224,9 @@ public:
bool EXT_color_buffer_float;
bool EXT_color_buffer_half_float;
bool EXT_debug_marker;
bool EXT_disjoint_timer_query;
bool EXT_depth_clamp;
bool EXT_discard_framebuffer;
bool EXT_disjoint_timer_query;
bool EXT_multisampled_render_to_texture2;
bool EXT_multisampled_render_to_texture;
bool EXT_protected_textures;
@@ -243,10 +244,10 @@ public:
bool KHR_parallel_shader_compile;
bool KHR_texture_compression_astc_hdr;
bool KHR_texture_compression_astc_ldr;
bool OES_depth_texture;
bool OES_depth24;
bool OES_packed_depth_stencil;
bool OES_EGL_image_external_essl3;
bool OES_depth24;
bool OES_depth_texture;
bool OES_packed_depth_stencil;
bool OES_rgb8_rgba8;
bool OES_standard_derivatives;
bool OES_texture_npot;
@@ -631,6 +632,7 @@ constexpr size_t OpenGLContext::getIndexForCap(GLenum cap) noexcept { //NOLINT
#ifdef BACKEND_OPENGL_VERSION_GL
case GL_PROGRAM_POINT_SIZE: index = 10; break;
#endif
case GL_DEPTH_CLAMP: index = 11; break;
default: break;
}
assert_invariant(index < state.enables.caps.size());
@@ -462,6 +462,14 @@ void OpenGLDriver::setRasterState(RasterState rs) noexcept {
} else {
gl.disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
}
if (gl.ext.EXT_depth_clamp) {
if (rs.depthClamp) {
gl.enable(GL_DEPTH_CLAMP);
} else {
gl.disable(GL_DEPTH_CLAMP);
}
}
}
void OpenGLDriver::setStencilState(StencilState ss) noexcept {
@@ -2246,6 +2254,10 @@ bool OpenGLDriver::isProtectedTexturesSupported() {
return getContext().ext.EXT_protected_textures;
}
bool OpenGLDriver::isDepthClampSupported() {
return getContext().ext.EXT_depth_clamp;
}
bool OpenGLDriver::isWorkaroundNeeded(Workaround workaround) {
switch (workaround) {
case Workaround::SPLIT_EASU:
+6
View File
@@ -201,6 +201,12 @@ using namespace glext;
# define GL_CLIP_DISTANCE1 0x3001
#endif
#if defined(GL_EXT_depth_clamp)
# define GL_DEPTH_CLAMP GL_DEPTH_CLAMP_EXT
#else
# define GL_DEPTH_CLAMP 0x864F
#endif
#if defined(GL_KHR_debug)
# define GL_DEBUG_OUTPUT GL_DEBUG_OUTPUT_KHR
# define GL_DEBUG_OUTPUT_SYNCHRONOUS GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR
@@ -125,6 +125,10 @@ public:
return mPhysicalDeviceFeatures.imageCubeArray == VK_TRUE;
}
inline bool isDepthClampSupported() const noexcept {
return mPhysicalDeviceFeatures.depthClamp == VK_TRUE;
}
inline bool isDebugMarkersSupported() const noexcept {
return mDebugMarkersSupported;
}
@@ -1038,6 +1038,10 @@ bool VulkanDriver::isProtectedTexturesSupported() {
return false;
}
bool VulkanDriver::isDepthClampSupported() {
return mContext.isDepthClampSupported();
}
bool VulkanDriver::isWorkaroundNeeded(Workaround workaround) {
switch (workaround) {
case Workaround::SPLIT_EASU: {
@@ -1823,6 +1827,8 @@ void VulkanDriver::bindPipeline(PipelineState const& pipelineState) {
.dstAlphaBlendFactor = getBlendFactor(rasterState.blendFunctionDstAlpha),
.colorWriteMask = (VkColorComponentFlags) (rasterState.colorWrite ? 0xf : 0x0),
.rasterizationSamples = rt->getSamples(),
.depthClamp = rasterState.depthClamp,
.reserved = 0,
.colorTargetCount = rt->getColorTargetCount(mCurrentRenderPass),
.colorBlendOp = rasterState.blendEquationRGB,
.alphaBlendOp = rasterState.blendEquationAlpha,
@@ -184,6 +184,7 @@ VulkanPipelineCache::PipelineCacheEntry* VulkanPipelineCache::createPipeline() n
vkRaster.polygonMode = VK_POLYGON_MODE_FILL;
vkRaster.cullMode = raster.cullMode;
vkRaster.frontFace = raster.frontFace;
vkRaster.depthClampEnable = raster.depthClamp;
vkRaster.depthBiasEnable = raster.depthBiasEnable;
vkRaster.depthBiasConstantFactor = raster.depthBiasConstantFactor;
vkRaster.depthBiasClamp = 0.0f;
@@ -90,7 +90,9 @@ public:
VkBlendFactor srcAlphaBlendFactor : 5;
VkBlendFactor dstAlphaBlendFactor : 5;
VkColorComponentFlags colorWriteMask : 4;
uint8_t rasterizationSamples; // offset = 4 bytes
uint8_t rasterizationSamples : 4;// offset = 4 bytes
uint8_t depthClamp : 1;
uint8_t reserved : 3;
uint8_t colorTargetCount; // offset = 5 bytes
BlendEquation colorBlendOp : 4; // offset = 6 bytes
BlendEquation alphaBlendOp : 4;
@@ -325,6 +325,7 @@ VkDevice createLogicalDevice(VkPhysicalDevice physicalDevice,
// We could simply enable all supported features, but since that may have performance
// consequences let's just enable the features we need.
VkPhysicalDeviceFeatures enabledFeatures{
.depthClamp = features.depthClamp,
.samplerAnisotropy = features.samplerAnisotropy,
.textureCompressionETC2 = features.textureCompressionETC2,
.textureCompressionBC = features.textureCompressionBC,
+2 -1
View File
@@ -24,6 +24,7 @@
#include <utils/compiler.h>
#include <utils/Entity.h>
#include <utils/FixedCapacityVector.h>
#include <math/mathfwd.h>
@@ -727,7 +728,7 @@ public:
void setDebugCamera(Camera* UTILS_NULLABLE camera) noexcept;
//! debugging: returns a Camera from the point of view of *the* dominant directional light used for shadowing.
Camera const* UTILS_NULLABLE getDirectionalShadowCamera() const noexcept;
utils::FixedCapacityVector<Camera const*> getDirectionalShadowCameras() const noexcept;
/** Result of a picking query */
+9 -2
View File
@@ -449,7 +449,8 @@ RenderPass::Command* RenderPass::instanceify(FEngine& engine,
UTILS_ALWAYS_INLINE // This function exists only to make the code more readable. we want it inlined.
inline // and we don't need it in the compilation unit
void RenderPass::setupColorCommand(Command& cmdDraw, Variant variant,
FMaterialInstance const* const UTILS_RESTRICT mi, bool inverseFrontFaces) noexcept {
FMaterialInstance const* const UTILS_RESTRICT mi,
bool inverseFrontFaces, bool hasDepthClamp) noexcept {
FMaterial const * const UTILS_RESTRICT ma = mi->getMaterial();
variant = Variant::filterVariant(variant, ma->isVariantLit());
@@ -490,6 +491,7 @@ void RenderPass::setupColorCommand(Command& cmdDraw, Variant variant,
cmdDraw.info.rasterState.colorWrite = mi->isColorWriteEnabled();
cmdDraw.info.rasterState.depthWrite = mi->isDepthWriteEnabled();
cmdDraw.info.rasterState.depthFunc = mi->getDepthFunc();
cmdDraw.info.rasterState.depthClamp = hasDepthClamp;
cmdDraw.info.materialVariant = variant;
// we keep "RasterState::colorWrite" to the value set by material (could be disabled)
}
@@ -587,6 +589,9 @@ RenderPass::Command* RenderPass::generateCommandsImpl(RenderPass::CommandTypeFla
bool const hasInstancedStereo =
renderFlags & IS_INSTANCED_STEREOSCOPIC;
bool const hasDepthClamp =
renderFlags & HAS_DEPTH_CLAMP;
float const cameraPositionDotCameraForward = dot(cameraPosition, cameraForward);
auto const* const UTILS_RESTRICT soaWorldAABBCenter = soa.data<FScene::WORLD_AABB_CENTER>();
@@ -607,6 +612,7 @@ RenderPass::Command* RenderPass::generateCommandsImpl(RenderPass::CommandTypeFla
cmd.info.rasterState.depthWrite = true;
cmd.info.rasterState.depthFunc = RasterState::DepthFunc::GE;
cmd.info.rasterState.alphaToCoverage = false;
cmd.info.rasterState.depthClamp = hasDepthClamp;
}
for (uint32_t i = range.first; i < range.last; ++i) {
@@ -722,7 +728,8 @@ RenderPass::Command* RenderPass::generateCommandsImpl(RenderPass::CommandTypeFla
// morphing.morphTargetBuffer->getHwHandle() : SamplerGroupHandle{};
if constexpr (isColorPass) {
RenderPass::setupColorCommand(cmd, renderableVariant, mi, inverseFrontFaces);
RenderPass::setupColorCommand(cmd, renderableVariant, mi,
inverseFrontFaces, hasDepthClamp);
const bool blendPass = Pass(cmd.key & PASS_MASK) == Pass::BLENDED;
if (blendPass) {
// TODO: at least for transparent objects, AABB should be per primitive
+2 -1
View File
@@ -285,6 +285,7 @@ public:
static constexpr RenderFlags HAS_SHADOWING = 0x01;
static constexpr RenderFlags HAS_INVERSE_FRONT_FACES = 0x02;
static constexpr RenderFlags IS_INSTANCED_STEREOSCOPIC = 0x04;
static constexpr RenderFlags HAS_DEPTH_CLAMP = 0x08;
// Arena used for commands
using Arena = utils::Arena<
@@ -453,7 +454,7 @@ private:
uint8_t instancedStereoEyeCount) noexcept;
static void setupColorCommand(Command& cmdDraw, Variant variant,
FMaterialInstance const* mi, bool inverseFrontFaces) noexcept;
FMaterialInstance const* mi, bool inverseFrontFaces, bool hasDepthClamp) noexcept;
static void updateSummedPrimitiveCounts(
FScene::RenderableSoa& renderableData, utils::Range<uint32_t> vr) noexcept;
+6 -6
View File
@@ -829,13 +829,13 @@ ShadowMap::Corners ShadowMap::computeFrustumCorners(
Corners const csViewFrustumCorners = {
.vertices = {
{ -1, -1, far },
{ 1, -1, far },
{ -1, 1, far },
{ 1, 1, far },
{ 1, -1, far },
{ -1, 1, far },
{ 1, 1, far },
{ -1, -1, near },
{ 1, -1, near },
{ -1, 1, near },
{ 1, 1, near },
{ 1, -1, near },
{ -1, 1, near },
{ 1, 1, near },
}
};
+26 -5
View File
@@ -66,15 +66,15 @@ namespace filament {
using namespace backend;
using namespace math;
// do this only if depth-clamp is available
static constexpr bool USE_DEPTH_CLAMP = false;
ShadowMapManager::ShadowMapManager(FEngine& engine) {
ShadowMapManager::ShadowMapManager(FEngine& engine)
: mIsDepthClampSupported(engine.getDriverApi().isDepthClampSupported()) {
FDebugRegistry& debugRegistry = engine.getDebugRegistry();
debugRegistry.registerProperty("d.shadowmap.visualize_cascades",
&engine.debug.shadowmap.visualize_cascades);
debugRegistry.registerProperty("d.shadowmap.disable_light_frustum_align",
&engine.debug.shadowmap.disable_light_frustum_align);
debugRegistry.registerProperty("d.shadowmap.depth_clamp",
&engine.debug.shadowmap.depth_clamp);
}
ShadowMapManager::~ShadowMapManager() {
@@ -367,7 +367,16 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FEngine& engine, FrameG
// generate and sort the commands for rendering the shadow map
RenderPass::RenderFlags renderPassFlags{};
if (view.isFrontFaceWindingInverted()) {
renderPassFlags |= RenderPass::HAS_INVERSE_FRONT_FACES;
}
if (mIsDepthClampSupported && engine.debug.shadowmap.depth_clamp) {
renderPassFlags |= RenderPass::HAS_DEPTH_CLAMP;
}
RenderPass const pass = passBuilder
.renderFlags(renderPassFlags)
.camera(cameraInfo)
.visibilityMask(entry.visibilityMask)
.geometry(scene->getRenderableData(), entry.range)
@@ -638,7 +647,8 @@ ShadowMapManager::ShadowTechnique ShadowMapManager::updateCascadeShadowMaps(FEng
updateNearFarPlanes(&cameraInfo.cullingProjection, cameraInfo.zn, cameraInfo.zf);
auto shaderParameters = shadowMap.updateDirectional(engine,
lightData, 0, cameraInfo, shadowMapInfo, sceneInfo, USE_DEPTH_CLAMP);
lightData, 0, cameraInfo, shadowMapInfo, sceneInfo,
mIsDepthClampSupported && engine.debug.shadowmap.depth_clamp);
if (shadowMap.hasVisibleShadows()) {
const size_t shadowIndex = shadowMap.getShadowIndex();
@@ -1072,4 +1082,15 @@ void ShadowMapManager::updateNearFarPlanes(mat4f* projection,
p[3].z = (sf * F.w - sn * N.w) * 0.5f;
}
utils::FixedCapacityVector<Camera const*>
ShadowMapManager::getDirectionalShadowCameras() const noexcept {
if (!mInitialized) return {};
auto const csm = getCascadedShadowMap();
auto result = utils::FixedCapacityVector<Camera const*>::with_capacity(csm.size());
for (ShadowMap const& sm : csm) {
result.push_back(sm.hasVisibleShadows() ? sm.getDebugCamera() : nullptr);
}
return result;
}
} // namespace filament
+9 -5
View File
@@ -40,6 +40,7 @@
#include <utils/BitmaskEnum.h>
#include <utils/compiler.h>
#include <utils/FixedCapacityVector.h>
#include <utils/debug.h>
#include <utils/Range.h>
#include <utils/Slice.h>
@@ -58,6 +59,7 @@
namespace filament {
class Camera;
class FCamera;
class FView;
class FrameGraph;
@@ -138,10 +140,7 @@ public:
bool hasSpotShadows() const { return !mSpotShadowMapCount; }
// for debugging only
FCamera const* getDirectionalShadowCamera() const noexcept {
if (!mInitialized) return nullptr;
return getShadowMap(0).getDebugCamera();
}
utils::FixedCapacityVector<Camera const*> getDirectionalShadowCameras() const noexcept;
private:
explicit ShadowMapManager(FEngine& engine);
@@ -233,6 +232,7 @@ private:
ShadowMapCacheContainer mShadowMapCache;
uint32_t mDirectionalShadowMapCount = 0;
uint32_t mSpotShadowMapCount = 0;
bool const mIsDepthClampSupported;
bool mInitialized = false;
ShadowMap& getShadowMap(size_t index) noexcept {
@@ -245,10 +245,14 @@ private:
}
utils::Slice<ShadowMap> getCascadedShadowMap() noexcept {
ShadowMap* const p = &getShadowMap(0);
ShadowMap const* const p = &getShadowMap(0);
return { p, mDirectionalShadowMapCount };
}
utils::Slice<ShadowMap> getCascadedShadowMap() const noexcept {
return const_cast<ShadowMapManager*>(this)->getCascadedShadowMap();
}
utils::Slice<ShadowMap> getSpotShadowMaps() noexcept {
ShadowMap* const p = &getShadowMap(CONFIG_MAX_SHADOW_CASCADES);
return { p, mSpotShadowMapCount };
+2 -2
View File
@@ -73,8 +73,8 @@ const char* View::getName() const noexcept {
return downcast(this)->getName();
}
Camera const* View::getDirectionalShadowCamera() const noexcept {
return downcast(this)->getDirectionalShadowCamera();
utils::FixedCapacityVector<Camera const*> View::getDirectionalShadowCameras() const noexcept {
return downcast(this)->getDirectionalShadowCameras();
}
void View::setShadowingEnabled(bool enabled) noexcept {
+8 -16
View File
@@ -28,12 +28,6 @@
#include <string_view>
#include <utility>
#ifndef NDEBUG
# define DEBUG_PROPERTIES_WRITABLE true
#else
# define DEBUG_PROPERTIES_WRITABLE false
#endif
using namespace filament::math;
using namespace utils;
@@ -79,17 +73,15 @@ bool FDebugRegistry::hasProperty(const char* name) const noexcept {
template<typename T>
bool FDebugRegistry::setProperty(const char* name, T v) noexcept {
if constexpr (DEBUG_PROPERTIES_WRITABLE) {
auto info = getPropertyInfo(name);
T* const addr = static_cast<T*>(info.first);
if (addr) {
auto old = *addr;
*addr = v;
if (info.second && old != v) {
info.second();
}
return true;
auto info = getPropertyInfo(name);
T* const addr = static_cast<T*>(info.first);
if (addr) {
auto old = *addr;
*addr = v;
if (info.second && old != v) {
info.second();
}
return true;
}
return false;
}
+1
View File
@@ -617,6 +617,7 @@ public:
bool focus_shadowcasters = true;
bool visualize_cascades = false;
bool disable_light_frustum_align = false;
bool depth_clamp = true;
float dzn = -1.0f;
float dzf = 1.0f;
float display_shadow_texture_scale = 0.25f;
+3 -3
View File
@@ -212,9 +212,9 @@ public:
void setStereoscopicOptions(StereoscopicOptions const& options) noexcept;
FCamera const* getDirectionalShadowCamera() const noexcept {
if (!mShadowMapManager) return nullptr;
return mShadowMapManager->getDirectionalShadowCamera();
utils::FixedCapacityVector<Camera const*> getDirectionalShadowCameras() const noexcept {
if (!mShadowMapManager) return {};
return mShadowMapManager->getDirectionalShadowCameras();
}
void setRenderTarget(FRenderTarget* renderTarget) noexcept {
+8 -2
View File
@@ -28,8 +28,14 @@
class Cube {
public:
Cube(filament::Engine& engine, filament::Material const* material, filament::math::float3 linearColor, bool culling = true);
Cube(Cube const&) = delete;
Cube& operator=(Cube const&) = delete;
Cube(Cube&& rhs) noexcept;
utils::Entity getSolidRenderable() {
return mSolidRenderable;
}
@@ -55,8 +61,8 @@ private:
filament::Material const* mMaterial = nullptr;
filament::MaterialInstance* mMaterialInstanceSolid = nullptr;
filament::MaterialInstance* mMaterialInstanceWireFrame = nullptr;
utils::Entity mSolidRenderable;
utils::Entity mWireFrameRenderable;
utils::Entity mSolidRenderable{};
utils::Entity mWireFrameRenderable{};
};
@@ -211,11 +211,11 @@ private:
filament::Camera* mOrthoCamera;
std::vector<std::unique_ptr<CView>> mViews;
CView* mMainView;
CView* mUiView;
CView* mMainView; // well, the main view
CView* mUiView; // the imgui ui
CView* mDepthView;
GodView* mGodView;
CView* mOrthoView;
GodView* mGodView; // the debug view with "god" camera
CView* mOrthoView; // directional shadow map view
size_t mWidth = 0;
size_t mHeight = 0;
+14 -2
View File
@@ -104,11 +104,23 @@ Cube::Cube(Engine& engine, filament::Material const* material, float3 linearColo
.build(engine, mWireFrameRenderable);
}
Cube::Cube(Cube&& rhs) noexcept
: mEngine(rhs.mEngine) {
using std::swap;
swap(rhs.mVertexBuffer, mVertexBuffer);
swap(rhs.mIndexBuffer, mIndexBuffer);
swap(rhs.mMaterial, mMaterial);
swap(rhs.mMaterialInstanceSolid, mMaterialInstanceSolid);
swap(rhs.mMaterialInstanceWireFrame, mMaterialInstanceWireFrame);
swap(rhs.mSolidRenderable, mSolidRenderable);
swap(rhs.mWireFrameRenderable, mWireFrameRenderable);
}
void Cube::mapFrustum(filament::Engine& engine, Camera const* camera) {
// the Camera far plane is at infinity, but we want it closer for display
const mat4 vm(camera->getModelMatrix());
mat4 p(vm * inverse(camera->getCullingProjectionMatrix()));
return mapFrustum(engine, p);
mapFrustum(engine, p);
}
void Cube::mapFrustum(filament::Engine& engine, filament::math::mat4 const& transform) {
@@ -122,7 +134,7 @@ void Cube::mapFrustum(filament::Engine& engine, filament::math::mat4 const& tran
void Cube::mapAabb(filament::Engine& engine, filament::Box const& box) {
mat4 p = mat4::translation(box.center) * mat4::scaling(box.halfExtent);
return mapFrustum(engine, p);
mapFrustum(engine, p);
}
Cube::~Cube() {
+58 -35
View File
@@ -1,4 +1,3 @@
#include <memory>
/*
* Copyright (C) 2015 The Android Open Source Project
@@ -56,6 +55,13 @@
#include <stb_image.h>
#include <algorithm>
#include <cstdlib>
#include <memory>
#include <vector>
#include <stdint.h>
#include "generated/resources/filamentapp.h"
using namespace filament;
@@ -138,10 +144,17 @@ void FilamentApp::run(const Config& config, SetupCallback setupCallback,
.package(FILAMENTAPP_TRANSPARENTCOLOR_DATA, FILAMENTAPP_TRANSPARENTCOLOR_SIZE)
.build(*mEngine);
std::unique_ptr<Cube> cameraCube(new Cube(*mEngine, mTransparentMaterial, {1,0,0}));
std::unique_ptr<Cube> cameraCube{ new Cube(*mEngine, mTransparentMaterial, { 1, 0, 0 }) };
// we can't cull the light-frustum because it's not applied a rigid transform
// and currently, filament assumes that for culling
std::unique_ptr<Cube> lightmapCube(new Cube(*mEngine, mTransparentMaterial, {0,1,0}, false));
std::vector<Cube> lightmapCubes;
lightmapCubes.reserve(4);
lightmapCubes.emplace_back(*mEngine, mTransparentMaterial, float3{ 0, 1, 0 }, false);
lightmapCubes.emplace_back(*mEngine, mTransparentMaterial, float3{ 0, 0, 1 }, false);
lightmapCubes.emplace_back(*mEngine, mTransparentMaterial, float3{ 1, 1, 0 }, false);
lightmapCubes.emplace_back(*mEngine, mTransparentMaterial, float3{ 1, 0, 0 }, false);
mScene = mEngine->createScene();
window->mMainView->getView()->setVisibleLayers(0x4, 0x4);
@@ -151,16 +164,15 @@ void FilamentApp::run(const Config& config, SetupCallback setupCallback,
rcm.setLayerMask(rcm.getInstance(cameraCube->getSolidRenderable()), 0x3, 0x2);
rcm.setLayerMask(rcm.getInstance(cameraCube->getWireFrameRenderable()), 0x3, 0x2);
rcm.setLayerMask(rcm.getInstance(lightmapCube->getSolidRenderable()), 0x3, 0x2);
rcm.setLayerMask(rcm.getInstance(lightmapCube->getWireFrameRenderable()), 0x3, 0x2);
// Create the camera mesh
mScene->addEntity(cameraCube->getWireFrameRenderable());
mScene->addEntity(cameraCube->getSolidRenderable());
mScene->addEntity(lightmapCube->getWireFrameRenderable());
mScene->addEntity(lightmapCube->getSolidRenderable());
for (auto&& cube : lightmapCubes) {
rcm.setLayerMask(rcm.getInstance(cube.getSolidRenderable()), 0x3, 0x2);
rcm.setLayerMask(rcm.getInstance(cube.getWireFrameRenderable()), 0x3, 0x2);
mScene->addEntity(cube.getWireFrameRenderable());
mScene->addEntity(cube.getSolidRenderable());
}
window->mDepthView->getView()->setVisibleLayers(0x4, 0x4);
window->mGodView->getView()->setVisibleLayers(0x6, 0x6);
@@ -425,10 +437,26 @@ void FilamentApp::run(const Config& config, SetupCallback setupCallback,
window->mDebugCamera->lookAt(eye, center, up);
// Update the cube distortion matrix used for frustum visualization.
const Camera* lightmapCamera = window->mMainView->getView()->getDirectionalShadowCamera();
if (lightmapCamera) {
lightmapCube->mapFrustum(*mEngine, lightmapCamera);
auto& rcm = mEngine->getRenderableManager();
auto const csm = window->mMainView->getView()->getDirectionalShadowCameras();
// show/hide the cascades
for (size_t i = 0 ; i < 4; i++) {
rcm.setLayerMask(rcm.getInstance(lightmapCubes[i].getSolidRenderable()), 0x3, 0x0);
rcm.setLayerMask(rcm.getInstance(lightmapCubes[i].getWireFrameRenderable()), 0x3, 0x0);
}
if (!csm.empty()) {
for (size_t i = 0, c = csm.size(); i < c; i++) {
if (csm[i]) {
lightmapCubes[i].mapFrustum(*mEngine, csm[i]);
}
uint8_t const layer = csm[i] ? 0x2 : 0x0;
rcm.setLayerMask(rcm.getInstance(lightmapCubes[i].getSolidRenderable()),
0x3, layer);
rcm.setLayerMask(rcm.getInstance(lightmapCubes[i].getWireFrameRenderable()),
0x3, layer);
}
}
cameraCube->mapFrustum(*mEngine, window->mMainCamera);
// Delay rendering for roughly one monitor refresh interval
@@ -452,11 +480,14 @@ void FilamentApp::run(const Config& config, SetupCallback setupCallback,
if (config.splitView) {
if(!window->mOrthoView->getView()->hasCamera()) {
Camera const* debugDirectionalShadowCamera =
window->mMainView->getView()->getDirectionalShadowCamera();
if (debugDirectionalShadowCamera) {
window->mOrthoView->setCamera(
const_cast<Camera*>(debugDirectionalShadowCamera));
auto const csm = window->mMainView->getView()->getDirectionalShadowCameras();
if (!csm.empty()) {
// here we could choose the cascade
Camera const* debugDirectionalShadowCamera = csm[0];
if (debugDirectionalShadowCamera) {
window->mOrthoView->setCamera(
const_cast<Camera*>(debugDirectionalShadowCamera));
}
}
}
}
@@ -484,7 +515,7 @@ void FilamentApp::run(const Config& config, SetupCallback setupCallback,
cleanupCallback(mEngine, window->mMainView->getView(), mScene);
cameraCube.reset();
lightmapCube.reset();
lightmapCubes.clear();
window.reset();
mIBL.reset();
@@ -736,12 +767,6 @@ FilamentApp::Window::Window(FilamentApp* filamentApp,
mGodView->setCamera(mMainCamera);
mGodView->setGodCamera(mDebugCamera);
mGodView->setCameraManipulator(mDebugCameraMan);
// Ortho view obviously uses an ortho camera
Camera const* debugDirectionalShadowCamera = mMainView->getView()->getDirectionalShadowCamera();
if (debugDirectionalShadowCamera) {
mOrthoView->setCamera(const_cast<Camera *>(debugDirectionalShadowCamera));
}
}
// configure the cameras
@@ -907,9 +932,7 @@ void FilamentApp::Window::configureCamerasForWindow() {
const bool splitview = mViews.size() > 2;
// To trigger a floating-point exception, users could shrink the window to be smaller than
// the sidebar. To prevent this we simply clamp the width of the main viewport.
const uint32_t mainWidth = splitview ? width : std::max(1, (int) width - sidebar);
const uint32_t mainWidth = std::max(2, (int) width - sidebar);
double near = mFilamentApp->mCameraNear;
double far = mFilamentApp->mCameraFar;
@@ -924,7 +947,7 @@ void FilamentApp::Window::configureCamerasForWindow() {
} else {
mMainCamera->setLensProjection(mFilamentApp->mCameraFocalLength, 1.0, near, far);
}
mDebugCamera->setProjection(45.0, double(width) / height, 0.0625, 4096, Camera::Fov::VERTICAL);
mDebugCamera->setProjection(45.0, double(mainWidth) / height, 0.0625, 4096, Camera::Fov::VERTICAL);
auto aspectRatio = double(mainWidth) / height;
if (mMainView->getView()->getStereoscopicOptions().enabled) {
@@ -935,12 +958,12 @@ void FilamentApp::Window::configureCamerasForWindow() {
// We're in split view when there are more views than just the Main and UI views.
if (splitview) {
uint32_t vpw = width / 2;
uint32_t vph = height / 2;
mMainView->setViewport ({ 0, 0, vpw, vph });
mDepthView->setViewport({ int32_t(vpw), 0, width - vpw, vph });
mGodView->setViewport ({ int32_t(vpw), int32_t(vph), width - vpw, height - vph });
mOrthoView->setViewport({ 0, int32_t(vph), vpw, height - vph });
uint32_t const vpw = mainWidth / 2;
uint32_t const vph = height / 2;
mMainView->setViewport ({ sidebar + 0, 0, vpw, vph });
mDepthView->setViewport({ sidebar + int32_t(vpw), 0, vpw, vph });
mGodView->setViewport ({ sidebar + int32_t(vpw), int32_t(vph), vpw, vph });
mOrthoView->setViewport({ sidebar + 0, int32_t(vph), vpw, vph });
} else {
mMainView->setViewport({ sidebar, 0, mainWidth, height });
}
+2
View File
@@ -896,6 +896,8 @@ int main(int argc, char** argv) {
debug.getPropertyAddress<bool>("d.shadowmap.focus_shadowcasters"));
ImGui::Checkbox("Disable light frustum alignment",
debug.getPropertyAddress<bool>("d.shadowmap.disable_light_frustum_align"));
ImGui::Checkbox("Depth clamp",
debug.getPropertyAddress<bool>("d.shadowmap.depth_clamp"));
bool debugDirectionalShadowmap;
if (debug.getProperty("d.shadowmap.debug_directional_shadowmap",