植物百科网
当前位置: 首页 农业百科

怎么看出图纸是交点法还是线元法(着色原理面法线)

时间:2023-05-24 作者: 小编 阅读量: 5 栏目名: 农业百科

法线在着色中起着核心作用。我们将在稍后解释这一现象的原因。另一种说法是,物体表面任何给定点的亮度取决于此处法线与光线方向之间的角度。此问题解决方案的复杂性因几何类型而异。与三角面垂直的矢量很容易通过三角面的两边叉积得到。三角网格的法线也可以在三角形的顶点上定义,在这种情况下,我们称之为顶点法线。如果两个矢量垂直,则结果为0。

法线(Normal)在着色(Shading)中起着核心作用。在本文中我们将介绍法线的基本概念,了解面法线和顶点法线的不同作用,并学习基于面法线和顶点法线的不同着色技术。

每个人都知道,如果我们将物体指向光源,物体就会变得更亮。物体表面的方向在它反射的光量(因此它看起来像多亮)中起着重要的作用。此方向可由物体表面任意一点P的法线N(Normal)表示:

请注意上图 中,当光线方向和法线方向之间的角度增加时,球体的亮度是如何降低的。我们将在稍后解释这一现象的原因。现在只需要记住:

  • 我们所说的法线(我们用大写字母表示)N是垂直于点P处表面切线的向量。换句话说,要计算P点的法线,我们需要在P点画出切线,然后找到垂直于切线的适量。
  • 物体表面一个点的亮度取决于该点处的表面法线与光线方向的关系。另一种说法是,物体表面任何给定点的亮度取决于此处法线与光线方向之间的角度。

现在的问题是,我们如何计算这个法线?此问题解决方案的复杂性因几何类型而异。球体的法线通常很容易找到。如果我们知道球体表面点的位置和球体中心的位置,则此处的法线可以通过如下简单代码得到:

Vec3f N = P - sphereCenter;

如果对象是Mesh网格,则每个三角形定义了一个面,垂直于这个面的向量就是三角面上的任何一个点的法线。与三角面垂直的矢量很容易通过三角面的两边叉积得到。请记住,v1 * v2 = -v2 * v1。因此,边的选择将影响法线方向。如果你按逆时针顺序声明三角形顶点,则可以使用以下代码:

Vec3f N = (v1-v0).crossProduct(v2-v0);

如果三角形位于 xz 平面中,则法线应为 (0,1,0),而不是(0,-1,0):

a上面给出的计算法线的方法就得到 面法线,因为在整个平面上法线都是相同的,无论你选择哪一点。三角网格的法线也可以在三角形的顶点上定义,在这种情况下,我们称之为 顶点法线 。顶点法线用于一种被称为平滑着色(Smooth Shading)的技术,我们将在后面部分介绍。现在,让我们聚焦于面法线。

在程序中如何以及何时计算表面需要着色的点的法线并不重要。重要的是,当你即将对点进行着色时,手头有这些信息。在本节的几个程序中,我们进行了一些基本的着色,我们在每一个几何类中都实现了一个特别的方法 getSurfaceProperties() 来计算交叉点的法线和其他变量(如纹理坐标),我们将在此课程的稍后部分讨论这些变量。以下是球体和三角网格的 getSurfaceProperties() 的实现代码:

