我的渲染技术进阶之旅解决Cinema 4D制作的3D模型无法导入Blender的问题
Posted 字节卷动
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我的渲染技术进阶之旅解决Cinema 4D制作的3D模型无法导入Blender的问题相关的知识,希望对你有一定的参考价值。
文章目录
一、问题描述
今天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, 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 文件结构说明:
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
# 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
文件。
-
选择导出-> 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.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模型。
以上是关于我的渲染技术进阶之旅解决Cinema 4D制作的3D模型无法导入Blender的问题的主要内容,如果未能解决你的问题,请参考以下文章
我的渲染技术进阶之旅OpenGL ES 使用表面剔除和深度测试解决渲染3D模型的时候,出现背面黑点的问题
我的渲染技术进阶之旅OpenGL ES 使用表面剔除和深度测试解决渲染3D模型的时候,出现背面黑点的问题