Compare commits

..

9 Commits

Author SHA1 Message Date
Benjamin Doherty
36c69dda9c Fix Android CI release build 2023-05-09 13:22:20 -04:00
Benjamin Doherty
1716c856c3 Merge branch 'rc/1.35.0' into release 2023-05-08 18:05:07 -04:00
Benjamin Doherty
8cac90d81e Bump MATERIAL_VERSION to 35 2023-05-01 13:37:24 -04:00
Benjamin Doherty
388b4f5efb Bump version to 1.35.0 2023-05-01 13:36:40 -04:00
Benjamin Doherty
4e888d142b Release Filament 1.34.0 2023-05-01 13:34:52 -04:00
Mathias Agopian
a5e6d9ef3d cleanup PlatformEGL a bit. (#6769)
- add a helper Config class to more easily manage EGL's attribute
  pairs.

- consolidate config selection code
2023-04-27 11:39:09 -07:00
Powei Feng
5e58af466c vulkan: fix RenderPass size (#6775) 2023-04-27 10:09:23 -07:00
Mathias Agopian
899c15f023 very basic API for materials to have global variables (#6764)
A material global is a variable seen by all materials. There are 4 such 
variable which are all vec4 and they can be set on a per-view basis.

All materials used during Renderer::render() will see the same value.

These variable can be accessed in the materials by using 
getMaterialGloabal{0|1|2|3}.
2023-04-25 17:20:43 -07:00
Powei Feng
861da7b5c9 Change mac/linux runners to more cores (#6768) 2023-04-25 15:12:49 -07:00
27 changed files with 314 additions and 113 deletions

View File

@@ -10,7 +10,7 @@ on:
jobs:
build-android:
name: build-android
runs-on: macos-latest
runs-on: macos-latest-xl
steps:
- uses: actions/checkout@v3.3.0

View File

@@ -10,7 +10,7 @@ on:
jobs:
build-ios:
name: build-ios
runs-on: macos-latest
runs-on: macos-latest-xl
steps:
- uses: actions/checkout@v3.3.0

View File

@@ -10,7 +10,7 @@ on:
jobs:
build-mac:
name: build-mac
runs-on: macos-latest
runs-on: macos-latest-xl
steps:
- uses: actions/checkout@v3.3.0

View File

@@ -15,7 +15,7 @@ jobs:
strategy:
matrix:
os: [macos-latest, ubuntu-22.04]
os: [macos-latest-xl, ubuntu-22.04-16core]
steps:
- uses: actions/checkout@v3.3.0
@@ -40,7 +40,7 @@ jobs:
build-android:
name: build-android
runs-on: macos-latest
runs-on: macos-latest-xl
steps:
- uses: actions/checkout@v3.3.0
@@ -54,7 +54,7 @@ jobs:
build-ios:
name: build-iOS
runs-on: macos-latest
runs-on: macos-latest-xl
steps:
- uses: actions/checkout@v3.3.0
@@ -67,7 +67,7 @@ jobs:
build-web:
name: build-web
runs-on: macos-latest
runs-on: macos-latest-xl
steps:
- uses: actions/checkout@v3.3.0

View File

@@ -31,7 +31,7 @@ jobs:
strategy:
matrix:
os: [macos-latest, ubuntu-22.04]
os: [macos-latest-xl, ubuntu-22.04-16core]
steps:
- name: Decide Git ref
@@ -65,7 +65,7 @@ jobs:
build-web:
name: build-web
runs-on: macos-latest
runs-on: macos-latest-xl
if: github.event_name == 'release' || github.event.inputs.platform == 'web'
steps:
@@ -98,7 +98,7 @@ jobs:
build-android:
name: build-android
runs-on: macos-latest
runs-on: macos-latest-xl
if: github.event_name == 'release' || github.event.inputs.platform == 'android'
steps:
@@ -153,7 +153,7 @@ jobs:
build-ios:
name: build-ios
runs-on: macos-latest
runs-on: macos-latest-xl
if: github.event_name == 'release' || github.event.inputs.platform == 'ios'
steps:

View File

@@ -10,7 +10,7 @@ on:
jobs:
build-web:
name: build-web
runs-on: macos-latest
runs-on: macos-latest-xl
steps:
- uses: actions/checkout@v3.3.0

View File

@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.34.0'
implementation 'com.google.android.filament:filament-android:1.35.0'
}
```
@@ -50,7 +50,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
iOS projects can use CocoaPods to install the latest release:
```
pod 'Filament', '~> 1.34.0'
pod 'Filament', '~> 1.35.0'
```
### Snapshots

View File

@@ -7,6 +7,10 @@ A new header is inserted each time a *tag* is created.
Instead, if you are authoring a PR for the main branch, add your release note to
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
## v1.35.0
- materials: Materials can now access up to 4 global `vec4` visible by all materials [⚠️ **Recompile Materials**]
## v1.34.0
- materials: picking is done in float (prepare for ES2) [⚠️ **New Material Version**]

View File

@@ -486,3 +486,22 @@ Java_com_google_android_filament_View_nSetGuardBandOptions(JNIEnv *, jclass,
View* view = (View*) nativeView;
view->setGuardBandOptions({ .enabled = (bool)enabled });
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetMaterialGlobal(JNIEnv * , jclass, jlong nativeView,
jint index, jfloat x, jfloat y, jfloat z, jfloat w) {
View *view = (View *) nativeView;
view->setMaterialGlobal((uint32_t)index, { x, y, z, w });
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nGetMaterialGlobal(JNIEnv *env, jclass clazz,
jlong nativeView, jint index, jfloatArray out_) {
jfloat* out = env->GetFloatArrayElements(out_, nullptr);
View *view = (View *) nativeView;
auto result = view->getMaterialGlobal(index);
std::copy_n(result.v, 4, out);
env->ReleaseFloatArrayElements(out_, out, 0);
}

View File

@@ -1117,6 +1117,37 @@ public class View {
float mFragCoordsZ;
}
/**
* Set the value of material global variables. There are up-to four such variable each of
* type float4. These variables can be read in a user Material with
* `getMaterialGlobal{0|1|2|3}()`. All variable start with a default value of { 0, 0, 0, 1 }
*
* @param index index of the variable to set between 0 and 3.
* @param value new value for the variable.
* @see #getMaterialGlobal
*/
public void setMaterialGlobal(int index, @NonNull @Size(min = 4) float[] value) {
Asserts.assertFloat4In(value);
nSetMaterialGlobal(getNativeObject(), index, value[0], value[1], value[2], value[3]);
}
/**
* Get the value of the material global variables.
* All variable start with a default value of { 0, 0, 0, 1 }
*
* @param index index of the variable to set between 0 and 3.
* @param out A 4-float array where the value will be stored, or null in which case the array is
* allocated.
* @return A 4-float array containing the current value of the variable.
* @see #setMaterialGlobal
*/
@NonNull @Size(min = 4)
public float[] getMaterialGlobal(int index, @Nullable @Size(min = 4) float[] out) {
out = Asserts.assertFloat4(out);
nGetMaterialGlobal(getNativeObject(), index, out);
return out;
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed View");
@@ -1173,6 +1204,9 @@ public class View {
private static native void nPick(long nativeView, int x, int y, Object handler, InternalOnPickCallback internalCallback);
private static native void nSetStencilBufferEnabled(long nativeView, boolean enabled);
private static native boolean nIsStencilBufferEnabled(long nativeView);
private static native void nSetMaterialGlobal(long nativeView, int index, float x, float y, float z, float w);
private static native void nGetMaterialGlobal(long nativeView, int index, float[] out);
/**
* List of available ambient occlusion techniques.

View File

@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.34.0
VERSION_NAME=1.35.0
POM_DESCRIPTION=Real-time physically based rendering engine for Android.

View File

@@ -2372,6 +2372,15 @@ type aliases:
match the API-level world space. To obtain the position of the API-level camera, custom
materials can use `getUserWorldFromWorldMatrix()` to transform `getWorldCameraPosition()`.
### Material globals
Name | Type | Description
:-----------------------------------|:--------:|:------------------------------------
**getMaterialGlobal0()** | float4 | A vec4 visible by all materials, its value is set by `View::setMaterialGlobal(0, float4)`. Its default value is {0,0,0,1}.
**getMaterialGlobal1()** | float4 | A vec4 visible by all materials, its value is set by `View::setMaterialGlobal(1, float4)`. Its default value is {0,0,0,1}.
**getMaterialGlobal2()** | float4 | A vec4 visible by all materials, its value is set by `View::setMaterialGlobal(2, float4)`. Its default value is {0,0,0,1}.
**getMaterialGlobal3()** | float4 | A vec4 visible by all materials, its value is set by `View::setMaterialGlobal(3, float4)`. Its default value is {0,0,0,1}.
### Vertex only
The following APIs are only available from the vertex block:

View File

@@ -26,6 +26,9 @@
#include <backend/DriverEnums.h>
#include <utility>
#include <vector>
namespace filament::backend {
/**
@@ -37,6 +40,27 @@ public:
PlatformEGL() noexcept;
protected:
// --------------------------------------------------------------------------------------------
// Helper for EGL configs and attributes parameters
class Config {
public:
Config();
Config(std::initializer_list<std::pair<EGLint, EGLint>> list);
EGLint& operator[](EGLint name);
EGLint operator[](EGLint name) const;
void erase(EGLint name) noexcept;
EGLint const* data() const noexcept {
return reinterpret_cast<EGLint const*>(mConfig.data());
}
size_t size() const noexcept {
return mConfig.size();
}
private:
std::vector<std::pair<EGLint, EGLint>> mConfig = {{ EGL_NONE, EGL_NONE }};
};
// --------------------------------------------------------------------------------------------
// Platform Interface
@@ -79,6 +103,8 @@ protected:
* @param name a string giving some context on the error. Typically __func__.
*/
static void logEglError(const char* name) noexcept;
static void logEglError(const char* name, EGLint error) noexcept;
static const char* getEglErrorName(EGLint error) noexcept;
/**
* Calls glGetError() to clear the current error flags. logs a warning to log.w if

View File

@@ -45,25 +45,31 @@ using namespace glext;
// ---------------------------------------------------------------------------------------------
void PlatformEGL::logEglError(const char* name) noexcept {
const char* err;
switch (eglGetError()) {
case EGL_NOT_INITIALIZED: err = "EGL_NOT_INITIALIZED"; break;
case EGL_BAD_ACCESS: err = "EGL_BAD_ACCESS"; break;
case EGL_BAD_ALLOC: err = "EGL_BAD_ALLOC"; break;
case EGL_BAD_ATTRIBUTE: err = "EGL_BAD_ATTRIBUTE"; break;
case EGL_BAD_CONTEXT: err = "EGL_BAD_CONTEXT"; break;
case EGL_BAD_CONFIG: err = "EGL_BAD_CONFIG"; break;
case EGL_BAD_CURRENT_SURFACE: err = "EGL_BAD_CURRENT_SURFACE";break;
case EGL_BAD_DISPLAY: err = "EGL_BAD_DISPLAY"; break;
case EGL_BAD_SURFACE: err = "EGL_BAD_SURFACE"; break;
case EGL_BAD_MATCH: err = "EGL_BAD_MATCH"; break;
case EGL_BAD_PARAMETER: err = "EGL_BAD_PARAMETER"; break;
case EGL_BAD_NATIVE_PIXMAP: err = "EGL_BAD_NATIVE_PIXMAP"; break;
case EGL_BAD_NATIVE_WINDOW: err = "EGL_BAD_NATIVE_WINDOW"; break;
case EGL_CONTEXT_LOST: err = "EGL_CONTEXT_LOST"; break;
default: err = "unknown"; break;
logEglError(name, eglGetError());
}
void PlatformEGL::logEglError(const char* name, EGLint error) noexcept {
slog.e << name << " failed with " << getEglErrorName(error) << io::endl;
}
const char* PlatformEGL::getEglErrorName(EGLint error) noexcept {
switch (error) {
case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED";
case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS";
case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC";
case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE";
case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT";
case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG";
case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY";
case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE";
case EGL_BAD_MATCH: return "EGL_BAD_MATCH";
case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER";
case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST";
default: return "unknown";
}
slog.e << name << " failed with " << err << io::endl;
}
void PlatformEGL::clearGlError() noexcept {
@@ -110,36 +116,24 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverCon
eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR");
eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR");
EGLint configsCount;
EGLint configAttribs[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, // 0
EGL_RED_SIZE, 8, // 2
EGL_GREEN_SIZE, 8, // 4
EGL_BLUE_SIZE, 8, // 6
EGL_ALPHA_SIZE, 8, // 8
EGL_DEPTH_SIZE, 24, // 10
EGL_RECORDABLE_ANDROID, 1, // 12
EGL_NONE // 14
};
EGLint contextAttribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 3,
EGL_NONE, EGL_NONE, // reserved for EGL_CONTEXT_OPENGL_NO_ERROR_KHR below
EGL_NONE
};
EGLint pbufferAttribs[] = {
EGLint const pbufferAttribs[] = {
EGL_WIDTH, 1,
EGL_HEIGHT, 1,
EGL_NONE
};
// Request a ES3 context
Config contextAttribs = {
{ EGL_CONTEXT_CLIENT_VERSION, 3 },
};
#ifdef NDEBUG
// When we don't have a shared context, and we're in release mode, we always activate the
// EGL_KHR_create_context_no_error extension.
if (!sharedContext && extensions.has("EGL_KHR_create_context_no_error")) {
contextAttribs[2] = EGL_CONTEXT_OPENGL_NO_ERROR_KHR;
contextAttribs[3] = EGL_TRUE;
contextAttribs[EGL_CONTEXT_OPENGL_NO_ERROR_KHR] = EGL_TRUE;
}
#endif
@@ -148,23 +142,7 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverCon
// find a config we can use if we don't have "EGL_KHR_no_config_context" and that we can use
// for the dummy pbuffer surface.
if (!eglChooseConfig(mEGLDisplay, configAttribs, &mEGLConfig, 1, &configsCount)) {
logEglError("eglChooseConfig");
goto error;
}
if (configsCount == 0) {
// warn and retry without EGL_RECORDABLE_ANDROID
logEglError("eglChooseConfig(..., EGL_RECORDABLE_ANDROID) failed. Continuing without it.");
// this is not fatal
configAttribs[12] = EGL_RECORDABLE_ANDROID;
configAttribs[13] = EGL_DONT_CARE;
if (!eglChooseConfig(mEGLDisplay, configAttribs, &mEGLConfig, 1, &configsCount) ||
configsCount == 0) {
logEglError("eglChooseConfig");
goto error;
}
}
mEGLConfig = findSwapChainConfig(0);
if (UTILS_UNLIKELY(!ext.egl.KHR_no_config_context)) {
// if we don't have the EGL_KHR_no_config_context the context must be created with
@@ -180,15 +158,27 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverCon
goto error;
}
mEGLContext = eglCreateContext(mEGLDisplay, eglConfig, (EGLContext)sharedContext, contextAttribs);
if (UTILS_UNLIKELY(mEGLContext == EGL_NO_CONTEXT && sharedContext &&
extensions.has("EGL_KHR_create_context_no_error"))) {
// context creation could fail because of EGL_CONTEXT_OPENGL_NO_ERROR_KHR
// not matching the sharedContext. Try with it.
contextAttribs[2] = EGL_CONTEXT_OPENGL_NO_ERROR_KHR;
contextAttribs[3] = EGL_TRUE;
mEGLContext = eglCreateContext(mEGLDisplay, eglConfig, (EGLContext)sharedContext, contextAttribs);
for (size_t tries = 0; tries < 3; tries++) {
mEGLContext = eglCreateContext(mEGLDisplay, eglConfig,
(EGLContext)sharedContext, contextAttribs.data());
if (UTILS_LIKELY(mEGLContext != EGL_NO_CONTEXT)) {
break;
}
GLint const error = eglGetError();
#ifdef NDEBUG
if (error == EGL_BAD_MATCH &&
sharedContext && extensions.has("EGL_KHR_create_context_no_error")) {
// context creation could fail because of EGL_CONTEXT_OPENGL_NO_ERROR_KHR
// not matching the sharedContext. Try with it.
contextAttribs[EGL_CONTEXT_OPENGL_NO_ERROR_KHR] = EGL_TRUE;
continue;
}
#endif
(void)error;
break;
}
if (UTILS_UNLIKELY(mEGLContext == EGL_NO_CONTEXT)) {
// eglCreateContext failed
logEglError("eglCreateContext");
@@ -245,21 +235,21 @@ void PlatformEGL::terminate() noexcept {
}
EGLConfig PlatformEGL::findSwapChainConfig(uint64_t flags) const {
// Find config that support ES3.
EGLConfig config = EGL_NO_CONFIG_KHR;
EGLint configsCount;
EGLint configAttribs[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, (flags & SWAP_CHAIN_CONFIG_TRANSPARENT) ? 8 : 0,
EGL_DEPTH_SIZE, 24,
EGL_RECORDABLE_ANDROID, 1,
EGL_NONE
Config configAttribs = {
{ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR },
{ EGL_RED_SIZE, 8 },
{ EGL_GREEN_SIZE, 8 },
{ EGL_BLUE_SIZE, 8 },
{ EGL_ALPHA_SIZE, (flags & SWAP_CHAIN_CONFIG_TRANSPARENT) ? 8 : 0 },
{ EGL_DEPTH_SIZE, 24 },
{ EGL_RECORDABLE_ANDROID, 1 },
};
if (UTILS_UNLIKELY(
!eglChooseConfig(mEGLDisplay, configAttribs, &config, 1, &configsCount))) {
!eglChooseConfig(mEGLDisplay, configAttribs.data(), &config, 1, &configsCount))) {
logEglError("eglChooseConfig");
return EGL_NO_CONFIG_KHR;
}
@@ -268,10 +258,9 @@ EGLConfig PlatformEGL::findSwapChainConfig(uint64_t flags) const {
// warn and retry without EGL_RECORDABLE_ANDROID
logEglError(
"eglChooseConfig(..., EGL_RECORDABLE_ANDROID) failed. Continuing without it.");
configAttribs[12] = EGL_RECORDABLE_ANDROID;
configAttribs[13] = EGL_DONT_CARE;
configAttribs[EGL_RECORDABLE_ANDROID] = EGL_DONT_CARE;
if (UTILS_UNLIKELY(
!eglChooseConfig(mEGLDisplay, configAttribs, &config, 1, &configsCount) ||
!eglChooseConfig(mEGLDisplay, configAttribs.data(), &config, 1, &configsCount) ||
configsCount == 0)) {
logEglError("eglChooseConfig");
return EGL_NO_CONFIG_KHR;
@@ -298,20 +287,16 @@ Platform::SwapChain* PlatformEGL::createSwapChain(
return nullptr;
}
EGLint attribs[] = {
EGL_NONE, EGL_NONE,
EGL_NONE
};
Config attribs;
if (ext.egl.KHR_gl_colorspace) {
if (flags & SWAP_CHAIN_CONFIG_SRGB_COLORSPACE) {
attribs[0] = EGL_GL_COLORSPACE_KHR;
attribs[1] = EGL_GL_COLORSPACE_SRGB_KHR;
attribs[EGL_GL_COLORSPACE_KHR] = EGL_GL_COLORSPACE_SRGB_KHR;
}
}
EGLSurface sur = eglCreateWindowSurface(mEGLDisplay, config,
(EGLNativeWindowType)nativeWindow, attribs);
(EGLNativeWindowType)nativeWindow, attribs.data());
if (UTILS_UNLIKELY(sur == EGL_NO_SURFACE)) {
logEglError("eglCreateWindowSurface");
@@ -338,21 +323,18 @@ Platform::SwapChain* PlatformEGL::createSwapChain(
return nullptr;
}
EGLint attribs[] = {
EGL_WIDTH, EGLint(width),
EGL_HEIGHT, EGLint(height),
EGL_NONE, EGL_NONE,
EGL_NONE
Config attribs = {
{ EGL_WIDTH, EGLint(width) },
{ EGL_HEIGHT, EGLint(height) },
};
if (ext.egl.KHR_gl_colorspace) {
if (flags & SWAP_CHAIN_CONFIG_SRGB_COLORSPACE) {
attribs[4] = EGL_GL_COLORSPACE_KHR;
attribs[5] = EGL_GL_COLORSPACE_SRGB_KHR;
attribs[EGL_GL_COLORSPACE_KHR] = EGL_GL_COLORSPACE_SRGB_KHR;
}
}
EGLSurface sur = eglCreatePbufferSurface(mEGLDisplay, config, attribs);
EGLSurface sur = eglCreatePbufferSurface(mEGLDisplay, config, attribs.data());
if (UTILS_UNLIKELY(sur == EGL_NO_SURFACE)) {
logEglError("eglCreatePbufferSurface");
@@ -464,6 +446,42 @@ void PlatformEGL::initializeGlExtensions() noexcept {
ext.gl.OES_EGL_image_external_essl3 = glExtensions.has("GL_OES_EGL_image_external_essl3");
}
// ---------------------------------------------------------------------------------------------
PlatformEGL::Config::Config() = default;
PlatformEGL::Config::Config(std::initializer_list<std::pair<EGLint, EGLint>> list)
: mConfig(list) {
mConfig.emplace_back(EGL_NONE, EGL_NONE);
}
EGLint& PlatformEGL::Config::operator[](EGLint name) {
auto pos = std::find_if(mConfig.begin(), mConfig.end(),
[name](auto&& v) { return v.first == name; });
if (pos == mConfig.end()) {
mConfig.insert(pos - 1, { name, EGL_NONE });
pos = mConfig.end() - 2;
}
return pos->second;
}
EGLint PlatformEGL::Config::operator[](EGLint name) const {
auto pos = std::find_if(mConfig.begin(), mConfig.end(),
[name](auto&& v) { return v.first == name; });
assert_invariant(pos != mConfig.end());
return pos->second;
}
void PlatformEGL::Config::erase(EGLint name) noexcept {
if (name != EGL_NONE) {
auto pos = std::find_if(mConfig.begin(), mConfig.end(),
[name](auto&& v) { return v.first == name; });
if (pos != mConfig.end()) {
mConfig.erase(pos);
}
}
}
} // namespace filament::backend
// ---------------------------------------------------------------------------------------------

View File

@@ -803,6 +803,26 @@ public:
PickingQuery& pick(uint32_t x, uint32_t y, backend::CallbackHandler* handler,
PickingQueryResultCallback callback) noexcept;
/**
* Set the value of material global variables. There are up-to four such variable each of
* type float4. These variables can be read in a user Material with
* `getMaterialGlobal{0|1|2|3}()`. All variable start with a default value of { 0, 0, 0, 1 }
*
* @param index index of the variable to set between 0 and 3.
* @param value new value for the variable.
* @see getMaterialGlobal
*/
void setMaterialGlobal(uint32_t index, math::float4 const& value);
/**
* Get the value of the material global variables.
* All variable start with a default value of { 0, 0, 0, 1 }
*
* @param index index of the variable to set between 0 and 3.
* @return current value of the variable.
* @see setMaterialGlobal
*/
math::float4 getMaterialGlobal(uint32_t index) const;
/**
* List of available ambient occlusion techniques

View File

@@ -171,6 +171,14 @@ void PerViewUniforms::prepareBlending(bool needsAlphaChannel) noexcept {
mUniforms.edit().needsAlphaChannel = needsAlphaChannel ? 1.0f : 0.0f;
}
void PerViewUniforms::prepareMaterialGlobals(
std::array<math::float4, 4> const& materialGlobals) noexcept {
mUniforms.edit().custom[0] = materialGlobals[0];
mUniforms.edit().custom[1] = materialGlobals[1];
mUniforms.edit().custom[2] = materialGlobals[2];
mUniforms.edit().custom[3] = materialGlobals[3];
}
void PerViewUniforms::prepareSSR(Handle<HwTexture> ssr,
float refractionLodOffset,
ScreenSpaceReflectionsOptions const& ssrOptions) noexcept {

View File

@@ -89,6 +89,7 @@ public:
void prepareStructure(TextureHandle structure) noexcept;
void prepareSSAO(TextureHandle ssao, AmbientOcclusionOptions const& options) noexcept;
void prepareBlending(bool needsAlphaChannel) noexcept;
void prepareMaterialGlobals(std::array<math::float4, 4> const& materialGlobals) noexcept;
// screen-space reflection and/or refraction (SSR)
void prepareSSR(TextureHandle ssr,

View File

@@ -288,4 +288,12 @@ View::PickingQuery& View::pick(uint32_t x, uint32_t y, backend::CallbackHandler*
return downcast(this)->pick(x, y, handler, callback);
}
void View::setMaterialGlobal(uint32_t index, math::float4 const& value) {
downcast(this)->setMaterialGlobal(index, value);
}
math::float4 View::getMaterialGlobal(uint32_t index) const {
return downcast(this)->getMaterialGlobal(index);
}
} // namespace filament

View File

@@ -645,6 +645,7 @@ void FView::prepare(FEngine& engine, DriverApi& driver, ArenaScope& arena,
mPerViewUniforms.prepareFog(userCameraPosition, mFogOptions);
mPerViewUniforms.prepareTemporalNoise(engine, mTemporalAntiAliasingOptions);
mPerViewUniforms.prepareBlending(needsAlphaChannel);
mPerViewUniforms.prepareMaterialGlobals(mMaterialGlobals);
}
void FView::bindPerViewUniformsAndSamplers(FEngine::DriverApi& driver) const noexcept {
@@ -1079,4 +1080,14 @@ View::PickingQuery& FView::pick(uint32_t x, uint32_t y, backend::CallbackHandler
return *pQuery;
}
void FView::setMaterialGlobal(uint32_t index, float4 const& value) {
ASSERT_PRECONDITION(index < 4, "material global variable index (%u) out of range", +index);
mMaterialGlobals[index] = value;
}
math::float4 FView::getMaterialGlobal(uint32_t index) const {
ASSERT_PRECONDITION(index < 4, "material global variable index (%u) out of range", +index);
return mMaterialGlobals[index];
}
} // namespace filament

View File

@@ -411,6 +411,10 @@ public:
void executePickingQueries(backend::DriverApi& driver,
backend::RenderTargetHandle handle, float scale) noexcept;
void setMaterialGlobal(uint32_t index, math::float4 const& value);
math::float4 getMaterialGlobal(uint32_t index) const;
private:
struct FPickingQuery : public PickingQuery {
@@ -535,6 +539,13 @@ private:
ShadowMapManager mShadowMapManager;
std::array<math::float4, 4> mMaterialGlobals = {{
{ 0, 0, 0, 1 },
{ 0, 0, 0, 1 },
{ 0, 0, 0, 1 },
{ 0, 0, 0, 1 },
}};
#ifndef NDEBUG
std::array<DebugRegistry::FrameHistory, 5*60> mDebugFrameHistory;
#endif

View File

@@ -1,12 +1,12 @@
Pod::Spec.new do |spec|
spec.name = "Filament"
spec.version = "1.34.0"
spec.version = "1.35.0"
spec.license = { :type => "Apache 2.0", :file => "LICENSE" }
spec.homepage = "https://google.github.io/filament"
spec.authors = "Google LLC."
spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL."
spec.platform = :ios, "11.0"
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.34.0/filament-v1.34.0-ios.tgz" }
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.35.0/filament-v1.35.0-ios.tgz" }
# Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon.
spec.pod_target_xcconfig = {

View File

@@ -27,7 +27,7 @@
namespace filament {
// update this when a new version of filament wouldn't work with older materials
static constexpr size_t MATERIAL_VERSION = 34;
static constexpr size_t MATERIAL_VERSION = 35;
/**
* Supported shading models

View File

@@ -158,8 +158,13 @@ struct PerViewUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
float ssrDistance; // ssr world raycast distance, 0 when ssr is off
float ssrStride; // ssr texel stride, >= 1.0
// --------------------------------------------------------------------------------------------
// user defined global variables
// --------------------------------------------------------------------------------------------
math::float4 custom[4];
// bring PerViewUib to 2 KiB
math::float4 reserved[60];
math::float4 reserved[56];
};
// 2 KiB == 128 float4s

View File

@@ -140,6 +140,11 @@ BufferInterfaceBlock const& UibGenerator::getPerViewUib() noexcept {
{ "ssrDistance", 0, Type::FLOAT },
{ "ssrStride", 0, Type::FLOAT },
// --------------------------------------------------------------------------------------------
// user defined global variables
// --------------------------------------------------------------------------------------------
{ "custom", 4, Type::FLOAT4, Precision::HIGH },
// bring PerViewUib to 2 KiB
{ "reserved", sizeof(PerViewUib::reserved)/16, Type::FLOAT4 }
})

View File

@@ -105,3 +105,23 @@ float getExposure() {
float getEV100() {
return frameUniforms.ev100;
}
//------------------------------------------------------------------------------
// user defined globals
//------------------------------------------------------------------------------
highp vec4 getMaterialGlobal0() {
return frameUniforms.custom[0];
}
highp vec4 getMaterialGlobal1() {
return frameUniforms.custom[1];
}
highp vec4 getMaterialGlobal2() {
return frameUniforms.custom[2];
}
highp vec4 getMaterialGlobal3() {
return frameUniforms.custom[3];
}

View File

@@ -615,7 +615,9 @@ class_<View>("View")
self->setRenderTarget(renderTarget);
}), allow_raw_pointers())
.function("setStencilBufferEnabled", &View::setStencilBufferEnabled)
.function("isStencilBufferEnabled", &View::isStencilBufferEnabled);
.function("isStencilBufferEnabled", &View::isStencilBufferEnabled)
.function("setMaterialGlobal", &View::setMaterialGlobal)
.function("getMaterialGlobal", &View::getMaterialGlobal);
/// Scene ::core class:: Flat container of renderables and lights.
/// See also the [Engine] methods `createScene` and `destroyScene`.

View File

@@ -1,6 +1,6 @@
{
"name": "filament",
"version": "1.34.0",
"version": "1.35.0",
"description": "Real-time physically based rendering engine",
"main": "filament.js",
"module": "filament.js",