Skip to content

Commit

Permalink
rendermodes!
Browse files Browse the repository at this point in the history
  • Loading branch information
Lilaa3 committed Oct 26, 2024
1 parent 2ffe7cc commit 32057cc
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 8 deletions.
53 changes: 45 additions & 8 deletions fast64_internal/f3d/bsdf_converter/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,12 @@ def bsdf_mat_to_abstracted(material: Material):
else:
abstracted_mat.lighting = True

# set color_inp to Base Color if the input exists, otherwise try Color, if neither work assert
color_inp = next(("Base Color" for inp in color_shader.inputs if inp.name == "Base Color"), None)
if color_inp is None:
color_inp = next(("Color" for inp in color_shader.inputs if inp.name == "Color"), None)
assert color_inp is not None, f"Could not find color input in {material.name}"

# uv map
found_uv_map_nodes = find_linked_nodes(output_node, lambda node: node.bl_idname == "ShaderNodeUVMap")
found_uv_map_names = list(dict.fromkeys([node.uv_map for node in found_uv_map_nodes]).keys())
Expand All @@ -592,7 +598,7 @@ def get_vtx_layer(nodes):
vtx_color_nodes = find_linked_nodes(
color_shader,
lambda node: node.bl_idname == "ShaderNodeVertexColor",
specific_input_sockets={"Color", "Base Color"},
specific_input_sockets={color_inp},
)
abstracted_mat.vertex_color = get_vtx_layer(vtx_color_nodes) if len(vtx_color_nodes) > 0 else None
# vertex alpha can sometimes be derived from the mean of the color, this is done by the f3d to bsdf converter as well
Expand All @@ -619,12 +625,12 @@ def get_vtx_layer(nodes):
alpha_textures = find_linked_nodes(
alpha_shader,
lambda node: node.bl_idname == "ShaderNodeTexImage",
specific_output_sockets={alpha_inp},
specific_input_sockets={alpha_inp},
)
color_textures = find_linked_nodes(
color_shader,
lambda node: node.bl_idname == "ShaderNodeTexImage",
specific_output_sockets={"Color", "Base Color"},
specific_input_sockets={color_inp},
)
textures: list[ShaderNodeTexImage] = list(dict.fromkeys(color_textures + alpha_textures).keys())
if len(textures) > 2:
Expand Down Expand Up @@ -657,8 +663,26 @@ def get_vtx_layer(nodes):
if abstracted_tex.set_alpha:
abstracted_mat.texture_sets_alpha = True
abstracted_mat.textures.append(abstracted_tex)
else:
abstracted_mat.color = Color(*shaders[0].inputs[0].default_value)
if not color_textures:
abstracted_mat.color.r, abstracted_mat.color.g, abstracted_mat.color.b = color_shader.inputs[
color_inp
].default_value[:3]
if not alpha_textures:
abstracted_mat.color.a = alpha_shader.inputs[alpha_inp].default_value

abstracted_mat.backface_culling = material.use_backface_culling
if bpy.app.version < (4, 2, 0): # before 4.2 we can just use the blend mode
abstracted_mat.output_method = {"CLIP": "CLIP", "BLEND": "XLU"}.get(material.blend_method, "OPA")
elif alpha_textures or abstracted_mat.color.a < 1.0: # otherwise we check if alpha is not 1 or uses a texture
abstracted_mat.output_method = "XLU"
# check if there is a "clip" node connected to alpha
greater_than_nodes = find_linked_nodes(
alpha_shader,
lambda node: node.bl_idname == "ShaderNodeMath" and node.operation == "GREATER_THAN",
specific_input_sockets={alpha_inp},
)
if len(greater_than_nodes) > 0:
abstracted_mat.output_method = "CLIP"
return abstracted_mat


Expand All @@ -667,7 +691,7 @@ def material_to_f3d(
material: Material,
lights_for_colors=False,
default_to_fog=False,
set_render_mode=False,
set_rendermode_without_fog=False,
):
print(f"Converting BSDF material {material.name}")

Expand Down Expand Up @@ -748,13 +772,26 @@ def set_combiner_cycle(inputs: list[str], suffix=""):
set_combiner_cycle(alpha_inputs, "_alpha")

rdp.g_tex_gen = abstracted_mat.uv_gen
rdp.g_mdsft_text_filt = "G_TF_POINT" if abstracted_mat.point_filtering else "G_TF_BILERP"
rdp.g_packed_normals = (
bool(abstracted_mat.vertex_color) and abstracted_mat.lighting and isUcodeF3DEX3(bpy.context.scene.f3d_type)
)
rdp.g_lighting = abstracted_mat.lighting if not bool(abstracted_mat.vertex_color) or rdp.g_packed_normals else False
rdp.g_fog = default_to_fog
rdp.g_mdsft_cycletype = "G_CYC_1CYCLE" if required_inputs <= 2 and not rdp.g_fog else "G_CYC_2CYCLE"
rdp.g_cull_back = abstracted_mat.backface_culling
rdp.g_mdsft_text_filt = "G_TF_POINT" if abstracted_mat.point_filtering else "G_TF_BILERP"
use_2cycle = required_inputs > 2 or rdp.g_fog
rdp.g_mdsft_cycletype = "G_CYC_2CYCLE" if use_2cycle else "G_CYC_1CYCLE"
f3d_mat.draw_layer.set_generic_draw_layer(abstracted_mat.output_method)

main_rendermode = {"OPA": "G_RM_AA_ZB_OPA_SURF", "XLU": "G_RM_AA_ZB_XLU_SURF", "CLIP": "G_RM_AA_ZB_TEX_EDGE"}[
abstracted_mat.output_method
]
if use_2cycle:
rdp.rendermode_preset_cycle_1 = "G_RM_FOG_SHADE_A" if rdp.g_fog else "G_RM_PASS"
rdp.rendermode_preset_cycle_2 = main_rendermode + "2"
else:
rdp.rendermode_preset_cycle_1 = main_rendermode
rdp.set_rendermode = set_rendermode_without_fog or rdp.g_fog # sm64 should only set rendermode for fog

with bpy.context.temp_override(material=new_material):
update_all_node_values(new_material, bpy.context) # Update nodes
Expand Down
8 changes: 8 additions & 0 deletions fast64_internal/f3d/f3d_material.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,14 @@ class DrawLayerProperty(PropertyGroup):
sm64: bpy.props.EnumProperty(items=sm64EnumDrawLayers, default="1", update=update_draw_layer)
oot: bpy.props.EnumProperty(items=ootEnumDrawLayers, default="Opaque", update=update_draw_layer)

def set_generic_draw_layer(self, output_method: str):
if output_method == "CLIP":
self.sm64, self.oot = "4", "Opaque"
elif output_method == "XLU":
self.sm64, self.oot = "5", "Transparent"
else:
self.sm64, self.oot = "1", "Opaque"

def key(self):
return (self.sm64, self.oot)

Expand Down

0 comments on commit 32057cc

Please sign in to comment.