feat: add MaterialInstance.setDepthFunc

This commit is contained in:
Nick Fisher
2024-11-15 22:56:40 +08:00
parent bb27f40cb2
commit 0b9f3160d9
9 changed files with 262 additions and 108 deletions

View File

@@ -7,6 +7,76 @@ library;
import 'dart:ffi' as ffi; import 'dart:ffi' as ffi;
@ffi.Native<ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Bool)>(
isLeaf: true)
external void MaterialInstance_setDepthWrite(
ffi.Pointer<TMaterialInstance> materialInstance,
bool enabled,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Bool)>(
isLeaf: true)
external void MaterialInstance_setDepthCulling(
ffi.Pointer<TMaterialInstance> materialInstance,
bool enabled,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Pointer<ffi.Char>,
ffi.Double, ffi.Double, ffi.Double, ffi.Double)>(isLeaf: true)
external void MaterialInstance_setParameterFloat4(
ffi.Pointer<TMaterialInstance> materialInstance,
ffi.Pointer<ffi.Char> name,
double x,
double y,
double w,
double z,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Pointer<ffi.Char>,
ffi.Double, ffi.Double)>(isLeaf: true)
external void MaterialInstance_setParameterFloat2(
ffi.Pointer<TMaterialInstance> materialInstance,
ffi.Pointer<ffi.Char> name,
double x,
double y,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Pointer<ffi.Char>,
ffi.Double)>(isLeaf: true)
external void MaterialInstance_setParameterFloat(
ffi.Pointer<TMaterialInstance> materialInstance,
ffi.Pointer<ffi.Char> name,
double value,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Pointer<ffi.Char>,
ffi.Int)>(isLeaf: true)
external void MaterialInstance_setParameterInt(
ffi.Pointer<TMaterialInstance> materialInstance,
ffi.Pointer<ffi.Char> name,
int value,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.UnsignedInt)>(
symbol: "MaterialInstance_setDepthFunc", isLeaf: true)
external void _MaterialInstance_setDepthFunc(
ffi.Pointer<TMaterialInstance> materialInstance,
int depthFunc,
);
void MaterialInstance_setDepthFunc(
ffi.Pointer<TMaterialInstance> materialInstance,
TDepthFunc depthFunc,
) =>
_MaterialInstance_setDepthFunc(
materialInstance,
depthFunc.value,
);
@ffi.Native< @ffi.Native<
ffi.Pointer<ffi.Void> Function(LoadFilamentResourceFromOwner, ffi.Pointer<ffi.Void> Function(LoadFilamentResourceFromOwner,
FreeFilamentResourceFromOwner, ffi.Pointer<ffi.Void>)>(isLeaf: true) FreeFilamentResourceFromOwner, ffi.Pointer<ffi.Void>)>(isLeaf: true)
@@ -1205,60 +1275,6 @@ external ffi.Pointer<TMaterialInstance> get_material_instance_at(
int materialIndex, int materialIndex,
); );
@ffi.Native<ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Bool)>(
isLeaf: true)
external void MaterialInstance_setDepthWrite(
ffi.Pointer<TMaterialInstance> materialInstance,
bool enabled,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Bool)>(
isLeaf: true)
external void MaterialInstance_setDepthCulling(
ffi.Pointer<TMaterialInstance> materialInstance,
bool enabled,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Pointer<ffi.Char>,
ffi.Double, ffi.Double, ffi.Double, ffi.Double)>(isLeaf: true)
external void MaterialInstance_setParameterFloat4(
ffi.Pointer<TMaterialInstance> materialInstance,
ffi.Pointer<ffi.Char> name,
double x,
double y,
double w,
double z,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Pointer<ffi.Char>,
ffi.Double, ffi.Double)>(isLeaf: true)
external void MaterialInstance_setParameterFloat2(
ffi.Pointer<TMaterialInstance> materialInstance,
ffi.Pointer<ffi.Char> name,
double x,
double y,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Pointer<ffi.Char>,
ffi.Double)>(isLeaf: true)
external void MaterialInstance_setParameterFloat(
ffi.Pointer<TMaterialInstance> materialInstance,
ffi.Pointer<ffi.Char> name,
double value,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Pointer<ffi.Char>,
ffi.Int)>(isLeaf: true)
external void MaterialInstance_setParameterInt(
ffi.Pointer<TMaterialInstance> materialInstance,
ffi.Pointer<ffi.Char> name,
int value,
);
@ffi.Native<TViewport Function(ffi.Pointer<TView>)>(isLeaf: true) @ffi.Native<TViewport Function(ffi.Pointer<TView>)>(isLeaf: true)
external TViewport View_getViewport( external TViewport View_getViewport(
ffi.Pointer<TView> view, ffi.Pointer<TView> view,
@@ -1487,19 +1503,6 @@ external void Viewer_captureRenderTargetRenderThread(
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete, ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
); );
@ffi.Native<
ffi.Pointer<TRenderTarget> Function(
ffi.Pointer<TViewer>, ffi.IntPtr, ffi.Uint32, ffi.Uint32,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TRenderTarget>)>>
)>(isLeaf: true)
external ffi.Pointer<TRenderTarget> Viewer_createRenderTargetRenderThread(
ffi.Pointer<TViewer> viewer,
int texture,
int width,
int height,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TRenderTarget>)>> onComplete,
);
@ffi.Native< @ffi.Native<
ffi.Void Function(ffi.Pointer<TViewer>, ffi.Void Function(ffi.Pointer<TViewer>,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true) ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
@@ -1518,6 +1521,24 @@ external void Viewer_loadIblRenderThread(
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete, ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
); );
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TViewer>,
ffi.IntPtr,
ffi.Uint32,
ffi.Uint32,
ffi.Pointer<
ffi.NativeFunction<
ffi.Void Function(ffi.Pointer<TRenderTarget>)>>)>(isLeaf: true)
external void Viewer_createRenderTargetRenderThread(
ffi.Pointer<TViewer> viewer,
int texture,
int width,
int height,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TRenderTarget>)>>
onComplete,
);
@ffi.Native< @ffi.Native<
ffi.Void Function( ffi.Void Function(
ffi.Pointer<TView>, ffi.Pointer<TEngine>, ffi.Int)>(isLeaf: true) ffi.Pointer<TView>, ffi.Pointer<TEngine>, ffi.Int)>(isLeaf: true)
@@ -2124,10 +2145,51 @@ external void Gizmo_setVisibility(
bool visible, bool visible,
); );
final class TCamera extends ffi.Opaque {}
final class TMaterialInstance extends ffi.Opaque {} final class TMaterialInstance extends ffi.Opaque {}
enum TDepthFunc {
/// !< Less or equal
LE(0),
/// !< Greater or equal
GE(1),
/// !< Strictly less than
L(2),
/// !< Strictly greater than
G(3),
/// !< Equal
E(4),
/// !< Not equal
NE(5),
/// !< Always. Depth / stencil testing is deactivated.
A(6),
/// !< Never. The depth / stencil test always fails.
N(7);
final int value;
const TDepthFunc(this.value);
static TDepthFunc fromValue(int value) => switch (value) {
0 => LE,
1 => GE,
2 => L,
3 => G,
4 => E,
5 => NE,
6 => A,
7 => N,
_ => throw ArgumentError("Unknown value for TDepthFunc: $value"),
};
}
final class TCamera extends ffi.Opaque {}
final class TEngine extends ffi.Opaque {} final class TEngine extends ffi.Opaque {}
final class TEntityManager extends ffi.Opaque {} final class TEntityManager extends ffi.Opaque {}

