Compare commits

..
52 Commits
Author SHA1 Message Date
Eliza Velasquez 0709f7d59a stuff 2024-03-06 15:02:15 -08:00
Eliza Velasquez 2027c9e237 stuff 2024-02-28 16:05:28 -08:00
Eliza Velasquez 86456c9e34 swizzle! struct indexing! 2024-02-27 17:04:25 -08:00
Eliza Velasquez fad58ba892 insert room for literal operand expressions 2024-02-27 15:39:40 -08:00
Eliza Velasquez 8ae296974c rename bunch of stuff 2024-02-27 14:31:32 -08:00
Eliza Velasquez f9575675d9 more global symbols 2024-02-27 12:54:41 -08:00
Eliza Velasquez 71025cf25a stringify, flesh out global symbols 2024-02-26 16:54:05 -08:00
Eliza Velasquez a067fb02b1 finish get_if 2024-02-26 14:37:14 -08:00
Eliza Velasquez ffde51ee6f continue eradicating get_if 2024-02-26 13:13:25 -08:00
Eliza Velasquez 35f99ed168 templatify 2024-02-23 15:07:18 -08:00
Eliza Velasquez a939ad03f8 stuff 2024-02-22 17:01:54 -08:00
Eliza Velasquez 05e628fff9 more codegen 2024-02-22 15:52:42 -08:00
Eliza Velasquez ad8473760a start literal value support 2024-02-21 17:09:01 -08:00
Eliza Velasquez cb672eb063 more rigorous glsl code gen 2024-02-21 16:04:20 -08:00
Eliza Velasquez 9811b785cb split locals and globals 2024-02-20 16:40:52 -08:00
Eliza Velasquez ff6d4d721e major refactor 2024-02-20 14:08:07 -08:00
Eliza Velasquez c8a5094c41 stuff 2024-02-16 15:03:53 -08:00
Eliza Velasquez 0f34603cfc stringify stuff 2024-02-14 17:11:24 -08:00
Eliza Velasquez 300f80448d test 2024-02-13 16:58:49 -08:00
Eliza Velasquez a41d343a75 wip: komi 2024-02-12 16:59:06 -08:00
Mathias Agopian 02f5903b67 fix external images
It turns out that many drivers require to rebind the external texture
after its content has changed, so we now always do that.

