فهرست منبع

Improve our attempt at exporting SpatialMaterials. (#341)

* Attempt basic spatial material conversion.

This improves our attempt at converting several material types
(Principled, Diffuse, and Emission) to SpatialMaterials. It still leaves
a lot to be desired, but implements more than our current approach.

What works:

- Principled albedo, metallic, roughness, anisotropy, emission, and
  clearcoat. Principled does not have emission strength, so we just
  assume 1.
- Emission strength and color
- Diffuse color and roughness.

Fixes #332.

* Add alpha support for spatial materials.

Everywhere we currently export a color we use mathutils.Color, which
doesn't support alpha. This adds an RGBA type we can use to export
colors with alpha.

Maybe we could use this in other places, but I'm not sure the
implications right now.

* Null-check NodeTree in SpatialMaterial export

* Add config.json for spatial export test.

* Update tests for spatial material export.
Ryan Roden-Corrent 5 سال پیش
والد
کامیت
274f668963

+ 52 - 1
io_scene_godot/converters/material/material.py

@@ -9,7 +9,7 @@ import os
 import bpy
 from .script_shader import export_script_shader
 from ...structures import (
-    InternalResource, ExternalResource, gamma_correct, ValidationError)
+    InternalResource, ExternalResource, gamma_correct, ValidationError, RGBA)
 
 
 def export_image(escn_file, export_settings, image):
@@ -58,7 +58,58 @@ def export_material(escn_file, export_settings, bl_object, material):
 def export_as_spatial_material(material_rsc_name, material):
     """Export a Blender Material as Godot Spatial Material"""
     mat = InternalResource("SpatialMaterial", material_rsc_name)
+
+    # basic properties we can extract from a blender Material
+    # we'll try to override these with better guesses if we can
     mat['albedo_color'] = gamma_correct(material.diffuse_color)
+    mat['metallic'] = material.metallic
+    mat['metallic_specular'] = material.specular_intensity
+    mat['roughness'] = material.roughness
+
+    if not material.node_tree:
+        return mat
+
+    out = material.node_tree.get_output_node("ALL")
+    if not (out and out.inputs["Surface"].links):
+        logging.warning("No Surface output for %s", material.name)
+        return mat
+
+    surf = out.inputs["Surface"].links[0].from_node
+
+    def val(key):
+        return surf.inputs[key].default_value
+
+    if surf.type == "BSDF_PRINCIPLED":
+        mat["albedo_color"] = RGBA([
+            *gamma_correct(val("Base Color"))[:3], val("Alpha")
+        ])
+        mat["flags_transparent"] = val("Alpha") < 1.0
+
+        mat["metallic"] = val("Metallic")
+        mat["metallic_specular"] = val("Specular")
+        mat["roughness"] = val("Roughness")
+
+        mat["anisotropy_enabled"] = val("Anisotropic") > 0
+        mat["anisotropy"] = val("Anisotropic")
+
+        mat["clearcoat_enabled"] = val("Clearcoat") > 0
+        mat["clearcoat"] = val("Clearcoat")
+        mat["clearcoat_gloss"] = 1.0 - val("Clearcoat Roughness")
+
+        mat["emission_enabled"] = any(val("Emission")[0:3])
+        mat["emission_energy"] = 1.0 * any(val("Emission")[0:3])
+        mat["emission"] = gamma_correct(val("Emission"))
+
+        mat["subsurf_scatter_enabled"] = val("Subsurface") > 0
+        mat["subsurf_scatter_strength"] = val("Subsurface")
+    elif surf.type == "EMISSION":
+        mat["emission_enabled"] = True
+        mat["emission_energy"] = val("Strength") / 100
+        mat["emission"] = gamma_correct(val("Color"))
+    elif surf.type == "BSDF_DIFFUSE":
+        mat["albedo_color"] = gamma_correct(val("Color"))
+        mat["albedo_color"] = gamma_correct(val("Roughness"))
+
     return mat
 
 

