Эх сурвалжийг харах

Merge pull request #244 from Jason0214/fix_material_crash

Fix export crash on RGB and Value const node
Lu Jiacheng 6 жил өмнө
parent
commit
33d549d5aa

+ 51 - 5
io_scene_godot/converters/material/script_shader/node_converters.py

@@ -408,7 +408,7 @@ class NodeConverterBase:
         # here not all the sockets are exported, because some of them
         # may not feasible to supported in godot. Here only export
         # those registed in `out_sockets_map`. Registering is done in
-        # `parse_to_fragment` or `parse_to_vertex`
+        # `parse_node_to_fragment` or `parse_node_to_vertex`
         id_to_define = list()
         for out_socket in self.bl_node.outputs:
             var = self.out_sockets_map.get(out_socket, None)
@@ -692,8 +692,52 @@ class RgbNodeConverter(NodeConverterBase):
 
     def parse_node_to_fragment(self):
         rgb_socket = self.bl_node.outputs[0]
-        self.out_sockets_map[rgb_socket] = blender_value_to_string(
-            rgb_socket.default_value)
+        rgb_id = self.generate_socket_id_str(rgb_socket)
+        rgb_value_str = blender_value_to_string(rgb_socket.default_value)
+        self.local_code.append("%s = %s" % (rgb_id, rgb_value_str))
+        self.out_sockets_map[rgb_socket] = rgb_id
+
+
+class MixRgbNodeConverter(NodeConverterBase):
+    """Converter for ShaderNodeMixRGB"""
+
+    def parse_node_to_fragment(self):
+        fac_socket = self.bl_node.inputs['Fac']
+        color1_socket = self.bl_node.inputs['Color1']
+        color2_socket = self.bl_node.inputs['Color2']
+
+        fac_id = self.in_sockets_map[fac_socket]
+        color1_id = self.in_sockets_map[color1_socket]
+        color2_id = self.in_sockets_map[color2_socket]
+
+        blend_type = self.bl_node.blend_type.lower()
+        rgb_mix_func_name = 'node_mix_rgb_' + blend_type
+
+        # clamp fac to (0, 1)
+        self.local_code.append("%s = clamp(%s, 0.0, 1.0)" % (fac_id, fac_id))
+
+        mix_func = find_function_by_name(rgb_mix_func_name)
+        if mix_func is None:
+            # TODO: supportt all the blend types
+            warning_str = 'blend type %s not supported at %s, fall back to ' \
+                'blend type MIX' % (self.bl_node.blend_type, self.bl_node.name)
+            logging.warning(warning_str)
+            # default blender type MIX
+            mix_func = find_function_by_name('node_mix_rgb_mix')
+            self.local_code.append("// " + warning_str)
+        assert mix_func is not None
+
+        out_color_socket = self.bl_node.outputs['Color']
+        out_color_id = self.generate_socket_id_str(out_color_socket)
+
+        in_args = (fac_id, color1_id, color2_id)
+        out_args = (out_color_id,)
+        self.add_function_call(mix_func, in_args, out_args)
+
+        if self.bl_node.use_clamp:
+            self.local_code.append("%s = clamp(%s, vec4(0.0), vec4(1.0))")
+
+        self.out_sockets_map[out_color_socket] = out_color_id
 
 
 class ValueNodeConverter(NodeConverterBase):
@@ -701,8 +745,9 @@ class ValueNodeConverter(NodeConverterBase):
 
     def parse_node_to_fragment(self):
         value_socket = self.bl_node.outputs['Value']
-        self.out_sockets_map[value_socket] = blender_value_to_string(
-            value_socket.default_value)
+        value_id = self.generate_socket_id_str(value_socket)
+        value_str = blender_value_to_string(value_socket.default_value)
+        self.out_sockets_map[value_socket] = "%s = %s" % (value_id, value_str)
 
 
 class ImageTextureNodeConverter(NodeConverterBase):
