Skip to content

Commit

Permalink
Fixed world material export to support environmental maps without emi…
Browse files Browse the repository at this point in the history
…ssion node
  • Loading branch information
Leauyy committed Oct 11, 2023
1 parent a4b2eff commit f2f5c38
Showing 1 changed file with 75 additions and 66 deletions.
141 changes: 75 additions & 66 deletions mitsuba-blender/io/exporter/materials.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,76 +432,85 @@ def convert_world(export_ctx, world, ignore_background):
if not output_node.inputs["Surface"].is_linked:
return
surface_node = output_node.inputs["Surface"].links[0].from_node
if surface_node.inputs['Strength'].is_linked:
raise NotImplementedError("Only default emitter strength value is supported.")#TODO: value input
strength = surface_node.inputs['Strength'].default_value

if strength == 0: # Don't add an emitter if it emits nothing
export_ctx.log('Ignoring envmap with zero strength.', 'INFO')
return

# Perform environment map check at the start
if surface_node.type in ['BACKGROUND', 'EMISSION']:
if surface_node.inputs['Strength'].is_linked:
raise NotImplementedError(
"Only default emitter strength value is supported.") # TODO: value input
strength = surface_node.inputs['Strength'].default_value

if strength == 0: # Don't add an emitter if it emits nothing
export_ctx.log('Ignoring envmap with zero strength.', 'INFO')
return
socket = surface_node.inputs["Color"]
if socket.is_linked:
color_node = socket.links[0].from_node
if color_node.type == 'TEX_ENVIRONMENT':
params.update({
'type': 'envmap',
'filename': export_ctx.export_texture(color_node.image),
'scale': strength
})
coordinate_mat = Matrix(((0,0,1,0),(1,0,0,0),(0,1,0,0),(0,0,0,1)))
to_world = Matrix()#4x4 Identity
if color_node.inputs["Vector"].is_linked:
vector_node = color_node.inputs["Vector"].links[0].from_node
if vector_node.type != 'MAPPING':
raise NotImplementedError("Node: %s is not supported. Only a mapping node is supported" % vector_node.bl_idname)
if not vector_node.inputs["Vector"].is_linked:
raise NotImplementedError("The node %s should be linked with a Texture coordinate node." % vector_node.bl_idname)
coord_node = vector_node.inputs["Vector"].links[0].from_node
coord_socket = vector_node.inputs["Vector"].links[0].from_socket
if coord_node.type != 'TEX_COORD':
raise NotImplementedError("Unsupported node type: %s." % coord_node.bl_idname)
if coord_socket.name != 'Generated':
raise NotImplementedError("Link should come from 'Generated'.")
#only supported node setup for transform
if vector_node.vector_type != 'TEXTURE':
raise NotImplementedError("Only 'Texture' mapping mode is supported.")
if vector_node.inputs["Location"].is_linked or vector_node.inputs["Rotation"].is_linked or vector_node.inputs["Scale"].is_linked:
raise NotImplementedError("Transfrom inputs shouldn't be linked.")

rotation = vector_node.inputs["Rotation"].default_value.to_matrix()
scale = vector_node.inputs["Scale"].default_value
location = vector_node.inputs["Location"].default_value
for i in range(3):
for j in range(3):
to_world[i][j] = rotation[i][j]
to_world[i][i] *= scale[i]
to_world[i][3] = location[i]
to_world = to_world
#TODO: support other types of mappings (vector, point...)
#change default position, apply transform and change coordinates
params['to_world'] = export_ctx.transform_matrix(to_world @ coordinate_mat)
elif color_node.type == 'RGB':
color = color_node.color
else:
raise NotImplementedError("Node type %s is not supported. Consider using an environment texture or RGB node instead." % color_node.bl_idname)
elif surface_node.type == 'TEX_ENVIRONMENT':
# Set to current node in next step we will get texEnvironment
socket = output_node.inputs["Surface"]
else:
raise NotImplementedError(
"Only Background and Emission nodes are supported as final nodes for World export, got '%s'" % surface_node.name)

if socket.is_linked:
color_node = socket.links[0].from_node
if color_node.type == 'TEX_ENVIRONMENT':
envmap = {
'type': 'envmap',
'filename': export_ctx.export_texture(color_node.image),
}
# The default background texture does not require emitter strength
if surface_node.type != 'TEX_ENVIRONMENT':
envmap['scale'] = strength
params.update(envmap)
coordinate_mat = Matrix(((0,0,1,0),(1,0,0,0),(0,1,0,0),(0,0,0,1)))
to_world = Matrix()#4x4 Identity
if color_node.inputs["Vector"].is_linked:
vector_node = color_node.inputs["Vector"].links[0].from_node
if vector_node.type != 'MAPPING':
raise NotImplementedError("Node: %s is not supported. Only a mapping node is supported" % vector_node.bl_idname)
if not vector_node.inputs["Vector"].is_linked:
raise NotImplementedError("The node %s should be linked with a Texture coordinate node." % vector_node.bl_idname)
coord_node = vector_node.inputs["Vector"].links[0].from_node
coord_socket = vector_node.inputs["Vector"].links[0].from_socket
if coord_node.type != 'TEX_COORD':
raise NotImplementedError("Unsupported node type: %s." % coord_node.bl_idname)
if coord_socket.name != 'Generated':
raise NotImplementedError("Link should come from 'Generated'.")
#only supported node setup for transform
if vector_node.vector_type != 'TEXTURE':
raise NotImplementedError("Only 'Texture' mapping mode is supported.")
if vector_node.inputs["Location"].is_linked or vector_node.inputs["Rotation"].is_linked or vector_node.inputs["Scale"].is_linked:
raise NotImplementedError("Transfrom inputs shouldn't be linked.")

rotation = vector_node.inputs["Rotation"].default_value.to_matrix()
scale = vector_node.inputs["Scale"].default_value
location = vector_node.inputs["Location"].default_value
for i in range(3):
for j in range(3):
to_world[i][j] = rotation[i][j]
to_world[i][i] *= scale[i]
to_world[i][3] = location[i]
to_world = to_world
#TODO: support other types of mappings (vector, point...)
#change default position, apply transform and change coordinates
params['to_world'] = export_ctx.transform_matrix(to_world @ coordinate_mat)
elif color_node.type == 'RGB':
color = color_node.color
else:
color = socket.default_value
if 'type' not in params: # Not an envmap
radiance = [x * strength for x in color[:3]]
if ignore_background and radiance == [0.05087608844041824]*3:
export_ctx.log("Ignoring Blender's default background...", 'INFO')
return
if np.sum(radiance) == 0:
export_ctx.log("Ignoring background emitter with zero emission.", 'INFO')
return
params.update({
'type': 'constant',
'radiance': export_ctx.spectrum(radiance)
})
raise NotImplementedError("Node type %s is not supported. Consider using an environment texture or RGB node instead." % color_node.bl_idname)
else:
raise NotImplementedError("Only Background and Emission nodes are supported as final nodes for World export, got '%s'" % surface_node.name)
color = socket.default_value
if 'type' not in params: # Not an envmap
radiance = [x * strength for x in color[:3]]
if ignore_background and radiance == [0.05087608844041824]*3:
export_ctx.log("Ignoring Blender's default background...", 'INFO')
return
if np.sum(radiance) == 0:
export_ctx.log("Ignoring background emitter with zero emission.", 'INFO')
return
params.update({
'type': 'constant',
'radiance': export_ctx.spectrum(radiance)
})
else:
# Single color field for emission, no nodes
params.update({
Expand Down

0 comments on commit f2f5c38

Please sign in to comment.