فهرست منبع

Implement basic cycles light handling. (#164)

Cycles lights are implemented using the node tree, and this patch
doesn't attempt to handle all the possibilities that enables.

However, it does succeed in exporting the basic options you can tweak
in the light settings panel, including:

- RGB Color (no alpha)
- Energy
- Negative Light (for strength < 0)
- Shadows enabled/disabled

This also removes the use_sphere check as cycles lights do not support
limited distance or use_sphere.

Fixes #150.

(cherry picked from commit b57cee82f36c2831efe4e701b122581d2f5a093f)
Lu Jiacheng 6 سال پیش
والد
کامیت
dfb78a7599

+ 46 - 9
io_scene_godot/converters/simple_nodes.py

@@ -68,6 +68,24 @@ def export_camera_node(escn_file, export_settings, node, parent_gd_node):
     return cam_node
 
 
+def find_shader_node(node_tree, name):
+    """Find the shader node from the tree with the given name."""
+    for node in node_tree.nodes:
+        if node.bl_idname == name:
+            return node
+    logging.warning("%s node not found", name)
+    return None
+
+
+def node_input(node, name):
+    """Get the named input value from the shader node."""
+    for inp in node.inputs:
+        if inp.name == name:
+            return inp.default_value
+    logging.warning("%s input not found in %s", name, node.bl_idname)
+    return None
+
+
 class LightNode(NodeTemplate):
     """Base class for godot light node"""
     _light_attr_conv = [
@@ -104,14 +122,16 @@ class LightNode(NodeTemplate):
 def export_light_node(escn_file, export_settings, node, parent_gd_node):
     """Exports lights - well, the ones it knows about. Other light types
     just throw a warning"""
-    light = node.data
+    bl_light_to_gd_light = {
+        "POINT": "OmniLight",
+        "SPOT": "SpotLight",
+        "SUN": "DirectionalLight",
+    }
 
-    if light.type == "POINT":
-        light_node = LightNode(node.name, 'OmniLight', parent_gd_node)
-    elif light.type == "SPOT":
-        light_node = LightNode(node.name, 'SpotLight', parent_gd_node)
-    elif light.type == "SUN":
-        light_node = LightNode(node.name, 'DirectionalLight', parent_gd_node)
+    light = node.data
+    if light.type in bl_light_to_gd_light:
+        light_node = LightNode(
+            node.name, bl_light_to_gd_light[light.type], parent_gd_node)
     else:
         light_node = None
         logging.warning(
@@ -123,9 +143,26 @@ def export_light_node(escn_file, export_settings, node, parent_gd_node):
             bl_attr, gd_attr, converter = item
             light_node[gd_attr] = converter(getattr(light, bl_attr))
 
-        # Properties cannot handled by a converter function
+        # Properties common to all lights
+        # These cannot be set via AttributeConvertInfo as it will not handle
+        # animations correctly
         light_node['transform'] = fix_directional_transform(node.matrix_local)
-        light_node['shadow_enabled'] = light.use_shadow
+        if light.use_nodes:
+            emission = find_shader_node(light.node_tree, 'ShaderNodeEmission')
+            if emission:
+                strength = node_input(emission, 'Strength') or 100
+                color = node_input(emission, 'Color') or [1, 1, 1]
+                # we don't have an easy way to get these in cycles
+                # don't set them and let godot use its defaults
+                del light_node['light_specular']
+                del light_node['shadow_color']
+                # strength=100 in cycles is roughly equivalent to energy=1
+                light_node['light_energy'] = abs(strength / 100.0)
+                light_node['light_color'] = gamma_correct(color)
+                light_node['shadow_enabled'] = light.cycles.cast_shadow
+                light_node['light_negative'] = strength < 0
+        else:
+            light_node['shadow_enabled'] = light.use_shadow
 
         escn_file.add_node(light_node)
 

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


+ 1 - 2
tests/reference_exports/material_cycle/material_anistropy.escn

@@ -268,12 +268,11 @@ surfaces/0 = {
 
 [node name="Point" type="DirectionalLight" parent="."]
 
-light_specular = 1.0
 light_energy = 1.0
 light_color = Color(1.0, 1.0, 1.0, 1.0)
-shadow_color = Color(0.0, 0.0, 0.0, 1.0)
 transform = Transform(0.701062, -0.562597, -0.438174, 0.452107, -0.124517, 0.88323, -0.551463, -0.8173, 0.16706, -2.09735, 4.28268, -0.137035)
 shadow_enabled = true
+light_negative = false
 
 [node name="object_with_uv" type="MeshInstance" parent="."]
 

+ 2 - 4
tests/reference_exports/material_cycle/material_cycle.escn

@@ -1699,27 +1699,25 @@ material/0 = SubResource(39)
 
 [node name="Spot001" type="SpotLight" parent="."]
 
-light_specular = 1.0
 light_energy = 1.0
 light_color = Color(1.0, 1.0, 1.0, 1.0)
-shadow_color = Color(0.0, 0.0, 0.0, 1.0)
 spot_angle = 17.4
 spot_angle_attenuation = 1.25
 spot_range = 25.0
 transform = Transform(0.629608, 0.0765798, 0.77313, -0.776913, 0.06206, 0.626542, 0.0, -0.99513, 0.0985693, 5.32508, 4.74617, 0.487329)
 shadow_enabled = true
+light_negative = false
 
 [node name="Spot" type="SpotLight" parent="."]
 
-light_specular = 1.0
 light_energy = 1.0
 light_color = Color(1.0, 1.0, 1.0, 1.0)
-shadow_color = Color(0.0, 0.0, 0.0, 1.0)
 spot_angle = 24.3
 spot_angle_attenuation = 1.25
 spot_range = 25.0
 transform = Transform(0.633641, 0.273452, -0.723687, 0.117184, 0.890727, 0.439173, 0.764701, -0.363082, 0.532357, -4.6068, 2.54209, 4.80618)
 shadow_enabled = true
+light_negative = false
 
 [node name="Plane" type="MeshInstance" parent="."]
 

+ 2 - 3
tests/reference_exports/material_cycle/material_normal.escn

@@ -844,12 +844,11 @@ material/0 = SubResource(12)
 
 [node name="Lamp" type="DirectionalLight" parent="."]
 
-light_specular = 1.0
-light_energy = 1.0
+light_energy = 0.04
 light_color = Color(1.0, 1.0, 1.0, 1.0)
-shadow_color = Color(0.0, 0.0, 0.0, 1.0)
 transform = Transform(-0.404791, -0.439839, 0.801677, 0.221124, 0.803611, 0.552553, -0.88727, 0.400938, -0.228035, 4.07625, 1.70784, -1.00545)
 shadow_enabled = true
+light_negative = false
 
 [node name="test_displacement" type="MeshInstance" parent="."]
 

BIN
tests/test_scenes/light/cycles_lights.blend


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