Răsfoiți Sursa

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 ani în urmă
părinte
comite
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
     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):
 class LightNode(NodeTemplate):
     """Base class for godot light node"""
     """Base class for godot light node"""
     _light_attr_conv = [
     _light_attr_conv = [
@@ -104,14 +122,16 @@ class LightNode(NodeTemplate):
 def export_light_node(escn_file, export_settings, node, parent_gd_node):
 def export_light_node(escn_file, export_settings, node, parent_gd_node):
     """Exports lights - well, the ones it knows about. Other light types
     """Exports lights - well, the ones it knows about. Other light types
     just throw a warning"""
     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:
     else:
         light_node = None
         light_node = None
         logging.warning(
         logging.warning(
@@ -123,9 +143,26 @@ def export_light_node(escn_file, export_settings, node, parent_gd_node):
             bl_attr, gd_attr, converter = item
             bl_attr, gd_attr, converter = item
             light_node[gd_attr] = converter(getattr(light, bl_attr))
             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['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)
         escn_file.add_node(light_node)
 
 

Fișier diff suprimat deoarece este prea mare
+ 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="."]
 [node name="Point" type="DirectionalLight" parent="."]
 
 
-light_specular = 1.0
 light_energy = 1.0
 light_energy = 1.0
 light_color = Color(1.0, 1.0, 1.0, 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)
 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
 shadow_enabled = true
+light_negative = false
 
 
 [node name="object_with_uv" type="MeshInstance" parent="."]
 [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="."]
 [node name="Spot001" type="SpotLight" parent="."]
 
 
-light_specular = 1.0
 light_energy = 1.0
 light_energy = 1.0
 light_color = Color(1.0, 1.0, 1.0, 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 = 17.4
 spot_angle_attenuation = 1.25
 spot_angle_attenuation = 1.25
 spot_range = 25.0
 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)
 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
 shadow_enabled = true
+light_negative = false
 
 
 [node name="Spot" type="SpotLight" parent="."]
 [node name="Spot" type="SpotLight" parent="."]
 
 
-light_specular = 1.0
 light_energy = 1.0
 light_energy = 1.0
 light_color = Color(1.0, 1.0, 1.0, 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 = 24.3
 spot_angle_attenuation = 1.25
 spot_angle_attenuation = 1.25
 spot_range = 25.0
 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)
 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
 shadow_enabled = true
+light_negative = false
 
 
 [node name="Plane" type="MeshInstance" parent="."]
 [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="."]
 [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)
 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)
 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
 shadow_enabled = true
+light_negative = false
 
 
 [node name="test_displacement" type="MeshInstance" parent="."]
 [node name="test_displacement" type="MeshInstance" parent="."]
 
 

BIN
tests/test_scenes/light/cycles_lights.blend


Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff