Skip to content

Commit

Permalink
Fix export crash on RGB and Value const node
Browse files Browse the repository at this point in the history
1. Fix crash on RGB and Value const node by adding a new identifier
2. Add support for limited blend type of MixRGB shader node, including
blend type (MIX, ADD, SUB, MUL, DIV, DIFF, DARKEN, LIGHTEN)
  • Loading branch information
Jason0214 committed Aug 4, 2019
1 parent 5d0f5c7 commit e3d07ec
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ def initialize_outputs(self):
# 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)
Expand Down Expand Up @@ -692,17 +692,62 @@ 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):
"""Converter for ShaderNodeValue"""

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):
Expand Down Expand Up @@ -861,6 +906,7 @@ def parse_node_to_fragment(self):
'ShaderNodeTexImage': ImageTextureNodeConverter,
'ShaderNodeTexCoord': TexCoordNodeConverter,
'ShaderNodeRGB': RgbNodeConverter,
'ShaderNodeMixRGB': MixRgbNodeConverter,
'ShaderNodeNormalMap': NormalMapNodeConverter,
'ShaderNodeBump': BumpNodeConverter,
'NodeReroute': RerouteNodeConverter,
Expand Down
6 changes: 3 additions & 3 deletions io_scene_godot/converters/material/script_shader/node_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ def add_fragment_output(self, output_shader_link):
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 (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,79 @@ def __init__(self, code, input_sockets, output_properties):
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="""
Expand Down Expand Up @@ -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)

0 comments on commit e3d07ec

Please sign in to comment.