View File

@@ -2277,6 +2277,11 @@ class ThermionFFIMaterialInstance extends MaterialInstance {
MaterialInstance_setParameterInt( MaterialInstance_setParameterInt(
_pointer, name.toNativeUtf8().cast<Char>(), value); _pointer, name.toNativeUtf8().cast<Char>(), value);
} }
@override
Future setDepthFunc(SampleCompareFunction depthFunc) async {
MaterialInstance_setDepthFunc(_pointer, TDepthFunc.values[depthFunc.index]);
}
} }

View File

@@ -1,5 +1,26 @@
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
enum SampleCompareFunction {
/// !< Less or equal
LE,
/// !< Greater or equal
GE,
/// !< Strictly less than
L,
/// !< Strictly greater than
G,
/// !< Equal
E,
/// !< Not equal
NE,
/// !< Always. Depth / stencil testing is deactivated.
A,
/// !< Never. The depth / stencil test always fails.
N;
}
abstract class MaterialInstance { abstract class MaterialInstance {
Future setDepthWriteEnabled(bool enabled); Future setDepthWriteEnabled(bool enabled);
Future setDepthFunc(SampleCompareFunction depthFunc);
Future setDepthCullingEnabled(bool enabled); Future setDepthCullingEnabled(bool enabled);
Future setParameterFloat4(String name, double x, double y, double z, double w); Future setParameterFloat4(String name, double x, double y, double z, double w);

View File

@@ -27,4 +27,22 @@ class ThermionWasmMaterialInstance extends MaterialInstance {
// TODO: implement setParameterFloat // TODO: implement setParameterFloat
throw UnimplementedError(); throw UnimplementedError();
} }
@override
Future setDepthFunc(SampleCompareFunction depthFunc) {
// TODO: implement setDepthFunc
throw UnimplementedError();
}
@override
Future setParameterFloat4(String name, double x, double y, double z, double w) {
// TODO: implement setParameterFloat4
throw UnimplementedError();
}
@override
Future setParameterInt(String name, int value) {
// TODO: implement setParameterInt
throw UnimplementedError();
}
} }

