Fixed vehicle rendering
This commit is contained in:
@@ -275,14 +275,17 @@ for m in used_mats:
|
||||
print("gen_vehicle: unpacked texture '%s' -> %s" %
|
||||
(img.name, tex_name))
|
||||
|
||||
# --- merged single material + ID map (CAR_MODELING.md) ---
|
||||
# Every mesh part is re-materialized onto a single material named
|
||||
# <base> so blender2ogre emits ONE submesh per part, and the exporter's
|
||||
# fixed-function .material is replaced with the VehicleIdMap shader
|
||||
# materials after the export. The ID map texture shares the color
|
||||
# atlas UV space (all parts MUST use that one UV space with no texel
|
||||
# shared between materials; fix the blend if not) and marks each
|
||||
# fragment: red = paint (atlas color), green = bloom (lights),
|
||||
# --- merged paint material + separate glass material (CAR_MODELING.md) ---
|
||||
# Every mesh part is re-materialized onto TWO materials: <base> for
|
||||
# paint/bloom faces and <base>-glass for glass faces, so blender2ogre
|
||||
# emits one submesh per part (glass-less parts) or two (glass last).
|
||||
# A single merged transparent submesh forced the WHOLE part (interior
|
||||
# included) into the transparent render queue, where the depth-writing
|
||||
# window glass culled interior parts that sorted behind it ("holes" in
|
||||
# the cabin with the road showing through). The ID map texture shares
|
||||
# the color atlas UV space (all parts MUST use that one UV space with
|
||||
# no texel shared between materials; fix the blend if not) and marks
|
||||
# each fragment: red = paint (atlas color), green = bloom (lights),
|
||||
# blue = glass.
|
||||
IDMAP_SIZE = 512
|
||||
|
||||
@@ -367,10 +370,10 @@ def bake_idmap(mesh_datas, path):
|
||||
|
||||
|
||||
def move_glass_faces_last():
|
||||
"""Re-order each mesh so glass faces export last: with the merged
|
||||
transparent material (depth_write on) the cabin stays visible
|
||||
through the windows only if glass triangles draw after the
|
||||
interior."""
|
||||
"""Re-order each mesh so glass faces export last. With glass on
|
||||
its own material slot (see the consolidation below) blender2ogre
|
||||
groups faces into submeshes by material anyway; the sort just
|
||||
keeps the glass submesh's triangles contiguous at the end."""
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type != 'MESH':
|
||||
continue
|
||||
@@ -410,13 +413,35 @@ for obj in bpy.data.objects:
|
||||
move_glass_faces_last()
|
||||
bake_idmap(all_mesh_datas, os.path.join(outdir, base + "-idmap.png"))
|
||||
|
||||
merged_mat = bpy.data.materials.new(base)
|
||||
merged_mat = bpy.data.materials.get(base)
|
||||
if merged_mat is None:
|
||||
merged_mat = bpy.data.materials.new(base)
|
||||
merged_mat.use_nodes = True
|
||||
# The blend already HAS a "<base>-glass" material (source materials are
|
||||
# renamed to <base>-<material>); reuse it — materials.new() would
|
||||
# silently create "<base>-glass.001", and the exported submesh material
|
||||
# name must match the .material template exactly.
|
||||
glass_mat = bpy.data.materials.get(base + "-glass")
|
||||
if glass_mat is None:
|
||||
glass_mat = bpy.data.materials.new(base + "-glass")
|
||||
glass_mat.use_nodes = True
|
||||
for me in all_mesh_datas:
|
||||
# materials.clear() zeroes every polygon's material_index, so
|
||||
# classify faces against the original slots first.
|
||||
glass_face = [
|
||||
p.material_index < len(me.materials) and
|
||||
me.materials[p.material_index] is not None and
|
||||
"glass" in me.materials[p.material_index].name.lower()
|
||||
for p in me.polygons
|
||||
]
|
||||
me.materials.clear()
|
||||
me.materials.append(merged_mat)
|
||||
print("gen_vehicle: consolidated %d mesh data blocks onto material "
|
||||
"'%s'" % (len(all_mesh_datas), base))
|
||||
if any(glass_face):
|
||||
me.materials.append(glass_mat)
|
||||
for p, g in zip(me.polygons, glass_face):
|
||||
p.material_index = 1 if g else 0
|
||||
print("gen_vehicle: consolidated %d mesh data blocks onto materials "
|
||||
"'%s'/'%s-glass'" % (len(all_mesh_datas), base, base))
|
||||
|
||||
# --- JSON fragment (Ogre coordinates) ---
|
||||
smn, smx = mesh_bbox(root.data)
|
||||
@@ -664,6 +689,18 @@ bpy.ops.ogre.export(filepath=scene_file,
|
||||
IDMAP_MATERIAL_TEMPLATE = """// written by gen_vehicle.py — merged ID-map vehicle material
|
||||
// (CAR_MODELING.md). Not a blender2ogre product; hand edits are
|
||||
// overwritten by every export.
|
||||
//
|
||||
// Three materials per car:
|
||||
// @BASE@ paint/bloom submeshes, fully opaque.
|
||||
// @BASE@-glass near glass submesh (<10 m): alpha-blended,
|
||||
// depth_write OFF so it lands in OGRE's
|
||||
// transparent collection and can never
|
||||
// depth-block the interior/characters behind it
|
||||
// (they render first, the glass blends over).
|
||||
// @BASE@-glass-opaque far glass submesh (>=10 m): solid.
|
||||
// The demo's SedanGlassLodListener swaps only the -glass submeshes
|
||||
// between the near and far variants; paint submeshes always keep
|
||||
// @BASE@.
|
||||
material @BASE@
|
||||
{
|
||||
receive_shadows on
|
||||
@@ -672,7 +709,42 @@ material @BASE@
|
||||
pass
|
||||
{
|
||||
cull_hardware clockwise
|
||||
depth_write on
|
||||
|
||||
vertex_program_ref VehicleIdMapVP
|
||||
{
|
||||
}
|
||||
|
||||
fragment_program_ref VehicleIdMapFP
|
||||
{
|
||||
param_named glassAlpha float 1.0
|
||||
}
|
||||
|
||||
texture_unit
|
||||
{
|
||||
texture @BASE@-atlas.png
|
||||
tex_address_mode wrap
|
||||
filtering linear linear none
|
||||
}
|
||||
|
||||
texture_unit
|
||||
{
|
||||
texture @BASE@-idmap.png
|
||||
tex_address_mode clamp
|
||||
filtering point point none
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
material @BASE@-glass
|
||||
{
|
||||
receive_shadows on
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
cull_hardware clockwise
|
||||
depth_write off
|
||||
scene_blend alpha_blend
|
||||
|
||||
vertex_program_ref VehicleIdMapVP
|
||||
@@ -701,7 +773,7 @@ material @BASE@
|
||||
}
|
||||
}
|
||||
|
||||
material @BASE@-opaque
|
||||
material @BASE@-glass-opaque
|
||||
{
|
||||
receive_shadows on
|
||||
technique
|
||||
@@ -742,8 +814,11 @@ with open(mat_path, "w") as f:
|
||||
f.write(IDMAP_MATERIAL_TEMPLATE.replace("@BASE@", base))
|
||||
print("gen_vehicle: wrote merged material %s" % mat_path)
|
||||
|
||||
# Drop the stale split-material files from pre-ID-map exports so the
|
||||
# resource dir does not accumulate them.
|
||||
# blender2ogre also writes a fixed-function <base>-glass.material for
|
||||
# the glass material slot; drop it (and the stale pre-ID-map split
|
||||
# files) — the template above defines every <base>* material and a
|
||||
# duplicate definition from another script would shadow it depending
|
||||
# on resource parse order.
|
||||
for suffix in ("-color", "-color-bloom", "-glass"):
|
||||
stale = os.path.join(outdir, base + suffix + ".material")
|
||||
if os.path.exists(stale):
|
||||
|
||||
Reference in New Issue
Block a user