class Sphere : public Object {... public:...void getSurfaceProperties(const Vec3f &hitPoint,const Vec3f &viewDirection,const uint32_t &triIndex,const Vec2f &uv,Vec3f &hitNormal,Vec2f &hitTextureCoordinates) const{hitNormal= Phit - center;hitNormal.normalize();...}... };class TriangleMesh : public Object {... public:void getSurfaceProperties(const Vec3f &hitPoint,const Vec3f &viewDirection,const uint32_t &triIndex,const Vec2f &uv,Vec3f &hitNormal,Vec2f &hitTextureCoordinates) const{// face normalconst Vec3f &v0 = P[trisIndex[triIndex * 3]];const Vec3f &v1 = P[trisIndex[triIndex * 31]];const Vec3f &v2 = P[trisIndex[triIndex * 32]];hitNormal = (v1 - v0).crossProduct(v2 - v0);hitNormal.normalize();...}... };

简单着色效果:面比率/Facing Ratio

现在,我们知道如何计算物体表面一个点的法线,已经有足够的信息来创建一个简单的着色效果,面比率 ,即 Facing Ratio。此技术计算待着色点的法线和查看方向的点积。计算查看方向也非常简单。当使用射线跟踪(Ray Tracing)方法时,查看方向就是与表面P点相交的光线的相反方向,在不使用射线跟踪时,还可以通过从表面上的点P跟踪到眼睛E的线来找到查看方向:

Vec3f V = (E - P).normalize(); // or -ray.dir if you use ray-tracing

请记住,如果两个向量平行并指向同一方向,则其点积返回 1,当两个向量相互垂直时则点积返回 0。如果向量指向相反的方向,则点积为负值,但如果我们使用此时的点积结果,颜色值就是负的,这时我们需要将结果压缩为 0:

float facingRatio = std::max(0, N.dotProduct(V));

当法线和矢量V指向同一方向时,点积返回1。如果两个矢量垂直,则结果为 0。如果我们使用这种简单的技术来着色框架中心的球体,那么球体的中心将是白色的,当远离中心时,球体会变暗,如下图所示:

Vec3f castRay(const Vec3f &orig, const Vec3f &dir,const std::vector<std::unique_ptr<Object>> &objects,const Options &options) {Vec3f hitColor = options.backgroundColor;float tnear = kInfinity;Vec2f uv;uint32_t index = 0;Object *hitObject = nullptr;if (trace(orig, dir, objects, tnear, index, uv, &hitObject)) {Vec3f hitPoint = origdir * tnear; // shaded pointVec3f hitNormal;Vec2f hitTexCoordinates;// compute the normal of the point of we want to shadehitObject->getSurfaceProperties(hitPoint, dir, index, uv, hitNormal, ...);hitColor = std::max(0.f, hitNormal.dotProduct(-dir)); // facing ratio}return hitColor; }

恭喜!你刚刚了解了第一种着色技术。现在让我们来了解一个更逼真的着色方法,它将模拟光对漫射物体的影响。但在了解这种方法之前,我们首先需要介绍和学习光的概念。

平面着色 vs. 平滑着色

三角面网格的问题在于它们不能表示完全光滑的表面(除非三角面非常小)。如果我们想要将刚才描述的Facing Ratio技术应用于多边形网格,我们需要计算射线相交的三角形的法线,并计算面法线和查看方向的点积。此方法的问题在于,它使对象具有以下图像中所示的面片化外观,这就是该方法被称为 平面着色(Flat Shading)的原因。

如前几次所述,只需计算矢量 v0v1 和矢量 v0v2 的叉积,即可找到三角面的法线,其中 v0、v1 和 v2 表示三角形的顶点。为了解决这个问题,Henri Gouraud在1971年引进了被称为 平滑着色 (Smooth Shading)的方法。此技术背后的理念是在多边形网格的表面产生连续阴影,尽管网格所代表的对象并不是连续的,因为它是从平面(多边形或三角形)集合中构建的。为此,Gouraud引入了顶点法线的概念。思路很简单,我们不计算或存储三角面的法线,而是为网格的每个顶点存储一个法线,法线的方向由三角网格的基础平滑表面决定。当我们想要计算三角面上一个点的颜色时不使用面法线,而是通过线性插值三角形的顶点法线性地插值,使用点的重心坐标来计算"伪平滑"法线值。该技术如下图所示:

顶点法线在三角形顶点上定义。你可以看到,它们是垂直于三角面网格对应的原始光滑底层表面。有时三角形网格不是从光滑的表面直接转换来的,那么顶点法线必须实时计算。当没有平滑的表面时,存在多种计算顶点法线的技术,但我们不会在本文中研究这一点。现在你可以使用Maya或Blender等软件为你完成此工作(在Maya中,你可以选择多边形网格,并在"Normals"菜单中选择"Soften Edges"选项)。

事实上,从实用和技术的角度来看,每个三角形都有3个顶点法线。这意味着三角网的顶点法线总数实际上等于三角形的数量乘以 3。在某些情况下,2个或更多三角形共享的顶点上定义的顶点法线相同(指向同一方向),但可以通过设置其指向不同的方向来实现不同的效果(例如,你可以构造表面的伪硬边)。

只要我们知道三角形的顶点法线,三角形上的某个点的重心坐标以及三角形索引,那么插值计算三角形表面任何点的法线就很简单。无论是栅格化还是射线追踪都可以提供这些信息。顶点法线由 3D建模 程序生成,然后,它们被导出到几何文件中,其中包含了三角形连接信息、顶点位置和三角形纹理坐标。我们需要做的就是结合点的重心坐标和三角形顶点法线计算这个点的法线(下面的17-20行):

void getSurfaceProperties(const Vec3f &hitPoint,const Vec3f &viewDirection,const uint32_t &triIndex,const Vec2f &uv,Vec3f &hitNormal,Vec2f &hitTextureCoordinates) const {// face normalconst Vec3f &v0 = P[trisIndex[triIndex * 3]];const Vec3f &v1 = P[trisIndex[triIndex * 31]];const Vec3f &v2 = P[trisIndex[triIndex * 32]];hitNormal = (v1 - v0).crossProduct(v2 - v0);#if 1// compute "smooth" normal using Gouraud's technique (interpolate vertex normals)const Vec3f &n0 = N[trisIndex[triIndex * 3]];const Vec3f &n1 = N[trisIndex[triIndex * 31]];const Vec3f &n2 = N[trisIndex[triIndex * 32]];hitNormal = (1 - uv.x - uv.y) * n0uv.x * n1uv.y * n2; #endif// doesn't need to be normalized as the N's are normalized but just for safetyhitNormal.normalize();// texture coordinatesconst Vec2f &st0 = texCoordinates[trisIndex[triIndex * 3]];const Vec2f &st1 = texCoordinates[trisIndex[triIndex * 31]];const Vec2f &st2 = texCoordinates[trisIndex[triIndex * 32]];hitTextureCoordinates = (1 - uv.x - uv.y) * st0uv.x * st1uv.y * st2; }

请注意,这只是看起来表面光滑。如果你看看下面图像中的多边形球体,仍然可以看到面片的轮廓,即使表面看起来光滑。该技术的确改善了三角网状的外观,但不能完全解决面片化问题。解决这个问题的唯一办法是使用 细分表面(subdivision surface),我们将在另一篇文章中讨论这一技术。此外,将光滑表面转换为三角网状时增加使用的三角形数量当然也可以使这一问题得到改善。


原文链接:http://www.bimant.com/blog/shading-normals/

    推荐阅读
  • 荣耀战魂steam启动游戏提示激活怎么办(steam买的荣耀战魂怎么激活)

    荣耀战魂目前在UBISOFT和steam上面都可以玩,而很多玩家在UBISOFT里面下载了游戏,然后在steam里面添加该游戏,却发现启动不了提示需要激活金钥。steam启动UBI客户端游戏提示激活解决教程:关闭uplay然后不开的情况下用steam启动游戏,uplay会自动同步云,然后就好了。或者管理员模式运行steam,然后不要用管理员模式运行游戏就可以了。

  • 麻辣小龙虾要准备些什么(别再一个一个刷小龙虾了)

    麻辣小龙虾要准备些什么?麻辣小龙虾要准备些什么已经立夏,也就是说马上要进入夏天了,请随时准备好迎接高温的天气吧,虽然不喜欢夏天的烈日,但是对于吃货来说,夏天的美食却是非常多的,特别是小龙虾在今年上市更早一些,可是外边夜市摊上的小龙虾大家都觉得不太干净,更喜欢自己在家中吃,但是自己在洗小龙虾的时候,相信很多人都会拿着一个小刷子,一个一个去刷洗小龙虾,其实学夜市摊老板这样做,洗得又快又干净!

  • 2022年退休人员养老金有什么变化(1954年出生的退休人员)

    从女性的年龄来计算,50岁退休的主要是生产一线的职工,大部分人从事的是体力劳动,按照计发月数195个月来计算,计算出来的平均年龄是66.25岁左右,这和从事体力劳动的平均年龄是基本吻合的;55岁退休的主要是干部和管理技术人员,个人账户养老金计发月数是170个月,也就是14.16年,这样计算的平均年龄是69.16岁。

  • 儿童孤独症的预防与矫治(6岁儿童孤独症筛查干预服务规范)

    下面更多详细答案一起来看看吧!儿童孤独症的预防与矫治来源:孤独症儿童很少主动与他人对视,不爱与外界接触犹如天上星星,一人一世界因此,他们也被称作来自“星星的孩子”

  • 论文选题可以从以下几个方面入手(论文选题一般都分为哪几种类型)

    通常,它是预先详细规定的,并由高级研究人员应用和组织。这种类型的主题选择通常相对“小”,资金较少。需要强调的一点是,主题选择“小”是相对于多级主题系统而言的,这通常意味着主题选择范围是单一的,并且论文可以是单篇论文。但是,这并不意味着研究的价值很小。

  • 怎样禁止小孩浏览不明网站(违反道德内容引民众反对)

    怎样禁止小孩浏览不明网站近日,美国《纽约时报》等多家媒体报道称,全球最大的色情网站“Pornhub”一直存在上传非法或严重违反道德的视频内容。上周,《纽约时报》的一篇评论文章再次批评Pornhub仍含有大量强暴、偷拍、种族主义、虐待等内容的视频。文章刊登后不久,支付渠道服务商万事达和维萨宣布暂停为Pornhub提供服务。面对谴责之声,Pornhub近日回应称,网站将组建专业审查团队对违法内容进行打击。

  • 劣质纸尿裤排名(全国纸尿裤抽检报告)

    抽检结果显示,当前市面上的纸尿裤渗透性能总体合格率非常高。结果显示,受检样品均未检出。纸尿裤接触的是人体的私密部位,一旦卫生标准不合格,则容易感染皮肤,引发炎症。此外,还有2款产品检出pH值不合格。pH值是考核纸尿裤亲肤程度的重要指标。使用pH值不达标的纸尿裤产品,可能破坏肌肤表层的皮脂膜,引起肌肤不适,甚至导致细菌入侵。

  • 培训心态决定一切(是每个培训师的必修课)

    由此可见,闭关是一个人走向卓越的必经之路。根据闭关的任务,选择不同的地点,更加有益于闭关任务的达成。每年可以去照一些商务照,让自己保持一个全新的一个形象。有的培训师相片已经有多年没有更新了,定期去拍一组商务照,及时更新自己。

  • 烤蘑菇方法(这样烤的蘑菇香软可口)

    蘑菇去根,洗干净备用烤盘铺上油纸,把蘑菇放在上面,每只上面都撒上一点盐,接下来我们就来聊聊关于烤蘑菇方法?以下内容大家不妨参考一二希望能帮到您!烤蘑菇方法蘑菇去根,洗干净备用。烤箱预热,放入蘑菇180度上下火烤15分钟。把蘑菇装盘就可以食用,记得要小心一点拿,尽量不要浪费了里面的汁,非常鲜美

  • 菜籽油适合儿童吃吗(但最好别给孩子吃)

    天然存在于牛羊等的脂肪组织和相关乳制品中的反式脂肪酸,一般不用担心,主要担心的是人造的,以及植物油遇到高温时发生反应所产生的反式脂肪酸。相比动物油来说,植物油会更健康。开始添加油后,首选富含富含α-亚麻酸的核桃油、亚麻籽油这类的植物油。