View File

@@ -6,10 +6,10 @@ extern "C"
#endif #endif
#include <stdint.h> #include <stdint.h>
#include "TMaterialInstance.h"
typedef int32_t EntityId; typedef int32_t EntityId;
typedef struct TCamera TCamera; typedef struct TCamera TCamera;
typedef struct TMaterialInstance TMaterialInstance;
typedef struct TEngine TEngine; typedef struct TEngine TEngine;
typedef struct TEntityManager TEntityManager; typedef struct TEntityManager TEntityManager;
typedef struct TViewer TViewer; typedef struct TViewer TViewer;
@@ -19,18 +19,18 @@ extern "C"
typedef struct TView TView; typedef struct TView TView;
typedef struct TGizmo TGizmo; typedef struct TGizmo TGizmo;
typedef struct TScene TScene; typedef struct TScene TScene;
struct TMaterialKey { struct TMaterialKey {
bool doubleSided = true; bool doubleSided;
bool unlit = true; bool unlit;
bool hasVertexColors = true; bool hasVertexColors;
bool hasBaseColorTexture = true; bool hasBaseColorTexture;
bool hasNormalTexture = true; bool hasNormalTexture;
bool hasOcclusionTexture = true; bool hasOcclusionTexture;
bool hasEmissiveTexture = true; bool hasEmissiveTexture;
bool useSpecularGlossiness = true; bool useSpecularGlossiness;
int alphaMode = 4; int alphaMode;
bool enableDiagnostics = 4; bool enableDiagnostics;
union { union {
#ifdef __cplusplus #ifdef __cplusplus
struct { struct {
@@ -43,42 +43,42 @@ extern "C"
}; };
#else #else
struct { struct {
bool hasMetallicRoughnessTexture = true; bool hasMetallicRoughnessTexture;
uint8_t metallicRoughnessUV = 7; uint8_t metallicRoughnessUV;
}; };
struct { struct {
bool hasSpecularGlossinessTexture = true; bool hasSpecularGlossinessTexture;
uint8_t specularGlossinessUV = 7; uint8_t specularGlossinessUV;
}; };
#endif #endif
}; };
uint8_t baseColorUV; uint8_t baseColorUV;
// -- 32 bit boundary -- // -- 32 bit boundary --
bool hasClearCoatTexture = true; bool hasClearCoatTexture;
uint8_t clearCoatUV = 7; uint8_t clearCoatUV;
bool hasClearCoatRoughnessTexture = true; bool hasClearCoatRoughnessTexture;
uint8_t clearCoatRoughnessUV = 7; uint8_t clearCoatRoughnessUV;
bool hasClearCoatNormalTexture = true; bool hasClearCoatNormalTexture;
uint8_t clearCoatNormalUV = 7; uint8_t clearCoatNormalUV;
bool hasClearCoat = true; bool hasClearCoat;
bool hasTransmission = true; bool hasTransmission;
bool hasTextureTransforms = 6; bool hasTextureTransforms;
// -- 32 bit boundary -- // -- 32 bit boundary --
uint8_t emissiveUV; uint8_t emissiveUV;
uint8_t aoUV; uint8_t aoUV;
uint8_t normalUV; uint8_t normalUV;
bool hasTransmissionTexture = true; bool hasTransmissionTexture;
uint8_t transmissionUV = 7; uint8_t transmissionUV;
// -- 32 bit boundary -- // -- 32 bit boundary --
bool hasSheenColorTexture = true; bool hasSheenColorTexture;
uint8_t sheenColorUV = 7; uint8_t sheenColorUV;
bool hasSheenRoughnessTexture = true; bool hasSheenRoughnessTexture;
uint8_t sheenRoughnessUV = 7; uint8_t sheenRoughnessUV;
bool hasVolumeThicknessTexture = true; bool hasVolumeThicknessTexture;
uint8_t volumeThicknessUV = 7; uint8_t volumeThicknessUV ;
bool hasSheen = true; bool hasSheen;
bool hasIOR = true; bool hasIOR;
bool hasVolume = true; bool hasVolume;
} ; } ;
typedef struct TMaterialKey TMaterialKey; typedef struct TMaterialKey TMaterialKey;

