虽然读取了3ds文件,但是3ds文件里并不包含顶点法线。为了计算光照,我们需要手工计算法线。过程如下:

三个不共线点构成一个三角形:

计算方法:向量ab与向量ac的叉乘得到过点a垂直于三角形abc所在平面的一条直线,这条垂线就是顶点a的法线。

下面就是代码:【修正了法线计算bug,2012.04.04】

 1 void CModel3ds::CalcNormals() 2 { 3     for(int i = 0; i<m_PolygonNum; ++i) 4     { 5         Vector3 v1 = Vector3_Sub(Vector3(m_pVBbuff[m_pIBbuff[i].p1].X, m_pVBbuff[m_pIBbuff[i].p1].Y, m_pVBbuff[m_pIBbuff[i].p1].Z), 6             Vector3(m_pVBbuff[m_pIBbuff[i].p2].X, m_pVBbuff[m_pIBbuff[i].p2].Y, m_pVBbuff[m_pIBbuff[i].p2].Z)); 7         Vector3 v2 = Vector3_Sub(Vector3(m_pVBbuff[m_pIBbuff[i].p1].X, m_pVBbuff[m_pIBbuff[i].p1].Y, m_pVBbuff[m_pIBbuff[i].p1].Z), 8             Vector3(m_pVBbuff[m_pIBbuff[i].p3].X, m_pVBbuff[m_pIBbuff[i].p3].Y, m_pVBbuff[m_pIBbuff[i].p3].Z)); 9         Vector3 tmp1 = Vector3_cross(v1,v2);10         m_pVBbuff[m_pIBbuff[i].p1].nx += tmp1.x;11         m_pVBbuff[m_pIBbuff[i].p1].ny += tmp1.y;12         m_pVBbuff[m_pIBbuff[i].p1].nz += tmp1.z;19         m_pVBbuff[m_pIBbuff[i].p2].nx += tmp1.x;20         m_pVBbuff[m_pIBbuff[i].p2].ny += tmp1.y;21         m_pVBbuff[m_pIBbuff[i].p2].nz += tmp1.z;28         m_pVBbuff[m_pIBbuff[i].p3].nx += tmp1.x;29         m_pVBbuff[m_pIBbuff[i].p3].ny += tmp1.y;30         m_pVBbuff[m_pIBbuff[i].p3].nz += tmp1.z;31     }32 33     for(int i = 0; i < m_VertexNum; ++i)34     {35         Vector3_norm(m_pVBbuff[i].nx,m_pVBbuff[i].ny,m_pVBbuff[i].nz);36     }37 }

上面这段代码简单来说就是求共顶点的三角形在其公共顶点的法线的平均值,他的结果当然不是精确的,但是大多数时候都是正常工作的:)

代码中定义的向量运算用到了我写的一个数学库中的函数,这个数学库不是为了效率,只是为了让上面的代码跟dx解耦,避免发代码还要包含一堆头文件。不然的话拷贝这段代码就很肯能因为头文件的问题导致不能编译,这又会导致一大堆麻烦事,所以下面这个库代码,仅仅就是保证正常工作(或许也有bug,但我会努力去fix和避免这种情况):

View Code

 1 #ifndef myVector_h__ 2 #define myVector_h__ 3  4 namespace MY_MATH 5 { 6     class Vector3 7     { 8     public: 9         Vector3():x(0),y(0),z(0){}10         Vector3(float _x, float _y, float _z):x(_x),y(_y),z(_z){}11         float x;12         float y;13         float z;14     };15 16     Vector3 Vector3_Sub(Vector3 src,Vector3 dest)17     {18         return Vector3(src.x - dest.x,src.y - dest.y,src.z - dest.z);19     }20 21     void Vector3_norm(float& x, float& y, float& z)22     {23         float tmp = sqrtf(x*x+y*y+z*z);24         x = x/tmp;y = y/tmp; z=z/tmp;25     }26     27     void Vector3_norm(Vector3& vec)28     {29         float tmp = sqrtf(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z);30         vec.x = vec.x/tmp;31         vec.y = vec.y/tmp;32         vec.z = vec.z/tmp;33     }34 35     Vector3 Vector3_cross(Vector3& v1, Vector3& v2)36     {37         return Vector3(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);38     }39 }40 41 42 43 #endif // myVector_h__

这个就是根据我们计算出来的法线进行基本光照渲染出来的截图,HLSL版本shader如下:

cbuffer mybuff{uniform row_major float4x4 world_matrix;uniform row_major float4x4 view_matrix;uniform row_major float4x4 proj_matrix;uniform float4 light_pos;};

struct VS_INPUT{    float4 Position : POSITION;    float3 Norm    : NORMAL0;    float2 Tex      : TEXCOORD0;};

struct VS_OUTPUT{    float4 Position : SV_POSITION;    float3 lt : TEXCOORD0;    float3 norm : TEXCOORD1;};

VS_OUTPUT VS_MAIN(VS_INPUT In){    VS_OUTPUT Output;    float4x4 tmp = mul(world_matrix,view_matrix);    tmp = mul(tmp,proj_matrix);    Output.Position = mul(In.Position, tmp);

    Output.lt = normalize(light_pos - In.Position);    Output.norm = normalize(mul(In.Norm, world_matrix));

return Output;}