+ 16 - 0
io_scene_godot/structures.py

@@ -333,6 +333,22 @@ class NodePath:
         )
 
 
+class RGBA:
+    """Color with an Alpha channel.
+
+    Use when you need to export a color with alpha, as mathutils.Color lacks
+    an alpha channel.
+    See https://developer.blender.org/T53540
+    """
+
+    def __init__(self, values):
+        self.values = values
+
+    def to_string(self):
+        """Convert the color to serialized form"""
+        return color_to_string(self.values)
+
+
 def fix_matrix(mtx):
     """ Shuffles a matrix to change from y-up to z-up"""
     # TODO: can this be replaced my a matrix multiplcation?

+ 12 - 0
tests/reference_exports/material/object_link_material.escn

@@ -4,11 +4,17 @@
 
 resource_name = ""
 albedo_color = Color(0.229957, 0.274814, 0.903545, 1.0)
+metallic = 0.0
+metallic_specular = 0.5
+roughness = 0.5
 
 [sub_resource id=2 type="SpatialMaterial"]
 
 resource_name = ""
 albedo_color = Color(0.903545, 0.903545, 0.903545, 1.0)
+metallic = 0.0
+metallic_specular = 0.5
+roughness = 0.5
 
 [sub_resource id=3 type="ArrayMesh"]
 
@@ -50,11 +56,17 @@ surfaces/1 = {
 
 resource_name = ""
 albedo_color = Color(0.903545, 0.169508, 0.242857, 1.0)
+metallic = 0.0
+metallic_specular = 0.5
+roughness = 0.5
 
 [sub_resource id=5 type="SpatialMaterial"]
 
 resource_name = ""
 albedo_color = Color(0.121702, 0.903545, 0.139942, 1.0)
+metallic = 0.0
+metallic_specular = 0.5
+roughness = 0.5
 
 [node type="Spatial" name="Scene"]
 

+ 6 - 0
tests/reference_exports/material/simple_materials.escn

@@ -4,11 +4,17 @@
 
 resource_name = ""
 albedo_color = Color(0.138926, 0.903545, 0.0, 1.0)
+metallic = 0.0
+metallic_specular = 0.5
+roughness = 0.5
 
 [sub_resource id=2 type="SpatialMaterial"]
 
 resource_name = ""
 albedo_color = Color(0.903545, 0.903545, 0.903545, 1.0)
+metallic = 0.0
+metallic_specular = 0.5
+roughness = 0.5
 
 [sub_resource id=3 type="ArrayMesh"]
 

+ 3 - 0
tests/reference_exports/material_cycle/material_cycle.escn

@@ -1379,6 +1379,9 @@ shader = SubResource(37)
 
 resource_name = ""
 albedo_color = Color(0.723069, 0.723069, 0.723069, 1.0)
+metallic = 0.0
+metallic_specular = 0.1
+roughness = 0.5
 
 [sub_resource id=40 type="ArrayMesh"]
 

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 56 - 0
tests/reference_exports/material_cycle/material_spatial/material_spatial.escn


+ 6 - 0
tests/reference_exports/shape_key/shapekey_with_multi_surface.escn

@@ -4,11 +4,17 @@
 
 resource_name = ""
 albedo_color = Color(0.413475, 0.685345, 0.903545, 1.0)
+metallic = 0.0
+metallic_specular = 0.5
+roughness = 0.5
 
 [sub_resource id=2 type="SpatialMaterial"]
 
 resource_name = ""
 albedo_color = Color(0.364638, 0.903545, 0.264181, 1.0)
+metallic = 0.0
+metallic_specular = 0.5
+roughness = 0.5
 
 [sub_resource id=3 type="ArrayMesh"]
 

+ 3 - 0
tests/test_scenes/material_cycle/material_spatial/config.json

@@ -0,0 +1,3 @@
+{
+    "material_mode": "SPATIAL"
+}

BIN
tests/test_scenes/material_cycle/material_spatial/material_spatial.blend


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است