View File

@@ -45,9 +45,21 @@
#include <stddef.h> #include <stddef.h>
#endif #endif
#include "APIBoundaryTypes.h" typedef struct TMaterialInstance TMaterialInstance;
#include "ResourceBuffer.hpp"
#include "ThermionDartAPIUtils.h" // copied from SamplerCompareFunc in DriverEnums.h
enum TDepthFunc {
// don't change the enums values
LE = 0, //!< Less or equal
GE, //!< Greater or equal
L, //!< Strictly less than
G, //!< Strictly greater than
E, //!< Equal
NE, //!< Not equal
A, //!< Always. Depth / stencil testing is deactivated.
N //!< Never. The depth / stencil test always fails.
};
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
@@ -59,6 +71,7 @@ extern "C"
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance* materialInstance, const char* name, double x, double y); EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance* materialInstance, const char* name, double x, double y);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat(TMaterialInstance* materialInstance, const char* name, double value); EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat(TMaterialInstance* materialInstance, const char* name, double value);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterInt(TMaterialInstance* materialInstance, const char* name, int value); EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterInt(TMaterialInstance* materialInstance, const char* name, int value);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthFunc(TMaterialInstance* materialInstance, TDepthFunc depthFunc);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -49,6 +49,7 @@
#include "APIBoundaryTypes.h" #include "APIBoundaryTypes.h"
#include "ResourceBuffer.hpp" #include "ResourceBuffer.hpp"
#include "ThermionDartAPIUtils.h" #include "ThermionDartAPIUtils.h"
#include "TMaterialInstance.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"

View File

@@ -45,6 +45,12 @@ namespace thermion
{ {
reinterpret_cast<::filament::MaterialInstance *>(materialInstance)->setParameter(propertyName, value); reinterpret_cast<::filament::MaterialInstance *>(materialInstance)->setParameter(propertyName, value);
} }
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthFunc(TMaterialInstance *tMaterialInstance, TDepthFunc tDepthFunc) {
auto *materialInstance = reinterpret_cast<::filament::MaterialInstance *>(tMaterialInstance);
auto depthFunc = static_cast<filament::MaterialInstance::DepthFunc>(tDepthFunc);
materialInstance->setDepthFunc(depthFunc);
}
#ifdef __cplusplus #ifdef __cplusplus
} }
} }

View File

@@ -146,6 +146,34 @@ void main() async {
}); });
group("MaterialInstance", () { group("MaterialInstance", () {
test('set depth func to always', () async {
var viewer = await testHelper.createViewer(
bg: kRed, cameraPosition: Vector3(0, 0, 6));
var materialInstance1 = await viewer.createUnlitMaterialInstance();
final cube1 = await viewer.createGeometry(GeometryHelper.cube(),
materialInstance: materialInstance1);
await materialInstance1!
.setParameterFloat4("baseColorFactor", 0.0, 1.0, 0.0, 1.0);
var materialInstance2 = await viewer.createUnlitMaterialInstance();
final cube2 = await viewer.createGeometry(GeometryHelper.cube(),
materialInstance: materialInstance2);
await viewer.setPosition(cube2, 1.0, 0.0, -1.0);
await materialInstance2!
.setParameterFloat4("baseColorFactor", 0.0, 0.0, 1.0, 1.0);
// with default depth func, blue cube renders behind the green cube
await testHelper.capture(viewer, "material_instance_depth_func_default");
await materialInstance2.setDepthFunc(SampleCompareFunction.A);
await testHelper.capture(viewer, "material_instance_depth_func_always");
await viewer.dispose();
});
test('disable depth write', () async { test('disable depth write', () async {
var viewer = await testHelper.createViewer(); var viewer = await testHelper.createViewer();
await viewer.setBackgroundColor(1.0, 0.0, 0.0, 1.0); await viewer.setBackgroundColor(1.0, 0.0, 0.0, 1.0);