文章目录
一、问题描述
今天UI输出了个3D模型给我,
然后我导入到Blender的时候出错,如下所示:
- 选择导入-> Wavefront(.obj) 去导入obj格式的3D模型
- 选择对应的obj文件,然后点击【导入OBj】按钮
- 好嘛,直接报错,如下所示:
- 错误一闪而过,不慌,错误窗口消失之后,点击下面这个X按钮,即可查看详情
- 查看详情,看起来像是加载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,not2
二、分析问题
2.1 查看material材质的mtl文件
打开
rabbit.mtl
查看内容如下所示,从第一行注释我们可以看出来是由
Cinema 4D
制作的3D模型
#WaveFront *.mtl file(generated by Cinema 4D)
newmtl AnimalFace_Rabbit
Ka 000
map_Ka -o 0.0001.000 AnimalFace_Rabbit_Albedo.png
Kd 0.800000011920930.800000011920930.80000001192093
map_Kd -o 0.0001.000 AnimalFace_Rabbit_Albedo.png
Ke 000
map_Ke -o 0.0001.000 AnimalFace_Rabbit_Albedo.png
Ks 0.250.250.25
Ns 40
illum 7
norm -o 0.0001.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.0000001.0000001.000000
Kd 0.8000000.8000000.800000
Ks 0.5000000.5000000.500000
Ke 0.00.00.0
Ni 1.450000
d 1.000000
illum 2
map_Kd diffuse.jpg
map_Bump normal.png
map_Ks specular.jpg
mtl 文件结构说明:
newmtl xxx
表示定义一个名为xxx
的材质;如我们代码使用了Scene_-_Root
这个材质Ns
表示材质的反射指数,反射指数越高则高光越密集,取值范围在一般为 [0,1000];Ni
表示材质的折射值(折射率),定义当前材料中的光密度(也称为折射率)。值的范围可以从0.001 到 10
。值1.0
表示光在穿过对象时不会弯曲。玻璃的折射率为 1.5 ;d
表示指定溶解因子(dissolve
),即这种材料溶解到背景中的程度。 1.0 的因子是完全不透明的。 0.0 的因子是完全透明的。Tr
表示材质的透明度(与d
的取值相反),默认值为0.0(完全不透明);Tf
表示材质的滤光折射率,三维向量表示;illum
表示材质的光照模型;使用数值指定照明模型。有关 illum 关键字的更多详细信息,请参见下面的注释。值 0 表示最简单的照明模型,依赖于由 map_Kd 语句中指定的纹理贴图修改的材质的 Kd(如果存在)。该资源的编译器认为照明模型的选择与 3D 打印用途无关,并且在某些软件应用程序导入时会被忽略。例如,threejs Javascript 库中的 MTL Loader似乎忽略了 illum 语句。Ka
表示材质的环境光(Ambient Color)
(r,g,b);以说明整个场景中分散的光(有关phong反射模型的Wikipedia条目),使用RGB组件的0到1之间的值。Kd
表示材质的散射光(Diffuse Color)
(r,g,b);它通常将大部分颜色贡献给对象参见 [Wikipedia entry for Diffuse Reflection]。在此示例中,Kd 表示灰色,它将被 map_Kd 语句中指定的彩色纹理贴图修改Ks
表示材质的镜面光(Apecular Color)
(r,g,b);表面闪亮且镜面状的颜色[有关镜面反射的Wikipedia条目]。Ke
表示材质的发射光,它与环境光,散射光和镜面光并存,代表材质发出的光量;map_Ka
表示为材质的环境反射指定纹理文件(纹理采样值与环境光相乘作为输出颜色的一部分加权);map_Kd
表示为材质的漫反射指定纹理文件;map_Ke
表示为材质的发射光指定纹理文件;map_d
表示为材质的透明度指定纹理文件;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![在这里插入图片描述](https://img-blog.csdnimg.cn/5a22e65188b9481480ec68035ce87457.png)```#someimplementations use 'map_bump'instead of 'bump'belowmap_bump lemur_bump.tga#bumpmap(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_RabbitKa 000map_Ka -o 0.0001.000 AnimalFace_Rabbit_Albedo.pngKd 0.800000011920930.800000011920930.80000001192093map_Kd -o 0.0001.000 AnimalFace_Rabbit_Albedo.pngKe 000map_Ke -o 0.0001.000 AnimalFace_Rabbit_Albedo.pngKs 0.250.250.25Ns 40illum 7map_Bump -o 0.0001.000 AnimalFace_Rabbit_Normal.png
改完之后重新让
Blender
导入,还是有问题
2.3.2 map_Ka、map_Kd 、map_Ks、map_Bump 的格式不对
2.3.2.1 正确语法
- https://en.wikipedia.org/wiki/Wavefront_.obj_file![在这里插入图片描述](https://img-blog.csdnimg.cn/65119bc0331f4648a07117b193810d30.png)
- MTL material format (Lightwave, OBJ)
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.2000.0000.000 logo.mpc
map_Kd -o 0.2000.0000.000 logo.mpc
map_Ks -o 0.2000.0000.000 logo.mpc
2.3.2.2 修改代码
参考上面的语法说明,要么删除冗余参数,要么填写3个参数,
这里我们简单的标记的代码不需要,删了,如下所示:
修改之后代码如下:
#WaveFront *.mtl file(generated by Cinema 4D)
newmtl AnimalFace_Rabbit
Ka 000
map_Ka AnimalFace_Rabbit_Albedo.png
Kd 0.800000011920930.800000011920930.80000001192093
map_Kd AnimalFace_Rabbit_Albedo.png
Ke 000
map_Ke AnimalFace_Rabbit_Albedo.png
Ks 0.250.250.25
Ns 40
illum 7
map_Bump AnimalFace_Rabbit_Normal.png
改完之后重新让
Blender
导入,至于可以导入了,如下所示:
2.5 重新导出obj格式和mtl文件
发现
Cinema 4D
生成的
obj
格式和
mtl
文件有问题,虽然改为之后可以导入到
Blender
中,但是感觉怪怪的,那么我就重新导出
Blender
生成的
obj
格式和
mtl
文件。
- 选择导出-> Wavefront(.obj) 去导入obj格式的3D模型
- 选择保存的目录和自定义保存的模型名称
- 点击【导出OBJ】,这样就导出来了
- 对比两个目录 对比
mtl
文件发现,Blender
重新导出的格式看着排版舒服多了obj
文件也重新输出,对比如下: - 复制纹理图片 先将两个遗漏的纹理图片复制到新目录 复制完后,只有obj和mtl文件不一样
- 修改
mtl
文件 我们发现重新导出的mtl
文件,还引用的老目录的那两个纹理图片,而且路径还是绝对路径,这得修改,因为我们最终是要将这个obj
模型渲染到手机上。
修改完后代码如下:
#Blender MTL File:'None'#Material Count:1
newmtl AnimalFace_Rabbit.004
Ns 39.999995
Ka 1.0000001.0000001.000000
Kd 0.8000000.8000000.800000
Ks 0.2500000.2500000.250000
Ke 0.0000000.0000000.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模型。
- Wavefront .obj file
- MTL material format (Lightwave, OBJ)
版权归原作者 字节卷动 所有, 如有侵权,请联系我们删除。