【我的渲染技术进阶之旅】解决Cinema 4D制作的3D模型无法导入Blender的问题

一、问题描述

今天UI输出了个3D模型给我,
在这里插入图片描述

然后我导入到Blender的时候出错,如下所示:

  1. 选择导入-> Wavefront(.obj) 去导入obj格式的3D模型
    在这里插入图片描述
  2. 选择对应的obj文件,然后点击【导入OBj】按钮
    在这里插入图片描述
  3. 好嘛,直接报错,如下所示:
    在这里插入图片描述
  4. 错误一闪而过,不慌,错误窗口消失之后,点击下面这个X按钮,即可查看详情
    在这里插入图片描述
  5. 查看详情,看起来像是加载material材质出错了
    在这里插入图片描述
Python: Traceback (most recent call last):
  File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_obj\__init__.py", line 135, in execute
    return import_obj.load(context, **keywords)
  File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_obj\import_obj.py", line 1233, in load
    create_materials(filepath, relpath, material_libs, unique_materials,
  File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_obj\import_obj.py", line 428, in create_materials
    load_material_image(context_material, context_mat_wrap,
  File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_obj\import_obj.py", line 171, in load_material_image
    _generic_tex_set(mat_wrap.base_color_texture, image, 'UV', map_offset, map_scale)
  File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_obj\import_obj.py", line 165, in _generic_tex_set
    nodetex.translation = translation
  File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\modules\bpy_extras\node_shader_utils.py", line 20, in wrapper
    return func(self, *args, **kwargs)
  File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\modules\bpy_extras\node_shader_utils.py", line 792, in translation_set
    self.node_mapping.inputs['Location'].default_value = translation
ValueError: bpy_struct: item.attr = val: sequences of dimension 0 should contain 3 items, not 2

二、分析问题

2.1 查看material材质的mtl文件

打开rabbit.mtl查看内容如下所示,从第一行注释我们可以看出来是由Cinema 4D制作的3D模型
在这里插入图片描述

# WaveFront *.mtl file (generated by Cinema 4D)

newmtl AnimalFace_Rabbit
Ka 0 0 0
map_Ka -o 0.000 1.000 AnimalFace_Rabbit_Albedo.png
Kd 0.80000001192093 0.80000001192093 0.80000001192093
map_Kd -o 0.000 1.000 AnimalFace_Rabbit_Albedo.png
Ke 0 0 0
map_Ke -o 0.000 1.000 AnimalFace_Rabbit_Albedo.png
Ks 0.25 0.25 0.25
Ns 40
illum 7
norm -o 0.000 1.000 AnimalFace_Rabbit_Normal.png

2.2 mtl文件介绍

在我的博客 【我的OpenGL学习进阶之旅】关于3D模型知识之:什么是obj文件和mtl文件 里面有介绍了mtl文件的格式,这里重新介绍一下:


# Blender MTL File: 'None'
# Material Count: 1

newmtl Scene_-_Root
Ns 225.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.0 0.0 0.0
Ni 1.450000
d 1.000000
illum 2
map_Kd diffuse.jpg
map_Bump normal.png
map_Ks specular.jpg

mtl 文件结构说明:

  1. newmtl xxx表示定义一个名为 xxx 的材质;如我们代码使用了Scene_-_Root这个材质
  2. Ns 表示材质的反射指数,反射指数越高则高光越密集,取值范围在一般为 [0,1000];
  3. Ni 表示材质的折射值(折射率),定义当前材料中的光密度(也称为折射率)。值的范围可以从 0.001 到 10。值 1.0 表示光在穿过对象时不会弯曲。玻璃的折射率为 1.5 ;
  4. d 表示指定溶解因子(dissolve),即这种材料溶解到背景中的程度。 1.0 的因子是完全不透明的。 0.0 的因子是完全透明的。
  5. Tr 表示材质的透明度(与 d 的取值相反),默认值为0.0(完全不透明);
  6. Tf 表示材质的滤光折射率,三维向量表示;
  7. illum 表示材质的光照模型;使用数值指定照明模型。有关 illum 关键字的更多详细信息,请参见下面的注释。值 0 表示最简单的照明模型,依赖于由 map_Kd 语句中指定的纹理贴图修改的材质的 Kd(如果存在)。该资源的编译器认为照明模型的选择与 3D 打印用途无关,并且在某些软件应用程序导入时会被忽略。例如,threejs Javascript 库中的 MTL Loader似乎忽略了 illum 语句。
  8. Ka 表示材质的环境光(Ambient Color)(r,g,b);以说明整个场景中分散的光(有关phong反射模型的Wikipedia条目),使用RGB组件的0到1之间的值。
  9. Kd 表示材质的散射光(Diffuse Color)(r,g,b);它通常将大部分颜色贡献给对象参见 [Wikipedia entry for Diffuse Reflection]。在此示例中,Kd 表示灰色,它将被 map_Kd 语句中指定的彩色纹理贴图修改
  10. Ks 表示材质的镜面光(Apecular Color)(r,g,b);表面闪亮且镜面状的颜色[有关镜面反射的Wikipedia条目]
  11. Ke 表示材质的发射光,它与环境光,散射光和镜面光并存,代表材质发出的光量;
  12. map_Ka 表示为材质的环境反射指定纹理文件(纹理采样值与环境光相乘作为输出颜色的一部分加权);
  13. map_Kd 表示为材质的漫反射指定纹理文件;
  14. map_Ke 表示为材质的发射光指定纹理文件;
  15. map_d 表示为材质的透明度指定纹理文件;
  16. bump 表示指定材质的凹凸纹理文件,凹凸纹理修改表面法线,用于凹凸纹理的图像表示相对于平均表面的表面拓扑或高度(没用过)。

MTL Files Material Definitions for OBJ Files
在这里插入图片描述
在这里插入图片描述

2.3 对比mtl文件和mtl语法并修改

2.3.1 norm不对

  • 对比找出语法错误
    通过对比,我们发现有个属性似乎不是mtl的语法,即norm,如下所示:
    在这里插入图片描述

  • 正确语法
    通过对比,感觉norm应该对应的是map_Bump ,
    参考 https://en.wikipedia.org/wiki/Wavefront_.obj_file
    在这里插入图片描述

    # some implementations use 'map_bump' instead of 'bump' below
    map_bump lemur_bump.tga
    
    # bump map (which by default uses luminance channel of the image)
    bump lemur_bump.tga
    

    使用map_bump 或者bump 都可以。

  • 修改代码如下:

    在这里插入图片描述

    # WaveFront *.mtl file (generated by Cinema 4D)
    
    newmtl AnimalFace_Rabbit
    Ka 0 0 0
    map_Ka -o 0.000 1.000 AnimalFace_Rabbit_Albedo.png
    Kd 0.80000001192093 0.80000001192093 0.80000001192093
    map_Kd -o 0.000 1.000 AnimalFace_Rabbit_Albedo.png
    Ke 0 0 0
    map_Ke -o 0.000 1.000 AnimalFace_Rabbit_Albedo.png
    Ks 0.25 0.25 0.25
    Ns 40
    illum 7
    map_Bump -o 0.000 1.000 AnimalFace_Rabbit_Normal.png
    
    
    
    

改完之后重新让Blender导入,还是有问题

2.3.2 map_Ka、map_Kd 、map_Ks、map_Bump 的格式不对

2.3.2.1 正确语法

在这里插入图片描述
map_Ka,map_Kd,map_Ks语法,关于-o的参数说明如下所示:
在这里插入图片描述
在渲染期间,Ka、Kd 和 Ks 值以及 map_Ka、map_Kd 和 map_Ks 值根据以下公式混合:

 result_color=tex_color(tv)*decal(tv)+mtl_color*(1.0-decal(tv))

其中 tv 是纹理顶点

result_color” is the blended Ka, Kd, and Ks values.

“result_color”是混合的 Ka、Kd 和 Ks 值。

下面列出语句的选项。

-blendu on | off
-blendv on | off
-clamp on | off
-imfchan r | g | b | m | l | z
-mm base gain
-o u v w
-s u v w
-t u v w
-texres value

正确示例:

在这里插入图片描述

newmtl bumpy_leath
 Ka spectral ident.rfl 1
 Kd spectral ident.rfl 1
 Ks spectral ident.rfl 1
 illum 2
 map_Ka brown.mpc
 map_Kd brown.mpc
 map_Ks brown.mpc
 bump -bm 2.000 leath.mpb

在这里插入图片描述

 Ka spectral ident.rfl 1
 Kd spectral ident.rfl 1
 Ks spectral ident.rfl 1
 illum 2
 map_Ka -o 0.200 0.000 0.000 logo.mpc
 map_Kd -o 0.200 0.000 0.000 logo.mpc
 map_Ks -o 0.200 0.000 0.000 logo.mpc

2.3.2.2 修改代码

参考上面的语法说明,要么删除冗余参数,要么填写3个参数,

这里我们简单的标记的代码不需要,删了,如下所示:
在这里插入图片描述
修改之后代码如下:
在这里插入图片描述

# WaveFront *.mtl file (generated by Cinema 4D)

newmtl AnimalFace_Rabbit
Ka 0 0 0
map_Ka  AnimalFace_Rabbit_Albedo.png
Kd 0.80000001192093 0.80000001192093 0.80000001192093
map_Kd  AnimalFace_Rabbit_Albedo.png
Ke 0 0 0
map_Ke  AnimalFace_Rabbit_Albedo.png
Ks 0.25 0.25 0.25
Ns 40
illum 7
map_Bump  AnimalFace_Rabbit_Normal.png

改完之后重新让Blender导入,至于可以导入了,如下所示:
在这里插入图片描述

2.5 重新导出obj格式和mtl文件

发现Cinema 4D生成的obj格式和mtl文件有问题,虽然改为之后可以导入到Blender中,但是感觉怪怪的,那么我就重新导出Blender生成的obj格式和mtl文件。

  1. 选择导出-> Wavefront(.obj) 去导入obj格式的3D模型
    在这里插入图片描述

  2. 选择保存的目录和自定义保存的模型名称
    在这里插入图片描述

  3. 点击【导出OBJ】,这样就导出来了
    在这里插入图片描述

  4. 对比两个目录
    在这里插入图片描述
    对比mtl文件发现,Blender重新导出的格式看着排版舒服多了
    在这里插入图片描述
    obj文件也重新输出,对比如下:
    在这里插入图片描述

  5. 复制纹理图片
    先将两个遗漏的纹理图片复制到新目录
    在这里插入图片描述
    在这里插入图片描述
    复制完后,只有obj和mtl文件不一样
    在这里插入图片描述

  6. 修改mtl文件
    我们发现重新导出的mtl文件,还引用的老目录的那两个纹理图片,而且路径还是绝对路径,这得修改,因为我们最终是要将这个obj模型渲染到手机上。

在这里插入图片描述
修改完后代码如下:

# Blender MTL File: 'None'
# Material Count: 1

newmtl AnimalFace_Rabbit.004
Ns 39.999995
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.250000 0.250000 0.250000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Bump AnimalFace_Rabbit_Normal.png
map_Kd AnimalFace_Rabbit_Albedo.png
map_Ke AnimalFace_Rabbit_Albedo.png

在这里插入图片描述
路径是相对路径,直接指向复制过来在同一个目录下的两个纹理图片
在这里插入图片描述
7. 重新导入Blender验证

将修改后的mtl文件保存,然后重新导入obj文件,展示如下,正常
在这里插入图片描述
好吧,这样我们就保存了一份由Blender输出的3D模型。

三、总结

Cinema 4D制作的3D模型无法导入Blender的问题,这一次是因为材质.mtl文件有语法问题,通过分析解决并重新导出由Blender制作的3D模型。

猜你喜欢

转载自blog.csdn.net/qq446282412/article/details/128648249