From 60f5f9057bb3bb5bb282fbdbd08d5962172e99f4 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Thu, 2 Jan 2025 12:47:41 -0800 Subject: [PATCH] Add OMI_materials_blend implementation --- .../misc/omi_materials_blend.gd | 92 ++++ .../omi_extensions/omi_extensions_plugin.gd | 2 + .../gltf/omi_mat_blend.gltf | 399 ++++++++++++++++++ .../gltf/omi_mat_blend.gltf.import | 36 ++ .../gltf/omi_mat_blend0.bin | Bin 0 -> 6120 bytes .../source/omi_mat_blend.tscn | 49 +++ .../test/omi_mat_blend_test.tscn | 7 + 7 files changed, 585 insertions(+) create mode 100644 addons/omi_extensions/misc/omi_materials_blend.gd create mode 100644 examples/omi_materials_blend/gltf/omi_mat_blend.gltf create mode 100644 examples/omi_materials_blend/gltf/omi_mat_blend.gltf.import create mode 100644 examples/omi_materials_blend/gltf/omi_mat_blend0.bin create mode 100644 examples/omi_materials_blend/source/omi_mat_blend.tscn create mode 100644 examples/omi_materials_blend/test/omi_mat_blend_test.tscn diff --git a/addons/omi_extensions/misc/omi_materials_blend.gd b/addons/omi_extensions/misc/omi_materials_blend.gd new file mode 100644 index 0000000..40a29b0 --- /dev/null +++ b/addons/omi_extensions/misc/omi_materials_blend.gd @@ -0,0 +1,92 @@ +@tool +class_name GLTFDocumentExtensionOMIMaterialsBlend +extends GLTFDocumentExtension + + +func _import_preflight(_state: GLTFState, extensions: PackedStringArray) -> Error: + if extensions.has("OMI_materials_blend"): + return OK + return ERR_SKIP + + +func _get_supported_extensions() -> PackedStringArray: + return PackedStringArray(["OMI_materials_blend"]) + + +func _apply_alpha_mode(alpha_mode: String, godot_mat: BaseMaterial3D) -> void: + match alpha_mode: + "BLEND": godot_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_DEPTH_PRE_PASS + "HASHED": godot_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_HASH + "MULTIPLY": godot_mat.blend_mode = BaseMaterial3D.BLEND_MODE_MUL + "PREMULT": godot_mat.blend_mode = BaseMaterial3D.BLEND_MODE_PREMULT_ALPHA + "ADD": godot_mat.blend_mode = BaseMaterial3D.BLEND_MODE_ADD + "SUBTRACT": godot_mat.blend_mode = BaseMaterial3D.BLEND_MODE_SUB + "REV_SUBTRACT": push_warning("REV_SUBTRACT alpha blend mode is not supported by Godot.") + "MAX": push_warning("MAX alpha blend mode is not supported by Godot.") + "MIN": push_warning("MIN alpha blend mode is not supported by Godot.") + + +func _read_apply_material_blend_extension(mat_blend_ext: Dictionary, godot_mat: BaseMaterial3D) -> void: + if mat_blend_ext.has("alwaysUseCutoff"): + if mat_blend_ext["alwaysUseCutoff"]: + godot_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_SCISSOR + if mat_blend_ext.has("alphaMode"): + _apply_alpha_mode(mat_blend_ext["alphaMode"], godot_mat) + + +func _import_post_parse(gltf_state: GLTFState) -> Error: + var materials: Array[Material] = gltf_state.get_materials() + var json_materials: Array = gltf_state.json.get("materials", []) + assert(materials.size() == json_materials.size()) + for i in range(materials.size()): + var mat_3d: BaseMaterial3D = materials[i] as BaseMaterial3D + var mat_dict: Dictionary = json_materials[i] + if mat_dict.has("alphaMode"): + _apply_alpha_mode(mat_dict["alphaMode"], mat_3d) + if mat_dict.has("extensions") and materials[i] is BaseMaterial3D: + var mat_extensions: Dictionary = mat_dict["extensions"] + if mat_extensions.has("OMI_materials_blend"): + var mat_blend_ext: Dictionary = mat_extensions["OMI_materials_blend"] + _read_apply_material_blend_extension(mat_blend_ext, mat_3d) + gltf_state.set_materials(materials) + return OK + + +func _write_material_blend_extension_if_needed(godot_mat: BaseMaterial3D, mat_dict: Dictionary) -> bool: + if godot_mat.blend_mode == BaseMaterial3D.BLEND_MODE_MIX: + if godot_mat.transparency == BaseMaterial3D.TRANSPARENCY_ALPHA_HASH: + var mat_blend_ext: Dictionary = mat_dict.get_or_add("extensions", {}).get_or_add("OMI_materials_blend", {}) + mat_blend_ext["alphaMode"] = "HASHED" + return true + return false + var mat_blend_ext: Dictionary = mat_dict.get_or_add("extensions", {}).get_or_add("OMI_materials_blend", {}) + match godot_mat.blend_mode: + BaseMaterial3D.BLEND_MODE_ADD: + mat_blend_ext["alphaMode"] = "ADD" + BaseMaterial3D.BLEND_MODE_SUB: + mat_blend_ext["alphaMode"] = "SUBTRACT" + BaseMaterial3D.BLEND_MODE_MUL: + mat_blend_ext["alphaMode"] = "MULTIPLY" + BaseMaterial3D.BLEND_MODE_PREMULT_ALPHA: + mat_blend_ext["alphaMode"] = "PREMULT" + if godot_mat.transparency == BaseMaterial3D.TRANSPARENCY_ALPHA_SCISSOR: + mat_blend_ext["alwaysUseCutoff"] = true + mat_dict["alphaCutoff"] = godot_mat.alpha_scissor_threshold + return true + + +func _export_post(gltf_state: GLTFState) -> Error: + var materials: Array[Material] = gltf_state.get_materials() + var json_materials: Array = gltf_state.json.get("materials", []) + assert(materials.size() == json_materials.size()) + var use_material_blend_extension: bool = false + for i in range(materials.size()): + var mat_dict: Dictionary = json_materials[i] + var written: bool = _write_material_blend_extension_if_needed(materials[i] as BaseMaterial3D, mat_dict) + use_material_blend_extension = use_material_blend_extension or written + if use_material_blend_extension: + gltf_state.add_used_extension("OMI_materials_blend", false) + var extensions_used: Array = gltf_state.json.get_or_add("extensionsUsed", []) + extensions_used.append("OMI_materials_blend") + gltf_state.json["extensionsUsed"] = extensions_used + return OK diff --git a/addons/omi_extensions/omi_extensions_plugin.gd b/addons/omi_extensions/omi_extensions_plugin.gd index 676e1bd..bb268d4 100644 --- a/addons/omi_extensions/omi_extensions_plugin.gd +++ b/addons/omi_extensions/omi_extensions_plugin.gd @@ -9,6 +9,8 @@ func _enter_tree() -> void: # NOTE: Be sure to also instance and register these at runtime if you want # the extensions at runtime. This editor plugin script won't run in games. var ext: GLTFDocumentExtension + ext = GLTFDocumentExtensionOMIMaterialsBlend.new() + GLTFDocument.register_gltf_document_extension(ext) ext = GLTFDocumentExtensionOMISeat.new() GLTFDocument.register_gltf_document_extension(ext, true) ext = GLTFDocumentExtensionOMISpawnPoint.new() diff --git a/examples/omi_materials_blend/gltf/omi_mat_blend.gltf b/examples/omi_materials_blend/gltf/omi_mat_blend.gltf new file mode 100644 index 0000000..919b821 --- /dev/null +++ b/examples/omi_materials_blend/gltf/omi_mat_blend.gltf @@ -0,0 +1,399 @@ +{ + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [0.5, 0.5, 0.5], + "min": [-0.5, -0.5, -0.5], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 0, 1, 1], + "min": [-1, -0.00001525925472, -1, 1], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 1, 1], + "min": [-1, -1, -1], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 3, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 1], + "min": [0, 0], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 4, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [23], + "min": [0], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 5, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [0.5, 0.5, 0.5], + "min": [-0.5, -0.5, -0.5], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 6, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 0, 1, 1], + "min": [-1, -0.00001525925472, -1, 1], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 7, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 1, 1], + "min": [-1, -1, -1], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 8, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 1], + "min": [0, 0], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 9, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [23], + "min": [0], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 10, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [0.5, 0.5, 0.5], + "min": [-0.5, -0.5, -0.5], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 11, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 0, 1, 1], + "min": [-1, -0.00001525925472, -1, 1], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 12, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 1, 1], + "min": [-1, -1, -1], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 13, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 1], + "min": [0, 0], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 14, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [23], + "min": [0], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 15, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [0.5, 0.5, 0.5], + "min": [-0.5, -0.5, -0.5], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 16, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 0, 1, 1], + "min": [-1, -0.00001525925472, -1, 1], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 17, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 1, 1], + "min": [-1, -1, -1], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 18, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 1], + "min": [0, 0], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 19, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [23], + "min": [0], + "normalized": false, + "type": "SCALAR" + }, + { + "bufferView": 20, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [0.5, 0.5, 0.5], + "min": [-0.5, -0.5, -0.5], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 21, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 0, 1, 1], + "min": [-1, -0.00001525925472, -1, 1], + "normalized": false, + "type": "VEC4" + }, + { + "bufferView": 22, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 1, 1], + "min": [-1, -1, -1], + "normalized": false, + "type": "VEC3" + }, + { + "bufferView": 23, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [1, 1], + "min": [0, 0], + "normalized": false, + "type": "VEC2" + }, + { + "bufferView": 24, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [23], + "min": [0], + "normalized": false, + "type": "SCALAR" + } + ], + "asset": { + "generator": "Godot Engine v4.3.stable.official@77dcf97d82cbfe4e4615475fa52ca03da645dbd8", + "version": "2.0" + }, + "bufferViews": [ + { "buffer": 0, "byteLength": 288, "byteOffset": 0, "byteStride": 12, "target": 34962 }, + { "buffer": 0, "byteLength": 384, "byteOffset": 288, "byteStride": 16, "target": 34962 }, + { "buffer": 0, "byteLength": 288, "byteOffset": 672, "byteStride": 12, "target": 34962 }, + { "buffer": 0, "byteLength": 192, "byteOffset": 960, "byteStride": 8, "target": 34962 }, + { "buffer": 0, "byteLength": 72, "byteOffset": 1152, "target": 34963 }, + { "buffer": 0, "byteLength": 288, "byteOffset": 1224, "byteStride": 12, "target": 34962 }, + { "buffer": 0, "byteLength": 384, "byteOffset": 1512, "byteStride": 16, "target": 34962 }, + { "buffer": 0, "byteLength": 288, "byteOffset": 1896, "byteStride": 12, "target": 34962 }, + { "buffer": 0, "byteLength": 192, "byteOffset": 2184, "byteStride": 8, "target": 34962 }, + { "buffer": 0, "byteLength": 72, "byteOffset": 2376, "target": 34963 }, + { "buffer": 0, "byteLength": 288, "byteOffset": 2448, "byteStride": 12, "target": 34962 }, + { "buffer": 0, "byteLength": 384, "byteOffset": 2736, "byteStride": 16, "target": 34962 }, + { "buffer": 0, "byteLength": 288, "byteOffset": 3120, "byteStride": 12, "target": 34962 }, + { "buffer": 0, "byteLength": 192, "byteOffset": 3408, "byteStride": 8, "target": 34962 }, + { "buffer": 0, "byteLength": 72, "byteOffset": 3600, "target": 34963 }, + { "buffer": 0, "byteLength": 288, "byteOffset": 3672, "byteStride": 12, "target": 34962 }, + { "buffer": 0, "byteLength": 384, "byteOffset": 3960, "byteStride": 16, "target": 34962 }, + { "buffer": 0, "byteLength": 288, "byteOffset": 4344, "byteStride": 12, "target": 34962 }, + { "buffer": 0, "byteLength": 192, "byteOffset": 4632, "byteStride": 8, "target": 34962 }, + { "buffer": 0, "byteLength": 72, "byteOffset": 4824, "target": 34963 }, + { "buffer": 0, "byteLength": 288, "byteOffset": 4896, "byteStride": 12, "target": 34962 }, + { "buffer": 0, "byteLength": 384, "byteOffset": 5184, "byteStride": 16, "target": 34962 }, + { "buffer": 0, "byteLength": 288, "byteOffset": 5568, "byteStride": 12, "target": 34962 }, + { "buffer": 0, "byteLength": 192, "byteOffset": 5856, "byteStride": 8, "target": 34962 }, + { "buffer": 0, "byteLength": 72, "byteOffset": 6048, "target": 34963 } + ], + "buffers": [{ "byteLength": 6120, "uri": "omi_mat_blend0.bin" }], + "extensionsUsed": ["GODOT_single_root", "OMI_materials_blend"], + "materials": [ + { + "alphaMode": "BLEND", + "extensions": { "OMI_materials_blend": { "alphaMode": "HASHED" } }, + "pbrMetallicRoughness": { + "baseColorFactor": [1, 1, 1, 1], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": { "OMI_materials_blend": { "alphaMode": "ADD" } }, + "pbrMetallicRoughness": { + "baseColorFactor": [1, 1, 1, 1], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "alphaCutoff": 0.25, + "alphaMode": "MASK", + "extensions": { "OMI_materials_blend": { "alphaMode": "ADD", "alwaysUseCutoff": true } }, + "pbrMetallicRoughness": { + "baseColorFactor": [1, 1, 1, 1], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": { "OMI_materials_blend": { "alphaMode": "SUBTRACT" } }, + "pbrMetallicRoughness": { + "baseColorFactor": [1, 1, 1, 1], + "metallicFactor": 0, + "roughnessFactor": 1 + } + }, + { + "extensions": { "OMI_materials_blend": { "alphaMode": "MULTIPLY" } }, + "pbrMetallicRoughness": { + "baseColorFactor": [1, 1, 1, 1], + "metallicFactor": 0, + "roughnessFactor": 1 + } + } + ], + "meshes": [ + { + "extras": { "targetNames": [] }, + "primitives": [ + { + "attributes": { "NORMAL": 2, "POSITION": 0, "TANGENT": 1, "TEXCOORD_0": 3 }, + "indices": 4, + "material": 0, + "mode": 4 + } + ] + }, + { + "extras": { "targetNames": [] }, + "primitives": [ + { + "attributes": { "NORMAL": 7, "POSITION": 5, "TANGENT": 6, "TEXCOORD_0": 8 }, + "indices": 9, + "material": 1, + "mode": 4 + } + ] + }, + { + "extras": { "targetNames": [] }, + "primitives": [ + { + "attributes": { "NORMAL": 12, "POSITION": 10, "TANGENT": 11, "TEXCOORD_0": 13 }, + "indices": 14, + "material": 2, + "mode": 4 + } + ] + }, + { + "extras": { "targetNames": [] }, + "primitives": [ + { + "attributes": { "NORMAL": 17, "POSITION": 15, "TANGENT": 16, "TEXCOORD_0": 18 }, + "indices": 19, + "material": 3, + "mode": 4 + } + ] + }, + { + "extras": { "targetNames": [] }, + "primitives": [ + { + "attributes": { "NORMAL": 22, "POSITION": 20, "TANGENT": 21, "TEXCOORD_0": 23 }, + "indices": 24, + "material": 4, + "mode": 4 + } + ] + } + ], + "nodes": [ + { "children": [1, 2, 3, 4, 5], "name": "OMIMaterialsBlend" }, + { "mesh": 0, "name": "Hashed", "translation": [-3, 0, 0] }, + { "mesh": 1, "name": "Add", "translation": [-1.5, 0, 0] }, + { "mesh": 2, "name": "AddAndScissorClipMask" }, + { "mesh": 3, "name": "Subtract", "translation": [1.5, 0, 0] }, + { "mesh": 4, "name": "Multiply", "translation": [3, 0, 0] } + ], + "scene": 0, + "scenes": [{ "nodes": [0] }] +} diff --git a/examples/omi_materials_blend/gltf/omi_mat_blend.gltf.import b/examples/omi_materials_blend/gltf/omi_mat_blend.gltf.import new file mode 100644 index 0000000..4a311e3 --- /dev/null +++ b/examples/omi_materials_blend/gltf/omi_mat_blend.gltf.import @@ -0,0 +1,36 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://bli0exbvummt3" +path="res://.godot/imported/omi_mat_blend.gltf-1efa9f950d20e3c92cd7852a1c1328c3.scn" + +[deps] + +source_file="res://examples/omi_materials_blend/gltf/omi_mat_blend.gltf" +dest_files=["res://.godot/imported/omi_mat_blend.gltf-1efa9f950d20e3c92cd7852a1c1328c3.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +_subresources={} +gltf/naming_version=1 +gltf/embedded_image_handling=1 diff --git a/examples/omi_materials_blend/gltf/omi_mat_blend0.bin b/examples/omi_materials_blend/gltf/omi_mat_blend0.bin new file mode 100644 index 0000000000000000000000000000000000000000..ca8ac8b16b73ebd5288edfaed320c0c6c9c0f9da GIT binary patch literal 6120 zcmeH~TXNJe5Jfu>2yc=AVGk?We@m=rBjrW6S{px+&*T437(|k|k?IUe-u@#@!H?6IIsjvG5yscg7?X-Le`9|FA z`Shpl!{^iK@7NEm9y3;k@7jF#+B~ZskC~qH_WE;DwK=y_^}gO)b#9;M=--QWzm{8j z<4xb%d)IgN)^7ZM=laDy*$2OWbNyo5CZ4}Smc>eu4Im}6w7 z8da3>POQn{Vya={QI#*lrxugq5xEwFD`4W%=qX3>bBIgbujJa#o>ym6y|d5PxcIL3 zW%~Q=ecRW+_IT5LPvh+)ZF8{|pVv37?Yhnv@V0gvomcftJI6WZv&1OL;t{zPgDYU- z(&#Bi@pFhv-LK@wId+_5VGpeP!S~0S$9)obd*V39j{hs!69oH2xfB*7a`NouTF*=I z$)%oG^00?1eyn%)`5G7B^}bBMD|+Ad^{+kNG~d&B`$*edY{lpGO>4WZ^98)E-EofX He2)DG*S<=v literal 0 HcmV?d00001 diff --git a/examples/omi_materials_blend/source/omi_mat_blend.tscn b/examples/omi_materials_blend/source/omi_mat_blend.tscn new file mode 100644 index 0000000..56d2658 --- /dev/null +++ b/examples/omi_materials_blend/source/omi_mat_blend.tscn @@ -0,0 +1,49 @@ +[gd_scene load_steps=7 format=3 uid="uid://b5y0bhenjvubp"] + +[sub_resource type="BoxMesh" id="BoxMesh_v8cks"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_wj58l"] +transparency = 3 +alpha_hash_scale = 1.0 +alpha_antialiasing_mode = 0 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_i0vps"] +blend_mode = 1 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_bvvji"] +transparency = 2 +alpha_scissor_threshold = 0.25 +alpha_antialiasing_mode = 0 +blend_mode = 1 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_pl7qt"] +blend_mode = 2 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_tlexc"] +blend_mode = 3 + +[node name="OMIMaterialsBlend" type="Node3D"] + +[node name="Hashed" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, 0) +mesh = SubResource("BoxMesh_v8cks") +surface_material_override/0 = SubResource("StandardMaterial3D_wj58l") + +[node name="Add" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.5, 0, 0) +mesh = SubResource("BoxMesh_v8cks") +surface_material_override/0 = SubResource("StandardMaterial3D_i0vps") + +[node name="AddAndScissorClipMask" type="MeshInstance3D" parent="."] +mesh = SubResource("BoxMesh_v8cks") +surface_material_override/0 = SubResource("StandardMaterial3D_bvvji") + +[node name="Subtract" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 0, 0) +mesh = SubResource("BoxMesh_v8cks") +surface_material_override/0 = SubResource("StandardMaterial3D_pl7qt") + +[node name="Multiply" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 0, 0) +mesh = SubResource("BoxMesh_v8cks") +surface_material_override/0 = SubResource("StandardMaterial3D_tlexc") diff --git a/examples/omi_materials_blend/test/omi_mat_blend_test.tscn b/examples/omi_materials_blend/test/omi_mat_blend_test.tscn new file mode 100644 index 0000000..a0b7a99 --- /dev/null +++ b/examples/omi_materials_blend/test/omi_mat_blend_test.tscn @@ -0,0 +1,7 @@ +[gd_scene load_steps=2 format=3 uid="uid://3hcpp8n7ekcs"] + +[ext_resource type="PackedScene" uid="uid://bli0exbvummt3" path="res://examples/omi_materials_blend/gltf/omi_mat_blend.gltf" id="1_3v27v"] + +[node name="OMIMaterialsBlendTest" type="Node3D"] + +[node name="OMIMaterialsBlend" parent="." instance=ExtResource("1_3v27v")]