Skip to content

Commit 5ee32dd

Browse files
committed
Add OMI_materials_blend implementation
1 parent 06b74ed commit 5ee32dd

File tree

7 files changed

+585
-0
lines changed

7 files changed

+585
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
@tool
2+
class_name GLTFDocumentExtensionOMIMaterialsBlend
3+
extends GLTFDocumentExtension
4+
5+
6+
func _import_preflight(_state: GLTFState, extensions: PackedStringArray) -> Error:
7+
if extensions.has("OMI_materials_blend"):
8+
return OK
9+
return ERR_SKIP
10+
11+
12+
func _get_supported_extensions() -> PackedStringArray:
13+
return PackedStringArray(["OMI_materials_blend"])
14+
15+
16+
func _apply_alpha_mode(alpha_mode: String, godot_mat: BaseMaterial3D) -> void:
17+
match alpha_mode:
18+
"BLEND": godot_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_DEPTH_PRE_PASS
19+
"HASH": godot_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_HASH
20+
"MULTIPLY": godot_mat.blend_mode = BaseMaterial3D.BLEND_MODE_MUL
21+
"PREMULT": godot_mat.blend_mode = BaseMaterial3D.BLEND_MODE_PREMULT_ALPHA
22+
"ADD": godot_mat.blend_mode = BaseMaterial3D.BLEND_MODE_ADD
23+
"SUBTRACT": godot_mat.blend_mode = BaseMaterial3D.BLEND_MODE_SUB
24+
"REV_SUBTRACT": push_warning("REV_SUBTRACT alpha blend mode is not supported by Godot.")
25+
"MAX": push_warning("MAX alpha blend mode is not supported by Godot.")
26+
"MIN": push_warning("MIN alpha blend mode is not supported by Godot.")
27+
28+
29+
func _read_apply_material_blend_extension(mat_blend_ext: Dictionary, godot_mat: BaseMaterial3D) -> void:
30+
if mat_blend_ext.has("alwaysUseCutoff"):
31+
if mat_blend_ext["alwaysUseCutoff"]:
32+
godot_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_SCISSOR
33+
if mat_blend_ext.has("alphaMode"):
34+
_apply_alpha_mode(mat_blend_ext["alphaMode"], godot_mat)
35+
36+
37+
func _import_post_parse(gltf_state: GLTFState) -> Error:
38+
var materials: Array[Material] = gltf_state.get_materials()
39+
var json_materials: Array = gltf_state.json.get("materials", [])
40+
assert(materials.size() == json_materials.size())
41+
for i in range(materials.size()):
42+
var mat_3d: BaseMaterial3D = materials[i] as BaseMaterial3D
43+
var mat_dict: Dictionary = json_materials[i]
44+
if mat_dict.has("alphaMode"):
45+
_apply_alpha_mode(mat_dict["alphaMode"], mat_3d)
46+
if mat_dict.has("extensions") and materials[i] is BaseMaterial3D:
47+
var mat_extensions: Dictionary = mat_dict["extensions"]
48+
if mat_extensions.has("OMI_materials_blend"):
49+
var mat_blend_ext: Dictionary = mat_extensions["OMI_materials_blend"]
50+
_read_apply_material_blend_extension(mat_blend_ext, mat_3d)
51+
gltf_state.set_materials(materials)
52+
return OK
53+
54+
55+
func _write_material_blend_extension_if_needed(godot_mat: BaseMaterial3D, mat_dict: Dictionary) -> bool:
56+
if godot_mat.blend_mode == BaseMaterial3D.BLEND_MODE_MIX:
57+
if godot_mat.transparency == BaseMaterial3D.TRANSPARENCY_ALPHA_HASH:
58+
var mat_blend_ext: Dictionary = mat_dict.get_or_add("extensions", {}).get_or_add("OMI_materials_blend", {})
59+
mat_blend_ext["alphaMode"] = "HASH"
60+
return true
61+
return false
62+
var mat_blend_ext: Dictionary = mat_dict.get_or_add("extensions", {}).get_or_add("OMI_materials_blend", {})
63+
match godot_mat.blend_mode:
64+
BaseMaterial3D.BLEND_MODE_ADD:
65+
mat_blend_ext["alphaMode"] = "ADD"
66+
BaseMaterial3D.BLEND_MODE_SUB:
67+
mat_blend_ext["alphaMode"] = "SUBTRACT"
68+
BaseMaterial3D.BLEND_MODE_MUL:
69+
mat_blend_ext["alphaMode"] = "MULTIPLY"
70+
BaseMaterial3D.BLEND_MODE_PREMULT_ALPHA:
71+
mat_blend_ext["alphaMode"] = "PREMULT"
72+
if godot_mat.transparency == BaseMaterial3D.TRANSPARENCY_ALPHA_SCISSOR:
73+
mat_blend_ext["alwaysUseCutoff"] = true
74+
mat_dict["alphaCutoff"] = godot_mat.alpha_scissor_threshold
75+
return true
76+
77+
78+
func _export_post(gltf_state: GLTFState) -> Error:
79+
var materials: Array[Material] = gltf_state.get_materials()
80+
var json_materials: Array = gltf_state.json.get("materials", [])
81+
assert(materials.size() == json_materials.size())
82+
var use_material_blend_extension: bool = false
83+
for i in range(materials.size()):
84+
var mat_dict: Dictionary = json_materials[i]
85+
var written: bool = _write_material_blend_extension_if_needed(materials[i] as BaseMaterial3D, mat_dict)
86+
use_material_blend_extension = use_material_blend_extension or written
87+
if use_material_blend_extension:
88+
gltf_state.add_used_extension("OMI_materials_blend", false)
89+
var extensions_used: Array = gltf_state.json.get_or_add("extensionsUsed", [])
90+
extensions_used.append("OMI_materials_blend")
91+
gltf_state.json["extensionsUsed"] = extensions_used
92+
return OK

addons/omi_extensions/omi_extensions_plugin.gd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ func _enter_tree() -> void:
99
# NOTE: Be sure to also instance and register these at runtime if you want
1010
# the extensions at runtime. This editor plugin script won't run in games.
1111
var ext: GLTFDocumentExtension
12+
ext = GLTFDocumentExtensionOMIMaterialsBlend.new()
13+
GLTFDocument.register_gltf_document_extension(ext)
1214
ext = GLTFDocumentExtensionOMISeat.new()
1315
GLTFDocument.register_gltf_document_extension(ext, true)
1416
ext = GLTFDocumentExtensionOMISpawnPoint.new()

0 commit comments

Comments
 (0)