Android OpenGL ES(二)----平滑着色
直线或者三角形上的每个片段混合后的颜色可以用一个varying生成。我们不仅能混合颜色,还可以给varying传递任何值,OpenGL会选择属于那条直线的两个值,或者属于那个三角形的三个值,并平滑地在那个基本图元上混合这些值,每个片段都会有一个不同的值。这种混合是使用线性插值实现的。要了解它是怎么工作的,让我们首先以一条直线为例开始讲解。
1.沿着一条直线做线性插值
假设有一条直线,它有一个红色顶点和一个绿色顶点,我们要从一个向另外一个混合颜色。
在这条直线的左边,每个片段的颜色更多地呈红色;随着向右边前进,那些片段的红色分量逐渐减少,在中间处,它们处于红色和绿色之间;随着与绿色顶点越来越近,片段也就变得越来越绿了。
我们可以看到每种颜色分量都随着直线长度线性缩放。因为这条线段的左侧顶点是红色,而右侧顶点是绿色,它的左端就是100%红色,中间是50%红色,而右端是0%的红色。
绿色的变化也是一样的。因为左侧顶点是红色,而右侧顶点是绿色的,这个线段的左端就是0%绿色,中间是50%绿色,而右端就是100%绿色。
一旦我们把这两个颜色叠加在一起,最终就得到一条混合后的直线。
这就是线性插值的基本解释。每种颜色的强度依赖于每个片段与包含那个颜色的顶点的距离。
为也计算这些,我们可以用顶点0和顶点1的值计算出当前片段对应的距离比。距离比仅仅是0到100之间的百分比,0%是左边的顶点,而100%就是右边的顶点。当我们从左向右移动,这个距离比例也会从0%向100%线性增加。这是几个距离比的例子:
要使用线性插值计算实际混合后的值,我们可以使用下面的公式:
Blended_value=(vertex_0_value*(100%-distance_radio))+(vertex_1_value*distance_radio)
这个计算公式是应用于每个分量的,因此,如果我们处理颜色值,这个计算就会分别应用在红色,绿色,蓝色和阿尔法分量上,计算的结果合并成一个新的颜色值。
让我们用这条直线的例子验证一下这个公式。设vertex_0_value为红色,它的RGB值是(1,0,0),设vertex_1_value为绿色,它的RGB值是(0,1,0)。计算一下这条线段上几个位置的颜色。
表4-1 线性插值公式
位置 |
距离比 |
公式 |
|
最左端 |
0% |
|
|
直线的四分之一处 |
25% |
(vertex_0_value*(1-distance_radio))+(vertex_1_value*distance_radio)=((1,0,0)*(100%-25%)+(0,1,0)*25%)=((1,0,0)*75%)+((0,1,0)*25%)=(0.75,0,0)+(0,0.25,0)=(0.75,0.25,0)(大红) |
|
中间 |
50% |
(vertex_0_value*(1-distance_radio))+(vertex_1_value*distance_radio)=((1,0,0)*(100%-50%)+(0,1,0)*50%)=((1,0,0)*50%)+((0,1,0)*50%)=(0.5,0,0)+(0,0.5,0)=(0.5,0.5,0)(半红半绿) |
|
直线的四分之三处 |
75% |
(vertex_0_value*(1-distance_radio))+(vertex_1_value*distance_radio)=((1,0,0)*(100%-75%)+(0,1,0)*75%)=((1,0,0)*25%)+((0,1,0)*75%)=(0.25,0,0)+(0,0.75,0)=(0.25,0.75,0)(大绿) |
|
最右端 |
100% |
(vertex_0_value*(1-distance_radio))+(vertex_1_value*distance_radio)=((1,0,0)*(100%-100%)+(0,1,0)*100%)=((1,0,0)*0%)+((0,1,0)*100%)=(0,1,0)(绿色) |
要注意到,任何时候两个颜色的权重加起来都是100%。如果红色是100%,绿色就是0%;如果红色是50%,那绿色就是50%。
使用一个varying,我们就可以把任何两种颜色混合在一起。当然,这不只限于颜色;任何其他属性也可以应用插值技术。
2.在一个三角形表面混合
当我们只处理两个点的时候,阐明线性插值是怎么工作的并不困难;我们知道,从某个颜色的一个顶点到另一个顶点,其比例是从100%到0%缩减,所有按比例缩减的颜色合在一起就得到了最后的颜色。
在一个三角形上的线性插值也是一样的工作原理,但是现在需要处理三个点和三种颜色。让我们看一个直观的例子:
这个三角形与三种颜色有关联:顶端顶点是青色,左端顶点是红色,右端定点是黄色。让我们把这个三角形按每个顶点衍生出来的颜色进行分解:
就像那条直线一样,每个颜色在接近它的顶点处都是最强的,向其他顶点移动就会变暗。我们同样用比例确定每种颜色的相对权重,但这次要使用的面积的比例,而不是长度。
对于这个三角形内任何给定的点,从那个点向每个顶点所对应的点画一条直线就可以生成三个内部三角形。这三个内部三角形的面积比例决定了那个点上每种颜色的权重。比如,那个点上黄色的强度就取决黄色顶点相对的那个内部三角形的面积。距离黄色顶点越金的点,它的相对三角形越大,在那个点的片段就越黄。
与直线一样,这些权重之和也总是等于100%。可以使用下面的公司计算三角形内任何一个点的颜色分量:
Blended_value=(vertex_0_value*vertex_0_weight)+(vertex_1_value*vertex_1_weight)+(vertex_2_value*(100%-vertex_0_weight-vertex_1_weight))
我们已经理解了它在直线上是怎么工作的,在这种情况下,我们就不需要为此举出具体的例子了。原理是一样的,只是这次要处理三个点而不是两个。
看不懂向量算法的可以先看看线性代数,当然两个公式相对来说很简单。要深入学习OpenGL ES涉及到两门课程,开始讲解可能不明显,后面的应用越来越多的时候涉及的课程的知识会越来越多。当然计算更多的是在线性代数,而后面空间的构思会涉及离散数学的图论里面的知识。
下一篇讲解OpenGL程序的基本编程。
版权声明:本文为博主原创文章,未经博主允许不得转载。
Android OpenGL ES(二)----平滑着色的更多相关文章
- Android OpenGL ES(十二):三维坐标系及坐标变换初步 .
OpenGL ES图形库最终的结果是在二维平面上显示3D物体(常称作模型Model)这是因为目前的打部分显示器还只能显示二维图形.但我们在构造3D模型时必须要有空间现象能力,所有对模型的描述还是使用三 ...
- Android OpenGL ES 开发教程 从入门到精通
感谢,摘自:http://blog.csdn.net/mapdigit/article/details/7526556 Android OpenGL ES 简明开发教程 Android OpenGL ...
- Android OpenGL ES(十三)通用的矩阵变换指令 .
Android OpenGL ES 对于不同坐标系下坐标变换,大都使用矩阵运算的方法来定义和实现的.这里介绍对应指定的坐标系(比如viewmodel, projection或是viewport) An ...
- Android OpenGL ES(七)基本几何图形定义 .
在前面Android OpenGL ES(六):创建实例应用OpenGLDemos程序框架 我们创建了示例程序的基本框架,并提供了一个“Hello World”示例,将屏幕显示为红色. 本例介绍Ope ...
- Android OpenGL ES(五)GLSurfaceView .
Android OpenGL ES 相关的包主要定义在 javax.microedition.khronos.opengles GL 绘图指令 javax.microedition.khrono ...
- Android OpenGL ES(一)OpenGL ES介绍
在学习Android OpenGL ES开发之前,你必须具备Java 语言开发经验和一些Android开发的基本知识,但并不需要有图形开发的经验,本教程也会涉及到一些基本的线性几何知识,如矢量,矩阵运 ...
- [OpenGL ES 02]OpenGL ES渲染管线与着色器
[OpenGL ES 02]OpenGL ES渲染管线与着色器 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循"署名-非商业用途-保持一致"创 ...
- [工作记录] Android OpenGL ES: non-square texture - continue
previous: [工作记录] Android OpenGL ES 2.0: square texture not supported on some device recently I found ...
- Android OpenGL ES(八)绘制点Point ..
上一篇介绍了OpenGL ES能够绘制的几种基本几何图形:点,线,三角形.将分别介绍这几种基本几何图形的例子.为方便起见,暂时在同一平面上绘制这些几何图形,在后面介绍完OpenGL ES的坐标系统和坐 ...
随机推荐
- C#对HTML转译需要注意的问题
在做B/S程序时我们多少会用到一点HTML特殊符号转译. 如:“&”——>“&” , "<"——>"<" , " ...
- Java数据结构之树和二叉树(2)
从这里始将要继续进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来 ...
- Cocos2dx Widget button透明区域过滤
小伟哥 遇到一个命题: button透明区域过滤.当点击一个建筑button.花的时候不得不想一些方法把点击透明区域过滤掉. 让点击也没有效果滴啦. 開始搜索了半天才有所思路. 在网络上非常多贴代码的 ...
- JavaScript创建Map对象(转)
JavaScript 里面本身没有map对象,用JavaScript的Array来实现Map的数据结构. /* * MAP对象,实现MAP功能 * * 接口: * size() 获取MAP元素 ...
- C#实现一个最简单的HTTP服务器
简介 本文用C#实现了一个最简单的HTTP服务器类,你可以将它嵌入到自己的项目中,或者也可以阅读代码来学习关于HTTP协议的知识. 背景 高性能的WEB应用一般都架设在强大的WEB服务器上,例如IIS ...
- OpenGL中的功能与OSG对应功能 (摘)
将OpenGL中的功能与OSG对应功能进行列举: OpenGL function OpenSceneGraph implementation glClear( GLbitfield mask ) os ...
- 分享 Java微信开发SDK
分享 Java微信开发SDK •发布于 4周前 •作者 朋也 •432 次浏览 •最后一次编辑是 2周前 •来自 分享 给大家分享两个java开发微信公众号的sdk jfinal-weixin ...
- HDOJ 1914 The Stable Marriage Problem
rt 稳定婚姻匹配问题 The Stable Marriage Problem Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 6553 ...
- oracle 有用站点
使用oradebug修改数据库scn – 提供专业ORACLE技术咨询和支持@Phone13429648788 - 惜分飞 Solaris上使用DTrace进行动态跟踪 老熊的三分地-Oracle及数 ...
- [原创]SSIS-WMI 数据读取器任务:监控物理磁盘空间
背景: 随着时间的推移,我们的DW会越来越大,也就意味着磁盘空间会越来越小,那如果哪一天留意不当,就会造成磁盘空间的不足而导致ETL失败,最终影响我们的系统的数据正确性和使用,更严重的有可 ...