C#软渲染中导入obj格式模型

v代表vertex顶点位置

vn代表normal法线

vt代表texture纹理索引

f代表面face 包含三组或四组数(可能更多,代表三角形面四边形面或多边形面),每组数包含三个值,第一个是顶点的索引,第二个是纹理的索引,第三个是法线的索引

obj格式还有其他的keyword,不过在我自己写的软渲染中目前只用到了这四个值。其他关键字可以参考网上博客。

首先自己在做软渲染的时候陷入了一个误区,自己设定的Vertex数据结构如下

public Vector point;
public UV uv;
public Vector normal;
public MyColor color;
public Vector WorldPos;
这个结构是没错的。当渲染一个三角形的时候传入的顶点必须包含point位置,让它经过mvp矩阵转到屏幕坐标,uv则是代表对应的纹理贴图的坐标,normal点法线,color(目前没用到) worldpos世界坐标,只经过model-to- world矩阵变换,在逐像素处理的过程中参与高光镜面反射的计算。自己 用word打开obj文件,发现信息都分开写了,不理解每一行为什么不按照Vertex的格式来写,然后读取的时候新建一个List 来保存所有信息, 这样读取还方便一些。后来更发现vn vt v的数目都不一样,不明白为什么。

后来联想到自己之前做的纹理映射,如下图,为什么错了呢,如果让2684这个面对应纹理的四个点,然后4873也对应一个面,这样最上面的面6578的两个点6 7就会出现相同的纹理,这样的话纹理显示是错误的。

C#软渲染中导入obj格式模型_第1张图片

试想当要渲染2684面的时候,第六点的法线是(0.57 0.57 -0.57) 第八点的法线是(0.57 0.57 0.57)...这样当渲染比如2684这个四边形的时候,只有这个面的中心点的法线是正确的(1 0 0)。面上的其他点都是插值得到的不正确值。

正确的做法确实是应该想obj格式写的那样。把v vn vt这些信息分开写,然后单独保存起来。当要渲染一个面drawprimitive的时候,根据面保存的索引信息,取出信息,新建vertex,然后用新建的顶点传入drawprimitive方法里。这样虽然不同面之间有共享顶点,但是还是能保证只是共享顶点的位置,法线信息UV信息会在渲染的时候重新赋值。

工程:https://github.com/BAJIAObujie/Renderer 中的OBJReader.cs,装配图元信息步骤在Device.cs中

效果图:

C#软渲染中导入obj格式模型_第2张图片

//--------------------------分割线------------------

之前看了网上挺多渲染流水线过程的文章,突然才发现虽然之前渲染出了模型,但是有一些点还是没有正确理解。这应该就是装配图元那一步吧。


你可能感兴趣的:(C#软渲染中导入obj格式模型)