@@ -861,6 +906,7 @@ NODE_CONVERTERS = {
     'ShaderNodeTexImage': ImageTextureNodeConverter,
     'ShaderNodeTexCoord': TexCoordNodeConverter,
     'ShaderNodeRGB': RgbNodeConverter,
+    'ShaderNodeMixRGB': MixRgbNodeConverter,
     'ShaderNodeNormalMap': NormalMapNodeConverter,
     'ShaderNodeBump': BumpNodeConverter,
     'NodeReroute': RerouteNodeConverter,

+ 3 - 3
io_scene_godot/converters/material/script_shader/node_tree.py

@@ -93,9 +93,9 @@ class ScriptShader:
             self._vertex_code_lines.insert(
                 0,
                 "%s = mat3(vec3(1, 0, 0), vec3(0, 0, 1), vec3(0, -1, 0))\
-                    * ((VERTEX - %s) * (1.0 / %s))" % (
-                        NodeConverterBase.AABB_UVW,
-                        self.UNI_AABB_POS, self.UNI_AABB_SIZE)
+                    * ((VERTEX - %s) * (1.0 / %s))"
+                % (NodeConverterBase.AABB_UVW,
+                   self.UNI_AABB_POS, self.UNI_AABB_SIZE)
             )
 
         for name in (

+ 74 - 1
io_scene_godot/converters/material/script_shader/shader_functions.py

@@ -245,6 +245,79 @@ void node_separate_rgb(vec4 color, out float r, out float g, out float b) {
 void node_combine_rgb(float r, float g, float b, out vec4 color) {
     color = vec4(r, g, b, 1.0);
 }
+"""),
+
+    ShaderFunction(code="""
+void node_mix_rgb_mix(float fac, vec4 in_color1, vec4 in_color2,
+                      out vec4 out_color) {
+    out_color = mix(in_color1, in_color2, fac);
+    out_color.a = in_color1.a;
+}
+"""),
+
+    ShaderFunction(code="""
+void node_mix_rgb_add(float fac, vec4 in_color1, vec4 in_color2,
+                      out vec4 out_color) {
+    out_color = mix(in_color1, in_color1 + in_color2, fac);
+    out_color.a = in_color1.a;
+}
+"""),
+
+    ShaderFunction(code="""
+void node_mix_rgb_subtract(float fac, vec4 in_color1, vec4 in_color2,
+                           out vec4 out_color) {
+    out_color = mix(in_color1, in_color1 - in_color2, fac);
+    out_color.a = in_color1.a;
+}
+"""),
+
+    ShaderFunction(code="""
+void node_mix_rgb_multiply(float fac, vec4 in_color1, vec4 in_color2,
+                           out vec4 out_color) {
+    out_color = mix(in_color1, in_color1 * in_color2, fac);
+    out_color.a = in_color1.a;
+}
+"""),
+
+    ShaderFunction(code="""
+void node_mix_rgb_divide(float fac, vec4 in_color1, vec4 in_color2,
+                         out vec4 out_color) {
+    float fac_cpl = 1.0 - fac;
+    out_color = in_color1;
+    if (in_color2.r != 0.0) {
+        out_color.r = fac_cpl * in_color1.r +  fac * in_color1.r / in_color2.r;
+    }
+    if (in_color2.g != 0.0) {
+        out_color.g = fac_cpl * in_color1.g +  fac * in_color1.g / in_color2.g;
+    }
+    if (in_color2.b != 0.0) {
+        out_color.b = fac_cpl * in_color1.b +  fac * in_color1.b / in_color2.b;
+    }
+}
+"""),
+
+    ShaderFunction(code="""
+void node_mix_rgb_difference(float fac, vec4 in_color1, vec4 in_color2,
+                             out vec4 out_color) {
+    out_color = mix(in_color1, abs(in_color1 - in_color2), fac);
+    out_color.a = in_color1.a;
+}
+"""),
+
+    ShaderFunction(code="""
+void node_mix_rgb_darken(float fac, vec4 in_color1, vec4 in_color2,
+                         out vec4 out_color) {
+    out_color.rgb = min(in_color1.rgb, in_color2.rgb * fac);
+    out_color.a = in_color1.a;
+}
+"""),
+
+    ShaderFunction(code="""
+void node_mix_rgb_lighten(float fac, vec4 in_color1, vec4 in_color2,
+                          out vec4 out_color) {
+    out_color.rgb = max(in_color1.rgb, in_color2.rgb * fac);
+    out_color.a = in_color1.a;
+}
 """),
 
     ShaderFunction(code="""
@@ -710,4 +783,4 @@ def find_node_function(node):
 def find_function_by_name(function_name):
     """Given identifier of a material node,
     return its corresponding function"""
-    return FUNCTION_NAME_MAPPING[function_name]
+    return FUNCTION_NAME_MAPPING.get(function_name, None)