Bug #6188
2024-01-26 14:17:48 -08:00
Mathias Agopian c39a870abc fix mobile debug builds, missing incluldes 2024-01-26 11:14:16 -08:00
Mathias Agopian 09b8008e17 add missing public headers in backend 2024-01-26 10:58:28 -08:00
Mathias Agopian 59b59cf6be add missing includes in libutils public headers 2024-01-26 10:58:00 -08:00
Mathias Agopian 0df6013263 update remote ui 2024-01-26 10:57:37 -08:00
Mathias Agopian d5041fced7 support execinfo.h on Android 33 and above
Note: this currently requires to compile filament with API_LEVEL 33.
2024-01-25 14:50:29 -08:00
Mathias Agopian 9c54b8a777 fix typo that broke FSR upscaling 2024-01-25 10:34:47 -08:00
Mathias Agopian 8a534d0940 Fix missing/extra includes in all public headers 2024-01-24 23:13:14 -08:00
Mathias Agopian 130825422e Shadowmap texture vizualizer
The vizualizer is implemented inside filament itself and activated
using the debug registry. This intended for filament development use.
2024-01-24 11:28:11 -08:00
Powei Feng 984006ee25 geometry: allow additional attributes in TangentSpaceMesh (#7483)
- Add methods for adding attributes to the input mesh
 - Add method in TangentSpaceMesh for when user provides the
   tangents
 - Separate client-side Algorithm enum from implementation algorithm
   (AlgorithmImpl)
 - Fix CMake config for combining static libs
2024-01-23 16:16:35 -08:00
Sungun Park b676002521 Release Filament 1.50.0 2024-01-23 21:10:06 +00:00
Sungun Park 8bdf7bd1e5 Update material version to 50 2024-01-22 15:25:06 -08:00
Mathias Agopian 1262cb286c backend option to disable parallel shader compile 2024-01-22 12:43:27 -08:00
Mathias Agopian ee6f3fb1dc Add sharpening option to TAA
We use the RCAS algorithm from FSR1. This is useful for when TAA
upscaling is enabled and similar to to what FSR2 is doing.
2024-01-19 14:40:04 -08:00
Mathias Agopian b9a9586abb taa: add a 32-sample mode and cleanup
32 sample may be more suited to 2x upsampling, it gives 8 samples per
high-res pixel (instead of 4). This is also what FSR 2.0 is using,
which is useful for comparing.
2024-01-19 14:40:04 -08:00
Mathias Agopian 6ee20a57aa remove all uses of our custom spinlock
This has caused issues and over time we have reduced the use of 
spinlocks, it was only used in few places and we still have evidence
that it's causing ANRs.

We use utils::Mutex instead which is a low overhead mutex implementation
on Linux systems.

FIXES=[321101014]
2024-01-19 12:05:07 -08:00
Mathias Agopian 368fa2bf39 fix IBLPrefilterContext::EquirectangularToCubemap
it was incorrectly mapping the equirect image to a cubemap due to a
typo in our overload of atan2 which was swapping its parameters.

atan2 is now removed, and we use atan(y,x) instead. Also modified the
code slightly so it matches almost exactly cmgen's.

FIXES=[320856413]
2024-01-18 21:10:21 -08:00
Mathias Agopian 8f642892b4 taa: fixes input filtering option=OFF when upscaling is off
when upscaling is off, the confidence value is always 1.
2024-01-18 21:07:13 -08:00
Powei Feng 5435a8ed3b Add missing includes (#7501)
BUG=320668410
2024-01-17 11:04:42 -08:00
Ben Doherty 5fd7a4e153 Don't render in background (#7486) 2024-01-12 10:17:00 -08:00
Sungun Park 20ff230b92 Fix a json parsing bug (#7490)
When parsing a lexeme, we use one less byte than it's intended to be for
comparing the current string.

This results in a success in cases like:
- true and truX
- false and falsX
- null and nulX
where X means an arbitrary character.

Fix this by the full intended length.
2024-01-11 12:47:11 -08:00
Ben Doherty 44ff79ad34 Metal: disable fast math (#7485) 2024-01-10 15:31:23 -08:00
Mathias AgopianandPowei Feng 102d2db008 Bokeh aspect ratio (#7482)
* Bokeh aspect ratio

new DoF option to set the bokeh aspect ratio, this can be used to
simulate anamorphic lenses

* Update android/filament-android/src/main/java/com/google/android/filament/View.java

Co-authored-by: Powei Feng <powei@google.com>

* Update web/filament-js/filament.d.ts

Co-authored-by: Powei Feng <powei@google.com>

---------

Co-authored-by: Powei Feng <powei@google.com>
2024-01-10 15:25:28 -08:00
Powei Feng 5c9039e650 Release Filament 1.49.3 2024-01-10 13:55:33 -08:00
Eliza Velasquez 1203c24f06 Generate dummy stereo variants for FL0 mats
See #7415 for a more detailed description of why this change is necessary.

The remaining variants which are filtered from FL0 materials are all related to
lighting, so further hacks like this won't be necessary.

Future work involves properly supporting differing sets of variants based on
shader language.
2024-01-10 13:50:53 -08:00
Mathias Agopian 9704d27aeb TAA upscaling
This feature is still work in progress. TAA can now optionally
upscale by 4x (this disables dynamic resolution scaling).
2024-01-09 14:07:18 -08:00
Mathias Agopian c6f2c3fc1c bloom: disable fireflies reduction when using TAA
TAA already does a fireflies reduction pass, so it's not needed when
applying bloom.
2024-01-09 14:04:01 -08:00
Mathias Agopian 2faf868341 fix missing includes (new CLion warnings) 2024-01-09 14:04:01 -08:00
Powei Feng 81f6260843 Fix typo oin MaterialCompiler (#7477) 2024-01-08 15:03:07 -08:00
Ben Doherty 1a9063d53a Metal: Always report material name in use-after-free detector (#7473) 2024-01-04 11:55:28 -08:00
Ben Doherty 6062b3c8c6 Fix ostream linking error when compiling Linux DSO (#7470) 2024-01-03 12:06:44 -08:00
Ben Doherty d9186c44ba matdbg: Load codicon font (#7469) 2024-01-03 10:41:18 -08:00
177 changed files with 6199 additions and 734 deletions
+2 -1
View File
@@ -1,7 +1,8 @@
;;; Directory Local Variables -*- no-byte-compile: t -*-
;;; For more information see (info "(emacs) Directory Variables")
((c++-mode . ((c-file-style . "filament")
((c++-mode . ((eglot-ignored-server-capabilities . (:documentFormattingProvider))
(c-file-style . "filament")
(apheleia-inhibit . t)))
(c-mode . ((c-file-style . "filament")
(apheleia-inhibit . t))))
+6 -3
View File
@@ -634,9 +634,9 @@ function(combine_static_libs TARGET OUTPUT DEPS)
# Loop through the dependent libraries and query their location on disk.
set(DEPS_FILES )
foreach(DEPENDENCY ${DEPS})
if(TARGET ${DEPENDENCY})
if (TARGET ${DEPENDENCY})
get_property(dep_type TARGET ${DEPENDENCY} PROPERTY TYPE)
if(dep_type STREQUAL "STATIC_LIBRARY")
if (dep_type STREQUAL "STATIC_LIBRARY")
list(APPEND DEPS_FILES "$<TARGET_FILE:${DEPENDENCY}>")
endif()
endif()
@@ -721,7 +721,6 @@ add_subdirectory(${LIBRARIES}/filabridge)
add_subdirectory(${LIBRARIES}/filaflat)
add_subdirectory(${LIBRARIES}/filagui)
add_subdirectory(${LIBRARIES}/filameshio)
add_subdirectory(${LIBRARIES}/geometry)
add_subdirectory(${LIBRARIES}/gltfio)
add_subdirectory(${LIBRARIES}/ibl)
add_subdirectory(${LIBRARIES}/iblprefilter)
@@ -749,12 +748,16 @@ add_subdirectory(${EXTERNAL}/jsmn/tnt)
add_subdirectory(${EXTERNAL}/stb/tnt)
add_subdirectory(${EXTERNAL}/getopt)
# Note that this has to be placed after mikktspace in order for combine_static_libs to work.
add_subdirectory(${LIBRARIES}/geometry)
if (FILAMENT_BUILD_FILAMAT OR IS_HOST_PLATFORM)
# spirv-tools must come before filamat, as filamat relies on the presence of the
# spirv-tools_SOURCE_DIR variable.
add_subdirectory(${EXTERNAL}/spirv-tools)
add_subdirectory(${EXTERNAL}/glslang/tnt)
add_subdirectory(${EXTERNAL}/spirv-cross/tnt)
add_subdirectory(${LIBRARIES}/astrict)
add_subdirectory(${LIBRARIES}/filamat)
# the material debugger requires filamat
+2 -2
View File
@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.49.3'
implementation 'com.google.android.filament:filament-android:1.50.0'
}
```
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
iOS projects can use CocoaPods to install the latest release:
```shell
pod 'Filament', '~> 1.49.3'
pod 'Filament', '~> 1.50.0'
```
### Snapshots
+9
View File
@@ -7,6 +7,15 @@ A new header is inserted each time a *tag* is created.
Instead, if you are authoring a PR for the main branch, add your release note to
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
## v1.50.1
- Metal: fix some shader artifacts by disabling fast math optimizations.
- backend: remove `atan2` overload which had a typo and wasn't useful. Fixes b/320856413.
- utils: remove usages of `SpinLock`. Fixes b/321101014.
## v1.50.0
- engine: TAA now supports 4x upscaling [BETA] [⚠️ **New Material Version**]
## v1.49.3
- matc: Generate stereo variants for FL0 materials [⚠️ **Recompile materials**]
@@ -1637,6 +1637,10 @@ public class View {
* circle of confusion scale factor (amount of blur)
*/
public float cocScale = 1.0f;
/**
* width/height aspect ratio of the circle of confusion (simulate anamorphic lenses)
*/
public float cocAspectRatio = 1.0f;
/**
* maximum aperture diameter in meters (zero to disable rotation)
*/
@@ -1921,6 +1925,7 @@ public class View {
UNIFORM_HELIX_X4,
HALTON_23_X8,
HALTON_23_X16,
HALTON_23_X32,
}
/**
@@ -1931,10 +1936,22 @@ public class View {
* history feedback, between 0 (maximum temporal AA) and 1 (no temporal AA).
*/
public float feedback = 0.12f;
/**
* texturing lod bias (typically -1 or -2)
*/
public float lodBias = -1.0f;
/**
* post-TAA sharpen, especially useful when upscaling is true.
*/
public float sharpness = 0.0f;
/**
* enables or disables temporal anti-aliasing
*/
public boolean enabled = false;
/**
* 4x TAA upscaling. Disables Dynamic Resolution. [BETA]
*/
public boolean upscaling = false;
/**
* whether to filter the history buffer
*/
+1 -1
View File
@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.49.3
VERSION_NAME=1.50.0
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
File diff suppressed because one or more lines are too long
Binary file not shown.
+1
View File
@@ -238,6 +238,7 @@ set(MATERIAL_SRCS
src/materials/resolveDepth.mat
src/materials/separableGaussianBlur.mat
src/materials/skybox.mat
src/materials/shadowmap.mat
src/materials/ssao/bilateralBlur.mat
src/materials/ssao/bilateralBlurBentNormals.mat
src/materials/ssao/mipmapDepth.mat
@@ -23,7 +23,6 @@
#include <utils/ostream.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
@@ -17,8 +17,6 @@
#ifndef TNT_FILAMENT_BACKEND_CALLBACKHANDLER_H
#define TNT_FILAMENT_BACKEND_CALLBACKHANDLER_H
#include <utils/compiler.h>
namespace filament::backend {
/**
@@ -28,7 +28,8 @@
#include <math/vec4.h>
#include <array> // FIXME: STL headers are not allowed in public headers
#include <array> // FIXME: STL headers are not allowed in public headers
#include <type_traits> // FIXME: STL headers are not allowed in public headers
#include <stddef.h>
#include <stdint.h>
+4 -6
View File
@@ -17,16 +17,14 @@
#ifndef TNT_FILAMENT_BACKEND_HANDLE_H
#define TNT_FILAMENT_BACKEND_HANDLE_H
#include <utils/compiler.h>
#if !defined(NDEBUG)
#include <utils/Log.h>
#include <utils/ostream.h>
#endif
#include <utils/debug.h>
#include <stdint.h>
#include <type_traits> // FIXME: STL headers are not allowed in public headers
#include <limits>
#include <type_traits>
#include <stdint.h>
namespace filament::backend {
@@ -54,7 +52,7 @@ struct HwVertexBuffer;
class HandleBase {
public:
using HandleId = uint32_t;
static constexpr const HandleId nullid = HandleId{ std::numeric_limits<HandleId>::max() };
static constexpr const HandleId nullid = HandleId{ UINT32_MAX };
constexpr HandleBase() noexcept: object(nullid) {}
@@ -20,7 +20,7 @@
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <limits>
#include <utils/ostream.h>
#include <stdint.h>
@@ -33,10 +33,7 @@ struct PipelineState {
RasterState rasterState;
StencilState stencilState;
PolygonOffset polygonOffset;
Viewport scissor{ 0, 0,
(uint32_t)std::numeric_limits<int32_t>::max(),
(uint32_t)std::numeric_limits<int32_t>::max()
};
Viewport scissor{ 0, 0, (uint32_t)INT32_MAX, (uint32_t)INT32_MAX };
};
} // namespace filament::backend
@@ -24,6 +24,7 @@
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/ostream.h>
#include <stddef.h>
#include <stdint.h>
+12 -6
View File
@@ -19,11 +19,11 @@
#ifndef TNT_FILAMENT_BACKEND_PLATFORM_H
#define TNT_FILAMENT_BACKEND_PLATFORM_H
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/Invocable.h>
#include <stddef.h>
namespace filament::backend {
class Driver;
@@ -41,18 +41,24 @@ public:
struct Stream {};
struct DriverConfig {
/*
* size of handle arena in bytes. Setting to 0 indicates default value is to be used.
/**
* Size of handle arena in bytes. Setting to 0 indicates default value is to be used.
* Driver clamps to valid values.
*/
size_t handleArenaSize = 0;
/*
* this number of most-recently destroyed textures will be tracked for use-after-free.
/**
* This number of most-recently destroyed textures will be tracked for use-after-free.
* Throws an exception when a texture is freed but still bound to a SamplerGroup and used in
* a draw call. 0 disables completely. Currently only respected by the Metal backend.
*/
size_t textureUseAfterFreePoolSize = 0;
/**
* Set to `true` to forcibly disable parallel shader compilation in the backend.
* Currently only honored by the GL backend.
*/
bool disableParallelShaderCompile = false;
};
Platform() noexcept;
@@ -21,8 +21,7 @@
#include <utils/compiler.h>
namespace filament {
namespace backend {
namespace filament::backend {
/**
* A PresentCallable is a callable object that, when called, schedules a frame for presentation on
@@ -98,7 +97,6 @@ private:
*/
using FrameFinishedCallback UTILS_DEPRECATED = void(*)(PresentCallable callable, void* user);
} // namespace backend
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRESENTCALLABLE
+6 -4
View File
@@ -17,17 +17,19 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_PROGRAM_H
#define TNT_FILAMENT_BACKEND_PRIVATE_PROGRAM_H
#include <utils/compiler.h>
#include <utils/CString.h>
#include <utils/FixedCapacityVector.h>
#include <utils/Invocable.h>
#include <utils/Log.h>
#include <utils/ostream.h>
#include <backend/DriverEnums.h>
#include <array>
#include <variant>
#include <array> // FIXME: STL headers are not allowed in public headers
#include <utility> // FIXME: STL headers are not allowed in public headers
#include <variant> // FIXME: STL headers are not allowed in public headers
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
@@ -24,9 +24,6 @@
#include <utils/compiler.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
struct UTILS_PUBLIC SamplerDescriptor {
@@ -17,9 +17,11 @@
#ifndef TNT_FILAMENT_BACKEND_TARGETBUFFERINFO_H
#define TNT_FILAMENT_BACKEND_TARGETBUFFERINFO_H
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <utils/ostream.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
@@ -18,8 +18,11 @@
#define TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
#include <backend/AcquiredImage.h>
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
#include <stdint.h>
namespace filament::backend {
class Driver;
@@ -17,11 +17,10 @@
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#include <stdint.h>
#include <backend/DriverEnums.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
#include <stdint.h>
namespace filament::backend {
@@ -30,7 +30,7 @@ struct PlatformCocoaTouchGLImpl;
class PlatformCocoaTouchGL : public OpenGLPlatform {
public:
PlatformCocoaTouchGL();
~PlatformCocoaTouchGL() noexcept;
~PlatformCocoaTouchGL() noexcept override;
// --------------------------------------------------------------------------------------------
// Platform Interface
@@ -17,18 +17,21 @@
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_H
#include <stdint.h>
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/eglplatform.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
#include <initializer_list>
#include <utility>
#include <vector>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
/**
@@ -17,8 +17,14 @@
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#include <backend/AcquiredImage.h>
#include <backend/Platform.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/platforms/PlatformEGL.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
class ExternalStreamManagerAndroid;
@@ -20,13 +20,18 @@
#include <backend/Platform.h>
#include <bluevk/BlueVK.h>
#include <utils/CString.h>
#include <utils/FixedCapacityVector.h>
#include <utils/PrivateImplementation.h>
#include <string_view>
#include <tuple>
#include <unordered_set>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
using SwapChain = Platform::SwapChain;
@@ -17,10 +17,7 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_CIRCULARBUFFER_H
#define TNT_FILAMENT_BACKEND_PRIVATE_CIRCULARBUFFER_H
#include <utils/compiler.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
@@ -19,12 +19,14 @@
#include "private/backend/CircularBuffer.h"
#include <utils/compiler.h>
#include <utils/Condition.h>
#include <utils/Mutex.h>
#include <vector>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
/*
@@ -32,11 +32,13 @@
#include <backend/TargetBufferInfo.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/ThreadUtils.h>
#include <cstddef>
#include <functional>
#include <tuple>
#include <type_traits>
#include <utility>
#ifndef NDEBUG
@@ -152,14 +154,14 @@ struct CommandType<void (Driver::*)(ARGS...)> {
}
// placement new declared as "throw" to avoid the compiler's null-check
inline void* operator new(std::size_t size, void* ptr) {
inline void* operator new(std::size_t, void* ptr) {
assert_invariant(ptr);
return ptr;
}
};
};
// convert an method of "class Driver" into a Command<> type
// convert a method of "class Driver" into a Command<> type
#define COMMAND_TYPE(method) CommandType<decltype(&Driver::method)>::Command<&Driver::method>
// ------------------------------------------------------------------------------------------------
@@ -29,6 +29,7 @@
#include <functional>
#include <stddef.h>
#include <stdint.h>
// Command debugging off. debugging virtuals are not called.
@@ -22,9 +22,18 @@
#include <utils/Allocator.h>
#include <utils/Log.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/ostream.h>
#include <tsl/robin_map.h>
#include <exception>
#include <type_traits>
#include <unordered_map>
#include <stddef.h>
#include <stdint.h>
#if !defined(NDEBUG) && UTILS_HAS_RTTI
# define HANDLE_TYPE_SAFETY 1
#else
@@ -222,7 +231,7 @@ private:
explicit Allocator(const utils::AreaPolicy::HeapArea& area);
// this is in fact always called with a constexpr size argument
[[nodiscard]] inline void* alloc(size_t size, size_t alignment, size_t extra) noexcept {
[[nodiscard]] inline void* alloc(size_t size, size_t, size_t extra) noexcept {
void* p = nullptr;
if (size <= mPool0.getSize()) p = mPool0.alloc(size, 16, extra);
else if (size <= mPool1.getSize()) p = mPool1.alloc(size, 16, extra);
@@ -19,9 +19,9 @@
#ifndef TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H
#define TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H
#include "backend/DriverEnums.h"
#include <backend/DriverEnums.h>
#include "utils/compiler.h"
#include <utils/compiler.h>
namespace filament::backend {
@@ -17,15 +17,13 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_SAMPLERGROUP_H
#define TNT_FILAMENT_BACKEND_PRIVATE_SAMPLERGROUP_H
#include "backend/DriverApiForward.h"
#include <utils/compiler.h>
#include <utils/FixedCapacityVector.h>
#include <backend/DriverApiForward.h>
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <backend/SamplerDescriptor.h>
#include <utils/FixedCapacityVector.h>
#include <utils/ostream.h>
#include <stddef.h>
namespace filament::backend {
+1
View File
@@ -19,6 +19,7 @@
#include <backend/PixelBufferDescriptor.h>
#include <cstring>
#include <stddef.h>
#include <stdint.h>
+14 -1
View File
@@ -21,7 +21,12 @@
#include <backend/AcquiredImage.h>
#include <backend/BufferDescriptor.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/Log.h>
#include <utils/ostream.h>
#include <utils/Systrace.h>
#include <math/half.h>
@@ -29,6 +34,13 @@
#include <math/vec3.h>
#include <math/vec4.h>
#include <functional>
#include <mutex>
#include <utility>
#include <stddef.h>
#include <stdint.h>
using namespace utils;
using namespace filament::math;
@@ -119,7 +131,8 @@ void DriverBase::purge() noexcept {
// ------------------------------------------------------------------------------------------------
void DriverBase::scheduleDestroySlow(BufferDescriptor&& buffer) noexcept {
scheduleCallback(buffer.getHandler(), [buffer = std::move(buffer)]() {
auto const handler = buffer.getHandler();
scheduleCallback(handler, [buffer = std::move(buffer)]() {
// user callback is called when BufferDescriptor gets destroyed
});
}
@@ -20,6 +20,7 @@
#include "MetalUtils.h"
#include <utils/Panic.h>
#include <utils/Log.h>
namespace filament::backend {
@@ -19,6 +19,7 @@
#include "MetalContext.h"
#include <utils/Panic.h>
#include <utils/Log.h>
#include <utils/trap.h>
#include <thread>
@@ -21,6 +21,7 @@
#include "MetalUtils.h"
#include <utils/Panic.h>
#include <utils/Log.h>
#include <utils/trap.h>
#define NSERROR_CHECK(message) \
@@ -103,10 +103,19 @@ void MetalShaderCompiler::terminate() noexcept {
NSString* objcSource = [[NSString alloc] initWithBytes:source.data()
length:source.size() - 1
encoding:NSUTF8StringEncoding];
// By default, Metal uses the most recent language version.
MTLCompileOptions* options = [MTLCompileOptions new];
// Disable Fast Math optimizations.
// This ensures that operations adhere to IEEE standards for floating-point arithmetic,
// which is crucial for half precision floats in scenarios where fast math optimizations
// lead to inaccuracies, such as in handling special values like NaN or Infinity.
options.fastMathEnabled = NO;
NSError* error = nil;
// When options is nil, Metal uses the most recent language version available.
id<MTLLibrary> library = [device newLibraryWithSource:objcSource
options:nil
options:options
error:&error];
if (library == nil) {
if (error) {
+2
View File
@@ -18,6 +18,8 @@
#include "MetalEnums.h"
#include <utils/Log.h>
namespace filament {
namespace backend {
@@ -427,7 +427,6 @@ void OpenGLContext::initBugs(Bugs* bugs, Extensions const& exts,
if (strstr(renderer, "Mali-T")) {
bugs->disable_glFlush = true;
bugs->disable_shared_context_draws = true;
bugs->texture_external_needs_rebind = true;
// We have not verified that timer queries work on Mali-T, so we disable to be safe.
bugs->dont_use_timer_query = true;
}
+1 -8
View File
@@ -222,10 +222,6 @@ public:
// Some drivers have gl state issues when drawing from shared contexts
bool disable_shared_context_draws;
// Some drivers require the GL_TEXTURE_EXTERNAL_OES target to be bound when
// the texture image changes, even if it's already bound to that texture
bool texture_external_needs_rebind;
// Some web browsers seem to immediately clear the default framebuffer when calling
// glInvalidateFramebuffer with WebGL 2.0
bool disable_invalidate_framebuffer;
@@ -433,9 +429,6 @@ private:
{ bugs.disable_shared_context_draws,
"disable_shared_context_draws",
""},
{ bugs.texture_external_needs_rebind,
"texture_external_needs_rebind",
""},
{ bugs.disable_invalidate_framebuffer,
"disable_invalidate_framebuffer",
""},
@@ -711,7 +704,7 @@ void OpenGLContext::bindTexture(GLuint unit, GLuint target, GLuint texId, size_t
update_state(state.textures.units[unit].targets[targetIndex].texture_id, texId, [&]() {
activeTexture(unit);
glBindTexture(target, texId);
}, (target == GL_TEXTURE_EXTERNAL_OES) && bugs.texture_external_needs_rebind);
}, target == GL_TEXTURE_EXTERNAL_OES);
}
void OpenGLContext::bindTexture(GLuint unit, GLuint target, GLuint texId) noexcept {
+4 -3
View File
@@ -147,9 +147,9 @@ Driver* OpenGLDriver::create(OpenGLPlatform* const platform,
#endif
size_t const defaultSize = FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB * 1024U * 1024U;
Platform::DriverConfig validConfig {driverConfig};
Platform::DriverConfig validConfig{ driverConfig };
validConfig.handleArenaSize = std::max(driverConfig.handleArenaSize, defaultSize);
OpenGLDriver* const driver = new OpenGLDriver(ec, validConfig);
OpenGLDriver* const driver = new(std::nothrow) OpenGLDriver(ec, validConfig);
return driver;
}
@@ -171,7 +171,8 @@ OpenGLDriver::OpenGLDriver(OpenGLPlatform* platform, const Platform::DriverConfi
mContext(),
mShaderCompilerService(*this),
mHandleAllocator("Handles", driverConfig.handleArenaSize),
mSamplerMap(32) {
mSamplerMap(32),
mDriverConfig(driverConfig) {
std::fill(mSamplerBindings.begin(), mSamplerBindings.end(), nullptr);
@@ -400,6 +400,9 @@ private:
// timer query implementation
OpenGLTimerQueryInterface* mTimerQueryImpl = nullptr;
const Platform::DriverConfig mDriverConfig;
Platform::DriverConfig const& getDriverConfig() const noexcept { return mDriverConfig; }
// for ES2 sRGB support
GLSwapChain* mCurrentDrawSwapChain = nullptr;
bool mRec709OutputColorspace = false;
@@ -151,6 +151,12 @@ bool ShaderCompilerService::isParallelShaderCompileSupported() const noexcept {
}
void ShaderCompilerService::init() noexcept {
if (UTILS_UNLIKELY(mDriver.getDriverConfig().disableParallelShaderCompile)) {
// user disabled parallel shader compile
mMode = Mode::SYNCHRONOUS;
return;
}
// Here we decide which mode we'll be using. We always prefer our own thread-pool if
// that mode is available because, we have no control on how the compilation queues are
// handled if done by the driver (so at the very least we'd need to decode this per-driver).
@@ -109,7 +109,7 @@ private:
};
enum class Mode {
UNDEFINED, // init() has not beed called yet.
UNDEFINED, // init() has not been called yet.
SYNCHRONOUS, // synchronous shader compilation
THREAD_POOL, // asynchronous shader compilation using a thread-pool (most common)
ASYNCHRONOUS // asynchronous shader compilation using KHR_parallel_shader_compile
@@ -15,6 +15,7 @@
*/
#include <backend/platforms/VulkanPlatform.h>
#include <backend/DriverEnums.h>
#include "vulkan/VulkanConstants.h"
#include "vulkan/VulkanDriverFactory.h"
@@ -23,6 +24,11 @@
#include <bluevk/BlueVK.h>
#include <tuple>
#include <stdint.h>
#include <stddef.h>
#if defined(__linux__) || defined(__FreeBSD__)
#define LINUX_OR_FREEBSD 1
#endif
+18 -12
View File
@@ -21,10 +21,14 @@
#include <utils/compiler.h>
#include <limits>
#include <math/mat3.h>
#include <math/mat4.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <float.h>
#include <stddef.h>
namespace filament {
@@ -70,7 +74,7 @@ public:
* @return This bounding box
*/
Box& set(const math::float3& min, const math::float3& max) noexcept {
// float3 ctor needed for visual studio
// float3 ctor needed for Visual Studio
center = (max + min) * math::float3(0.5f);
halfExtent = (max - min) * math::float3(0.5f);
return *this;
@@ -130,17 +134,17 @@ public:
struct UTILS_PUBLIC Aabb {
/** min coordinates */
math::float3 min = std::numeric_limits<float>::max();
math::float3 min = FLT_MAX;
/** max coordinates */
math::float3 max = std::numeric_limits<float>::lowest();
math::float3 max = -FLT_MAX;
/**
* Computes the center of the box.
* @return (max + min)/2
*/
math::float3 center() const noexcept {
// float3 ctor needed for visual studio
// float3 ctor needed for Visual Studio
return (max + min) * math::float3(0.5f);
}
@@ -149,7 +153,7 @@ struct UTILS_PUBLIC Aabb {
* @return (max - min)/2
*/
math::float3 extent() const noexcept {
// float3 ctor needed for visual studio
// float3 ctor needed for Visual Studio
return (max - min) * math::float3(0.5f);
}
@@ -198,12 +202,14 @@ struct UTILS_PUBLIC Aabb {
* @return the maximum signed distance to the box. Negative if p is in the box
*/
float contains(math::float3 p) const noexcept {
// we don't use std::max to avoid a dependency on <algorithm>
auto const maximum = [](auto a, auto b) { return a > b ? a : b; };
float d = min.x - p.x;
d = std::max(d, min.y - p.y);
d = std::max(d, min.z - p.z);
d = std::max(d, p.x - max.x);
d = std::max(d, p.y - max.y);
d = std::max(d, p.z - max.z);
d = maximum(d, min.y - p.y);
d = maximum(d, min.z - p.z);
d = maximum(d, p.x - max.x);
d = maximum(d, p.y - max.y);
d = maximum(d, p.z - max.z);
return d;
}
+3 -1
View File
@@ -22,11 +22,13 @@
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/BufferDescriptor.h>
#include <utils/compiler.h>
#include <stdint.h>
#include <stddef.h>
namespace filament {
class FBufferObject;
+7 -2
View File
@@ -28,6 +28,11 @@
#include <math/vec4.h>
#include <math/mat4.h>
#include <math.h>
#include <stdint.h>
#include <stddef.h>
namespace utils {
class Entity;
} // namespace utils
@@ -184,7 +189,7 @@ public:
* @see Fov.
*/
static math::mat4 projection(Fov direction, double fovInDegrees,
double aspect, double near, double far = std::numeric_limits<double>::infinity());
double aspect, double near, double far = INFINITY);
/** Returns the projection matrix from the focal length.
*
@@ -194,7 +199,7 @@ public:
* @param far distance in world units from the camera to the far plane. \p far > \p near.
*/
static math::mat4 projection(double focalLengthInMillimeters,
double aspect, double near, double far = std::numeric_limits<double>::infinity());
double aspect, double near, double far = INFINITY);
/** Sets the projection matrix from a frustum defined by six planes.
+3
View File
@@ -24,6 +24,9 @@
#include <math/vec3.h>
#include <math/vec4.h>
#include <stdint.h>
#include <stddef.h>
namespace filament {
//! RGB color in linear space
+3
View File
@@ -26,6 +26,9 @@
#include <math/mathfwd.h>
#include <stdint.h>
#include <stddef.h>
namespace filament {
class Engine;
-1
View File
@@ -18,7 +18,6 @@
#define TNT_FILAMENT_COLOR_SPACE_H
#include <math/vec2.h>
#include <math/vec3.h>
namespace filament::color {
+1 -1
View File
@@ -25,7 +25,7 @@
#include <math/mathfwd.h>
#include <stdint.h>
#include <stddef.h>
namespace filament {
+5
View File
@@ -19,9 +19,14 @@
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
#include <utils/compiler.h>
#include <utils/Invocable.h>
#include <stdint.h>
#include <stddef.h>
namespace utils {
class Entity;
+2
View File
@@ -25,6 +25,8 @@
#include <utils/compiler.h>
#include <stdint.h>
namespace filament {
/**
+3
View File
@@ -23,9 +23,12 @@
#include <math/mat4.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <utils/unwindows.h> // Because we define NEAR and FAR in the Plane enum.
#include <stdint.h>
namespace filament {
class Box;
+1
View File
@@ -27,6 +27,7 @@
#include <utils/compiler.h>
#include <stdint.h>
#include <stddef.h>
namespace filament {
@@ -25,6 +25,8 @@
#include <math/mathfwd.h>
#include <stdint.h>
namespace filament {
class Engine;
+5 -2
View File
@@ -18,11 +18,14 @@
#define TNT_FILAMENT_INSTANCEBUFFER_H
#include <filament/FilamentAPI.h>
#include <filament/Engine.h>
#include <utils/compiler.h>
#include <math/mathfwd.h>
#include <stddef.h>
namespace filament {
/**
@@ -45,7 +48,7 @@ public:
* >= 1 and <= \c Engine::getMaxAutomaticInstances()
* @see Engine::getMaxAutomaticInstances
*/
Builder(size_t instanceCount) noexcept;
explicit Builder(size_t instanceCount) noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
+3
View File
@@ -27,6 +27,9 @@
#include <math/mathfwd.h>
#include <math/quat.h>
#include <stdint.h>
#include <stddef.h>
namespace utils {
class Entity;
} // namespace utils
+5
View File
@@ -30,7 +30,12 @@
#include <math/mathfwd.h>
#include <type_traits>
#include <utility>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
namespace utils {
class CString;
@@ -28,6 +28,12 @@
#include <math/mathfwd.h>
#include <type_traits>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
namespace filament {
class Material;
@@ -21,8 +21,11 @@
#include <filament/Engine.h>
#include <utils/compiler.h>
#include <math/mathfwd.h>
#include <stddef.h>
namespace filament {
+11 -3
View File
@@ -19,10 +19,13 @@
#include <filament/Color.h>
#include <stdint.h>
#include <math/vec2.h>
#include <math/vec3.h>
#include <math.h>
#include <stdint.h>
namespace filament {
class Texture;
@@ -293,6 +296,7 @@ struct DepthOfFieldOptions {
MEDIAN
};
float cocScale = 1.0f; //!< circle of confusion scale factor (amount of blur)
float cocAspectRatio = 1.0f; //!< width/height aspect ratio of the circle of confusion (simulate anamorphic lenses)
float maxApertureDiameter = 0.01f; //!< maximum aperture diameter in meters (zero to disable rotation)
bool enabled = false; //!< enable or disable depth of field effect
Filter filter = Filter::MEDIAN; //!< filter to use for filling gaps in the kernel
@@ -426,7 +430,7 @@ struct MultiSampleAntiAliasingOptions {
* Options for Temporal Anti-aliasing (TAA)
* Most TAA parameters are extremely costly to change, as they will trigger the TAA post-process
* shaders to be recompiled. These options should be changed or set during initialization.
* `filterWidth`, `feedback` and `jitterPattern`, however, could be changed an any time.
* `filterWidth`, `feedback` and `jitterPattern`, however, can be changed at any time.
*
* `feedback` of 0.1 effectively accumulates a maximum of 19 samples in steady state.
* see "A Survey of Temporal Antialiasing Techniques" by Lei Yang and all for more information.
@@ -436,7 +440,10 @@ struct MultiSampleAntiAliasingOptions {
struct TemporalAntiAliasingOptions {
float filterWidth = 1.0f; //!< reconstruction filter width typically between 0.2 (sharper, aliased) and 1.5 (smoother)
float feedback = 0.12f; //!< history feedback, between 0 (maximum temporal AA) and 1 (no temporal AA).
float lodBias = -1.0f; //!< texturing lod bias (typically -1 or -2)
float sharpness = 0.0f; //!< post-TAA sharpen, especially useful when upscaling is true.
bool enabled = false; //!< enables or disables temporal anti-aliasing
bool upscaling = false; //!< 4x TAA upscaling. Disables Dynamic Resolution. [BETA]
enum class BoxType : uint8_t {
AABB, //!< use an AABB neighborhood
@@ -454,7 +461,8 @@ struct TemporalAntiAliasingOptions {
RGSS_X4, //! 4-samples, rotated grid sampling
UNIFORM_HELIX_X4, //! 4-samples, uniform grid in helix sequence
HALTON_23_X8, //! 8-samples of halton 2,3
HALTON_23_X16 //! 16-samples of halton 2,3
HALTON_23_X16, //! 16-samples of halton 2,3
HALTON_23_X32 //! 32-samples of halton 2,3
};
bool filterHistory = true; //!< whether to filter the history buffer
+3
View File
@@ -24,7 +24,10 @@
#include <backend/DriverEnums.h>
#include <backend/TargetBufferInfo.h>
#include <utils/compiler.h>
#include <stddef.h>
#include <stdint.h>
namespace filament {
@@ -29,9 +29,15 @@
#include <utils/FixedCapacityVector.h>
#include <math/mathfwd.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <type_traits>
#include <float.h>
#include <stddef.h>
#include <stdint.h>
namespace utils {
class Entity;
} // namespace utils
@@ -873,8 +879,8 @@ void RenderableManager::setMorphTargetBufferAt(Instance instance, uint8_t level,
template<typename VECTOR, typename INDEX, typename, typename>
Box RenderableManager::computeAABB(VECTOR const* vertices, INDEX const* indices, size_t count,
size_t stride) noexcept {
math::float3 bmin(std::numeric_limits<float>::max());
math::float3 bmax(std::numeric_limits<float>::lowest());
math::float3 bmin(FLT_MAX);
math::float3 bmax(-FLT_MAX);
for (size_t i = 0; i < count; ++i) {
VECTOR const* p = reinterpret_cast<VECTOR const*>(
(char const*)vertices + indices[i] * stride);
-3
View File
@@ -23,9 +23,6 @@
#include <utils/compiler.h>
#include <backend/PresentCallable.h>
#include <backend/DriverEnums.h>
#include <math/vec4.h>
#include <stdint.h>
+2
View File
@@ -24,6 +24,8 @@
#include <utils/compiler.h>
#include <utils/Invocable.h>
#include <stddef.h>
namespace utils {
class Entity;
} // namespace utils
+1 -1
View File
@@ -26,7 +26,7 @@
#include <math/mathfwd.h>
#include <stddef.h>
#include <stdint.h>
namespace filament {
+2 -1
View File
@@ -23,9 +23,10 @@
#include <utils/compiler.h>
#include <stdint.h>
#include <math/mathfwd.h>
#include <stdint.h>
namespace filament {
class FSkybox;
+2 -2
View File
@@ -20,12 +20,12 @@
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/PixelBufferDescriptor.h>
#include <backend/CallbackHandler.h>
#include <utils/compiler.h>
#include <stdint.h>
namespace filament {
class FStream;
+2 -1
View File
@@ -21,11 +21,12 @@
#include <backend/CallbackHandler.h>
#include <backend/DriverEnums.h>
#include <backend/PresentCallable.h>
#include <utils/compiler.h>
#include <utils/Invocable.h>
#include <stdint.h>
namespace filament {
class Engine;
+4
View File
@@ -20,12 +20,16 @@
#define TNT_FILAMENT_TEXTURE_H
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/PixelBufferDescriptor.h>
#include <utils/compiler.h>
#include <utility>
#include <stddef.h>
#include <stdint.h>
namespace filament {
@@ -25,6 +25,8 @@
#include <math.h>
#include <stdint.h>
namespace filament {
/**
+2
View File
@@ -21,6 +21,8 @@
#include <math/mathfwd.h>
#include <stdint.h>
namespace filament {
/**
@@ -26,6 +26,7 @@
#include <iterator>
#include <stddef.h>
namespace utils {
class Entity;
+3
View File
@@ -27,6 +27,9 @@
#include <utils/compiler.h>
#include <stddef.h>
#include <stdint.h>
namespace filament {
class FVertexBuffer;
+5 -3
View File
@@ -19,17 +19,19 @@
#ifndef TNT_FILAMENT_VIEW_H
#define TNT_FILAMENT_VIEW_H
#include <filament/Color.h>
#include <filament/FilamentAPI.h>
#include <filament/Options.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/Entity.h>
#include <math/mathfwd.h>
#include <utility>
#include <stddef.h>
#include <stdint.h>
namespace filament {
namespace backend {
-3
View File
@@ -23,9 +23,6 @@
#include <utils/compiler.h>
#include <math/scalar.h>
#include <math/mathfwd.h>
#include <stddef.h>
#include <stdint.h>
+1 -2
View File
@@ -71,8 +71,7 @@ void PerShadowMapUniforms::prepareCamera(Transaction const& transaction,
s.clipControl = engine.getDriverApi().getClipSpaceParams();
}
void PerShadowMapUniforms::prepareLodBias(Transaction const& transaction,
float bias) noexcept {
void PerShadowMapUniforms::prepareLodBias(Transaction const& transaction, float bias) noexcept {
auto& s = edit(transaction);
s.lodBias = bias;
}
+2 -1
View File
@@ -96,9 +96,10 @@ void PerViewUniforms::prepareCamera(FEngine& engine, const CameraInfo& camera) n
s.clipControl = engine.getDriverApi().getClipSpaceParams();
}
void PerViewUniforms::prepareLodBias(float bias) noexcept {
void PerViewUniforms::prepareLodBias(float bias, float2 derivativesScale) noexcept {
auto& s = mUniforms.edit();
s.lodBias = bias;
s.derivativesScale = derivativesScale;
}
void PerViewUniforms::prepareExposure(float ev100) noexcept {
+1 -1
View File
@@ -69,7 +69,7 @@ public:
void terminate(backend::DriverApi& driver);
void prepareCamera(FEngine& engine, const CameraInfo& camera) noexcept;
void prepareLodBias(float bias) noexcept;
void prepareLodBias(float bias, math::float2 derivativesScale) noexcept;
/*
* @param viewport viewport (should be same as RenderPassParams::viewport)
+218 -105
View File
@@ -27,9 +27,12 @@
#include "details/Engine.h"
#include "fg/FrameGraph.h"
#include "fg/FrameGraphId.h"
#include "fg/FrameGraphResources.h"
#include "fg/FrameGraphTexture.h"
#include "fsr.h"
#include "FrameHistory.h"
#include "PerViewUniforms.h"
#include "RenderPass.h"
@@ -41,15 +44,46 @@
#include "generated/resources/materials.h"
#include <filament/Material.h>
#include <filament/MaterialEnums.h>
#include <filament/Options.h>
#include <filament/Viewport.h>
#include <private/filament/EngineEnums.h>
#include <backend/DriverEnums.h>
#include <backend/DriverApiForward.h>
#include <backend/Handle.h>
#include <backend/PipelineState.h>
#include <backend/PixelBufferDescriptor.h>
#include <private/backend/BackendUtils.h>
#include <math/half.h>
#include <math/mat2.h>
#include <math/mat3.h>
#include <math/mat4.h>
#include <math/scalar.h>
#include <math/vec2.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <utils/algorithm.h>
#include <utils/BitmaskEnum.h>
#include <utils/debug.h>
#include <utils/compiler.h>
#include <utils/FixedCapacityVector.h>
#include <algorithm>
#include <array>
#include <cmath>
#include <limits>
#include <string_view>
#include <variant>
#include <utility>
#include <stddef.h>
#include <stdint.h>
namespace filament {
@@ -81,7 +115,7 @@ PostProcessManager::PostProcessMaterial::PostProcessMaterial() noexcept {
}
PostProcessManager::PostProcessMaterial::PostProcessMaterial(MaterialInfo const& info) noexcept
: PostProcessMaterial() {
: PostProcessMaterial() {
mData = info.data; // aliased to mMaterial
mSize = info.size;
mConstants = info.constants;
@@ -133,7 +167,7 @@ void PostProcessManager::PostProcessMaterial::loadMaterial(FEngine& engine) cons
mHasMaterial = true;
auto builder = Material::Builder();
builder.package(mData, mSize);
for (auto const& constant : mConstants) {
for (auto const& constant: mConstants) {
std::visit([&](auto&& arg) {
builder.constant(constant.name.data(), constant.name.size(), arg);
}, constant.value);
@@ -155,63 +189,60 @@ PipelineState PostProcessManager::PostProcessMaterial::getPipelineState(
FMaterial* const material = getMaterial(engine);
material->prepareProgram(Variant{ variantKey });
return {
.program = material->getProgram(Variant{variantKey}),
.program = material->getProgram(Variant{ variantKey }),
.rasterState = material->getRasterState(),
.scissor = material->getDefaultInstance()->getScissor()
};
}
UTILS_NOINLINE
FMaterialInstance* PostProcessManager::PostProcessMaterial::getMaterialInstance(FEngine& engine) const noexcept {
FMaterialInstance* PostProcessManager::PostProcessMaterial::getMaterialInstance(
FEngine& engine) const noexcept {
FMaterial* const material = getMaterial(engine);
return material->getDefaultInstance();
}
// ------------------------------------------------------------------------------------------------
const PostProcessManager::JitterSequence<4> PostProcessManager::sRGSS4 = {{
const PostProcessManager::JitterSequence<4> PostProcessManager::sRGSS4 = {{{
{ 0.625f, 0.125f },
{ 0.125f, 0.375f },
{ 0.875f, 0.625f },
{ 0.375f, 0.875f }
}};
}}};
const PostProcessManager::JitterSequence<4> PostProcessManager::sUniformHelix4 = {{
const PostProcessManager::JitterSequence<4> PostProcessManager::sUniformHelix4 = {{{
{ 0.25f, 0.25f },
{ 0.75f, 0.75f },
{ 0.25f, 0.75f },
{ 0.75f, 0.25f },
}};
}}};
const PostProcessManager::JitterSequence<16> PostProcessManager::sHaltonSamples = {{
{ filament::halton( 0, 2), filament::halton( 0, 3) },
{ filament::halton( 1, 2), filament::halton( 1, 3) },
{ filament::halton( 2, 2), filament::halton( 2, 3) },
{ filament::halton( 3, 2), filament::halton( 3, 3) },
{ filament::halton( 4, 2), filament::halton( 4, 3) },
{ filament::halton( 5, 2), filament::halton( 5, 3) },
{ filament::halton( 6, 2), filament::halton( 6, 3) },
{ filament::halton( 7, 2), filament::halton( 7, 3) },
{ filament::halton( 8, 2), filament::halton( 8, 3) },
{ filament::halton( 9, 2), filament::halton( 9, 3) },
{ filament::halton(10, 2), filament::halton(10, 3) },
{ filament::halton(11, 2), filament::halton(11, 3) },
{ filament::halton(12, 2), filament::halton(12, 3) },
{ filament::halton(13, 2), filament::halton(13, 3) },
{ filament::halton(14, 2), filament::halton(14, 3) },
{ filament::halton(15, 2), filament::halton(15, 3) }
}};
template<size_t COUNT>
constexpr auto halton() {
std::array<float2, COUNT> h;
for (size_t i = 0; i < COUNT; i++) {
h[i] = {
filament::halton(i, 2),
filament::halton(i, 3) };
}
return h;
}
const PostProcessManager::JitterSequence<32>
PostProcessManager::sHaltonSamples = { halton<32>() };
PostProcessManager::PostProcessManager(FEngine& engine) noexcept
: mEngine(engine),
mWorkaroundSplitEasu(false),
mWorkaroundAllowReadOnlyAncillaryFeedbackLoop(false) {
mWorkaroundSplitEasu(false),
mWorkaroundAllowReadOnlyAncillaryFeedbackLoop(false) {
}
PostProcessManager::~PostProcessManager() noexcept = default;
UTILS_NOINLINE
void PostProcessManager::registerPostProcessMaterial(std::string_view name, MaterialInfo const& info) {
void PostProcessManager::registerPostProcessMaterial(std::string_view name,
MaterialInfo const& info) {
mMaterialRegistry.try_emplace(name, info);
}
@@ -276,6 +307,7 @@ static const PostProcessManager::MaterialInfo sMaterialList[] = {
{ "fsr_rcas", MATERIAL(FSR_RCAS) },
{ "debugShadowCascades", MATERIAL(DEBUGSHADOWCASCADES) },
{ "resolveDepth", MATERIAL(RESOLVEDEPTH) },
{ "shadowmap", MATERIAL(SHADOWMAP) },
};
void PostProcessManager::init() noexcept {
@@ -294,13 +326,13 @@ void PostProcessManager::init() noexcept {
driver.isWorkaroundNeeded(Workaround::ALLOW_READ_ONLY_ANCILLARY_FEEDBACK_LOOP);
#pragma nounroll
for (auto const& info : sMaterialListFeatureLevel0) {
for (auto const& info: sMaterialListFeatureLevel0) {
registerPostProcessMaterial(info.name, info);
}
if (mEngine.getActiveFeatureLevel() >= FeatureLevel::FEATURE_LEVEL_1) {
#pragma nounroll
for (auto const& info : sMaterialList) {
for (auto const& info: sMaterialList) {
registerPostProcessMaterial(info.name, info);
}
}
@@ -772,7 +804,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::screenSpaceAmbientOcclusion(
auto ssao = resources.getRenderPassInfo();
auto const& desc = resources.getDescriptor(data.depth);
// estimate of the size in pixel of a 1m tall/wide object viewed from 1m away (i.e. at z=-1)
// Estimate of the size in pixel units of a 1m tall/wide object viewed from 1m away (i.e. at z=-1)
const float projectionScale = std::min(
0.5f * cameraInfo.projection[0].x * desc.width,
0.5f * cameraInfo.projection[1].y * desc.height);
@@ -929,7 +961,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::bilateralBlurPass(FrameGraph
auto const& desc = resources.getDescriptor(data.blurred);
// unnormalized gaussian half-kernel of a given standard deviation
// returns number of samples stored in array (max 16)
// returns number of samples stored in the array (max 16)
constexpr size_t kernelArraySize = 16; // limited by bilateralBlur.mat
auto gaussianKernel =
[kernelArraySize](float* outKernel, size_t gaussianWidth, float stdDev) -> uint32_t {
@@ -973,7 +1005,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::generateGaussianMipmap(Frame
auto const subResourceDesc = fg.getSubResourceDescriptor(input);
// create one subresource per level to be generated from the input. These will be our
// Create one subresource per level to be generated from the input. These will be our
// destinations.
struct MipmapPassData {
FixedCapacityVector<FrameGraphId<FrameGraphTexture>> out;
@@ -1134,7 +1166,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::gaussianBlurPass(FrameGraph&
size_t const m = computeGaussianCoefficients(kernel,
std::min(sizeof(kernel) / sizeof(*kernel), kernelStorageSize));
std::string_view sourceParameterName = is2dArray ? "sourceArray"sv : "source"sv;
std::string_view const sourceParameterName = is2dArray ? "sourceArray"sv : "source"sv;
// horizontal pass
mi->setParameter(sourceParameterName, hwIn, {
.filterMag = SamplerMagFilter::LINEAR,
@@ -1180,7 +1212,7 @@ PostProcessManager::ScreenSpaceRefConfig PostProcessManager::prepareMipmapSSR(Fr
// The kernel-size was determined empirically so that we don't get too many artifacts
// due to the down-sampling with a box filter (which happens implicitly).
// requires only 6 stored coefficients and 11 tap/pass
// Requires only 6 stored coefficients and 11 tap/pass
// e.g.: size of 13 (4 stored coefficients)
// +-------+-------+-------*===*-------+-------+-------+
// ... | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | ...
@@ -1344,10 +1376,10 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::generateMipmapSSR(
FrameGraphId<FrameGraphTexture> output,
bool needInputDuplication, ScreenSpaceRefConfig const& config) noexcept {
// descriptor of our actual input image (e.g. reflection buffer or refraction framebuffer)
// Descriptor of our actual input image (e.g. reflection buffer or refraction framebuffer)
auto const& desc = fg.getDescriptor(input);
// descriptor of the destination. output is a subresource (i.e. a layer of a 2D array)
// Descriptor of the destination. `output` is a subresource (i.e. a layer of a 2D array)
auto const& outDesc = fg.getDescriptor(output);
/*
@@ -1396,7 +1428,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> depth,
const CameraInfo& cameraInfo,
bool translucent,
float bokehAspectRatio,
float2 bokehScale,
const DepthOfFieldOptions& dofOptions) noexcept {
assert_invariant(depth);
@@ -1407,7 +1439,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
const TextureFormat format = translucent ? TextureFormat::RGBA16F
: TextureFormat::R11F_G11F_B10F;
// rotate the bokeh based on the aperture diameter (i.e. angle of the blades)
// Rotate the bokeh based on the aperture diameter (i.e. angle of the blades)
float bokehAngle = f::PI / 6.0f;
if (dofOptions.maxApertureDiameter > 0.0f) {
bokehAngle += f::PI_2 * saturate(cameraInfo.A / dofOptions.maxApertureDiameter);
@@ -1651,8 +1683,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
// we assume the width/height is already multiple of 16
assert_invariant(!(colorDesc.width & 0xF) && !(colorDesc.height & 0xF));
const uint32_t tileBufferWidth = colorDesc.width / dofResolution;
const uint32_t tileBufferHeight = colorDesc.height / dofResolution;
const uint32_t tileBufferWidth = width;
const uint32_t tileBufferHeight = height;
const size_t tileReductionCount = ctz(tileSize / dofResolution);
struct PostProcessDofTiling1 {
@@ -1786,8 +1818,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
mi->setParameter("tiles", tilesCocMinMax,
{ .filterMin = SamplerMinFilter::NEAREST });
mi->setParameter("cocToTexelScale", float2{
bokehAspectRatio / (inputDesc.width * dofResolution),
1.0 / (inputDesc.height * dofResolution)
bokehScale.x / (inputDesc.width * dofResolution),
bokehScale.y / (inputDesc.height * dofResolution)
});
mi->setParameter("cocToPixelScale", (1.0f / float(dofResolution)));
mi->setParameter("ringCounts", float4{
@@ -1893,14 +1925,6 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
return ppDoFCombine->output;
}
PostProcessManager::BloomPassOutput PostProcessManager::bloom(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input,
BloomOptions& inoutBloomOptions,
backend::TextureFormat outFormat,
math::float2 scale) noexcept {
return bloomPass(fg, input, outFormat, inoutBloomOptions, scale);
}
FrameGraphId<FrameGraphTexture> PostProcessManager::downscalePass(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input,
FrameGraphTexture::Descriptor const& outDesc,
@@ -1932,9 +1956,11 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::downscalePass(FrameGraph& fg
return downsamplePass->output;
}
PostProcessManager::BloomPassOutput PostProcessManager::bloomPass(FrameGraph& fg,
PostProcessManager::BloomPassOutput PostProcessManager::bloom(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input, TextureFormat outFormat,
BloomOptions& inoutBloomOptions, float2 scale) noexcept {
BloomOptions& inoutBloomOptions,
TemporalAntiAliasingOptions const& taaOptions,
float2 scale) noexcept {
// Figure out a good size for the bloom buffer. We must use a fixed bloom buffer size so
// that the size/strength of the bloom doesn't vary much with the resolution, otherwise
@@ -1976,6 +2002,9 @@ PostProcessManager::BloomPassOutput PostProcessManager::bloomPass(FrameGraph& fg
bool threshold = inoutBloomOptions.threshold;
// we don't need to do the fireflies reduction if we have TAA (it already does it)
bool fireflies = threshold && !taaOptions.enabled;
while (2 * bloomWidth < float(desc.width) || 2 * bloomHeight < float(desc.height)) {
if (inoutBloomOptions.quality == QualityLevel::LOW ||
inoutBloomOptions.quality == QualityLevel::MEDIUM) {
@@ -1984,8 +2013,9 @@ PostProcessManager::BloomPassOutput PostProcessManager::bloomPass(FrameGraph& fg
.height = (desc.height = std::max(1u, desc.height / 2)),
.format = outFormat
},
threshold, inoutBloomOptions.highlight, threshold);
threshold, inoutBloomOptions.highlight, fireflies);
threshold = false; // we do the thresholding only once during down sampling
fireflies = false; // we do the fireflies reduction only once during down sampling
} else if (inoutBloomOptions.quality == QualityLevel::HIGH ||
inoutBloomOptions.quality == QualityLevel::ULTRA) {
// In high quality mode, we increase the size of the bloom buffer such that the
@@ -2006,7 +2036,7 @@ PostProcessManager::BloomPassOutput PostProcessManager::bloomPass(FrameGraph& fg
input = downscalePass(fg, input,
{ .width = width, .height = height, .format = outFormat },
threshold, inoutBloomOptions.highlight, threshold);
threshold, inoutBloomOptions.highlight, fireflies);
struct BloomPassData {
FrameGraphId<FrameGraphTexture> out;
@@ -2539,6 +2569,8 @@ void PostProcessManager::prepareTaa(FrameGraph& fg,
case JitterPattern::HALTON_23_X8:
return sHaltonSamples(frameIndex % 8);
case JitterPattern::HALTON_23_X16:
return sHaltonSamples(frameIndex % 16);
case JitterPattern::HALTON_23_X32:
return sHaltonSamples(frameIndex);
}
};
@@ -2588,6 +2620,7 @@ void PostProcessManager::configureTemporalAntiAliasingMaterial(
}
};
setConstantParameter(ma, "upscaling", taaOptions.upscaling);
setConstantParameter(ma, "historyReprojection", taaOptions.historyReprojection);
setConstantParameter(ma, "filterHistory", taaOptions.filterHistory);
setConstantParameter(ma, "filterInput", taaOptions.filterInput);
@@ -2635,6 +2668,10 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::taa(FrameGraph& fg,
auto& taaPass = fg.addPass<TAAData>("TAA",
[&](FrameGraph::Builder& builder, auto& data) {
auto desc = fg.getDescriptor(input);
if (taaOptions.upscaling) {
desc.width *= 2;
desc.height *= 2;
}
data.color = builder.sample(input);
data.depth = builder.sample(depth);
data.history = builder.sample(colorHistory);
@@ -2669,18 +2706,26 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::taa(FrameGraph& fg,
{ -1.0f, 1.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f },
};
float sum = 0.0;
constexpr float2 subSampleOffsets[4] = {
{ -0.25f, 0.25f }, { 0.25f, 0.25f }, { 0.25f, -0.25f }, { -0.25f, -0.25f }
};
float4 sum = 0.0;
float4 weights[9];
// this doesn't get vectorized (probably because of exp()), so don't bother
// unrolling it.
#pragma nounroll
for (size_t i = 0; i < 9; i++) {
float2 const d = (sampleOffsets[i] - current.jitter) / taaOptions.filterWidth;
// This is a gaussian fit of a 3.3-wide Blackman-Harris window
// see: "High Quality Temporal Supersampling" by Brian Karis
weights[i][0] = std::exp(-2.29f * (d.x * d.x + d.y * d.y));
sum += weights[i][0];
float2 const o = sampleOffsets[i];
for (size_t j = 0; j < 4; j++) {
float2 const s = taaOptions.upscaling ? subSampleOffsets[j] : float2{ 0 };
float2 const d = (o - current.jitter - s) / taaOptions.filterWidth;
// This is a gaussian fit of a 3.3-wide Blackman-Harris window
// see: "High Quality Temporal Supersampling" by Brian Karis
weights[i][j] = std::exp(-2.29f * (d.x * d.x + d.y * d.y));
}
sum += weights[i];
}
for (auto& w : weights) {
w /= sum;
@@ -2725,24 +2770,77 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::taa(FrameGraph& fg,
});
input = colorGradingConfig.asSubpass ? taaPass->tonemappedOutput : taaPass->output;
auto history = input;
// optional sharpen pass from FSR1
if (taaOptions.sharpness > 0.0f) {
input = rcas(fg, taaOptions.sharpness,
input, fg.getDescriptor(input), colorGradingConfig.translucent);
}
struct ExportColorHistoryData {
FrameGraphId<FrameGraphTexture> color;
};
auto& exportHistoryPass = fg.addPass<ExportColorHistoryData>("Export TAA history",
fg.addPass<ExportColorHistoryData>("Export TAA history",
[&](FrameGraph::Builder& builder, auto& data) {
// We need to use sideEffect here to ensure this pass won't be culled.
// The "output" of this pass is going to be used during the next frame as
// an "import".
builder.sideEffect();
data.color = builder.sample(input); // FIXME: an access must be declared for detach(), why?
}, [&current](FrameGraphResources const& resources, auto const& data,
backend::DriverApi&) {
resources.detach(data.color,
&current.color, &current.desc);
data.color = builder.sample(history); // FIXME: an access must be declared for detach(), why?
}, [&current](FrameGraphResources const& resources, auto const& data, auto&) {
resources.detach(data.color, &current.color, &current.desc);
});
return exportHistoryPass->color;
return input;
}
FrameGraphId<FrameGraphTexture> PostProcessManager::rcas(
FrameGraph& fg,
float sharpness,
FrameGraphId<FrameGraphTexture> input,
FrameGraphTexture::Descriptor const& outDesc,
bool translucent) {
struct QuadBlitData {
FrameGraphId<FrameGraphTexture> input;
FrameGraphId<FrameGraphTexture> output;
};
auto& ppFsrRcas = fg.addPass<QuadBlitData>("FidelityFX FSR1 Rcas",
[&](FrameGraph::Builder& builder, auto& data) {
data.input = builder.sample(input);
data.output = builder.createTexture("FFX FSR1 Rcas output", outDesc);
data.output = builder.declareRenderPass(data.output);
},
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
auto input = resources.getTexture(data.input);
auto out = resources.getRenderPassInfo();
auto const& outputDesc = resources.getDescriptor(data.input);
auto& material = getPostProcessMaterial("fsr_rcas");
FMaterialInstance* const mi = material.getMaterialInstance(mEngine);
FSRUniforms uniforms;
FSR_SharpeningSetup(&uniforms, { .sharpness = 2.0f - 2.0f * sharpness });
mi->setParameter("RcasCon", uniforms.RcasCon);
mi->setParameter("color", input, {}); // uses texelFetch
mi->setParameter("resolution", float4{
outputDesc.width, outputDesc.height,
1.0f / outputDesc.width, 1.0f / outputDesc.height });
mi->commit(driver);
mi->use(driver);
const uint8_t variant = uint8_t(
translucent ? PostProcessVariant::TRANSLUCENT : PostProcessVariant::OPAQUE);
PipelineState const pipeline(material.getPipelineState(mEngine, variant));
render(out, pipeline, driver);
});
return ppFsrRcas->output;
}
FrameGraphId<FrameGraphTexture> PostProcessManager::upscale(FrameGraph& fg, bool translucent,
@@ -2905,41 +3003,9 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::upscale(FrameGraph& fg, bool
auto output = ppQuadBlit->output;
// if we had to take the low quality fallback, we still do the "sharpen pass"
if (dsrOptions.sharpness > 0.0f && (dsrOptions.quality != QualityLevel::LOW || lowQualityFallback)) {
auto& ppFsrRcas = fg.addPass<QuadBlitData>("FidelityFX FSR1 Rcas",
[&](FrameGraph::Builder& builder, auto& data) {
data.input = builder.sample(output);
data.output = builder.createTexture("FFX FSR1 Rcas output", outDesc);
data.output = builder.declareRenderPass(data.output);
},
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
auto color = resources.getTexture(data.input);
auto out = resources.getRenderPassInfo();
auto const& outputDesc = resources.getDescriptor(data.output);
auto& material = getPostProcessMaterial("fsr_rcas");
FMaterialInstance* const mi = material.getMaterialInstance(mEngine);
FSRUniforms uniforms;
FSR_SharpeningSetup(&uniforms, { .sharpness = 2.0f - 2.0f * dsrOptions.sharpness });
mi->setParameter("RcasCon", uniforms.RcasCon);
mi->setParameter("color", color, { }); // uses texelFetch
mi->setParameter("resolution", float4{
outputDesc.width, outputDesc.height,
1.0f / outputDesc.width, 1.0f / outputDesc.height });
mi->commit(driver);
mi->use(driver);
const uint8_t variant = uint8_t(translucent ?
PostProcessVariant::TRANSLUCENT : PostProcessVariant::OPAQUE);
PipelineState const pipeline(material.getPipelineState(mEngine, variant));
render(out, pipeline, driver);
});
output = ppFsrRcas->output;
if (dsrOptions.sharpness > 0.0f &&
(dsrOptions.quality != QualityLevel::LOW || lowQualityFallback)) {
output = rcas(fg, dsrOptions.sharpness, output, outDesc, translucent);
}
// we rely on automatic culling of unused render passes
@@ -3149,7 +3215,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::vsmMipmapPass(FrameGraph& fg
auto& material = getPostProcessMaterial("vsmMipmap");
// When generating shadow map mip levels, we want to preserve the 1 texel border.
// (note clearing never respects the scissor in filament)
// (note clearing never respects the scissor in Filament)
PipelineState pipeline(material.getPipelineState(mEngine));
pipeline.scissor = { 1u, 1u, dim - 2u, dim - 2u };
@@ -3208,4 +3274,51 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::debugShadowCascades(FrameGra
return debugShadowCascadePass->output;
}
FrameGraphId<FrameGraphTexture> PostProcessManager::debugDisplayShadowTexture(
FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input,
FrameGraphId<FrameGraphTexture> shadowmap, float scale,
uint8_t layer, uint8_t level, uint8_t channel, float power) noexcept {
if (shadowmap) {
struct ShadowMapData {
FrameGraphId<FrameGraphTexture> color;
FrameGraphId<FrameGraphTexture> depth;
};
auto const& desc = fg.getDescriptor(input);
float const ratio = float(desc.height) / float(desc.width);
float const screenScale = float(fg.getDescriptor(shadowmap).height) / float(desc.height);
float2 const s = { screenScale * scale * ratio, screenScale * scale };
auto& shadomapDebugPass = fg.addPass<ShadowMapData>("shadowmap debug pass",
[&](FrameGraph::Builder& builder, auto& data) {
data.color = builder.read(input,
FrameGraphTexture::Usage::COLOR_ATTACHMENT);
data.color = builder.write(data.color,
FrameGraphTexture::Usage::COLOR_ATTACHMENT);
data.depth = builder.sample(shadowmap);
builder.declareRenderPass("color target", {
.attachments = { .color = { data.color }}
});
},
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
auto out = resources.getRenderPassInfo();
auto in = resources.getTexture(data.depth);
auto const& material = getPostProcessMaterial("shadowmap");
FMaterialInstance* const mi = material.getMaterialInstance(mEngine);
mi->setParameter("shadowmap", in, {
.filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST });
mi->setParameter("scale", s);
mi->setParameter("layer", (uint32_t)layer);
mi->setParameter("level", (uint32_t)level);
mi->setParameter("channel", (uint32_t)channel);
mi->setParameter("power", power);
commitAndRender(out, material, driver);
});
input = shadomapDebugPass->color;
}
return input;
}
} // namespace filament
+19 -8
View File
@@ -36,6 +36,7 @@
#include <tsl/robin_map.h>
#include <array>
#include <random>
#include <string_view>
#include <variant>
@@ -162,7 +163,7 @@ public:
FrameGraphId<FrameGraphTexture> depth,
const CameraInfo& cameraInfo,
bool translucent,
float bokehAspectRatio,
math::float2 bokehScale,
const DepthOfFieldOptions& dofOptions) noexcept;
// Bloom
@@ -171,7 +172,9 @@ public:
FrameGraphId<FrameGraphTexture> flare;
};
BloomPassOutput bloom(FrameGraph& fg, FrameGraphId<FrameGraphTexture> input,
BloomOptions& inoutBloomOptions, backend::TextureFormat outFormat,
backend::TextureFormat outFormat,
BloomOptions& inoutBloomOptions,
TemporalAntiAliasingOptions const& taaOptions,
math::float2 scale) noexcept;
FrameGraphId<FrameGraphTexture> flarePass(FrameGraph& fg,
@@ -239,6 +242,13 @@ public:
filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc,
backend::SamplerMagFilter filter) noexcept;
FrameGraphId<FrameGraphTexture> rcas(
FrameGraph& fg,
float sharpness,
FrameGraphId<FrameGraphTexture> input,
FrameGraphTexture::Descriptor const& outDesc,
bool translucent);
// upscale/downscale blitter using shaders
FrameGraphId<FrameGraphTexture> blit(FrameGraph& fg, bool translucent,
FrameGraphId<FrameGraphTexture> input,
@@ -272,6 +282,11 @@ public:
FrameGraphId<FrameGraphTexture> input,
FrameGraphId<FrameGraphTexture> depth) noexcept;
FrameGraphId<FrameGraphTexture> debugDisplayShadowTexture(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input,
FrameGraphId<FrameGraphTexture> shadowmap, float scale,
uint8_t layer, uint8_t level, uint8_t channel, float power) noexcept;
backend::Handle<backend::HwTexture> getOneTexture() const;
backend::Handle<backend::HwTexture> getZeroTexture() const;
backend::Handle<backend::HwTexture> getOneTextureArray() const;
@@ -342,10 +357,6 @@ private:
math::int2 axis, float zf, backend::TextureFormat format,
BilateralPassConfig const& config) noexcept;
BloomPassOutput bloomPass(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input, backend::TextureFormat outFormat,
BloomOptions& inoutBloomOptions, math::float2 scale) noexcept;
FrameGraphId<FrameGraphTexture> downscalePass(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input,
FrameGraphTexture::Descriptor const& outDesc,
@@ -364,12 +375,12 @@ private:
template<size_t SIZE>
struct JitterSequence {
auto operator()(size_t i) const noexcept { return positions[i % SIZE] - 0.5f; }
const math::float2 positions[SIZE];
const std::array<math::float2, SIZE> positions;
};
static const JitterSequence<4> sRGSS4;
static const JitterSequence<4> sUniformHelix4;
static const JitterSequence<16> sHaltonSamples;
static const JitterSequence<32> sHaltonSamples;
bool mWorkaroundSplitEasu : 1;
bool mWorkaroundAllowReadOnlyAncillaryFeedbackLoop : 1;
+6
View File
@@ -294,6 +294,8 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FEngine& engine, FrameG
// Shadow Passes
// -------------------------------------------------------------------------------------------
fg.getBlackboard()["shadowmap"] = prepareShadowPass->shadows;
struct ShadowPassData {
FrameGraphId<FrameGraphTexture> tempBlurSrc{}; // temporary shadowmap when blurring
FrameGraphId<FrameGraphTexture> output;
@@ -943,6 +945,10 @@ void ShadowMapManager::calculateTextureRequirements(FEngine& engine, FView& view
mipLevels = std::max(1, FTexture::maxLevelCount(maxDimension) - lowMipmapLevel);
}
// publish the debugging data
engine.debug.shadowmap.display_shadow_texture_layer_count = layersNeeded;
engine.debug.shadowmap.display_shadow_texture_level_count = mipLevels;
mTextureAtlasRequirements = {
(uint16_t)maxDimension,
layersNeeded,
+5 -4
View File
@@ -30,11 +30,12 @@
#include <math/vec4.h>
#include <utils/JobSystem.h>
#include <utils/SpinLock.h>
#include <utils/Mutex.h>
#include <utils/Systrace.h>
#include <cmath>
#include <cstdlib>
#include <mutex>
#include <tuple>
namespace filament {
@@ -648,9 +649,9 @@ FColorGrading::FColorGrading(FEngine& engine, const Builder& builder) {
Config c;
// This lock protects the data inside Config, which is written to by the Filament thread,
// and read from multiple Job threads.
utils::SpinLock configLock;
utils::Mutex configLock;
{
std::lock_guard<utils::SpinLock> lock(configLock);
std::lock_guard<utils::Mutex> const lock(configLock);
c.lutDimension = builder->dimension;
c.adaptationTransform = adaptationTransform(builder->whiteBalance);
c.colorGradingIn = selectColorGradingTransformIn(builder->toneMapping);
@@ -687,7 +688,7 @@ FColorGrading::FColorGrading(FEngine& engine, const Builder& builder) {
[data, converted, b, &c, &configLock, builder](JobSystem&, JobSystem::Job*) {
Config config;
{
std::lock_guard<utils::SpinLock> lock(configLock);
std::lock_guard<utils::Mutex> lock(configLock);
config = c;
}
half4* UTILS_RESTRICT p = (half4*) data + b * config.lutDimension * config.lutDimension;
+8
View File
@@ -548,12 +548,20 @@ public:
struct {
struct {
bool debug_directional_shadowmap = false;
bool display_shadow_texture = false;
bool far_uses_shadowcasters = true;
bool focus_shadowcasters = true;
bool visualize_cascades = false;
bool tightly_bound_scene = true;
float dzn = -1.0f;
float dzf = 1.0f;
float display_shadow_texture_scale = 0.25f;
int display_shadow_texture_layer = 0;
int display_shadow_texture_level = 0;
int display_shadow_texture_channel = 0;
int display_shadow_texture_layer_count = 0;
int display_shadow_texture_level_count = 0;
float display_shadow_texture_power = 1;
} shadowmap;
struct {
bool camera_at_origin = true;
+1
View File
@@ -33,6 +33,7 @@
#include <utils/Mutex.h>
#include <atomic>
#include <optional>
namespace filament {
+1 -1
View File
@@ -117,7 +117,7 @@ void FMaterialInstance::initDefaultInstance(FEngine& engine, FMaterial const* ma
if (!material->getSamplerInterfaceBlock().isEmpty()) {
mSamplers = SamplerGroup(material->getSamplerInterfaceBlock().getSize());
mSbHandle = driver.createSamplerGroup(
mSamplers.getSize(), utils::FixedSizeString<32>("Default material"));
mSamplers.getSize(), utils::FixedSizeString<32>(mMaterial->getName().c_str_safe()));
}
const RasterState& rasterState = material->getRasterState();
+54 -7
View File
@@ -70,6 +70,22 @@ FRenderer::FRenderer(FEngine& engine) :
&engine.debug.renderer.doFrameCapture);
debugRegistry.registerProperty("d.renderer.disable_buffer_padding",
&engine.debug.renderer.disable_buffer_padding);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture",
&engine.debug.shadowmap.display_shadow_texture);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture_scale",
&engine.debug.shadowmap.display_shadow_texture_scale);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture_layer",
&engine.debug.shadowmap.display_shadow_texture_layer);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture_level",
&engine.debug.shadowmap.display_shadow_texture_level);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture_channel",
&engine.debug.shadowmap.display_shadow_texture_channel);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture_layer_count",
&engine.debug.shadowmap.display_shadow_texture_layer_count);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture_level_count",
&engine.debug.shadowmap.display_shadow_texture_level_count);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture_power",
&engine.debug.shadowmap.display_shadow_texture_power);
DriverApi& driver = engine.getDriverApi();
@@ -495,6 +511,14 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
// This configures post-process materials by setting constant parameters
if (taaOptions.enabled) {
ppm.configureTemporalAntiAliasingMaterial(taaOptions);
if (taaOptions.upscaling) {
// for now TAA upscaling is incompatible with regular dsr
dsrOptions.enabled = false;
// also, upscaling doesn't work well with quater-resolution SSAO
aoOptions.resolution = 1.0;
// Currently we only support a fixed TAA upscaling ratio
scale = 0.5f;
}
}
}
@@ -525,7 +549,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
};
// whether we're scaled at all
const bool scaled = any(notEqual(scale, float2(1.0f)));
bool scaled = any(notEqual(scale, float2(1.0f)));
// vp is the user defined viewport within the View
filament::Viewport const& vp = view.getViewport();
@@ -614,7 +638,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
view.prepare(engine, driver, arena, svp, cameraInfo, getShaderUserTime(), needsAlphaChannel);
view.prepareUpscaler(scale, dsrOptions);
view.prepareUpscaler(scale, taaOptions, dsrOptions);
/*
* Allocate command buffer
@@ -977,8 +1001,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
auto& history = view.getFrameHistory();
auto& current = history.getCurrent();
current.ssr.projection = projection;
resources.detach(data.history,
&current.ssr.color, &current.ssr.desc);
resources.detach(data.history, &current.ssr.color, &current.ssr.desc);
});
}
@@ -1011,6 +1034,15 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
if (taaOptions.enabled) {
input = ppm.taa(fg, input, depth, view.getFrameHistory(), &FrameHistoryEntry::taa,
taaOptions, colorGradingConfig);
if (taaOptions.upscaling) {
scale = 1.0f;
scaled = false;
UTILS_UNUSED_IN_RELEASE auto const& inputDesc = fg.getDescriptor(input);
svp.width = inputDesc.width;
svp.height = inputDesc.height;
xvp.width *= 2;
xvp.height *= 2;
}
}
// --------------------------------------------------------------------------------------------
@@ -1026,16 +1058,21 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
// The bokeh height is always correct regardless of the dynamic resolution scaling.
// (because the CoC is calculated w.r.t. the height), so we only need to adjust
// the width.
float const bokehAspectRatio = scale.x / scale.y;
float const aspect = (scale.x / scale.y) * dofOptions.cocAspectRatio;
float2 const bokehScale{
aspect < 1.0f ? aspect : 1.0f,
aspect > 1.0f ? 1.0f / aspect : 1.0f
};
input = ppm.dof(fg, input, depth, cameraInfo, needsAlphaChannel,
bokehAspectRatio, dofOptions);
bokehScale, dofOptions);
}
FrameGraphId<FrameGraphTexture> bloom, flare;
if (bloomOptions.enabled) {
// Generate the bloom buffer, which is stored in the blackboard as "bloom". This is
// consumed by the colorGrading pass and will be culled if colorGrading is disabled.
auto [bloom_, flare_] = ppm.bloom(fg, input, bloomOptions, TextureFormat::R11F_G11F_B10F, scale);
auto [bloom_, flare_] = ppm.bloom(fg, input, TextureFormat::R11F_G11F_B10F,
bloomOptions, taaOptions, scale);
bloom = bloom_;
flare = flare_;
}
@@ -1112,6 +1149,16 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
"SwapChain::CONFIG_HAS_STENCIL_BUFFER flag set.");
}
if (UTILS_UNLIKELY(engine.debug.shadowmap.display_shadow_texture)) {
auto shadowmap = blackboard.get<FrameGraphTexture>("shadowmap");
input = ppm.debugDisplayShadowTexture(fg, input, shadowmap,
engine.debug.shadowmap.display_shadow_texture_scale,
engine.debug.shadowmap.display_shadow_texture_layer,
engine.debug.shadowmap.display_shadow_texture_level,
engine.debug.shadowmap.display_shadow_texture_channel,
engine.debug.shadowmap.display_shadow_texture_power);
}
// auto debug = structure
// fg.forwardResource(fgViewRenderTarget, debug ? debug : input);
+15 -4
View File
@@ -725,11 +725,22 @@ UTILS_NOINLINE
});
}
void FView::prepareUpscaler(float2 scale, DynamicResolutionOptions const& options) const noexcept {
void FView::prepareUpscaler(float2 scale,
TemporalAntiAliasingOptions const& taaOptions,
DynamicResolutionOptions const& dsrOptions) const noexcept {
SYSTRACE_CALL();
const float bias = (options.quality >= QualityLevel::HIGH) ?
std::log2(std::min(scale.x, scale.y)) : 0.0f;
mPerViewUniforms.prepareLodBias(bias);
float bias = 0.0f;
float2 derivativesScale{ 1.0f };
if (dsrOptions.enabled && dsrOptions.quality >= QualityLevel::HIGH) {
bias = std::log2(std::min(scale.x, scale.y));
}
if (taaOptions.enabled) {
bias += taaOptions.lodBias;
if (taaOptions.upscaling) {
derivativesScale = 0.5f;
}
}
mPerViewUniforms.prepareLodBias(bias, derivativesScale);
}
void FView::prepareCamera(FEngine& engine, const CameraInfo& cameraInfo) const noexcept {
+3 -1
View File
@@ -133,7 +133,9 @@ public:
return mName.c_str_safe();
}
void prepareUpscaler(math::float2 scale, DynamicResolutionOptions const& options) const noexcept;
void prepareUpscaler(math::float2 scale,
TemporalAntiAliasingOptions const& taaOptions,
DynamicResolutionOptions const& dsrOptions) const noexcept;
void prepareCamera(FEngine& engine, const CameraInfo& cameraInfo) const noexcept;
void prepareViewport(
+1 -1
View File
@@ -132,7 +132,7 @@ public:
Descriptor descriptor;
SubResourceDescriptor subResourceDescriptor;
// weather the resource was detached
// whether the resource was detached
bool detached = false;
// An Edge with added data from this resource
+103 -42
View File
@@ -34,6 +34,11 @@ material {
}
],
constants : [
{
type : bool,
name : upscaling,
default : false
},
{
type : bool,
name : historyReprojection,
@@ -109,12 +114,41 @@ fragment {
// no clipping (for debugging only)
#define BOX_CLIPPING_NONE 2
float luma(const vec3 color) {
if (materialConstants_useYCoCg) {
return color.x;
} else {
return luminance(color);
}
float rcp(float x) {
return 1.0 / x;
}
float lumaRGB(const vec3 c) {
return luminance(c);
}
float lumaYCoCg(const vec3 c) {
return c.x;
}
float luma(const vec3 c) {
return materialConstants_useYCoCg ? lumaYCoCg(c) : lumaRGB(c);
}
vec3 tonemap(const vec3 c) {
return c * rcp(1.0 + max3(c));
}
vec4 tonemap(const vec4 c) {
return vec4(c.rgb * rcp(1.0 + max3(c.rgb)), c.a);
}
vec3 tonemap(const float w, const vec3 c) {
return c * (w * rcp(1.0 + max3(c)));
}
vec4 tonemap(const float w, const vec4 c) {
return vec4(c.rgb * (w * rcp(1.0 + max3(c.rgb))), c.a);
}
vec3 untonemap(const vec3 c) {
const float epsilon = 1.0 / 65504.0;
return c * rcp(max(epsilon, 1.0 - max3(c)));
}
vec3 RGB_YCoCg(const vec3 c) {
@@ -159,15 +193,16 @@ vec4 clipToBox(const int quality,
// Optimized to 5 taps by removing the corner samples
// And modified for mediump support
vec4 sampleTextureCatmullRom(const sampler2D tex, const highp vec2 uv, const highp vec2 texSize) {
// We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding
// down the sample location to get the exact center of our "starting" texel. The starting texel will be at
// location [1, 1] in the grid, where [0, 0] is the top left corner.
// We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate.
// We'll do this by rounding down the sample location to get the exact center of our "starting"
// texel. The starting texel will be at location [1, 1] in the grid, where [0, 0] is the
// top left corner.
highp vec2 samplePos = uv * texSize;
highp vec2 texPos1 = floor(samplePos - 0.5) + 0.5;
// Compute the fractional offset from our starting texel to our original sample location, which we'll
// feed into the Catmull-Rom spline function to get our filter weights.
// Compute the fractional offset from our starting texel to our original sample location,
// which we'll feed into the Catmull-Rom spline function to get our filter weights.
highp vec2 f = samplePos - texPos1;
highp vec2 f2 = f * f;
highp vec2 f3 = f2 * f;
@@ -200,13 +235,20 @@ vec4 sampleTextureCatmullRom(const sampler2D tex, const highp vec2 uv, const hig
float k3 = w3.x * w12.y;
float k4 = w12.x * w3.y;
vec4 result = textureLod(tex, vec2(texPos12.x, texPos0.y), 0.0) * k0
+ textureLod(tex, vec2(texPos0.x, texPos12.y), 0.0) * k1
+ textureLod(tex, vec2(texPos12.x, texPos12.y), 0.0) * k2
+ textureLod(tex, vec2(texPos3.x, texPos12.y), 0.0) * k3
+ textureLod(tex, vec2(texPos12.x, texPos3.y), 0.0) * k4;
vec4 s[5];
s[0] = textureLod(tex, vec2(texPos12.x, texPos0.y), 0.0);
s[1] = textureLod(tex, vec2(texPos0.x, texPos12.y), 0.0);
s[2] = textureLod(tex, vec2(texPos12.x, texPos12.y), 0.0);
s[3] = textureLod(tex, vec2(texPos3.x, texPos12.y), 0.0);
s[4] = textureLod(tex, vec2(texPos12.x, texPos3.y), 0.0);
result *= 1.0 / (k0 + k1 + k2 + k3 + k4);
vec4 result = k0 * s[0]
+ k1 * s[1]
+ k2 * s[2]
+ k3 * s[3]
+ k4 * s[4];
result *= rcp(k0 + k1 + k2 + k3 + k4);
// we could end-up with negative values
result = max(vec4(0), result);
@@ -240,8 +282,9 @@ void postProcess(inout PostProcessInputs postProcess) {
history.rgb = RGB_YCoCg(history.rgb);
}
highp vec2 p = uv.xy;
vec4 color = textureLod(materialParams_color, p, 0.0);
highp vec2 size = vec2(textureSize(materialParams_color, 0));
highp vec2 p = (floor(uv.xy * size) + 0.5) / size;
vec4 filtered = textureLod(materialParams_color, p, 0.0);
vec3 s[9];
if (materialConstants_filterInput || materialConstants_boxClipping != BOX_CLIPPING_NONE) {
@@ -249,31 +292,48 @@ void postProcess(inout PostProcessInputs postProcess) {
s[1] = textureLodOffset(materialParams_color, p, 0.0, ivec2( 0, -1)).rgb;
s[2] = textureLodOffset(materialParams_color, p, 0.0, ivec2( 1, -1)).rgb;
s[3] = textureLodOffset(materialParams_color, p, 0.0, ivec2(-1, 0)).rgb;
s[4] = color.rgb;
s[4] = filtered.rgb;
s[5] = textureLodOffset(materialParams_color, p, 0.0, ivec2( 1, 0)).rgb;
s[6] = textureLodOffset(materialParams_color, p, 0.0, ivec2(-1, 1)).rgb;
s[7] = textureLodOffset(materialParams_color, p, 0.0, ivec2( 0, 1)).rgb;
s[8] = textureLodOffset(materialParams_color, p, 0.0, ivec2( 1, 1)).rgb;
}
if (materialConstants_useYCoCg) {
color.rgb = RGB_YCoCg(color.rgb);
if (materialConstants_filterInput || materialConstants_boxClipping != BOX_CLIPPING_NONE) {
if (materialConstants_useYCoCg) {
for (int i = 0; i < 9; i++) {
s[i] = RGB_YCoCg(s[i]);
}
}
}
vec4 filtered;
vec2 subPixelOffset = p - uv.xy; // +/- [0.25, 0.25]
float confidence = materialConstants_upscaling ? 0.0 : 1.0;
if (materialConstants_filterInput) {
// unjitter/filter input
filtered = vec4(0, 0, 0, color.a);
for (int i = 0; i < 9; i++) {
filtered.rgb += s[i] * materialParams.filterWeights[i][0];
// figure out which set of coeficients to use
filtered = vec4(0, 0, 0, filtered.a);
if (materialConstants_upscaling) {
int jxp = subPixelOffset.y > 0.0 ? 3 : 0;
int jxn = subPixelOffset.y > 0.0 ? 2 : 1;
int j = subPixelOffset.x > 0.0 ? jxp : jxn;
for (int i = 0; i < 9; i++) {
float w = materialParams.filterWeights[i][j];
filtered.rgb += s[i] * w;
confidence = max(confidence, w);
}
} else {
for (int i = 0; i < 9; i++) {
float w = materialParams.filterWeights[i][0];
filtered.rgb += s[i] * w;
}
}
} else {
filtered = color;
if (materialConstants_useYCoCg) {
filtered.rgb = RGB_YCoCg(filtered.rgb);
}
if (materialConstants_upscaling) {
confidence = float(materialParams.jitter.x * subPixelOffset.x > 0.0 &&
materialParams.jitter.y * subPixelOffset.y > 0.0);
}
}
// build the history clamping box
@@ -318,29 +378,30 @@ void postProcess(inout PostProcessInputs postProcess) {
history = clipToBox(materialConstants_boxClipping, boxmin, boxmax, filtered, history);
}
float lumaColor = luma(filtered.rgb);
float lumaHistory = luma(history.rgb);
float alpha = materialParams.alpha;
float alpha = materialParams.alpha * confidence;
if (materialConstants_preventFlickering) {
// [Lottes] prevents flickering by modulating the blend weight by the difference in luma
float lumaColor = luma(filtered.rgb);
float lumaHistory = luma(history.rgb);
float diff = 1.0 - abs(lumaColor - lumaHistory) / (0.001 + max(lumaColor, lumaHistory));
alpha *= diff * diff;
}
// tonemapping for handling HDR
filtered.rgb *= 1.0 / (1.0 + lumaColor);
history.rgb *= 1.0 / (1.0 + lumaHistory);
// go back to RGB space before tonemapping
if (materialConstants_useYCoCg) {
filtered.rgb = YCoCg_RGB(filtered.rgb);
history.rgb = YCoCg_RGB(history.rgb);
}
// tonemap before mixing
filtered.rgb = tonemap(filtered.rgb);
history.rgb = tonemap(history.rgb);
// combine history and current frame
vec4 result = mix(history, filtered, alpha);
// untonemap result
result.rgb *= 1.0 / (1.0 - luma(result.rgb));
if (materialConstants_useYCoCg) {
result.rgb = YCoCg_RGB(result.rgb);
}
result.rgb = untonemap(result.rgb);
#if POST_PROCESS_OPAQUE
// kill the work performed above
+5
View File
@@ -43,6 +43,8 @@ fragment {
#define FSR_RCAS_F 1
#if !POST_PROCESS_OPAQUE
# define FSR_RCAS_PASSTHROUGH_ALPHA
// todo: make this a spec constant
# define FSR_RCAS_DENOISE
#endif
#include "ffx_fsr1.h"
@@ -61,6 +63,9 @@ fragment {
#endif
p, materialParams.RcasCon);
// todo: make this an option
postProcess.color.rgb = max(vec3(0), postProcess.color.rgb);
#if POST_PROCESS_OPAQUE
postProcess.color.a = 1.0;
#endif
+59
View File
@@ -0,0 +1,59 @@
material {
name : shadowmap,
parameters : [
{
type : sampler2dArray,
name : shadowmap,
precision : high
},
{
type : float,
name : power,
precision : high
},
{
type : float2,
name : scale,
},
{
type : int,
name : layer
},
{
type : int,
name : level
},
{
type : int,
name : channel
}
],
variables : [
vertex
],
vertexDomain : device,
depthWrite : false,
depthCulling : false,
domain: postprocess
}
vertex {
void postProcessVertex(inout PostProcessVertexInputs postProcess) {
postProcess.vertex.xy = postProcess.normalizedUV;
postProcess.position.xy = 1.0 + (postProcess.position.xy - 1.0) * materialParams.scale;
}
}
fragment {
void dummy(){}
void postProcess(inout PostProcessInputs postProcess) {
highp vec2 uv = uvToRenderTargetUV(variable_vertex.xy);
highp vec3 p = vec3(uv, float(materialParams.layer));
float m = float(materialParams.level);
highp float c = textureLod(materialParams_shadowmap, p, m)[materialParams.channel];
c = pow(abs(c), materialParams.power);
postProcess.color.rgb = vec3(c);
postProcess.color.a = 1.0;
}
}
+2 -2
View File
@@ -1,12 +1,12 @@
Pod::Spec.new do |spec|
spec.name = "Filament"
spec.version = "1.49.3"
spec.version = "1.50.0"
spec.license = { :type => "Apache 2.0", :file => "LICENSE" }
spec.homepage = "https://google.github.io/filament"
spec.authors = "Google LLC."
spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL."
spec.platform = :ios, "11.0"
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.49.3/filament-v1.49.3-ios.tgz" }
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.50.0/filament-v1.50.0-ios.tgz" }
# Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon.
spec.pod_target_xcconfig = {
@@ -47,6 +47,9 @@ const float kToastDelayDuration = 2.0f;
- (void)createRenderables;
- (void)createLights;
- (void)appWillResignActive:(NSNotification*)notification;
- (void)appDidBecomeActive:(NSNotification*)notification;
@end
@implementation FILViewController {
@@ -73,6 +76,16 @@ const float kToastDelayDuration = 2.0f;
self.title = @"https://google.github.io/filament/remote";
// Observe lifecycle notifications to prevent us from rendering in the background.
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(appWillResignActive:)
name:UIApplicationWillResignActiveNotification
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(appDidBecomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
// Arguments:
// --model <path>
// path to glb or gltf file to load from documents directory
@@ -125,6 +138,14 @@ const float kToastDelayDuration = 2.0f;
[self.view addSubview:_toastLabel];
}
- (void)appWillResignActive:(NSNotification*)notification {
[self stopDisplayLink];
}
- (void)appDidBecomeActive:(NSNotification*)notification {
[self startDisplayLink];
}
- (void)viewWillAppear:(BOOL)animated {
[self startDisplayLink];
}
@@ -330,6 +351,7 @@ const float kToastDelayDuration = 2.0f;
}
- (void)dealloc {
[NSNotificationCenter.defaultCenter removeObserver:self];
delete _server;
delete _automation;
self.modelView.engine->destroy(_indirectLight);
+108
View File
@@ -0,0 +1,108 @@
cmake_minimum_required(VERSION 3.19)
project(astrict)
set(TARGET astrict)
set(PUBLIC_HDR_DIR include)
# ==================================================================================================
# Sources and headers
# ==================================================================================================
set(HDRS
include/astrict/CommonTypes.h
include/astrict/DebugCommon.h
include/astrict/DebugGlsl.h
include/astrict/FromGlsl.h
include/astrict/GlslTypes.h
include/astrict/ToGlsl.h)
set(PRIVATE_HDRS)
set(SRCS
src/DebugCommon.cpp
src/DebugGlsl.cpp
src/FromGlsl.cpp
src/ToGlsl.cpp)
# ==================================================================================================
# Include and target definitions
# ==================================================================================================
include_directories(${PUBLIC_HDR_DIR})
include_directories(${CMAKE_BINARY_DIR})
# astrict
add_library(${TARGET} STATIC ${HDRS} ${PRIVATE_HDRS} ${SRCS})
target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
set_target_properties(${TARGET} PROPERTIES FOLDER Libs)
target_link_libraries(${TARGET} backend_headers math utils)
# We are being naughty and accessing private headers here
# For spirv-tools, we're just following glslang's example
target_include_directories(${TARGET} PRIVATE ${spirv-tools_SOURCE_DIR}/include)
# glslang libraries have circular dependencies. To make sure the proper object are part of the link
# we need to force archive re-scan on new symbol dependencies via start/end-group.
# Read more about this here https://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking
if (APPLE OR MSVC)
target_link_libraries(${TARGET} glslang SPIRV SPIRV-Tools-opt spirv-cross-glsl)
else()
target_link_libraries(${TARGET}
-Wl,--start-group glslang SPIRV SPIRV-Tools-opt spirv-cross-glsl -Wl,--end-group)
endif()
# ==================================================================================================
# Compiler flags
# ==================================================================================================
# this must match options enabled in glslang's CMakeLists.txt
target_compile_options(${TARGET} PRIVATE -DAMD_EXTENSIONS -DNV_EXTENSIONS )
if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W0 /Zc:__cplusplus")
endif()
if (FILAMENT_ENABLE_MATDBG)
add_definitions(-DFILAMENT_ENABLE_MATDBG)
endif()
# ==================================================================================================
# Installation
# ==================================================================================================
# Astrict has dependencies on a bunch of SPIRV-related libraries. To make things simpler, we bundle
# them together into a single shared library and copy this into the installation folder. This
# requires us to explicitly list the dependencies below, as CMake doesn't have a way to recursively
# query dependencies.
set(ASTRICT_DEPS
OGLCompiler
OSDependent
SPIRV
SPIRV-Tools
SPIRV-Tools-opt
astrict
glslang
spirv-cross-core
spirv-cross-glsl
spirv-cross-msl
)
set(ASTRICT_COMBINED_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libastrict_combined.a")
combine_static_libs(astrict "${ASTRICT_COMBINED_OUTPUT}" "${ASTRICT_DEPS}")
set(ASTRICT_LIB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}astrict${CMAKE_STATIC_LIBRARY_SUFFIX})
install(FILES "${ASTRICT_COMBINED_OUTPUT}" DESTINATION lib/${DIST_DIR} RENAME ${ASTRICT_LIB_NAME})
install(DIRECTORY ${PUBLIC_HDR_DIR}/astrict DESTINATION include)
# ==================================================================================================
# Tests
# ==================================================================================================
project(test_astrict)
set(TARGET test_astrict)
set(SRCS
tests/test_FromGlsl.cpp)
add_executable(${TARGET} ${SRCS})
target_include_directories(${TARGET} PRIVATE src)
target_link_libraries(${TARGET} astrict gtest)
set_target_properties(${TARGET} PROPERTIES FOLDER Tests)

Some files were not shown because too many files have changed in this diff Show More