fix normal morph target
This commit is contained in:
@@ -1,35 +0,0 @@
|
||||
package com.example.holovox_filament
|
||||
|
||||
import androidx.annotation.NonNull
|
||||
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
||||
import io.flutter.plugin.common.MethodChannel.Result
|
||||
|
||||
/** MimeticAvatarPlugin */
|
||||
class MimeticAvatarPlugin: FlutterPlugin, MethodCallHandler {
|
||||
/// The MethodChannel that will the communication between Flutter and native Android
|
||||
///
|
||||
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
|
||||
/// when the Flutter Engine is detached from the Activity
|
||||
private lateinit var channel : MethodChannel
|
||||
|
||||
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "holovox_filament")
|
||||
channel.setMethodCallHandler(this)
|
||||
}
|
||||
|
||||
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
|
||||
if (call.method == "getPlatformVersion") {
|
||||
result.success("Android ${android.os.Build.VERSION.RELEASE}")
|
||||
} else {
|
||||
result.notImplemented()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
channel.setMethodCallHandler(null)
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.example.holovox_filament
|
||||
|
||||
import androidx.annotation.NonNull
|
||||
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
||||
import io.flutter.plugin.common.MethodChannel.Result
|
||||
|
||||
/** MimeticFilamentPlugin */
|
||||
class MimeticFilamentPlugin: FlutterPlugin, MethodCallHandler {
|
||||
/// The MethodChannel that will the communication between Flutter and native Android
|
||||
///
|
||||
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
|
||||
/// when the Flutter Engine is detached from the Activity
|
||||
private lateinit var channel : MethodChannel
|
||||
|
||||
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "holovox_filament")
|
||||
channel.setMethodCallHandler(this)
|
||||
}
|
||||
|
||||
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
|
||||
if (call.method == "getPlatformVersion") {
|
||||
result.success("Android ${android.os.Build.VERSION.RELEASE}")
|
||||
} else {
|
||||
result.notImplemented()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
channel.setMethodCallHandler(null)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#import <Flutter/Flutter.h>
|
||||
|
||||
@interface MimeticFilamentPlugin : NSObject<FlutterPlugin>
|
||||
@interface HolovoxFilamentPlugin : NSObject<FlutterPlugin>
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#import "MimeticFilamentPlugin.h"
|
||||
#import "HolovoxFilamentPlugin.h"
|
||||
#import "filament/FilamentNativeViewFactory.h"
|
||||
|
||||
FilamentNativeViewFactory* factory;
|
||||
|
||||
@implementation MimeticFilamentPlugin
|
||||
@implementation HolovoxFilamentPlugin
|
||||
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||||
factory =
|
||||
[[FilamentNativeViewFactory alloc] initWithRegistrar:registrar];
|
||||
|
||||
@@ -43,20 +43,26 @@ static void* freeResourceGlobal(void* mem, size_t size, void* misc) {
|
||||
- (void)handleMethodCall:(FlutterMethodCall* _Nonnull)call result:(FlutterResult _Nonnull )result {
|
||||
if([@"initialize" isEqualToString:call.method]) {
|
||||
if(!call.arguments)
|
||||
_viewer = new holovox::FilamentViewer(_layer, nullptr, loadResourceGlobal, freeResourceGlobal);
|
||||
_viewer = new holovox::FilamentViewer(_layer, nullptr, nullptr, loadResourceGlobal, freeResourceGlobal);
|
||||
else
|
||||
_viewer = new holovox::FilamentViewer(_layer, [call.arguments UTF8String], loadResourceGlobal, freeResourceGlobal);
|
||||
_viewer = new holovox::FilamentViewer(_layer, [call.arguments[0] UTF8String], [call.arguments[1] UTF8String], loadResourceGlobal, freeResourceGlobal);
|
||||
[_controller setViewer:_viewer];
|
||||
[_controller startDisplayLink];
|
||||
result(@"OK");
|
||||
} else if([@"loadSkybox" isEqualToString:call.method]) {
|
||||
if(!_viewer)
|
||||
return;
|
||||
|
||||
_viewer->loadSkybox([call.arguments[0] UTF8String], [call.arguments[1] UTF8String]);
|
||||
result(@"OK");
|
||||
} else if([@"loadGlb" isEqualToString:call.method]) {
|
||||
if(!_viewer)
|
||||
return; // TODO should throw exception here
|
||||
_viewer->loadGlb([call.arguments UTF8String]);
|
||||
result(@"OK");
|
||||
} else if([@"loadGltf" isEqualToString:call.method]) {
|
||||
if(!_viewer)
|
||||
return;
|
||||
return; // TODO should throw exception here
|
||||
_viewer->loadGltf([call.arguments[0] UTF8String], [call.arguments[1] UTF8String]);
|
||||
result(@"OK");
|
||||
} else if([@"panStart" isEqualToString:call.method]) {
|
||||
|
||||
@@ -13,11 +13,12 @@ A new flutter plugin project.
|
||||
s.license = { :file => '../LICENSE' }
|
||||
s.author = { 'Your Company' => 'email@example.com' }
|
||||
s.source = { :path => '.' }
|
||||
s.source_files = 'Classes/**/*', 'src/*.*', 'src/morph/*'
|
||||
s.dependency 'Filament', '~> 1.12.4'
|
||||
s.source_files = 'Classes/**/*', 'src/*.*', 'src/morph/*.*', 'src/morph/UbershaderLoader.cpp'
|
||||
#s.dependency 'Filament', '~> 1.12.8'
|
||||
s.dependency 'Flutter'
|
||||
s.platform = :ios, '12.1'
|
||||
s.static_framework = true
|
||||
s.vendored_libraries = "lib/*.a"
|
||||
|
||||
# Flutter.framework does not contain a i386 slice.
|
||||
s.user_target_xcconfig = {
|
||||
@@ -26,6 +27,7 @@ A new flutter plugin project.
|
||||
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/holovox_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/holovox_filament/ios/src", "${PODS_ROOT}/../.symlinks/plugins/holovox_filament/ios/morph"',
|
||||
'OTHER_CXXFLAGS' => '--std=c++17 -fmodules -fcxx-modules',
|
||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
||||
'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/holovox_filament/ios/lib"',
|
||||
#"CLANG_CXX_LIBRARY" => "libc++"
|
||||
}
|
||||
s.pod_target_xcconfig = {
|
||||
@@ -33,8 +35,11 @@ A new flutter plugin project.
|
||||
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
||||
'OTHER_CXXFLAGS' => '--std=c++17 -fmodules -fcxx-modules',
|
||||
"OTHER_LDFLAGS" => '-lfilament -lbackend -lmathio -lfilameshio -lviewer -lfilamat -lgeometry -lutils -lfilabridge -lgltfio_resources_lite -lgltfio_core -lfilament-iblprefilter -limage -lcamutils -lgltfio_resources -lmath -lfilaflat -ldracodec -libl',
|
||||
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/holovox_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/holovox_filament/ios/src", "${PODS_ROOT}/../.symlinks/plugins/holovox_filament/ios/morph"',
|
||||
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
|
||||
'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/holovox_filament/ios/lib"',
|
||||
}
|
||||
|
||||
s.swift_version = '5.0'
|
||||
end
|
||||
|
||||
@@ -16,16 +16,16 @@
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef TNT_FILAMENT_DRIVER_BUFFERDESCRIPTOR_H
|
||||
#define TNT_FILAMENT_DRIVER_BUFFERDESCRIPTOR_H
|
||||
#ifndef TNT_FILAMENT_BACKEND_BUFFERDESCRIPTOR_H
|
||||
#define TNT_FILAMENT_BACKEND_BUFFERDESCRIPTOR_H
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace filament::backend {
|
||||
|
||||
/**
|
||||
* A CPU memory-buffer descriptor, typically used to transfer data from the CPU to the GPU.
|
||||
@@ -91,6 +91,56 @@ public:
|
||||
: buffer(const_cast<void*>(buffer)), size(size), callback(callback), user(user) {
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Helper to create a BufferDescriptor that uses a KNOWN method pointer w/ object passed
|
||||
* by pointer as the callback. e.g.:
|
||||
* auto bd = BufferDescriptor::make(buffer, size, &Foo::method, foo);
|
||||
*
|
||||
* @param buffer Memory address of the CPU buffer to reference
|
||||
* @param size Size of the CPU buffer in bytes
|
||||
* @return a new BufferDescriptor
|
||||
*/
|
||||
template<typename T, void(T::*method)(void const* buffer, size_t size)>
|
||||
static BufferDescriptor make(
|
||||
void const* buffer, size_t size, T* data) noexcept {
|
||||
return {
|
||||
buffer, size,
|
||||
[](void* b, size_t s, void* u) {
|
||||
(*static_cast<T**>(u)->*method)(b, s);
|
||||
}, data
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to create a BufferDescriptor that uses a functor as the callback.
|
||||
*
|
||||
* Caveats:
|
||||
* - DO NOT CALL setCallback() when using this helper.
|
||||
* - This make a heap allocation
|
||||
*
|
||||
* @param buffer Memory address of the CPU buffer to reference
|
||||
* @param size Size of the CPU buffer in bytes
|
||||
* @param functor functor of type f(void const* buffer, size_t size)
|
||||
* @return a new BufferDescriptor
|
||||
*/
|
||||
template<typename T>
|
||||
static BufferDescriptor make(
|
||||
void const* buffer, size_t size, T&& functor) noexcept {
|
||||
return {
|
||||
buffer, size,
|
||||
[](void* b, size_t s, void* u) {
|
||||
T& that = *static_cast<T*>(u);
|
||||
that(b, s);
|
||||
delete &that;
|
||||
},
|
||||
new T(std::forward<T>(functor))
|
||||
};
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set or replace the release callback function
|
||||
* @param callback The new callback function
|
||||
@@ -126,7 +176,10 @@ private:
|
||||
void* user = nullptr;
|
||||
};
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_DRIVER_BUFFERDESCRIPTOR_H
|
||||
#if !defined(NDEBUG)
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::BufferDescriptor& b);
|
||||
#endif
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_BUFFERDESCRIPTOR_H
|
||||
|
||||
@@ -16,14 +16,16 @@
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef TNT_FILAMENT_DRIVER_DRIVERENUMS_H
|
||||
#define TNT_FILAMENT_DRIVER_DRIVERENUMS_H
|
||||
#ifndef TNT_FILAMENT_BACKEND_DRIVERENUMS_H
|
||||
#define TNT_FILAMENT_BACKEND_DRIVERENUMS_H
|
||||
|
||||
#include <utils/BitmaskEnum.h>
|
||||
#include <utils/unwindows.h> // Because we define ERROR in the FenceStatus enum.
|
||||
|
||||
#include <backend/PresentCallable.h>
|
||||
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <math/vec4.h>
|
||||
|
||||
#include <array> // FIXME: STL headers are not allowed in public headers
|
||||
@@ -318,7 +320,7 @@ enum class PixelDataType : uint8_t {
|
||||
BYTE, //!< signed byte
|
||||
USHORT, //!< unsigned short (16-bit)
|
||||
SHORT, //!< signed short (16-bit)
|
||||
UINT, //!< unsigned int (16-bit)
|
||||
UINT, //!< unsigned int (32-bit)
|
||||
INT, //!< signed int (32-bit)
|
||||
HALF, //!< half-float (16-bit float)
|
||||
FLOAT, //!< float (32-bits float)
|
||||
@@ -561,6 +563,48 @@ static constexpr bool isDepthFormat(TextureFormat format) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr bool isUnsignedIntFormat(TextureFormat format) {
|
||||
switch (format) {
|
||||
case TextureFormat::R8UI:
|
||||
case TextureFormat::R16UI:
|
||||
case TextureFormat::R32UI:
|
||||
case TextureFormat::RG8UI:
|
||||
case TextureFormat::RG16UI:
|
||||
case TextureFormat::RG32UI:
|
||||
case TextureFormat::RGB8UI:
|
||||
case TextureFormat::RGB16UI:
|
||||
case TextureFormat::RGB32UI:
|
||||
case TextureFormat::RGBA8UI:
|
||||
case TextureFormat::RGBA16UI:
|
||||
case TextureFormat::RGBA32UI:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr bool isSignedIntFormat(TextureFormat format) {
|
||||
switch (format) {
|
||||
case TextureFormat::R8I:
|
||||
case TextureFormat::R16I:
|
||||
case TextureFormat::R32I:
|
||||
case TextureFormat::RG8I:
|
||||
case TextureFormat::RG16I:
|
||||
case TextureFormat::RG32I:
|
||||
case TextureFormat::RGB8I:
|
||||
case TextureFormat::RGB16I:
|
||||
case TextureFormat::RGB32I:
|
||||
case TextureFormat::RGBA8I:
|
||||
case TextureFormat::RGBA16I:
|
||||
case TextureFormat::RGBA32I:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//! returns whether this format a compressed format
|
||||
static constexpr bool isCompressedFormat(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::EAC_R11;
|
||||
@@ -917,6 +961,9 @@ using FrameScheduledCallback = void(*)(PresentCallable callable, void* user);
|
||||
|
||||
using FrameCompletedCallback = void(*)(void* user);
|
||||
|
||||
enum class Workaround : uint16_t {
|
||||
SPLIT_EASU
|
||||
};
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
@@ -926,4 +973,36 @@ template<> struct utils::EnableBitMaskOperators<filament::backend::TargetBufferF
|
||||
template<> struct utils::EnableBitMaskOperators<filament::backend::TextureUsage>
|
||||
: public std::true_type {};
|
||||
|
||||
#endif // TNT_FILAMENT_DRIVER_DRIVERENUMS_H
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::BufferUsage usage);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::CullingMode mode);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::ElementType type);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::PixelDataFormat format);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::PixelDataType type);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::Precision precision);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::PrimitiveType type);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::TargetBufferFlags f);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::SamplerCompareFunc func);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::SamplerCompareMode mode);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::SamplerFormat format);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::SamplerMagFilter filter);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::SamplerMinFilter filter);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::SamplerParams params);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::SamplerType type);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::SamplerWrapMode wrap);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::ShaderModel model);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::TextureCubemapFace face);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::TextureFormat format);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::TextureUsage usage);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::BufferObjectBinding binding);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::TextureSwizzle swizzle);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::AttributeArray& type);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::FaceOffsets& type);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::PolygonOffset& po);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::RasterState& rs);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::RenderPassParams& b);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::Viewport& v);
|
||||
#endif
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_DRIVERENUMS_H
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_DRIVER_HANDLE_H
|
||||
#define TNT_FILAMENT_DRIVER_HANDLE_H
|
||||
#ifndef TNT_FILAMENT_BACKEND_HANDLE_H
|
||||
#define TNT_FILAMENT_BACKEND_HANDLE_H
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Log.h>
|
||||
@@ -113,4 +113,4 @@ using VertexBufferHandle = Handle<HwVertexBuffer>;
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_DRIVER_HANDLE_H
|
||||
#endif // TNT_FILAMENT_BACKEND_HANDLE_H
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_DRIVER_PIPELINESTATE_H
|
||||
#define TNT_FILAMENT_DRIVER_PIPELINESTATE_H
|
||||
#ifndef TNT_FILAMENT_BACKEND_PIPELINESTATE_H
|
||||
#define TNT_FILAMENT_BACKEND_PIPELINESTATE_H
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Handle.h>
|
||||
@@ -24,8 +24,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace filament::backend {
|
||||
|
||||
//! \privatesection
|
||||
|
||||
@@ -39,8 +38,10 @@ struct PipelineState {
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
#if !defined(NDEBUG)
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::PipelineState& ps);
|
||||
#endif
|
||||
|
||||
#endif //TNT_FILAMENT_DRIVER_PIPELINESTATE_H
|
||||
#endif //TNT_FILAMENT_BACKEND_PIPELINESTATE_H
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef TNT_FILAMENT_DRIVER_PIXEL_BUFFERDESCRIPTOR_H
|
||||
#define TNT_FILAMENT_DRIVER_PIXEL_BUFFERDESCRIPTOR_H
|
||||
#ifndef TNT_FILAMENT_BACKEND_PIXELBUFFERDESCRIPTOR_H
|
||||
#define TNT_FILAMENT_BACKEND_PIXELBUFFERDESCRIPTOR_H
|
||||
|
||||
#include <backend/BufferDescriptor.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
@@ -105,6 +105,71 @@ public:
|
||||
alignment(1) {
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
template<typename T, void(T::*method)(void const* buffer, size_t size)>
|
||||
static PixelBufferDescriptor make(void const* buffer, size_t size,
|
||||
PixelDataFormat format, PixelDataType type, uint8_t alignment,
|
||||
uint32_t left, uint32_t top, uint32_t stride, T* data) noexcept {
|
||||
return { buffer, size, format, type, alignment, left, top, stride,
|
||||
[](void* b, size_t s, void* u) {
|
||||
(*static_cast<T**>(u)->*method)(b, s); }, data };
|
||||
}
|
||||
|
||||
template<typename T, void(T::*method)(void const* buffer, size_t size)>
|
||||
static PixelBufferDescriptor make(void const* buffer, size_t size,
|
||||
PixelDataFormat format, PixelDataType type, T* data) noexcept {
|
||||
return { buffer, size, format, type, [](void* b, size_t s, void* u) {
|
||||
(*static_cast<T**>(u)->*method)(b, s); }, data };
|
||||
}
|
||||
|
||||
template<typename T, void(T::*method)(void const* buffer, size_t size)>
|
||||
static PixelBufferDescriptor make(void const* buffer, size_t size,
|
||||
backend::CompressedPixelDataType format, uint32_t imageSize, T* data) noexcept {
|
||||
return { buffer, size, format, imageSize, [](void* b, size_t s, void* u) {
|
||||
(*static_cast<T**>(u)->*method)(b, s); }, data
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static PixelBufferDescriptor make(void const* buffer, size_t size,
|
||||
PixelDataFormat format, PixelDataType type, uint8_t alignment,
|
||||
uint32_t left, uint32_t top, uint32_t stride, T&& functor) noexcept {
|
||||
return { buffer, size, format, type, alignment, left, top, stride,
|
||||
[](void* b, size_t s, void* u) {
|
||||
T& that = *static_cast<T*>(u);
|
||||
that(b, s);
|
||||
delete &that;
|
||||
}, new T(std::forward<T>(functor))
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static PixelBufferDescriptor make(void const* buffer, size_t size,
|
||||
PixelDataFormat format, PixelDataType type, T&& functor) noexcept {
|
||||
return { buffer, size, format, type,
|
||||
[](void* b, size_t s, void* u) {
|
||||
T& that = *static_cast<T*>(u);
|
||||
that(b, s);
|
||||
delete &that;
|
||||
}, new T(std::forward<T>(functor))
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static PixelBufferDescriptor make(void const* buffer, size_t size,
|
||||
backend::CompressedPixelDataType format, uint32_t imageSize, T&& functor) noexcept {
|
||||
return { buffer, size, format, imageSize,
|
||||
[](void* b, size_t s, void* u) {
|
||||
T& that = *static_cast<T*>(u);
|
||||
that(b, s);
|
||||
delete &that;
|
||||
}, new T(std::forward<T>(functor))
|
||||
};
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Computes the size in bytes needed to fit an image of given dimensions and format
|
||||
*
|
||||
@@ -213,4 +278,8 @@ public:
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_DRIVER_PIXEL_BUFFERDESCRIPTOR_H
|
||||
#if !defined(NDEBUG)
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::PixelBufferDescriptor& b);
|
||||
#endif
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_PIXELBUFFERDESCRIPTOR_H
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef TNT_FILAMENT_DRIVER_PLATFORM_H
|
||||
#define TNT_FILAMENT_DRIVER_PLATFORM_H
|
||||
#ifndef TNT_FILAMENT_BACKEND_PLATFORM_H
|
||||
#define TNT_FILAMENT_BACKEND_PLATFORM_H
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
@@ -100,4 +100,4 @@ public:
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_DRIVER_PLATFORM_H
|
||||
#endif // TNT_FILAMENT_BACKEND_PLATFORM_H
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef TNT_FILAMENT_BACKEND_PRESENT_CALLABLE
|
||||
#define TNT_FILAMENT_BACKEND_PRESENT_CALLABLE
|
||||
#ifndef TNT_FILAMENT_BACKEND_PRESENTCALLABLE
|
||||
#define TNT_FILAMENT_BACKEND_PRESENTCALLABLE
|
||||
|
||||
#include <utils/compiler.h>
|
||||
|
||||
@@ -101,4 +101,4 @@ using FrameFinishedCallback UTILS_DEPRECATED = void(*)(PresentCallable callable,
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_PRESENT_FRAME_CALLABLE
|
||||
#endif // TNT_FILAMENT_BACKEND_PRESENTCALLABLE
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_DRIVER_TARGETBUFFERINFO_H
|
||||
#define TNT_FILAMENT_DRIVER_TARGETBUFFERINFO_H
|
||||
#ifndef TNT_FILAMENT_BACKEND_TARGETBUFFERINFO_H
|
||||
#define TNT_FILAMENT_BACKEND_TARGETBUFFERINFO_H
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Handle.h>
|
||||
@@ -104,4 +104,9 @@ public:
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
#endif //TNT_FILAMENT_DRIVER_TARGETBUFFERINFO_H
|
||||
#if !defined(NDEBUG)
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::TargetBufferInfo& tbi);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::MRT& mrt);
|
||||
#endif
|
||||
|
||||
#endif //TNT_FILAMENT_BACKEND_TARGETBUFFERINFO_H
|
||||
|
||||
@@ -383,7 +383,7 @@ public:
|
||||
//! Returns the camera's field of view in degrees
|
||||
float getFieldOfViewInDegrees(Fov direction) const noexcept;
|
||||
|
||||
//! Returns a Frustum object in world space
|
||||
//! Returns the camera's culling Frustum in world space
|
||||
class Frustum getFrustum() const noexcept;
|
||||
|
||||
//! Returns the entity representing this camera
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef TNT_FILAMENT_COLOR_GRADING_H
|
||||
#define TNT_FILAMENT_COLOR_GRADING_H
|
||||
#ifndef TNT_FILAMENT_COLORGRADING_H
|
||||
#define TNT_FILAMENT_COLORGRADING_H
|
||||
|
||||
#include <filament/FilamentAPI.h>
|
||||
#include <filament/ToneMapper.h>
|
||||
@@ -66,6 +66,7 @@ class FColorGrading;
|
||||
*
|
||||
* The various transforms held by ColorGrading are applied in the following order:
|
||||
* - Exposure
|
||||
* - Night adaptation
|
||||
* - White balance
|
||||
* - Channel mixer
|
||||
* - Shadows/mid-tones/highlights
|
||||
@@ -76,12 +77,14 @@ class FColorGrading;
|
||||
* - Curves
|
||||
* - Tone mapping
|
||||
* - Luminance scaling
|
||||
* - Gamut mapping
|
||||
*
|
||||
* Defaults
|
||||
* ========
|
||||
*
|
||||
* Here are the default color grading options:
|
||||
* - Exposure: 0.0
|
||||
* - Night adaptation: 0.0
|
||||
* - White balance: temperature 0, and tint 0
|
||||
* - Channel mixer: red {1,0,0}, green {0,1,0}, blue {0,0,1}
|
||||
* - Shadows/mid-tones/highlights: shadows {1,1,1,0}, mid-tones {1,1,1,0}, highlights {1,1,1,0},
|
||||
@@ -93,6 +96,7 @@ class FColorGrading;
|
||||
* - Curves: gamma {1,1,1}, midPoint {1,1,1}, and scale {1,1,1}
|
||||
* - Tone mapping: ACESLegacyToneMapper
|
||||
* - Luminance scaling: false
|
||||
* - Gamut mapping: false
|
||||
*
|
||||
* @see View
|
||||
*/
|
||||
@@ -186,12 +190,25 @@ public:
|
||||
* When luminance scaling is enabled, tone mapping is performed on the luminance of each
|
||||
* pixel instead of per-channel.
|
||||
*
|
||||
* @param luminanceScaling Enables or disables EVILS post-tone mapping
|
||||
* @param luminanceScaling Enables or disables luminance scaling post-tone mapping
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
Builder& luminanceScaling(bool luminanceScaling) noexcept;
|
||||
|
||||
/**
|
||||
* Enables or disables gamut mapping to the destination color space's gamut. When gamut
|
||||
* mapping is turned off, out-of-gamut colors are clipped to the destination's gamut,
|
||||
* which may produce hue skews (blue skewing to purple, green to yellow, etc.). When
|
||||
* gamut mapping is enabled, out-of-gamut colors are brought back in gamut by trying to
|
||||
* preserve the perceived chroma and lightness of the original values.
|
||||
*
|
||||
* @param gamutMapping Enables or disables gamut mapping
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
Builder& gamutMapping(bool gamutMapping) noexcept;
|
||||
|
||||
/**
|
||||
* Adjusts the exposure of this image. The exposure is specified in stops:
|
||||
* each stop brightens (positive values) or darkens (negative values) the image by
|
||||
@@ -205,6 +222,19 @@ public:
|
||||
*/
|
||||
Builder& exposure(float exposure) noexcept;
|
||||
|
||||
/**
|
||||
* Controls the amount of night adaptation to replicate a more natural representation of
|
||||
* low-light conditions as perceived by the human vision system. In low-light conditions,
|
||||
* peak luminance sensitivity of the eye shifts toward the blue end of the color spectrum:
|
||||
* darker tones appear brighter, reducing contrast, and colors are blue shifted (the darker
|
||||
* the more intense the effect).
|
||||
*
|
||||
* @param adaptation Amount of adaptation, between 0 (no adaptation) and 1 (full adaptation).
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
Builder& nightAdaptation(float adaptation) noexcept;
|
||||
|
||||
/**
|
||||
* Adjusts the while balance of the image. This can be used to remove color casts
|
||||
* and correct the appearance of the white point in the scene, or to alter the
|
||||
@@ -402,4 +432,4 @@ public:
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_COLOR_GRADING_H
|
||||
#endif // TNT_FILAMENT_COLORGRADING_H
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef TNT_FILAMENT_DEBUG_H
|
||||
#define TNT_FILAMENT_DEBUG_H
|
||||
#ifndef TNT_FILAMENT_DEBUGREGISTRY_H
|
||||
#define TNT_FILAMENT_DEBUGREGISTRY_H
|
||||
|
||||
#include <filament/FilamentAPI.h>
|
||||
|
||||
@@ -128,4 +128,4 @@ public:
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif /* TNT_FILAMENT_DEBUG_H */
|
||||
#endif /* TNT_FILAMENT_DEBUGREGISTRY_H */
|
||||
|
||||
@@ -444,7 +444,7 @@ public:
|
||||
|
||||
/**
|
||||
* Kicks the hardware thread (e.g. the OpenGL, Vulkan or Metal thread) and blocks until
|
||||
* all commands to this point are executed. Note that this doesn't guarantee that the
|
||||
* all commands to this point are executed. Note that does guarantee that the
|
||||
* hardware is actually finished.
|
||||
*
|
||||
* <p>This is typically used right after destroying the <code>SwapChain</code>,
|
||||
@@ -454,8 +454,25 @@ public:
|
||||
*/
|
||||
void flushAndWait();
|
||||
|
||||
/**
|
||||
* Kicks the hardware thread (e.g. the OpenGL, Vulkan or Metal thread) but does not wait
|
||||
* for commands to be either executed or the hardware finished.
|
||||
*
|
||||
* <p>This is typically used after creating a lot of objects to start draining the command
|
||||
* queue which has a limited size.</p>
|
||||
*/
|
||||
void flush();
|
||||
|
||||
/**
|
||||
* Drains the user callback message queue and immediately execute all pending callbacks.
|
||||
*
|
||||
* <p> Typically this should be called once per frame right after the application's vsync tick,
|
||||
* and typically just before computing parameters (e.g. object positions) for the next frame.
|
||||
* This is useful because otherwise callbacks will be executed by filament at a later time,
|
||||
* which may increase latency in certain applications.</p>
|
||||
*/
|
||||
void pumpMessageQueues();
|
||||
|
||||
/**
|
||||
* Returns the default Material.
|
||||
*
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_FILAMENT_API_H
|
||||
#define TNT_FILAMENT_FILAMENT_API_H
|
||||
#ifndef TNT_FILAMENT_FILAMENTAPI_H
|
||||
#define TNT_FILAMENT_FILAMENTAPI_H
|
||||
|
||||
#include <utils/compiler.h>
|
||||
|
||||
@@ -88,4 +88,4 @@ protected:
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_FILAMENT_API_H
|
||||
#endif // TNT_FILAMENT_FILAMENTAPI_H
|
||||
|
||||
@@ -52,8 +52,9 @@ public:
|
||||
Frustum& operator=(Frustum&& rhs) noexcept = default;
|
||||
|
||||
/**
|
||||
* Creates a frustum from a projection matrix (usually the projection * view matrix)
|
||||
* @param pv a 4x4 projection matrix
|
||||
* Creates a frustum from a projection matrix in GL convention
|
||||
* (usually the projection * view matrix)
|
||||
* @param pv a 4x4 projection matrix in GL convention
|
||||
*/
|
||||
explicit Frustum(const math::mat4f& pv);
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef TNT_FILAMENT_INDIRECT_LIGHT_H
|
||||
#define TNT_FILAMENT_INDIRECT_LIGHT_H
|
||||
#ifndef TNT_FILAMENT_INDIRECTLIGHT_H
|
||||
#define TNT_FILAMENT_INDIRECTLIGHT_H
|
||||
|
||||
#include <filament/FilamentAPI.h>
|
||||
|
||||
@@ -346,4 +346,4 @@ public:
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_INDIRECT_LIGHT_H
|
||||
#endif // TNT_FILAMENT_INDIRECTLIGHT_H
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <filament/FilamentAPI.h>
|
||||
#include <filament/Color.h>
|
||||
|
||||
#include <filament/MaterialEnums.h>
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
@@ -37,6 +39,7 @@ class UniformInterfaceBlock;
|
||||
class UTILS_PUBLIC MaterialInstance : public FilamentAPI {
|
||||
public:
|
||||
using CullingMode = filament::backend::CullingMode;
|
||||
using TransparencyMode = filament::TransparencyMode;
|
||||
|
||||
template<typename T>
|
||||
using is_supported_parameter_t = typename std::enable_if<
|
||||
@@ -197,6 +200,11 @@ public:
|
||||
*/
|
||||
void setDoubleSided(bool doubleSided) noexcept;
|
||||
|
||||
/**
|
||||
* Specifies how transparent objects should be rendered (default is DEFAULT).
|
||||
*/
|
||||
void setTransparencyMode(TransparencyMode mode) noexcept;
|
||||
|
||||
/**
|
||||
* Overrides the default triangle culling state that was set on the material.
|
||||
*/
|
||||
|
||||
362
ios/include/filament/Options.h
Normal file
362
ios/include/filament/Options.h
Normal file
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_OPTIONS_H
|
||||
#define TNT_FILAMENT_OPTIONS_H
|
||||
|
||||
#include <filament/Color.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace filament {
|
||||
|
||||
class Texture;
|
||||
|
||||
enum class QualityLevel : uint8_t {
|
||||
LOW,
|
||||
MEDIUM,
|
||||
HIGH,
|
||||
ULTRA
|
||||
};
|
||||
|
||||
enum class BlendMode : uint8_t {
|
||||
OPAQUE,
|
||||
TRANSLUCENT
|
||||
};
|
||||
|
||||
/**
|
||||
* Dynamic resolution can be used to either reach a desired target frame rate
|
||||
* by lowering the resolution of a View, or to increase the quality when the
|
||||
* rendering is faster than the target frame rate.
|
||||
*
|
||||
* This structure can be used to specify the minimum scale factor used when
|
||||
* lowering the resolution of a View, and the maximum scale factor used when
|
||||
* increasing the resolution for higher quality rendering. The scale factors
|
||||
* can be controlled on each X and Y axis independently. By default, all scale
|
||||
* factors are set to 1.0.
|
||||
*
|
||||
* enabled: enable or disables dynamic resolution on a View
|
||||
*
|
||||
* homogeneousScaling: by default the system scales the major axis first. Set this to true
|
||||
* to force homogeneous scaling.
|
||||
*
|
||||
* minScale: the minimum scale in X and Y this View should use
|
||||
*
|
||||
* maxScale: the maximum scale in X and Y this View should use
|
||||
*
|
||||
* quality: upscaling quality.
|
||||
* LOW: 1 bilinear tap, Medium: 4 bilinear taps, High: 9 bilinear taps (tent)
|
||||
*
|
||||
* \note
|
||||
* Dynamic resolution is only supported on platforms where the time to render
|
||||
* a frame can be measured accurately. Dynamic resolution is currently only
|
||||
* supported on Android.
|
||||
*
|
||||
* @see Renderer::FrameRateOptions
|
||||
*
|
||||
*/
|
||||
struct DynamicResolutionOptions {
|
||||
math::float2 minScale = math::float2(0.5f); //!< minimum scale factors in x and y
|
||||
math::float2 maxScale = math::float2(1.0f); //!< maximum scale factors in x and y
|
||||
float sharpness = 0.9f; //!< sharpness when QualityLevel::MEDIUM or higher is used [0 (disabled), 1 (sharpest)]
|
||||
bool enabled = false; //!< enable or disable dynamic resolution
|
||||
bool homogeneousScaling = false; //!< set to true to force homogeneous scaling
|
||||
|
||||
/**
|
||||
* Upscaling quality
|
||||
* LOW: bilinear filtered blit. Fastest, poor quality
|
||||
* MEDIUM: AMD FidelityFX FSR1 w/ mobile optimizations
|
||||
* HIGH: AMD FidelityFX FSR1 w/ mobile optimizations
|
||||
* ULTRA: AMD FidelityFX FSR1
|
||||
* FSR1 require a well anti-aliased (MSAA or TAA), noise free scene.
|
||||
*
|
||||
* The default upscaling quality is set to LOW.
|
||||
*/
|
||||
QualityLevel quality = QualityLevel::LOW;
|
||||
};
|
||||
|
||||
/**
|
||||
* Options to control the bloom effect
|
||||
*
|
||||
* enabled: Enable or disable the bloom post-processing effect. Disabled by default.
|
||||
*
|
||||
* levels: Number of successive blurs to achieve the blur effect, the minimum is 3 and the
|
||||
* maximum is 12. This value together with resolution influences the spread of the
|
||||
* blur effect. This value can be silently reduced to accommodate the original
|
||||
* image size.
|
||||
*
|
||||
* resolution: Resolution of bloom's minor axis. The minimum value is 2^levels and the
|
||||
* the maximum is lower of the original resolution and 4096. This parameter is
|
||||
* silently clamped to the minimum and maximum.
|
||||
* It is highly recommended that this value be smaller than the target resolution
|
||||
* after dynamic resolution is applied (horizontally and vertically).
|
||||
*
|
||||
* strength: how much of the bloom is added to the original image. Between 0 and 1.
|
||||
*
|
||||
* blendMode: Whether the bloom effect is purely additive (false) or mixed with the original
|
||||
* image (true).
|
||||
*
|
||||
* anamorphism: Bloom's aspect ratio (x/y), for artistic purposes.
|
||||
*
|
||||
* threshold: When enabled, a threshold at 1.0 is applied on the source image, this is
|
||||
* useful for artistic reasons and is usually needed when a dirt texture is used.
|
||||
*
|
||||
* dirt: A dirt/scratch/smudges texture (that can be RGB), which gets added to the
|
||||
* bloom effect. Smudges are visible where bloom occurs. Threshold must be
|
||||
* enabled for the dirt effect to work properly.
|
||||
*
|
||||
* dirtStrength: Strength of the dirt texture.
|
||||
*/
|
||||
struct BloomOptions {
|
||||
enum class BlendMode : uint8_t {
|
||||
ADD, //!< Bloom is modulated by the strength parameter and added to the scene
|
||||
INTERPOLATE //!< Bloom is interpolated with the scene using the strength parameter
|
||||
};
|
||||
Texture* dirt = nullptr; //!< user provided dirt texture
|
||||
float dirtStrength = 0.2f; //!< strength of the dirt texture
|
||||
float strength = 0.10f; //!< bloom's strength between 0.0 and 1.0
|
||||
uint32_t resolution = 360; //!< resolution of vertical axis (2^levels to 2048)
|
||||
float anamorphism = 1.0f; //!< bloom x/y aspect-ratio (1/32 to 32)
|
||||
uint8_t levels = 6; //!< number of blur levels (3 to 11)
|
||||
BlendMode blendMode = BlendMode::ADD; //!< how the bloom effect is applied
|
||||
bool threshold = true; //!< whether to threshold the source
|
||||
bool enabled = false; //!< enable or disable bloom
|
||||
float highlight = 1000.0f; //!< limit highlights to this value before bloom [10, +inf]
|
||||
|
||||
bool lensFlare = false; //!< enable screen-space lens flare
|
||||
bool starburst = true; //!< enable starburst effect on lens flare
|
||||
float chromaticAberration = 0.005f; //!< amount of chromatic aberration
|
||||
uint8_t ghostCount = 4; //!< number of flare "ghosts"
|
||||
float ghostSpacing = 0.6f; //!< spacing of the ghost in screen units [0, 1[
|
||||
float ghostThreshold = 10.0f; //!< hdr threshold for the ghosts
|
||||
float haloThickness = 0.1f; //!< thickness of halo in vertical screen units, 0 to disable
|
||||
float haloRadius = 0.4f; //!< radius of halo in vertical screen units [0, 0.5]
|
||||
float haloThreshold = 10.0f; //!< hdr threshold for the halo
|
||||
};
|
||||
|
||||
/**
|
||||
* Options to control fog in the scene
|
||||
*/
|
||||
struct FogOptions {
|
||||
float distance = 0.0f; //!< distance in world units from the camera where the fog starts ( >= 0.0 )
|
||||
float maximumOpacity = 1.0f; //!< fog's maximum opacity between 0 and 1
|
||||
float height = 0.0f; //!< fog's floor in world units
|
||||
float heightFalloff = 1.0f; //!< how fast fog dissipates with altitude
|
||||
LinearColor color{0.5f}; //!< fog's color (linear), see fogColorFromIbl
|
||||
float density = 0.1f; //!< fog's density at altitude given by 'height'
|
||||
float inScatteringStart = 0.0f; //!< distance in world units from the camera where in-scattering starts
|
||||
float inScatteringSize = -1.0f; //!< size of in-scattering (>0 to activate). Good values are >> 1 (e.g. ~10 - 100).
|
||||
bool fogColorFromIbl = false; //!< Fog color will be modulated by the IBL color in the view direction.
|
||||
bool enabled = false; //!< enable or disable fog
|
||||
};
|
||||
|
||||
/**
|
||||
* Options to control Depth of Field (DoF) effect in the scene.
|
||||
*
|
||||
* cocScale can be used to set the depth of field blur independently from the camera
|
||||
* aperture, e.g. for artistic reasons. This can be achieved by setting:
|
||||
* cocScale = cameraAperture / desiredDoFAperture
|
||||
*
|
||||
* @see Camera
|
||||
*/
|
||||
struct DepthOfFieldOptions {
|
||||
enum class Filter : uint8_t {
|
||||
NONE = 0,
|
||||
MEDIAN = 2
|
||||
};
|
||||
float cocScale = 1.0f; //!< circle of confusion scale factor (amount of blur)
|
||||
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
|
||||
bool nativeResolution = false; //!< perform DoF processing at native resolution
|
||||
/**
|
||||
* Number of of rings used by the gather kernels. The number of rings affects quality
|
||||
* and performance. The actual number of sample per pixel is defined
|
||||
* as (ringCount * 2 - 1)^2. Here are a few commonly used values:
|
||||
* 3 rings : 25 ( 5x 5 grid)
|
||||
* 4 rings : 49 ( 7x 7 grid)
|
||||
* 5 rings : 81 ( 9x 9 grid)
|
||||
* 17 rings : 1089 (33x33 grid)
|
||||
*
|
||||
* With a maximum circle-of-confusion of 32, it is never necessary to use more than 17 rings.
|
||||
*
|
||||
* Usually all three settings below are set to the same value, however, it is often
|
||||
* acceptable to use a lower ring count for the "fast tiles", which improves performance.
|
||||
* Fast tiles are regions of the screen where every pixels have a similar
|
||||
* circle-of-confusion radius.
|
||||
*
|
||||
* A value of 0 means default, which is 5 on desktop and 3 on mobile.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
uint8_t foregroundRingCount = 0; //!< number of kernel rings for foreground tiles
|
||||
uint8_t backgroundRingCount = 0; //!< number of kernel rings for background tiles
|
||||
uint8_t fastGatherRingCount = 0; //!< number of kernel rings for fast tiles
|
||||
/** @}*/
|
||||
|
||||
/**
|
||||
* maximum circle-of-confusion in pixels for the foreground, must be in [0, 32] range.
|
||||
* A value of 0 means default, which is 32 on desktop and 24 on mobile.
|
||||
*/
|
||||
uint16_t maxForegroundCOC = 0;
|
||||
|
||||
/**
|
||||
* maximum circle-of-confusion in pixels for the background, must be in [0, 32] range.
|
||||
* A value of 0 means default, which is 32 on desktop and 24 on mobile.
|
||||
*/
|
||||
uint16_t maxBackgroundCOC = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Options to control the vignetting effect.
|
||||
*/
|
||||
struct VignetteOptions {
|
||||
float midPoint = 0.5f; //!< high values restrict the vignette closer to the corners, between 0 and 1
|
||||
float roundness = 0.5f; //!< controls the shape of the vignette, from a rounded rectangle (0.0), to an oval (0.5), to a circle (1.0)
|
||||
float feather = 0.5f; //!< softening amount of the vignette effect, between 0 and 1
|
||||
LinearColorA color{0.0f, 0.0f, 0.0f, 1.0f}; //!< color of the vignette effect, alpha is currently ignored
|
||||
bool enabled = false; //!< enables or disables the vignette effect
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure used to set the precision of the color buffer and related quality settings.
|
||||
*
|
||||
* @see setRenderQuality, getRenderQuality
|
||||
*/
|
||||
struct RenderQuality {
|
||||
/**
|
||||
* Sets the quality of the HDR color buffer.
|
||||
*
|
||||
* A quality of HIGH or ULTRA means using an RGB16F or RGBA16F color buffer. This means
|
||||
* colors in the LDR range (0..1) have a 10 bit precision. A quality of LOW or MEDIUM means
|
||||
* using an R11G11B10F opaque color buffer or an RGBA16F transparent color buffer. With
|
||||
* R11G11B10F colors in the LDR range have a precision of either 6 bits (red and green
|
||||
* channels) or 5 bits (blue channel).
|
||||
*/
|
||||
QualityLevel hdrColorBuffer = QualityLevel::HIGH;
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for screen space Ambient Occlusion (SSAO) and Screen Space Cone Tracing (SSCT)
|
||||
* @see setAmbientOcclusionOptions()
|
||||
*/
|
||||
struct AmbientOcclusionOptions {
|
||||
float radius = 0.3f; //!< Ambient Occlusion radius in meters, between 0 and ~10.
|
||||
float power = 1.0f; //!< Controls ambient occlusion's contrast. Must be positive.
|
||||
float bias = 0.0005f; //!< Self-occlusion bias in meters. Use to avoid self-occlusion. Between 0 and a few mm.
|
||||
float resolution = 0.5f;//!< How each dimension of the AO buffer is scaled. Must be either 0.5 or 1.0.
|
||||
float intensity = 1.0f; //!< Strength of the Ambient Occlusion effect.
|
||||
float bilateralThreshold = 0.05f; //!< depth distance that constitute an edge for filtering
|
||||
QualityLevel quality = QualityLevel::LOW; //!< affects # of samples used for AO.
|
||||
QualityLevel lowPassFilter = QualityLevel::MEDIUM; //!< affects AO smoothness
|
||||
QualityLevel upsampling = QualityLevel::LOW; //!< affects AO buffer upsampling quality
|
||||
bool enabled = false; //!< enables or disables screen-space ambient occlusion
|
||||
bool bentNormals = false; //!< enables bent normals computation from AO, and specular AO
|
||||
float minHorizonAngleRad = 0.0f; //!< min angle in radian to consider
|
||||
/**
|
||||
* Screen Space Cone Tracing (SSCT) options
|
||||
* Ambient shadows from dominant light
|
||||
*/
|
||||
struct Ssct {
|
||||
float lightConeRad = 1.0f; //!< full cone angle in radian, between 0 and pi/2
|
||||
float shadowDistance = 0.3f; //!< how far shadows can be cast
|
||||
float contactDistanceMax = 1.0f; //!< max distance for contact
|
||||
float intensity = 0.8f; //!< intensity
|
||||
math::float3 lightDirection{ 0, -1, 0 }; //!< light direction
|
||||
float depthBias = 0.01f; //!< depth bias in world units (mitigate self shadowing)
|
||||
float depthSlopeBias = 0.01f; //!< depth slope bias (mitigate self shadowing)
|
||||
uint8_t sampleCount = 4; //!< tracing sample count, between 1 and 255
|
||||
uint8_t rayCount = 1; //!< # of rays to trace, between 1 and 255
|
||||
bool enabled = false; //!< enables or disables SSCT
|
||||
} ssct;
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for Temporal Anti-aliasing (TAA)
|
||||
* @see setTemporalAntiAliasingOptions()
|
||||
*/
|
||||
struct TemporalAntiAliasingOptions {
|
||||
float filterWidth = 1.0f; //!< reconstruction filter width typically between 0 (sharper, aliased) and 1 (smoother)
|
||||
float feedback = 0.04f; //!< history feedback, between 0 (maximum temporal AA) and 1 (no temporal AA).
|
||||
bool enabled = false; //!< enables or disables temporal anti-aliasing
|
||||
};
|
||||
|
||||
/**
|
||||
* List of available post-processing anti-aliasing techniques.
|
||||
* @see setAntiAliasing, getAntiAliasing, setSampleCount
|
||||
*/
|
||||
enum class AntiAliasing : uint8_t {
|
||||
NONE = 0, //!< no anti aliasing performed as part of post-processing
|
||||
FXAA = 1 //!< FXAA is a low-quality but very efficient type of anti-aliasing. (default).
|
||||
};
|
||||
|
||||
/**
|
||||
* List of available post-processing dithering techniques.
|
||||
*/
|
||||
enum class Dithering : uint8_t {
|
||||
NONE = 0, //!< No dithering
|
||||
TEMPORAL = 1 //!< Temporal dithering (default)
|
||||
};
|
||||
|
||||
/**
|
||||
* List of available shadow mapping techniques.
|
||||
* @see setShadowType
|
||||
*/
|
||||
enum class ShadowType : uint8_t {
|
||||
PCF, //!< percentage-closer filtered shadows (default)
|
||||
VSM //!< variance shadows
|
||||
};
|
||||
|
||||
/**
|
||||
* View-level options for VSM Shadowing.
|
||||
* @see setVsmShadowOptions()
|
||||
* @warning This API is still experimental and subject to change.
|
||||
*/
|
||||
struct VsmShadowOptions {
|
||||
/**
|
||||
* Sets the number of anisotropic samples to use when sampling a VSM shadow map. If greater
|
||||
* than 0, mipmaps will automatically be generated each frame for all lights.
|
||||
*
|
||||
* The number of anisotropic samples = 2 ^ vsmAnisotropy.
|
||||
*/
|
||||
uint8_t anisotropy = 0;
|
||||
|
||||
/**
|
||||
* Whether to generate mipmaps for all VSM shadow maps.
|
||||
*/
|
||||
bool mipmapping = false;
|
||||
|
||||
/**
|
||||
* EVSM exponent.
|
||||
* The maximum value permissible is 5.54 for a shadow map in fp16, or 42.0 for a
|
||||
* shadow map in fp32. Currently the shadow map bit depth is always fp16.
|
||||
*/
|
||||
float exponent = 5.54f;
|
||||
|
||||
/**
|
||||
* VSM minimum variance scale, must be positive.
|
||||
*/
|
||||
float minVarianceScale = 0.5f;
|
||||
|
||||
/**
|
||||
* VSM light bleeding reduction amount, between 0 and 1.
|
||||
*/
|
||||
float lightBleedReduction = 0.15f;
|
||||
};
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif //TNT_FILAMENT_OPTIONS_H
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_RENDERABLECOMPONENTMANAGER_H
|
||||
#define TNT_FILAMENT_RENDERABLECOMPONENTMANAGER_H
|
||||
#ifndef TNT_FILAMENT_RENDERABLEMANAGER_H
|
||||
#define TNT_FILAMENT_RENDERABLEMANAGER_H
|
||||
|
||||
#include <filament/Box.h>
|
||||
#include <filament/FilamentAPI.h>
|
||||
@@ -582,4 +582,4 @@ Box RenderableManager::computeAABB(VECTOR const* vertices, INDEX const* indices,
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_RENDERABLECOMPONENTMANAGER_H
|
||||
#endif // TNT_FILAMENT_RENDERABLEMANAGER_H
|
||||
|
||||
@@ -181,7 +181,7 @@ public:
|
||||
/**
|
||||
* Specifies how a texture's channels map to color components
|
||||
*
|
||||
* Texture Swizzle is only supported is isTextureSwizzleSupported() returns true.
|
||||
* Texture Swizzle is only supported if isTextureSwizzleSupported() returns true.
|
||||
*
|
||||
* @param r texture channel for red component
|
||||
* @param g texture channel for green component
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_TONE_MAPPER_H
|
||||
#define TNT_FILAMENT_TONE_MAPPER_H
|
||||
#ifndef TNT_FILAMENT_TONEMAPPER_H
|
||||
#define TNT_FILAMENT_TONEMAPPER_H
|
||||
|
||||
#include <utils/compiler.h>
|
||||
|
||||
@@ -232,4 +232,4 @@ struct UTILS_PUBLIC DisplayRangeToneMapper final : public ToneMapper {
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_TONE_MAPPER_H
|
||||
#endif // TNT_FILAMENT_TONEMAPPER_H
|
||||
|
||||
@@ -21,10 +21,12 @@
|
||||
|
||||
#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>
|
||||
|
||||
@@ -35,7 +37,6 @@ class ColorGrading;
|
||||
class MaterialInstance;
|
||||
class RenderTarget;
|
||||
class Scene;
|
||||
class Texture;
|
||||
class Viewport;
|
||||
|
||||
/**
|
||||
@@ -61,325 +62,21 @@ class Viewport;
|
||||
*/
|
||||
class UTILS_PUBLIC View : public FilamentAPI {
|
||||
public:
|
||||
enum class QualityLevel : uint8_t {
|
||||
LOW,
|
||||
MEDIUM,
|
||||
HIGH,
|
||||
ULTRA
|
||||
};
|
||||
using QualityLevel = QualityLevel;
|
||||
using BlendMode = BlendMode;
|
||||
using AntiAliasing = AntiAliasing;
|
||||
using Dithering = Dithering;
|
||||
using ShadowType = ShadowType;
|
||||
|
||||
enum class BlendMode : uint8_t {
|
||||
OPAQUE,
|
||||
TRANSLUCENT
|
||||
};
|
||||
|
||||
/**
|
||||
* Dynamic resolution can be used to either reach a desired target frame rate
|
||||
* by lowering the resolution of a View, or to increase the quality when the
|
||||
* rendering is faster than the target frame rate.
|
||||
*
|
||||
* This structure can be used to specify the minimum scale factor used when
|
||||
* lowering the resolution of a View, and the maximum scale factor used when
|
||||
* increasing the resolution for higher quality rendering. The scale factors
|
||||
* can be controlled on each X and Y axis independently. By default, all scale
|
||||
* factors are set to 1.0.
|
||||
*
|
||||
* enabled: enable or disables dynamic resolution on a View
|
||||
*
|
||||
* homogeneousScaling: by default the system scales the major axis first. Set this to true
|
||||
* to force homogeneous scaling.
|
||||
*
|
||||
* minScale: the minimum scale in X and Y this View should use
|
||||
*
|
||||
* maxScale: the maximum scale in X and Y this View should use
|
||||
*
|
||||
* quality: upscaling quality.
|
||||
* LOW: 1 bilinear tap, Medium: 4 bilinear taps, High: 9 bilinear taps (tent)
|
||||
*
|
||||
* \note
|
||||
* Dynamic resolution is only supported on platforms where the time to render
|
||||
* a frame can be measured accurately. Dynamic resolution is currently only
|
||||
* supported on Android.
|
||||
*
|
||||
* @see Renderer::FrameRateOptions
|
||||
*
|
||||
*/
|
||||
struct DynamicResolutionOptions {
|
||||
math::float2 minScale = math::float2(0.5f); //!< minimum scale factors in x and y
|
||||
math::float2 maxScale = math::float2(1.0f); //!< maximum scale factors in x and y
|
||||
bool enabled = false; //!< enable or disable dynamic resolution
|
||||
bool homogeneousScaling = false; //!< set to true to force homogeneous scaling
|
||||
QualityLevel quality = QualityLevel::LOW; //!< Upscaling quality
|
||||
};
|
||||
|
||||
/**
|
||||
* Options to control the bloom effect
|
||||
*
|
||||
* enabled: Enable or disable the bloom post-processing effect. Disabled by default.
|
||||
*
|
||||
* levels: Number of successive blurs to achieve the blur effect, the minimum is 3 and the
|
||||
* maximum is 12. This value together with resolution influences the spread of the
|
||||
* blur effect. This value can be silently reduced to accommodate the original
|
||||
* image size.
|
||||
*
|
||||
* resolution: Resolution of bloom's minor axis. The minimum value is 2^levels and the
|
||||
* the maximum is lower of the original resolution and 4096. This parameter is
|
||||
* silently clamped to the minimum and maximum.
|
||||
* It is highly recommended that this value be smaller than the target resolution
|
||||
* after dynamic resolution is applied (horizontally and vertically).
|
||||
*
|
||||
* strength: how much of the bloom is added to the original image. Between 0 and 1.
|
||||
*
|
||||
* blendMode: Whether the bloom effect is purely additive (false) or mixed with the original
|
||||
* image (true).
|
||||
*
|
||||
* anamorphism: Bloom's aspect ratio (x/y), for artistic purposes.
|
||||
*
|
||||
* threshold: When enabled, a threshold at 1.0 is applied on the source image, this is
|
||||
* useful for artistic reasons and is usually needed when a dirt texture is used.
|
||||
*
|
||||
* dirt: A dirt/scratch/smudges texture (that can be RGB), which gets added to the
|
||||
* bloom effect. Smudges are visible where bloom occurs. Threshold must be
|
||||
* enabled for the dirt effect to work properly.
|
||||
*
|
||||
* dirtStrength: Strength of the dirt texture.
|
||||
*/
|
||||
struct BloomOptions {
|
||||
enum class BlendMode : uint8_t {
|
||||
ADD, //!< Bloom is modulated by the strength parameter and added to the scene
|
||||
INTERPOLATE //!< Bloom is interpolated with the scene using the strength parameter
|
||||
};
|
||||
Texture* dirt = nullptr; //!< user provided dirt texture
|
||||
float dirtStrength = 0.2f; //!< strength of the dirt texture
|
||||
float strength = 0.10f; //!< bloom's strength between 0.0 and 1.0
|
||||
uint32_t resolution = 360; //!< resolution of vertical axis (2^levels to 2048)
|
||||
float anamorphism = 1.0f; //!< bloom x/y aspect-ratio (1/32 to 32)
|
||||
uint8_t levels = 6; //!< number of blur levels (3 to 11)
|
||||
BlendMode blendMode = BlendMode::ADD; //!< how the bloom effect is applied
|
||||
bool threshold = true; //!< whether to threshold the source
|
||||
bool enabled = false; //!< enable or disable bloom
|
||||
float highlight = 1000.0f; //!< limit highlights to this value before bloom [10, +inf]
|
||||
|
||||
bool lensFlare = false; //!< enable screen-space lens flare
|
||||
bool starburst = true; //!< enable starburst effect on lens flare
|
||||
float chromaticAberration = 0.005f; //!< amount of chromatic aberration
|
||||
uint8_t ghostCount = 4; //!< number of flare "ghosts"
|
||||
float ghostSpacing = 0.6f; //!< spacing of the ghost in screen units [0, 1[
|
||||
float ghostThreshold = 10.0f; //!< hdr threshold for the ghosts
|
||||
float haloThickness = 0.1f; //!< thickness of halo in vertical screen units, 0 to disable
|
||||
float haloRadius = 0.4f; //!< radius of halo in vertical screen units [0, 0.5]
|
||||
float haloThreshold = 10.0f; //!< hdr threshold for the halo
|
||||
};
|
||||
|
||||
/**
|
||||
* Options to control fog in the scene
|
||||
*/
|
||||
struct FogOptions {
|
||||
float distance = 0.0f; //!< distance in world units from the camera where the fog starts ( >= 0.0 )
|
||||
float maximumOpacity = 1.0f; //!< fog's maximum opacity between 0 and 1
|
||||
float height = 0.0f; //!< fog's floor in world units
|
||||
float heightFalloff = 1.0f; //!< how fast fog dissipates with altitude
|
||||
LinearColor color{0.5f}; //!< fog's color (linear), see fogColorFromIbl
|
||||
float density = 0.1f; //!< fog's density at altitude given by 'height'
|
||||
float inScatteringStart = 0.0f; //!< distance in world units from the camera where in-scattering starts
|
||||
float inScatteringSize = -1.0f; //!< size of in-scattering (>0 to activate). Good values are >> 1 (e.g. ~10 - 100).
|
||||
bool fogColorFromIbl = false; //!< Fog color will be modulated by the IBL color in the view direction.
|
||||
bool enabled = false; //!< enable or disable fog
|
||||
};
|
||||
|
||||
/**
|
||||
* Options to control Depth of Field (DoF) effect in the scene.
|
||||
*
|
||||
* cocScale can be used to set the depth of field blur independently from the camera
|
||||
* aperture, e.g. for artistic reasons. This can be achieved by setting:
|
||||
* cocScale = cameraAperture / desiredDoFAperture
|
||||
*
|
||||
* @see Camera
|
||||
*/
|
||||
struct DepthOfFieldOptions {
|
||||
enum class Filter : uint8_t {
|
||||
NONE = 0,
|
||||
MEDIAN = 2
|
||||
};
|
||||
float cocScale = 1.0f; //!< circle of confusion scale factor (amount of blur)
|
||||
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
|
||||
bool nativeResolution = false; //!< perform DoF processing at native resolution
|
||||
/**
|
||||
* Number of of rings used by the gather kernels. The number of rings affects quality
|
||||
* and performance. The actual number of sample per pixel is defined
|
||||
* as (ringCount * 2 - 1)^2. Here are a few commonly used values:
|
||||
* 3 rings : 25 ( 5x 5 grid)
|
||||
* 4 rings : 49 ( 7x 7 grid)
|
||||
* 5 rings : 81 ( 9x 9 grid)
|
||||
* 17 rings : 1089 (33x33 grid)
|
||||
*
|
||||
* With a maximum circle-of-confusion of 32, it is never necessary to use more than 17 rings.
|
||||
*
|
||||
* Usually all three settings below are set to the same value, however, it is often
|
||||
* acceptable to use a lower ring count for the "fast tiles", which improves performance.
|
||||
* Fast tiles are regions of the screen where every pixels have a similar
|
||||
* circle-of-confusion radius.
|
||||
*
|
||||
* A value of 0 means default, which is 5 on desktop and 3 on mobile.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
uint8_t foregroundRingCount = 0; //!< number of kernel rings for foreground tiles
|
||||
uint8_t backgroundRingCount = 0; //!< number of kernel rings for background tiles
|
||||
uint8_t fastGatherRingCount = 0; //!< number of kernel rings for fast tiles
|
||||
/** @}*/
|
||||
|
||||
/**
|
||||
* maximum circle-of-confusion in pixels for the foreground, must be in [0, 32] range.
|
||||
* A value of 0 means default, which is 32 on desktop and 24 on mobile.
|
||||
*/
|
||||
uint16_t maxForegroundCOC = 0;
|
||||
|
||||
/**
|
||||
* maximum circle-of-confusion in pixels for the background, must be in [0, 32] range.
|
||||
* A value of 0 means default, which is 32 on desktop and 24 on mobile.
|
||||
*/
|
||||
uint16_t maxBackgroundCOC = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Options to control the vignetting effect.
|
||||
*/
|
||||
struct VignetteOptions {
|
||||
float midPoint = 0.5f; //!< high values restrict the vignette closer to the corners, between 0 and 1
|
||||
float roundness = 0.5f; //!< controls the shape of the vignette, from a rounded rectangle (0.0), to an oval (0.5), to a circle (1.0)
|
||||
float feather = 0.5f; //!< softening amount of the vignette effect, between 0 and 1
|
||||
LinearColorA color{0.0f, 0.0f, 0.0f, 1.0f}; //!< color of the vignette effect, alpha is currently ignored
|
||||
bool enabled = false; //!< enables or disables the vignette effect
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure used to set the precision of the color buffer and related quality settings.
|
||||
*
|
||||
* @see setRenderQuality, getRenderQuality
|
||||
*/
|
||||
struct RenderQuality {
|
||||
/**
|
||||
* Sets the quality of the HDR color buffer.
|
||||
*
|
||||
* A quality of HIGH or ULTRA means using an RGB16F or RGBA16F color buffer. This means
|
||||
* colors in the LDR range (0..1) have a 10 bit precision. A quality of LOW or MEDIUM means
|
||||
* using an R11G11B10F opaque color buffer or an RGBA16F transparent color buffer. With
|
||||
* R11G11B10F colors in the LDR range have a precision of either 6 bits (red and green
|
||||
* channels) or 5 bits (blue channel).
|
||||
*/
|
||||
QualityLevel hdrColorBuffer = QualityLevel::HIGH;
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for screen space Ambient Occlusion (SSAO) and Screen Space Cone Tracing (SSCT)
|
||||
* @see setAmbientOcclusionOptions()
|
||||
*/
|
||||
struct AmbientOcclusionOptions {
|
||||
float radius = 0.3f; //!< Ambient Occlusion radius in meters, between 0 and ~10.
|
||||
float power = 1.0f; //!< Controls ambient occlusion's contrast. Must be positive.
|
||||
float bias = 0.0005f; //!< Self-occlusion bias in meters. Use to avoid self-occlusion. Between 0 and a few mm.
|
||||
float resolution = 0.5f;//!< How each dimension of the AO buffer is scaled. Must be either 0.5 or 1.0.
|
||||
float intensity = 1.0f; //!< Strength of the Ambient Occlusion effect.
|
||||
float bilateralThreshold = 0.05f; //!< depth distance that constitute an edge for filtering
|
||||
QualityLevel quality = QualityLevel::LOW; //!< affects # of samples used for AO.
|
||||
QualityLevel lowPassFilter = QualityLevel::MEDIUM; //!< affects AO smoothness
|
||||
QualityLevel upsampling = QualityLevel::LOW; //!< affects AO buffer upsampling quality
|
||||
bool enabled = false; //!< enables or disables screen-space ambient occlusion
|
||||
bool bentNormals = false; //!< enables bent normals computation from AO, and specular AO
|
||||
float minHorizonAngleRad = 0.0f; //!< min angle in radian to consider
|
||||
/**
|
||||
* Screen Space Cone Tracing (SSCT) options
|
||||
* Ambient shadows from dominant light
|
||||
*/
|
||||
struct Ssct {
|
||||
float lightConeRad = 1.0f; //!< full cone angle in radian, between 0 and pi/2
|
||||
float shadowDistance = 0.3f; //!< how far shadows can be cast
|
||||
float contactDistanceMax = 1.0f; //!< max distance for contact
|
||||
float intensity = 0.8f; //!< intensity
|
||||
math::float3 lightDirection{ 0, -1, 0 }; //!< light direction
|
||||
float depthBias = 0.01f; //!< depth bias in world units (mitigate self shadowing)
|
||||
float depthSlopeBias = 0.01f; //!< depth slope bias (mitigate self shadowing)
|
||||
uint8_t sampleCount = 4; //!< tracing sample count, between 1 and 255
|
||||
uint8_t rayCount = 1; //!< # of rays to trace, between 1 and 255
|
||||
bool enabled = false; //!< enables or disables SSCT
|
||||
} ssct;
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for Temporal Anti-aliasing (TAA)
|
||||
* @see setTemporalAntiAliasingOptions()
|
||||
*/
|
||||
struct TemporalAntiAliasingOptions {
|
||||
float filterWidth = 1.0f; //!< reconstruction filter width typically between 0 (sharper, aliased) and 1 (smoother)
|
||||
float feedback = 0.04f; //!< history feedback, between 0 (maximum temporal AA) and 1 (no temporal AA).
|
||||
bool enabled = false; //!< enables or disables temporal anti-aliasing
|
||||
};
|
||||
|
||||
/**
|
||||
* List of available post-processing anti-aliasing techniques.
|
||||
* @see setAntiAliasing, getAntiAliasing, setSampleCount
|
||||
*/
|
||||
enum class AntiAliasing : uint8_t {
|
||||
NONE = 0, //!< no anti aliasing performed as part of post-processing
|
||||
FXAA = 1 //!< FXAA is a low-quality but very efficient type of anti-aliasing. (default).
|
||||
};
|
||||
|
||||
/**
|
||||
* List of available post-processing dithering techniques.
|
||||
*/
|
||||
enum class Dithering : uint8_t {
|
||||
NONE = 0, //!< No dithering
|
||||
TEMPORAL = 1 //!< Temporal dithering (default)
|
||||
};
|
||||
|
||||
/**
|
||||
* List of available shadow mapping techniques.
|
||||
* @see setShadowType
|
||||
*/
|
||||
enum class ShadowType : uint8_t {
|
||||
PCF, //!< percentage-closer filtered shadows (default)
|
||||
VSM //!< variance shadows
|
||||
};
|
||||
|
||||
/**
|
||||
* View-level options for VSM Shadowing.
|
||||
* @see setVsmShadowOptions()
|
||||
* @warning This API is still experimental and subject to change.
|
||||
*/
|
||||
struct VsmShadowOptions {
|
||||
/**
|
||||
* Sets the number of anisotropic samples to use when sampling a VSM shadow map. If greater
|
||||
* than 0, mipmaps will automatically be generated each frame for all lights.
|
||||
*
|
||||
* The number of anisotropic samples = 2 ^ vsmAnisotropy.
|
||||
*/
|
||||
uint8_t anisotropy = 0;
|
||||
|
||||
/**
|
||||
* Whether to generate mipmaps for all VSM shadow maps.
|
||||
*/
|
||||
bool mipmapping = false;
|
||||
|
||||
/**
|
||||
* EVSM exponent.
|
||||
* The maximum value permissible is 5.54 for a shadow map in fp16, or 42.0 for a
|
||||
* shadow map in fp32. Currently the shadow map bit depth is always fp16.
|
||||
*/
|
||||
float exponent = 5.54f;
|
||||
|
||||
/**
|
||||
* VSM minimum variance scale, must be positive.
|
||||
*/
|
||||
float minVarianceScale = 0.5f;
|
||||
|
||||
/**
|
||||
* VSM light bleeding reduction amount, between 0 and 1.
|
||||
*/
|
||||
float lightBleedReduction = 0.15f;
|
||||
};
|
||||
using DynamicResolutionOptions = DynamicResolutionOptions;
|
||||
using BloomOptions = BloomOptions;
|
||||
using FogOptions = FogOptions;
|
||||
using DepthOfFieldOptions = DepthOfFieldOptions;
|
||||
using VignetteOptions = VignetteOptions;
|
||||
using RenderQuality = RenderQuality;
|
||||
using AmbientOcclusionOptions = AmbientOcclusionOptions;
|
||||
using TemporalAntiAliasingOptions = TemporalAntiAliasingOptions;
|
||||
using VsmShadowOptions = VsmShadowOptions;
|
||||
|
||||
/**
|
||||
* Sets the View's name. Only useful for debugging.
|
||||
@@ -875,6 +572,116 @@ public:
|
||||
//! debugging: returns a Camera from the point of view of *the* dominant directional light used for shadowing.
|
||||
Camera const* getDirectionalLightCamera() const noexcept;
|
||||
|
||||
|
||||
/** Result of a picking query */
|
||||
struct PickingQueryResult {
|
||||
utils::Entity renderable{}; //! RenderableManager Entity at the queried coordinates
|
||||
float depth{}; //! Depth buffer value (1 (near plane) to 0 (infinity))
|
||||
uint32_t reserved1{};
|
||||
uint32_t reserved2{};
|
||||
/**
|
||||
* screen space coordinates in GL convention, this can be used to compute the view or
|
||||
* world space position of the picking hit. For e.g.:
|
||||
* clip_space_position = (fragCoords.xy / viewport.wh, fragCoords.z) * 2.0 - 1.0
|
||||
* view_space_position = inverse(projection) * clip_space_position
|
||||
* world_space_position = model * view_space_position
|
||||
*
|
||||
* The viewport, projection and model matrices can be obtained from Camera. Because
|
||||
* pick() has some latency, it might be more accurate to obtain these values at the
|
||||
* time the View::pick() call is made.
|
||||
*/
|
||||
math::float3 fragCoords; //! screen space coordinates in GL convention
|
||||
};
|
||||
|
||||
/** User data for PickingQueryResultCallback */
|
||||
struct PickingQuery {
|
||||
// note: this is enough to store a std::function<> -- just saying...
|
||||
void* storage[4];
|
||||
};
|
||||
|
||||
/** callback type used for picking queries. */
|
||||
using PickingQueryResultCallback = void(*)(PickingQueryResult const& result, PickingQuery* pq);
|
||||
|
||||
/**
|
||||
* Helper for creating a picking query from Foo::method, by pointer.
|
||||
* e.g.: pick<Foo, &Foo::bar>(x, y, &foo);
|
||||
*
|
||||
* @tparam T Class of the method to call (e.g.: Foo)
|
||||
* @tparam method Method to call on T (e.g.: &Foo::bar)
|
||||
* @param x Horizontal coordinate to query in the viewport with origin on the left.
|
||||
* @param y Vertical coordinate to query on the viewport with origin at the bottom.
|
||||
* @param data A pointer to an instance of T
|
||||
*/
|
||||
template<typename T, void(T::*method)(PickingQueryResult const&)>
|
||||
void pick(uint32_t x, uint32_t y, T* instance) noexcept {
|
||||
PickingQuery& query = pick(x, y, [](PickingQueryResult const& result, PickingQuery* pq) {
|
||||
void* user = pq->storage;
|
||||
(*static_cast<T**>(user)->*method)(result);
|
||||
});
|
||||
query.storage[0] = instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for creating a picking query from Foo::method, by copy for a small object
|
||||
* e.g.: pick<Foo, &Foo::bar>(x, y, foo);
|
||||
*
|
||||
* @tparam T Class of the method to call (e.g.: Foo)
|
||||
* @tparam method Method to call on T (e.g.: &Foo::bar)
|
||||
* @param x Horizontal coordinate to query in the viewport with origin on the left.
|
||||
* @param y Vertical coordinate to query on the viewport with origin at the bottom.
|
||||
* @param data An instance of T
|
||||
*/
|
||||
template<typename T, void(T::*method)(PickingQueryResult const&)>
|
||||
void pick(uint32_t x, uint32_t y, T instance) noexcept {
|
||||
static_assert(sizeof(instance) <= sizeof(PickingQuery::storage), "user data too large");
|
||||
PickingQuery& query = pick(x, y, [](PickingQueryResult const& result, PickingQuery* pq) {
|
||||
void* user = pq->storage;
|
||||
T* that = static_cast<T*>(user);
|
||||
(that->*method)(result);
|
||||
that->~T();
|
||||
});
|
||||
new(query.storage) T(std::move(instance));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for creating a picking query from a small functor
|
||||
* e.g.: pick(x, y, [](PickingQueryResult const& result){});
|
||||
*
|
||||
* @param x Horizontal coordinate to query in the viewport with origin on the left.
|
||||
* @param y Vertical coordinate to query on the viewport with origin at the bottom.
|
||||
* @param functor A functor, typically a lambda function.
|
||||
*/
|
||||
template<typename T>
|
||||
void pick(uint32_t x, uint32_t y, T functor) noexcept {
|
||||
static_assert(sizeof(functor) <= sizeof(PickingQuery::storage), "functor too large");
|
||||
PickingQuery& query = pick(x, y,
|
||||
(PickingQueryResultCallback)[](PickingQueryResult const& result, PickingQuery* pq) {
|
||||
void* user = pq->storage;
|
||||
T& that = *static_cast<T*>(user);
|
||||
that(result);
|
||||
that.~T();
|
||||
});
|
||||
new(query.storage) T(std::move(functor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a picking query. Multiple queries can be created (e.g.: multi-touch).
|
||||
* Picking queries are all executed when Renderer::render() is called on this View.
|
||||
* The provided callback is guaranteed to be called at some point in the future.
|
||||
*
|
||||
* Typically it takes a couple frames to receive the result of a picking query.
|
||||
*
|
||||
* @param x Horizontal coordinate to query in the viewport with origin on the left.
|
||||
* @param y Vertical coordinate to query on the viewport with origin at the bottom.
|
||||
* @param callback User callback, called when the picking query result is available.
|
||||
* @return A reference to a PickingQuery structure, which can be used to store up to
|
||||
* 8*sizeof(void*) bytes of user data. This user data is later accessible
|
||||
* in the PickingQueryResultCallback callback 3rd parameter.
|
||||
*/
|
||||
PickingQuery& pick(uint32_t x, uint32_t y,
|
||||
PickingQueryResultCallback callback) noexcept;
|
||||
|
||||
|
||||
/**
|
||||
* List of available ambient occlusion techniques
|
||||
* @deprecated use AmbientOcclusionOptions::enabled instead
|
||||
@@ -905,7 +712,6 @@ public:
|
||||
AmbientOcclusion getAmbientOcclusion() const noexcept;
|
||||
};
|
||||
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_VIEW_H
|
||||
|
||||
@@ -63,6 +63,9 @@ using namespace gltfio;
|
||||
using namespace utils;
|
||||
using namespace std::chrono;
|
||||
|
||||
namespace foo {
|
||||
MaterialProvider* createUbershaderLoader(filament::Engine* engine);
|
||||
}
|
||||
|
||||
namespace filament {
|
||||
class IndirectLight;
|
||||
@@ -70,7 +73,12 @@ namespace filament {
|
||||
}
|
||||
|
||||
namespace gltfio {
|
||||
MaterialProvider* createGPUMorphShaderLoader(const void* data, uint64_t size, Engine* engine);
|
||||
MaterialProvider* createGPUMorphShaderLoader(
|
||||
const void* opaqueData,
|
||||
uint64_t opaqueDataSize,
|
||||
const void* fadeData,
|
||||
uint64_t fadeDataSize,
|
||||
Engine* engine);
|
||||
void decomposeMatrix(const filament::math::mat4f& mat, filament::math::float3* translation,
|
||||
filament::math::quatf* rotation, filament::math::float3* scale);
|
||||
}
|
||||
@@ -113,12 +121,14 @@ filament::math::mat4f composeMatrix(const filament::math::float3& translation,
|
||||
|
||||
FilamentViewer::FilamentViewer(
|
||||
void* layer,
|
||||
const char* shaderPath,
|
||||
const char* opaqueShaderPath,
|
||||
const char* fadeShaderPath,
|
||||
LoadResource loadResource,
|
||||
FreeResource freeResource) : _layer(layer),
|
||||
_loadResource(loadResource),
|
||||
_freeResource(freeResource),
|
||||
materialProviderResources(nullptr, 0) {
|
||||
opaqueShaderResources(nullptr, 0),
|
||||
fadeShaderResources(nullptr, 0) {
|
||||
_engine = Engine::create(Engine::Backend::OPENGL);
|
||||
|
||||
_renderer = _engine->createRenderer();
|
||||
@@ -134,13 +144,19 @@ FilamentViewer::FilamentViewer(
|
||||
|
||||
_swapChain = _engine->createSwapChain(_layer);
|
||||
|
||||
if(shaderPath) {
|
||||
materialProviderResources = _loadResource(shaderPath);
|
||||
_materialProvider = createGPUMorphShaderLoader(materialProviderResources.data, materialProviderResources.size, _engine);
|
||||
// if(shaderPath) {
|
||||
opaqueShaderResources = _loadResource(opaqueShaderPath);
|
||||
fadeShaderResources = _loadResource(fadeShaderPath);
|
||||
_materialProvider = createGPUMorphShaderLoader(
|
||||
opaqueShaderResources.data,
|
||||
opaqueShaderResources.size,
|
||||
fadeShaderResources.data,
|
||||
fadeShaderResources.size,
|
||||
_engine);
|
||||
// _freeResource((void*)rb.data, rb.size, nullptr); <- TODO this is being freed too early, need to pass to callback?
|
||||
} else {
|
||||
_materialProvider = createUbershaderLoader(_engine);
|
||||
}
|
||||
// } else {
|
||||
// _materialProvider = foo::createUbershaderLoader(_engine);
|
||||
// }
|
||||
EntityManager& em = EntityManager::get();
|
||||
_ncm = new NameComponentManager(em);
|
||||
_assetLoader = AssetLoader::create({_engine, _materialProvider, _ncm, &em});
|
||||
@@ -191,7 +207,8 @@ void FilamentViewer::loadResources(string relativeResourcePath) {
|
||||
void FilamentViewer::releaseSourceAssets() {
|
||||
std::cout << "Releasing source data" << std::endl;
|
||||
_asset->releaseSourceData();
|
||||
_freeResource((void*)materialProviderResources.data, materialProviderResources.size, nullptr);
|
||||
_freeResource((void*)opaqueShaderResources.data, opaqueShaderResources.size, nullptr);
|
||||
_freeResource((void*)fadeShaderResources.data, fadeShaderResources.size, nullptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -200,6 +217,44 @@ void FilamentViewer::animateWeights(float* data, int numWeights, int length, flo
|
||||
morphAnimationBuffer = std::make_unique<MorphAnimationBuffer>(data, numWeights, length / numWeights, 1000 / frameRate );
|
||||
}
|
||||
|
||||
void FilamentViewer::loadGlb(const char* const uri) {
|
||||
if(_asset) {
|
||||
_resourceLoader->evictResourceData();
|
||||
_scene->removeEntities(_asset->getEntities(), _asset->getEntityCount());
|
||||
_assetLoader->destroyAsset(_asset);
|
||||
}
|
||||
_asset = nullptr;
|
||||
_animator = nullptr;
|
||||
|
||||
ResourceBuffer rbuf = _loadResource(uri);
|
||||
|
||||
// Parse the glTF file and create Filament entities.
|
||||
_asset = _assetLoader->createAssetFromJson((uint8_t*)rbuf.data, rbuf.size);
|
||||
|
||||
if (!_asset) {
|
||||
std::cerr << "Unable to parse asset" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
_resourceLoader->loadResources(_asset);
|
||||
const Entity* entities = _asset->getEntities();
|
||||
RenderableManager& rm = _engine->getRenderableManager();
|
||||
for(int i =0; i< _asset->getEntityCount(); i++) {
|
||||
Entity e = entities[i];
|
||||
auto inst = rm.getInstance(e);
|
||||
rm.setCulling(inst, false);
|
||||
}
|
||||
|
||||
_animator = _asset->getAnimator();
|
||||
|
||||
_scene->addEntities(_asset->getEntities(), _asset->getEntityCount());
|
||||
|
||||
|
||||
_freeResource((void*)rbuf.data, rbuf.size, nullptr);
|
||||
|
||||
transformToUnitCube();
|
||||
}
|
||||
|
||||
void FilamentViewer::loadGltf(const char* const uri, const char* const relativeResourcePath) {
|
||||
if(_asset) {
|
||||
_resourceLoader->evictResourceData();
|
||||
@@ -280,16 +335,23 @@ void FilamentViewer::playAnimation(int index) {
|
||||
}
|
||||
|
||||
void FilamentViewer::loadSkybox(const char* const skyboxPath, const char* const iblPath) {
|
||||
|
||||
std::cout << "Loading skybox from " << skyboxPath << std::endl;
|
||||
|
||||
ResourceBuffer skyboxBuffer = _loadResource(skyboxPath);
|
||||
|
||||
std::cout << "Loaded skybox resource buffer of size " << skyboxBuffer.size << std::endl;
|
||||
|
||||
image::KtxBundle* skyboxBundle =
|
||||
new image::KtxBundle(static_cast<const uint8_t*>(skyboxBuffer.data),
|
||||
static_cast<uint32_t>(skyboxBuffer.size));
|
||||
_skyboxTexture = image::ktx::createTexture(_engine, skyboxBundle, false);
|
||||
_skyboxTexture = image::ktx::createTexture(_engine, skyboxBundle, true);
|
||||
_skybox = filament::Skybox::Builder().environment(_skyboxTexture).build(*_engine);
|
||||
_scene->setSkybox(_skybox);
|
||||
_freeResource((void*)skyboxBuffer.data, skyboxBuffer.size, nullptr);
|
||||
|
||||
std::cout << "Loading IBL from " << iblPath << std::endl;
|
||||
|
||||
// Load IBL.
|
||||
ResourceBuffer iblBuffer = _loadResource(iblPath);
|
||||
|
||||
|
||||
@@ -94,8 +94,9 @@ namespace holovox {
|
||||
|
||||
class FilamentViewer {
|
||||
public:
|
||||
FilamentViewer(void* layer, const char* shaderPath, LoadResource loadResource, FreeResource freeResource);
|
||||
FilamentViewer(void* layer, const char* opaqueShaderPath, const char* fadeShaderPath, LoadResource loadResource, FreeResource freeResource);
|
||||
~FilamentViewer();
|
||||
void loadGlb(const char* const uri);
|
||||
void loadGltf(const char* const uri, const char* relativeResourcePath);
|
||||
void loadSkybox(const char* const skyboxUri, const char* const iblUri);
|
||||
void updateViewportAndCameraProjection(int height, int width, float scaleFactor);
|
||||
@@ -127,7 +128,8 @@ namespace holovox {
|
||||
LoadResource _loadResource;
|
||||
FreeResource _freeResource;
|
||||
|
||||
ResourceBuffer materialProviderResources;
|
||||
ResourceBuffer opaqueShaderResources;
|
||||
ResourceBuffer fadeShaderResources;
|
||||
|
||||
Scene* _scene;
|
||||
View* _view;
|
||||
|
||||
@@ -35,6 +35,16 @@ using namespace filament;
|
||||
using namespace filamat;
|
||||
using namespace filament::math;
|
||||
using namespace utils;
|
||||
|
||||
#include "upcast.h"
|
||||
|
||||
#include <backend/Handle.h>
|
||||
|
||||
#include <filament/Texture.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
|
||||
|
||||
namespace gltfio {
|
||||
|
||||
static constexpr uint8_t kUnused = 0xff;
|
||||
@@ -62,6 +72,7 @@ namespace gltfio {
|
||||
targetMesh = mesh;
|
||||
for(int i = 0; i < numPrimitives; i++) {
|
||||
int primitiveIndex = primitiveIndices[i];
|
||||
//for(int primitiveIndex = 0; primitiveIndex < targetMesh->primitives_count; primitiveIndex++) {
|
||||
std::cout << "Adding primitive at index " << primitiveIndex << " to morpher " << std::endl;
|
||||
addPrimitive(mesh, primitiveIndex);
|
||||
}
|
||||
@@ -106,7 +117,6 @@ namespace gltfio {
|
||||
auto textureSize = textureWidth * 3 * sizeof(float) * prim->numTargets;
|
||||
auto textureBuffer = (float *const) malloc(textureSize);
|
||||
|
||||
|
||||
if(!textureBuffer) {
|
||||
std::cout << "Error allocating texture buffer" << std::endl;
|
||||
exit(-1);
|
||||
@@ -117,7 +127,7 @@ namespace gltfio {
|
||||
uint32_t offset = 0;
|
||||
|
||||
// assume the primitive morph target source buffer is laid out like:
|
||||
// |target0_v0_pos * 3|target0_v0_norm * 3|target0_v1_pos * 3|target0_v1_norm * 3|...|target1_v0_pos * 3|target1_v0_norm * 3|target1_v1_pos * 3|target1_v1_norm * 3|...
|
||||
// |target0_v0_pos * 3|target0_v1_pos * 3|...|target0_v0_norm * 3|target0_v1_norm * 3|...|target1_v0_pos * 3|target1_v1_pos * 3|...|target1_v0_norm * 3|target1_v1_norm * 3|...
|
||||
// where:
|
||||
// - target0/target1/etc is the first/second/etc morph target
|
||||
// - v0/v1/etc is the first/second/etc vertex
|
||||
@@ -126,7 +136,7 @@ namespace gltfio {
|
||||
if(target.type == cgltf_attribute_type_position
|
||||
|| (numAttributes > 1 && target.type == cgltf_attribute_type_normal)
|
||||
) {
|
||||
|
||||
float attr = (float)textureBuffer[offset];
|
||||
memcpy(textureBuffer+offset, target.bufferObject, target.bufferSize);
|
||||
offset += int(target.bufferSize / sizeof(float));
|
||||
}
|
||||
@@ -137,7 +147,7 @@ namespace gltfio {
|
||||
.height(1)
|
||||
.depth(prim->numTargets)
|
||||
.sampler(Texture::Sampler::SAMPLER_2D_ARRAY)
|
||||
.format(Texture::InternalFormat::RGB32F)
|
||||
.format(backend::TextureFormat::RGB32F)
|
||||
.levels(0x01)
|
||||
.build(engine);
|
||||
|
||||
@@ -146,8 +156,8 @@ namespace gltfio {
|
||||
Texture::PixelBufferDescriptor descriptor(
|
||||
textureBuffer,
|
||||
textureSize,
|
||||
Texture::Format::RGB,
|
||||
Texture::Type::FLOAT,
|
||||
backend::PixelDataFormat::RGB,
|
||||
backend::PixelDataType::FLOAT,
|
||||
FREE_CALLBACK,
|
||||
nullptr);
|
||||
prim->texture->setImage(engine, 0, 0,0, 0, textureWidth, 1, prim->numTargets, std::move(descriptor));
|
||||
@@ -155,7 +165,8 @@ namespace gltfio {
|
||||
for(int i = 0; i < mAsset->getMaterialInstanceCount(); i++) {
|
||||
const char* name = materialInstances[i]->getName();
|
||||
if(strcmp(name, prim->materialName) == 0) {
|
||||
std::cout << "Found material instance for primitive under name : " << name << std::endl;
|
||||
const char* m = materialInstances[i]->getMaterial()->getName();
|
||||
std::cout << "Found material instance for material " << m << " and primitive under name : " << name << std::endl;
|
||||
prim->materialInstance = materialInstances[i]; //std::unique_ptr<MaterialInstance>(materialInstances[i]);
|
||||
break;
|
||||
}
|
||||
@@ -165,7 +176,7 @@ namespace gltfio {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
float dimensions[] = { (float(prim->numVertices) * float(numAttributes)), float(numAttributes), float(prim->numTargets) };
|
||||
float dimensions[] = { float(prim->numVertices), float(numAttributes), float(prim->numTargets) };
|
||||
|
||||
prim->materialInstance->setParameter("dimensions", dimensions, 3);
|
||||
// TextureSampler sampler(filament::backend::SamplerMagFilter::NEAREST, filament::TextureSampler::WrapMode::REPEAT);
|
||||
@@ -214,12 +225,7 @@ namespace gltfio {
|
||||
if (atype == cgltf_attribute_type_tangent) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
atype == cgltf_attribute_type_position || (numAttributes > 1 && atype == cgltf_attribute_type_normal)
|
||||
) {
|
||||
|
||||
|
||||
// All position & normal attributes must have the same data type.
|
||||
if (atype == cgltf_attribute_type_position || numAttributes > 1 && atype == cgltf_attribute_type_normal) {
|
||||
assert_invariant(
|
||||
!previous || previous->component_type == accessor->component_type);
|
||||
assert_invariant(!previous || previous->type == accessor->type);
|
||||
@@ -234,9 +240,122 @@ namespace gltfio {
|
||||
|
||||
animatedPrimitive->targets.push_back({data, size, targetIndex, atype});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
animatablePrimitives.push_back(std::move(animatedPrimitive));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// assert(
|
||||
// FTexture::validatePixelFormatAndType(
|
||||
// backend::TextureFormat::RGB32F,
|
||||
// backend::PixelDataFormat::RGB,
|
||||
// backend::PixelDataType::FLOAT));
|
||||
|
||||
// namespace filament {
|
||||
|
||||
// class FEngine;
|
||||
// class FStream;
|
||||
|
||||
// class FTexture : public Texture {
|
||||
// public:
|
||||
// FTexture(FEngine& engine, const Builder& builder);
|
||||
|
||||
// // frees driver resources, object becomes invalid
|
||||
// void terminate(FEngine& engine);
|
||||
|
||||
// backend::Handle<backend::HwTexture> getHwHandle() const noexcept { return mHandle; }
|
||||
|
||||
// size_t getWidth(size_t level = 0) const noexcept;
|
||||
// size_t getHeight(size_t level = 0) const noexcept;
|
||||
// size_t getDepth(size_t level = 0) const noexcept;
|
||||
// size_t getLevelCount() const noexcept { return mLevelCount; }
|
||||
// size_t getMaxLevelCount() const noexcept { return FTexture::maxLevelCount(mWidth, mHeight); }
|
||||
// Sampler getTarget() const noexcept { return mTarget; }
|
||||
// InternalFormat getFormat() const noexcept { return mFormat; }
|
||||
// Usage getUsage() const noexcept { return mUsage; }
|
||||
|
||||
// void setImage(FEngine& engine, size_t level,
|
||||
// uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height,
|
||||
// PixelBufferDescriptor&& buffer) const;
|
||||
|
||||
// void setImage(FEngine& engine, size_t level,
|
||||
// uint32_t xoffset, uint32_t yoffset, uint32_t zoffset,
|
||||
// uint32_t width, uint32_t height, uint32_t depth,
|
||||
// PixelBufferDescriptor&& buffer) const;
|
||||
|
||||
// void setImage(FEngine& engine, size_t level,
|
||||
// PixelBufferDescriptor&& buffer, const FaceOffsets& faceOffsets) const;
|
||||
|
||||
// void generatePrefilterMipmap(FEngine& engine,
|
||||
// PixelBufferDescriptor&& buffer, const FaceOffsets& faceOffsets,
|
||||
// PrefilterOptions const* options);
|
||||
|
||||
// void setExternalImage(FEngine& engine, void* image) noexcept;
|
||||
// void setExternalImage(FEngine& engine, void* image, size_t plane) noexcept;
|
||||
// void setExternalStream(FEngine& engine, FStream* stream) noexcept;
|
||||
|
||||
// void generateMipmaps(FEngine& engine) const noexcept;
|
||||
|
||||
// void setSampleCount(size_t sampleCount) noexcept { mSampleCount = uint8_t(sampleCount); }
|
||||
// size_t getSampleCount() const noexcept { return mSampleCount; }
|
||||
// bool isMultisample() const noexcept { return mSampleCount > 1; }
|
||||
// bool isCompressed() const noexcept { return backend::isCompressedFormat(mFormat); }
|
||||
|
||||
// bool isCubemap() const noexcept { return mTarget == Sampler::SAMPLER_CUBEMAP; }
|
||||
|
||||
// FStream const* getStream() const noexcept { return mStream; }
|
||||
|
||||
// /*
|
||||
// * Utilities
|
||||
// */
|
||||
|
||||
// // synchronous call to the backend. returns whether a backend supports a particular format.
|
||||
// static bool isTextureFormatSupported(FEngine& engine, InternalFormat format) noexcept;
|
||||
|
||||
// // synchronous call to the backend. returns whether a backend supports texture swizzling.
|
||||
// static bool isTextureSwizzleSupported(FEngine& engine) noexcept;
|
||||
|
||||
// // storage needed on the CPU side for texture data uploads
|
||||
// static size_t computeTextureDataSize(Texture::Format format, Texture::Type type,
|
||||
// size_t stride, size_t height, size_t alignment) noexcept;
|
||||
|
||||
// // Size a of a pixel in bytes for the given format
|
||||
// static size_t getFormatSize(InternalFormat format) noexcept;
|
||||
|
||||
// // Returns the with or height for a given mipmap level from the base value.
|
||||
// static inline size_t valueForLevel(uint8_t level, size_t baseLevelValue) {
|
||||
// return std::max(size_t(1), baseLevelValue >> level);
|
||||
// }
|
||||
|
||||
// // Returns the max number of levels for a texture of given max dimensions
|
||||
// static inline uint8_t maxLevelCount(uint32_t maxDimension) noexcept {
|
||||
// return std::max(1, std::ilogbf(maxDimension) + 1);
|
||||
// }
|
||||
|
||||
// // Returns the max number of levels for a texture of given dimensions
|
||||
// static inline uint8_t maxLevelCount(uint32_t width, uint32_t height) noexcept {
|
||||
// return std::max(1, std::ilogbf(std::max(width, height)) + 1);
|
||||
// }
|
||||
|
||||
// static bool validatePixelFormatAndType(backend::TextureFormat internalFormat,
|
||||
// backend::PixelDataFormat format, backend::PixelDataType type) noexcept;
|
||||
|
||||
// private:
|
||||
// friend class Texture;
|
||||
// FStream* mStream = nullptr;
|
||||
// backend::Handle<backend::HwTexture> mHandle;
|
||||
// uint32_t mWidth = 1;
|
||||
// uint32_t mHeight = 1;
|
||||
// uint32_t mDepth = 1;
|
||||
// InternalFormat mFormat = InternalFormat::RGBA8;
|
||||
// Sampler mTarget = Sampler::SAMPLER_2D;
|
||||
// uint8_t mLevelCount = 1;
|
||||
// uint8_t mSampleCount = 1;
|
||||
// Usage mUsage = Usage::DEFAULT;
|
||||
// };
|
||||
|
||||
|
||||
// } // namespace filament
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace gltfio {
|
||||
MaterialInstance* materialInstance;
|
||||
};
|
||||
|
||||
int numAttributes = 1; // just position for now - normals not working with indexing inside shader? byte offset seems not calculated correctly
|
||||
int numAttributes = 2;
|
||||
|
||||
void addPrimitive(cgltf_mesh const *mesh, int primitiveIndex);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <math/mat4.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "gltfio/resources/gltfresources_lite.h"
|
||||
|
||||
@@ -22,7 +23,12 @@ namespace {
|
||||
|
||||
class GPUMorphShaderLoader : public MaterialProvider {
|
||||
public:
|
||||
GPUMorphShaderLoader(const void* mData, uint64_t size, filament::Engine* engine);
|
||||
GPUMorphShaderLoader(
|
||||
const void* opaqueMaterial,
|
||||
uint64_t opaqueMaterialSize,
|
||||
const void* fadeMaterial,
|
||||
uint64_t fadeMaterialSize,
|
||||
filament::Engine* engine);
|
||||
~GPUMorphShaderLoader() {}
|
||||
|
||||
MaterialInstance* createMaterialInstance(MaterialKey* config, UvMap* uvmap,
|
||||
@@ -42,8 +48,10 @@ namespace {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const void* mData;
|
||||
const size_t mSize;
|
||||
const void* opaqueData;
|
||||
const size_t opaqueDataSize;
|
||||
const void* fadeData;
|
||||
const size_t fadeDataSize;
|
||||
|
||||
Material* getMaterial(const MaterialKey& config) const;
|
||||
|
||||
@@ -59,18 +67,41 @@ namespace {
|
||||
Engine* mEngine;
|
||||
};
|
||||
|
||||
GPUMorphShaderLoader::GPUMorphShaderLoader(const void* data, uint64_t size, Engine* engine) : mData(data), mSize(size), mEngine(engine) {
|
||||
|
||||
unsigned char texels[4] = {};
|
||||
mDummyTexture = Texture::Builder()
|
||||
.width(1).height(1)
|
||||
.format(Texture::InternalFormat::RGBA8)
|
||||
.build(*mEngine);
|
||||
Texture::PixelBufferDescriptor pbd(texels, sizeof(texels), Texture::Format::RGBA,
|
||||
Texture::Type::UBYTE);
|
||||
mDummyTexture->setImage(*mEngine, 0, std::move(pbd));
|
||||
#define MATINDEX(shading, alpha, sheen, transmit, volume) (volume ? 11 : (transmit ? 10 : (sheen ? 9 : (int(shading) + 3 * int(alpha)))))
|
||||
|
||||
|
||||
GPUMorphShaderLoader::GPUMorphShaderLoader(const void* opaqueData,
|
||||
uint64_t opaqueDataSize,
|
||||
const void* fadeData,
|
||||
uint64_t fadeDataSize,
|
||||
Engine* engine) : opaqueData(opaqueData), opaqueDataSize(opaqueDataSize), fadeData(fadeData), fadeDataSize(fadeDataSize), mEngine(engine) {
|
||||
|
||||
// unsigned char texels[4] = {};
|
||||
// mDummyTexture = Texture::Builder()
|
||||
// .width(1)
|
||||
// .height(1)
|
||||
// .format(backend::TextureFormat::RGBA8)
|
||||
// .sampler(backend::SamplerType::SAMPLER_2D_ARRAY)
|
||||
// .build(*mEngine);
|
||||
// Texture::PixelBufferDescriptor pbd(
|
||||
// texels,
|
||||
// sizeof(texels),
|
||||
// backend::PixelDataFormat::RGBA,
|
||||
// backend::PixelDataType::UBYTE,
|
||||
// nullptr);
|
||||
// mDummyTexture->setImage(*mEngine, 0,0,0,0,0,0,0,std::move(pbd));
|
||||
unsigned char texels[4] = {};
|
||||
mDummyTexture = Texture::Builder()
|
||||
.width(1).height(1)
|
||||
.format(Texture::InternalFormat::RGBA8)
|
||||
.build(*mEngine);
|
||||
Texture::PixelBufferDescriptor pbd(texels, sizeof(texels), Texture::Format::RGBA,
|
||||
Texture::Type::UBYTE);
|
||||
mDummyTexture->setImage(*mEngine, 0, std::move(pbd));
|
||||
}
|
||||
|
||||
|
||||
size_t GPUMorphShaderLoader::getMaterialsCount() const noexcept {
|
||||
return sizeof(mMaterials) / sizeof(mMaterials[0]);
|
||||
}
|
||||
@@ -90,13 +121,33 @@ namespace {
|
||||
Material* GPUMorphShaderLoader::getMaterial(const MaterialKey& config) const {
|
||||
const ShadingMode shading = config.unlit ? UNLIT :
|
||||
(config.useSpecularGlossiness ? SPECULAR_GLOSSINESS : LIT);
|
||||
const int matindex = 0;
|
||||
|
||||
const int matindex = MATINDEX(shading, config.alphaMode, config.hasSheen, config.hasTransmission, config.hasVolume);
|
||||
if (mMaterials[matindex] != nullptr) {
|
||||
return mMaterials[matindex];
|
||||
}
|
||||
switch (matindex) {
|
||||
case MATINDEX(LIT, AlphaMode::OPAQUE, false, false, false):
|
||||
{
|
||||
filamat::Package pkg = filamat::Package(opaqueData, opaqueDataSize);
|
||||
mMaterials[matindex] = Material::Builder().package(pkg.getData(), pkg.getSize()).build(*mEngine);
|
||||
}
|
||||
break;
|
||||
case MATINDEX(LIT, AlphaMode::BLEND, false, false, false):
|
||||
{
|
||||
filamat::Package pkg = filamat::Package(fadeData, fadeDataSize);
|
||||
mMaterials[matindex] = Material::Builder().package(pkg.getData(), pkg.getSize()).build(*mEngine);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
filamat::Package pkg = filamat::Package(fadeData, fadeDataSize);
|
||||
mMaterials[matindex] = Material::Builder().package(pkg.getData(), pkg.getSize()).build(*mEngine);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
filamat::Package pkg = filamat::Package(mData, mSize);
|
||||
return Material::Builder().package(pkg.getData(), pkg.getSize()).build(*mEngine);
|
||||
return mMaterials[matindex];
|
||||
}
|
||||
|
||||
MaterialInstance* GPUMorphShaderLoader::createMaterialInstance(MaterialKey* config, UvMap* uvmap,
|
||||
@@ -145,7 +196,9 @@ namespace {
|
||||
|
||||
mi->setDoubleSided(config->doubleSided);
|
||||
mi->setCullingMode(config->doubleSided ? CullingMode::NONE : CullingMode::BACK);
|
||||
|
||||
mi->setTransparencyMode(config->doubleSided ?
|
||||
MaterialInstance::TransparencyMode::TWO_PASSES_TWO_SIDES :
|
||||
MaterialInstance::TransparencyMode::DEFAULT);
|
||||
// Initially, assume that the clear coat texture can be honored. This is changed to false when
|
||||
// running into a sampler count limitation. TODO: check if these constraints can now be relaxed.
|
||||
bool clearCoatNeedsTexture = true;
|
||||
@@ -176,7 +229,6 @@ namespace {
|
||||
getUvIndex(config->sheenRoughnessUV, config->hasSheenRoughnessTexture));
|
||||
mi->setParameter("sheenColorUvMatrix", identity);
|
||||
mi->setParameter("sheenRoughnessUvMatrix", identity);
|
||||
|
||||
}
|
||||
if (config->hasVolume) {
|
||||
clearCoatNeedsTexture = false;
|
||||
@@ -196,6 +248,8 @@ namespace {
|
||||
mi->setParameter("normalMap", mDummyTexture, sampler);
|
||||
mi->setParameter("baseColorMap", mDummyTexture, sampler);
|
||||
mi->setParameter("metallicRoughnessMap", mDummyTexture, sampler);
|
||||
// mi->setParameter("roughnessFactor", mDummyTexture, sampler);
|
||||
|
||||
mi->setParameter("occlusionMap", mDummyTexture, sampler);
|
||||
mi->setParameter("emissiveMap", mDummyTexture, sampler);
|
||||
if (clearCoatNeedsTexture) {
|
||||
@@ -227,8 +281,18 @@ namespace {
|
||||
|
||||
namespace gltfio {
|
||||
|
||||
MaterialProvider* createGPUMorphShaderLoader(const void* data, uint64_t size, filament::Engine* engine) {
|
||||
return new GPUMorphShaderLoader(data, size,engine);
|
||||
MaterialProvider* createGPUMorphShaderLoader(
|
||||
const void* opaqueData,
|
||||
uint64_t opaqueDataSize,
|
||||
const void* fadeData,
|
||||
uint64_t fadeDataSize,
|
||||
filament::Engine* engine) {
|
||||
return new GPUMorphShaderLoader(
|
||||
opaqueData,
|
||||
opaqueDataSize,
|
||||
fadeData,
|
||||
fadeDataSize,
|
||||
engine);
|
||||
}
|
||||
|
||||
} // namespace gltfio
|
||||
|
||||
308
ios/src/morph/UbershaderLoader.cpp
Normal file
308
ios/src/morph/UbershaderLoader.cpp
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <gltfio/MaterialProvider.h>
|
||||
|
||||
#include <filament/MaterialInstance.h>
|
||||
#include <filament/Texture.h>
|
||||
#include <filament/TextureSampler.h>
|
||||
|
||||
#include <math/mat4.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "gltfio/resources/gltfresources.h"
|
||||
|
||||
using namespace filament;
|
||||
using namespace filament::math;
|
||||
using namespace gltfio;
|
||||
using namespace utils;
|
||||
|
||||
namespace {
|
||||
|
||||
using CullingMode = MaterialInstance::CullingMode;
|
||||
|
||||
class UbershaderLoader : public MaterialProvider {
|
||||
public:
|
||||
UbershaderLoader(filament::Engine* engine);
|
||||
~UbershaderLoader() {}
|
||||
|
||||
MaterialInstance* createMaterialInstance(MaterialKey* config, UvMap* uvmap,
|
||||
const char* label) override;
|
||||
|
||||
size_t getMaterialsCount() const noexcept override;
|
||||
const Material* const* getMaterials() const noexcept override;
|
||||
void destroyMaterials() override;
|
||||
|
||||
bool needsDummyData(VertexAttribute attrib) const noexcept override {
|
||||
switch (attrib) {
|
||||
case VertexAttribute::UV0:
|
||||
case VertexAttribute::UV1:
|
||||
case VertexAttribute::COLOR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Material* getMaterial(const MaterialKey& config) const;
|
||||
|
||||
enum ShadingMode {
|
||||
UNLIT = 0,
|
||||
LIT = 1,
|
||||
SPECULAR_GLOSSINESS = 2,
|
||||
};
|
||||
|
||||
mutable Material* mMaterials[12] = {};
|
||||
Texture* mDummyTexture = nullptr;
|
||||
|
||||
Engine* mEngine;
|
||||
};
|
||||
|
||||
#if GLTFIO_LITE
|
||||
|
||||
#define CREATE_MATERIAL(name) Material::Builder() \
|
||||
.package(GLTFRESOURCES_LITE_ ## name ## _DATA, GLTFRESOURCES_LITE_ ## name ## _SIZE) \
|
||||
.build(*mEngine);
|
||||
|
||||
#else
|
||||
|
||||
#define CREATE_MATERIAL(name) Material::Builder() \
|
||||
.package(GLTFRESOURCES_ ## name ## _DATA, GLTFRESOURCES_ ## name ## _SIZE) \
|
||||
.build(*mEngine);
|
||||
|
||||
#endif
|
||||
|
||||
#define MATINDEX(shading, alpha, sheen, transmit, volume) (volume ? 11 : (transmit ? 10 : (sheen ? 9 : (int(shading) + 3 * int(alpha)))))
|
||||
|
||||
UbershaderLoader::UbershaderLoader(Engine* engine) : mEngine(engine) {
|
||||
unsigned char texels[4] = {};
|
||||
mDummyTexture = Texture::Builder()
|
||||
.width(1).height(1)
|
||||
.format(Texture::InternalFormat::RGBA8)
|
||||
.build(*mEngine);
|
||||
Texture::PixelBufferDescriptor pbd(texels, sizeof(texels), Texture::Format::RGBA,
|
||||
Texture::Type::UBYTE);
|
||||
mDummyTexture->setImage(*mEngine, 0, std::move(pbd));
|
||||
}
|
||||
|
||||
size_t UbershaderLoader::getMaterialsCount() const noexcept {
|
||||
return sizeof(mMaterials) / sizeof(mMaterials[0]);
|
||||
}
|
||||
|
||||
const Material* const* UbershaderLoader::getMaterials() const noexcept {
|
||||
return &mMaterials[0];
|
||||
}
|
||||
|
||||
void UbershaderLoader::destroyMaterials() {
|
||||
for (auto& material : mMaterials) {
|
||||
mEngine->destroy(material);
|
||||
material = nullptr;
|
||||
}
|
||||
mEngine->destroy(mDummyTexture);
|
||||
}
|
||||
|
||||
Material* UbershaderLoader::getMaterial(const MaterialKey& config) const {
|
||||
const ShadingMode shading = config.unlit ? UNLIT :
|
||||
(config.useSpecularGlossiness ? SPECULAR_GLOSSINESS : LIT);
|
||||
const int matindex = MATINDEX(shading, config.alphaMode, config.hasSheen, config.hasTransmission, config.hasVolume);
|
||||
if (mMaterials[matindex] != nullptr) {
|
||||
return mMaterials[matindex];
|
||||
}
|
||||
switch (matindex) {
|
||||
|
||||
case MATINDEX(LIT, AlphaMode::OPAQUE, false, false, false): mMaterials[matindex] = CREATE_MATERIAL(LIT_OPAQUE); break;
|
||||
|
||||
|
||||
|
||||
case MATINDEX(LIT, AlphaMode::BLEND, false, false, false): mMaterials[matindex] = CREATE_MATERIAL(LIT_FADE); break;
|
||||
|
||||
|
||||
|
||||
case MATINDEX(LIT, AlphaMode::MASK, false, false, false): mMaterials[matindex] = CREATE_MATERIAL(LIT_MASKED); break;
|
||||
case MATINDEX(UNLIT, AlphaMode::OPAQUE, false, false, false): mMaterials[matindex] = CREATE_MATERIAL(UNLIT_OPAQUE); break;
|
||||
case MATINDEX(UNLIT, AlphaMode::MASK, false, false, false): mMaterials[matindex] = CREATE_MATERIAL(UNLIT_MASKED); break;
|
||||
case MATINDEX(UNLIT, AlphaMode::BLEND, false, false, false): mMaterials[matindex] = CREATE_MATERIAL(UNLIT_FADE); break;
|
||||
case MATINDEX(SPECULAR_GLOSSINESS, AlphaMode::OPAQUE, false, false, false): mMaterials[matindex] = CREATE_MATERIAL(SPECULARGLOSSINESS_OPAQUE); break;
|
||||
case MATINDEX(SPECULAR_GLOSSINESS, AlphaMode::MASK, false, false, false): mMaterials[matindex] = CREATE_MATERIAL(SPECULARGLOSSINESS_MASKED); break;
|
||||
case MATINDEX(SPECULAR_GLOSSINESS, AlphaMode::BLEND, false, false, false): mMaterials[matindex] = CREATE_MATERIAL(SPECULARGLOSSINESS_FADE); break;
|
||||
case MATINDEX(0, 0, false, true, false): mMaterials[matindex] = CREATE_MATERIAL(LIT_TRANSMISSION); break;
|
||||
case MATINDEX(0, 0, true, false, false): mMaterials[matindex] = CREATE_MATERIAL(LIT_SHEEN); break;
|
||||
case MATINDEX(0, 0, false, false, true): mMaterials[matindex] = CREATE_MATERIAL(LIT_VOLUME); break;
|
||||
|
||||
}
|
||||
if (mMaterials[matindex] == nullptr) {
|
||||
slog.w << "Unsupported glTF material configuration; falling back to LIT_OPAQUE." << io::endl;
|
||||
MaterialKey litOpaque = config;
|
||||
litOpaque.alphaMode = AlphaMode::OPAQUE;
|
||||
litOpaque.hasTransmission = false;
|
||||
litOpaque.hasVolume = false;
|
||||
litOpaque.hasSheen = false;
|
||||
litOpaque.useSpecularGlossiness = false;
|
||||
litOpaque.unlit = false;
|
||||
return getMaterial(litOpaque);
|
||||
}
|
||||
|
||||
return mMaterials[matindex];
|
||||
}
|
||||
|
||||
MaterialInstance* UbershaderLoader::createMaterialInstance(MaterialKey* config, UvMap* uvmap,
|
||||
const char* label) {
|
||||
// Diagnostics are not supported with LOAD_UBERSHADERS, please use GENERATE_SHADERS instead.
|
||||
if (config->enableDiagnostics) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (config->hasVolume && config->hasSheen) {
|
||||
slog.w << "Volume and sheen are not supported together in ubershader mode,"
|
||||
" removing sheen (" << label << ")." << io::endl;
|
||||
config->hasSheen = false;
|
||||
}
|
||||
|
||||
if (config->hasTransmission && config->hasSheen) {
|
||||
slog.w << "Transmission and sheen are not supported together in ubershader mode,"
|
||||
" removing sheen (" << label << ")." << io::endl;
|
||||
config->hasSheen = false;
|
||||
}
|
||||
|
||||
const bool clearCoatConflict = config->hasVolume || config->hasTransmission || config->hasSheen;
|
||||
|
||||
// Due to sampler overload, disable transmission if necessary and print a friendly warning.
|
||||
if (config->hasClearCoat && clearCoatConflict) {
|
||||
slog.w << "Volume, transmission and sheen are not supported in ubershader mode for clearcoat"
|
||||
" materials (" << label << ")." << io::endl;
|
||||
config->hasVolume = false;
|
||||
config->hasTransmission = false;
|
||||
config->hasSheen = false;
|
||||
}
|
||||
|
||||
constrainMaterial(config, uvmap);
|
||||
auto getUvIndex = [uvmap](uint8_t srcIndex, bool hasTexture) -> int {
|
||||
return hasTexture ? int(uvmap->at(srcIndex)) - 1 : -1;
|
||||
};
|
||||
Material* material = getMaterial(*config);
|
||||
MaterialInstance* mi = material->createInstance(label);
|
||||
mi->setParameter("baseColorIndex",
|
||||
getUvIndex(config->baseColorUV, config->hasBaseColorTexture));
|
||||
mi->setParameter("normalIndex", getUvIndex(config->normalUV, config->hasNormalTexture));
|
||||
mi->setParameter("metallicRoughnessIndex",
|
||||
getUvIndex(config->metallicRoughnessUV, config->hasMetallicRoughnessTexture));
|
||||
mi->setParameter("aoIndex", getUvIndex(config->aoUV, config->hasOcclusionTexture));
|
||||
mi->setParameter("emissiveIndex", getUvIndex(config->emissiveUV, config->hasEmissiveTexture));
|
||||
|
||||
mi->setDoubleSided(config->doubleSided);
|
||||
mi->setCullingMode(config->doubleSided ? CullingMode::NONE : CullingMode::BACK);
|
||||
mi->setTransparencyMode(config->doubleSided ?
|
||||
MaterialInstance::TransparencyMode::TWO_PASSES_TWO_SIDES :
|
||||
MaterialInstance::TransparencyMode::DEFAULT);
|
||||
|
||||
#if !GLTFIO_LITE
|
||||
|
||||
// Initially, assume that the clear coat texture can be honored. This is changed to false when
|
||||
// running into a sampler count limitation. TODO: check if these constraints can now be relaxed.
|
||||
bool clearCoatNeedsTexture = true;
|
||||
|
||||
mat3f identity;
|
||||
mi->setParameter("baseColorUvMatrix", identity);
|
||||
mi->setParameter("metallicRoughnessUvMatrix", identity);
|
||||
mi->setParameter("normalUvMatrix", identity);
|
||||
mi->setParameter("occlusionUvMatrix", identity);
|
||||
mi->setParameter("emissiveUvMatrix", identity);
|
||||
|
||||
if (config->hasClearCoat) {
|
||||
mi->setParameter("clearCoatIndex",
|
||||
getUvIndex(config->clearCoatUV, config->hasClearCoatTexture));
|
||||
mi->setParameter("clearCoatRoughnessIndex",
|
||||
getUvIndex(config->clearCoatRoughnessUV, config->hasClearCoatRoughnessTexture));
|
||||
mi->setParameter("clearCoatNormalIndex",
|
||||
getUvIndex(config->clearCoatNormalUV, config->hasClearCoatNormalTexture));
|
||||
mi->setParameter("clearCoatUvMatrix", identity);
|
||||
mi->setParameter("clearCoatRoughnessUvMatrix", identity);
|
||||
mi->setParameter("clearCoatNormalUvMatrix", identity);
|
||||
} else {
|
||||
if (config->hasSheen) {
|
||||
clearCoatNeedsTexture = false;
|
||||
mi->setParameter("sheenColorIndex",
|
||||
getUvIndex(config->sheenColorUV, config->hasSheenColorTexture));
|
||||
mi->setParameter("sheenRoughnessIndex",
|
||||
getUvIndex(config->sheenRoughnessUV, config->hasSheenRoughnessTexture));
|
||||
mi->setParameter("sheenColorUvMatrix", identity);
|
||||
mi->setParameter("sheenRoughnessUvMatrix", identity);
|
||||
|
||||
}
|
||||
if (config->hasVolume) {
|
||||
clearCoatNeedsTexture = false;
|
||||
mi->setParameter("volumeThicknessUvMatrix", identity);
|
||||
mi->setParameter("volumeThicknessIndex",
|
||||
getUvIndex(config->transmissionUV, config->hasVolumeThicknessTexture));
|
||||
}
|
||||
if (config->hasTransmission) {
|
||||
clearCoatNeedsTexture = false;
|
||||
mi->setParameter("transmissionUvMatrix", identity);
|
||||
mi->setParameter("transmissionIndex",
|
||||
getUvIndex(config->transmissionUV, config->hasTransmissionTexture));
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
// In the GLTFIO_LITE configuration we do not support UV matrices, clear coat, sheen, specular
|
||||
// glossiness, or transmission. For more details, see `gltflite.mat.in`. To configure a custom
|
||||
// set of features, create your own MaterialProvider class, perhaps using UbershaderLoader as a
|
||||
// starting point.
|
||||
const bool clearCoatNeedsTexture = false;
|
||||
|
||||
#endif
|
||||
|
||||
TextureSampler sampler;
|
||||
mi->setParameter("normalMap", mDummyTexture, sampler);
|
||||
mi->setParameter("baseColorMap", mDummyTexture, sampler);
|
||||
mi->setParameter("metallicRoughnessMap", mDummyTexture, sampler);
|
||||
mi->setParameter("occlusionMap", mDummyTexture, sampler);
|
||||
mi->setParameter("emissiveMap", mDummyTexture, sampler);
|
||||
if (clearCoatNeedsTexture) {
|
||||
mi->setParameter("clearCoatMap", mDummyTexture, sampler);
|
||||
mi->setParameter("clearCoatRoughnessMap", mDummyTexture, sampler);
|
||||
mi->setParameter("clearCoatNormalMap", mDummyTexture, sampler);
|
||||
}
|
||||
if (!config->hasClearCoat) {
|
||||
if (config->hasTransmission) {
|
||||
mi->setParameter("transmissionMap", mDummyTexture, sampler);
|
||||
}
|
||||
if (config->hasSheen) {
|
||||
mi->setParameter("sheenColorMap", mDummyTexture, sampler);
|
||||
mi->setParameter("sheenRoughnessMap", mDummyTexture, sampler);
|
||||
}
|
||||
}
|
||||
|
||||
if (mi->getMaterial()->hasParameter("ior")) {
|
||||
mi->setParameter("ior", 1.5f);
|
||||
}
|
||||
if (mi->getMaterial()->hasParameter("reflectance")) {
|
||||
mi->setParameter("reflectance", 0.5f);
|
||||
}
|
||||
|
||||
return mi;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace foo {
|
||||
|
||||
MaterialProvider* createUbershaderLoader(filament::Engine* engine) {
|
||||
return new UbershaderLoader(engine);
|
||||
}
|
||||
|
||||
} // namespace gltfio
|
||||
@@ -19,7 +19,12 @@ abstract class FilamentController {
|
||||
Future releaseSourceAssets();
|
||||
Future playAnimation(int index);
|
||||
|
||||
// Weights is expected to be a contiguous sequence of floats of size W*F, where W is the number of weights and F is the number of frames
|
||||
///
|
||||
/// Set the weights of all morph targets in the mesh to the specified weights at successive frames (where [framerate] is the number of times per second the weights should be updated).
|
||||
/// Accepts a list of doubles representing a sequence of "frames", stacked end-to-end.
|
||||
/// Each frame is [numWeights] in length, where each entry is the weight to be applied to the morph target located at that index in the mesh primitive at that frame.
|
||||
/// In other words, weights is a contiguous sequence of floats of size W*F, where W is the number of weights and F is the number of frames
|
||||
///
|
||||
Future animate(List<double> weights, int numWeights, double frameRate);
|
||||
Future createMorpher(String meshName, List<int> primitives);
|
||||
Future zoom(double z);
|
||||
@@ -28,12 +33,10 @@ abstract class FilamentController {
|
||||
class HolovoxFilamentController extends FilamentController {
|
||||
late int _id;
|
||||
late MethodChannel _channel;
|
||||
final String materialPath;
|
||||
|
||||
final Function(int id)? onFilamentViewCreatedHandler;
|
||||
|
||||
HolovoxFilamentController(
|
||||
{this.materialPath = "packages/holovox_filament/assets/compiled.mat",
|
||||
this.onFilamentViewCreatedHandler});
|
||||
HolovoxFilamentController({this.onFilamentViewCreatedHandler});
|
||||
|
||||
@override
|
||||
void onFilamentViewCreated(int id) async {
|
||||
@@ -51,7 +54,10 @@ class HolovoxFilamentController extends FilamentController {
|
||||
|
||||
@override
|
||||
Future _initialize() async {
|
||||
await _channel.invokeMethod("initialize", materialPath);
|
||||
await _channel.invokeMethod("initialize", [
|
||||
"packages/holovox_filament/assets/lit_opaque.filamat",
|
||||
"packages/holovox_filament/assets/lit_fade.filamat"
|
||||
]);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -59,8 +65,9 @@ class HolovoxFilamentController extends FilamentController {
|
||||
await _channel.invokeMethod("loadSkybox", [skyboxPath, lightingPath]);
|
||||
}
|
||||
|
||||
Future loadGlb(String path) {
|
||||
throw Exception();
|
||||
Future loadGlb(String path) async {
|
||||
print("Loading GLB at $path ");
|
||||
await _channel.invokeMethod("loadGlb", path);
|
||||
}
|
||||
|
||||
Future loadGltf(String path, String relativeResourcePath) async {
|
||||
|
||||
Reference in New Issue
Block a user