float4 PS_MAIN(VS_OUTPUT In) : SV_Target{    float4 diff = {1.0,1.0,1.0,1.0};    float4 ambient = {0.1,0.1,0.1,1.0};return ambient + diff*saturate(dot(In.lt,In.norm));}

转载于:https://www.cnblogs.com/Baesky/archive/2012/04/01/calc_normals.html

根据模型顶点坐标计算法线相关推荐

  1. 不标准椭圆顶点坐标计算

    不标准椭圆顶点的坐标是指椭圆不满足标准方程的情况下的顶点坐标. 计算不标准椭圆顶点坐标的方法是使用椭圆的一般式方程: $$\frac{(x-h)^2}{a^2} + \frac{(y-k)^2}{b^ ...

  2. C语言根据用户输入的3个顶点,【if 语句】根据用户的输入 3 个顶点坐标计算三角形的面积和周长,如果不能构成三角形提示错误....

    #include #include //输入三个点 void inputThreePoint(double *p) { \x09for(int i=0;i<6;i+=2) \x09{ \x09\ ...

  3. Unity 模型顶点法线不统一————使用Blender修改顶点法线

    遇到的问题:使用Blender创建的模型,顶点法线都是默认的,或者说顶点法线是基于自身三角形(矩形)的.这就导致同一个空间位置上的一个(在图形学引擎中被视为多个)顶点拥有若干个不同的法线向量.当你使用 ...

  4. Python模型顶点法线修复

    Python模型顶点法线修复 参考: https://zhuanlan.zhihu.com/p/52297977

  5. 五边形顶点坐标_足球顶点坐标的计算

    &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp 预备知识 解三棱锥顶角,空间旋转矩阵 图 1:足球透视图 足 ...

  6. 文本框固定任意一顶点后,拖动相对点任意旋转缩放,计算缩放后顶点坐标

    问题描述 鼠标拖动缩放文本框的时候,需要重新计算缩放后文本框四个顶点的坐标,然后重新绘制新文本框 在Office上,缩放文本框的操作一般是鼠标拖动八个控制点其中一个,然后固定住与其相对的控制点的位置, ...

  7. Unity获取模型的顶点坐标

    using UnityEngine; using System.Collections;/// <summary> /// 获取模型的所有顶点坐标 /// </summary> ...

  8. 根据凸多边形顶点坐标来计算面积算法与实现

    本文我们来介绍一下如何利用凸多边形的所有顶点的坐标来计算其面积,并使用该算法制作一个小的示例程序. 注:对于凹多边形的面积,可以将其分解为若干个凸多边形分别计算求和,关于凹多边形的分解算法请参考Box ...

  9. python计算直角三角形顶点坐标

    已知圆上三个点坐标分别为(a,b).(c,d).与(a,b)夹角是60度,求顶点坐标 import numpy as np import matplotlib.pyplot as pltdef get ...

  10. vtk中的算法举例-计算法线、法线方向

    研究使用vtk,必须要深入底层的实现方法,因为不管以后自己用来开发3D处理的框架还是用其他的cgal.pytorch3d.openmesh等框架,都需要将各种点线面的处理算法进行改造使用. inlin ...

最新文章

  1. Expression Blend 4 激活码
  2. 使用Keras进行深度学习:(二)CNN讲解及实践
  3. 快速上手RaphaelJS--RaphaelJS_Starter翻译(二)
  4. 有进步--第二周作业
  5. Opencv 学习笔记之——鼠标操作画出感兴趣区域
  6. [JLOI2015]管道连接(斯坦纳树)
  7. 论文阅读02:基于深度学习的图像细粒度分类算法
  8. 20200702:最长公共子序列(leetcode1143)
  9. NP、P、NPC、NP-hard 概念辨析
  10. 数据分析工作到底在做什么
  11. postgresql 客户端启动配置
  12. 关于mangos多线程处理方式
  13. python快速编程入门教材免费阅读,Python快速编程入门(第2版)
  14. PDF怎么编辑,如何给PDF添加书签
  15. 藏语计算机基础知识,2017年青海民族大学计算机学院738藏语与现代汉语基础考研题库...
  16. 毕业设计 : 题目:基于深度学习的水果识别 设计 开题 技术
  17. openpyxl中的load_workbook()函数
  18. 1100 Mars Numbers (20分)
  19. 还在手动部署 Kubernetes 集群吗,是时候使用 Kubespray 完成自动化部署了!
  20. 乐高大颗粒作品15:移动篮球框

热门文章

  1. 将Alfred与BetterZip整合,提高你的Mac工作效率
  2. iOS 应用的启动流程和优化详解
  3. Swift 标记 MAKE TODO FIXME
  4. 阿里云POLARDB 2.0重磅来袭!为何用户如此的期待?
  5. 一篇关于蓝牙SDP和L2CAP协议的文章
  6. RunAs 增强性扩展命令(支持自动提交密码,安全授权)
  7. BZOJ1222: [HNOI2001]产品加工(诡异背包dp)
  8. 读Zepto源码之assets模块
  9. windows 架设SVN服务器
  10. ubuntu 14.04英文环境设置成中文