在vertex shader里也可以检索纹理。我本来觉得这没什么好奇怪的,因为我一直也觉得这很当然可以啊~当初橙书(OpenGL Shading Language Edtion2)也说过texture2D这类函数不是fragment shader专用的,倒还有texture2DLod这种在vertex shader里专用的(后面一句是马后炮~),只是我不知道怎么用,在哪里用,以及更重要的:为什么要用。

为什么要在vertex shader里检索纹理。

都知道,纹理里的一般是一幅图像,无论是外部导入的还是通过FBO等手段渲染到的。既然如此,有意义的当然是图像里的每一个像素啦,通过纹理坐标检索纹理中的像素打印到屏幕某个地方,并可控制细节程度……反映在GPU编程中,一般就是把当前绑定的纹理的纹理单元(默认为0)传送给Fragment Shader作为sampler,在vertex shader里用gl_TexCoord[0] = glMutiTexCoord0这样的语句,获取固定流水线中为每个顶点设置好的纹理坐标(顶点纹理索引,即glMutiTexCoord0),赋给本质为varying的gl_TexCoord[0],让它带着纹理坐标在光栅化过程中插值——对应每个像素点拥有属于它的插值后像素纹理索引(gl_TexCoord[0]),以此作为参数用texture2D类函数检索纹理sampler。

直接在顶点阶段就检索纹理意义何在?获得的只是那些顶点的纹理坐标检索出的“孤立”像素值而已。

你认识吗?GPGPU。

[gpgpu.org]

GPGPU(General Purpose Graphic Process Unit,通用目的图形处理单元),是应用GPU的高速并行能力和浮点运算能力进行科学计算等SIMD类型[单指令多数据]的应用。在这里,GPU-shader不仅仅着眼于图形。而GPGPU的一个重要概念就是:纹理 =  数组。是的,为什么不可以呢?纹理确实就是数组啊。我们能传入shader的只有具体的数值,bool,int,float,vec,matrix,其中最大的matrix4也只有16个量。那么如果我们要把大量的数据传入shader,譬如一个巨大的float数组,怎么办呢?对啊,用纹理!这时候,纹理内部每个数值不再是像素的值,而是数组的数据项。我们只是通过纹理这种灵活的媒介,让数据“进入”GPU的视野,让shader可以对这些数据项变量进行访问和操作。

顺带一提,现在科学计算领域已经进入GPGPU的进化时代 -CUDA时代了。好吧,不要扯远了。

既然纹理 = 数组, VTF顶点纹理拾取的存在就不言自明了:其实不是在拾取含有图像像素信息的那个纹理,而是在拾取含有顶点数据信息的那个“数组”啊!在这里,数组的索引就是顶点纹理坐标……看例子:

//RenderMonkey:
//Vertex Program
varying vec4 vertColor;
uniform sampler2D baseMap;void main( void )
{//vertColor = texture2D(baseMap, gl_MultiTexCoord0.xy);  与下句等价  vertColor = texture2DLod(baseMap, gl_MultiTexCoord0.xy, 0.0);        vec4 pos = gl_ModelViewMatrix * (gl_Vertex) ;gl_Position = gl_ProjectionMatrix * pos ;
}//Fragment Program
varying vec4 vertColor;void main( void )
{gl_FragColor = vertColor;
}

这个例子是说明:诶?原来Vertex Shader里也可以做纹理拾取口牙!顺带一提,这里用texture2D,和用“texture2DLod+尾参数[细节参数LOD] = 0.0”的效果是一样的:


(对比用。这是FTF,传统的fragment shader获取纹理)

(这是VTF,顶点纹理拾取,也就是上面代码的产物,对比两图哈)

纹理只是普通的纹理。只是为了证明VTF能行- -。把顶点纹理的值做插值,预料最后的结果类似于顶点颜色插值,三角片元的颜色在三角的三顶点所获得的纹理颜色间进行线性插值,得出如此“重过渡味+模糊”的怪象(嘛~这纹理即使是那FTF出来的也是怪象)。然后测试texture2DLod这个函数,把最后的LOD参数增大调为0.4:

lod是细节参数,这跟以前的FTF(PTF)差不多。好吧,换张纹理后,再用VTF做点更有趣的:

//RenderMonkey:
//Vertex Program
varying vec4 vertColor;
uniform sampler2D baseMap; void main( void )
{ vertColor = texture2DLod(baseMap, gl_MultiTexCoord0.xy, 0.0);vec4 offset = vec4(0.0);if(gl_Vertex.z > 0.0)offset = vertColor;else if(gl_Vertex.z < 0.0)offset = vec4(1.0)-vertColor;vec4 pos = gl_ModelViewMatrix * (gl_Vertex+ offset) ; gl_Position = gl_ProjectionMatrix * pos ;
} //Fragment Program
varying vec4 vertColor; void main( void )
{ gl_FragColor = vertColor;
}

  能猜到结果变成这样吗?哈,VTF出来的vertColor果然充满力量:

另外一个例子则用VTF做点有意义的事情。还记得高度图纹理吗?(我在[Terrain Texture-Array Demo] 里也用到过~)

//RenderMonkey:
//Vertex Program
varying vec2  texCoord;
uniform sampler2D Texture0;void main(void)
{vec4 vcol =  texture2D( Texture0, gl_MultiTexCoord0.xy);float gray = 0.2990*vcol.r + 0.5870*vcol.g + 0.1140*vcol.b;vec4 pos =  gl_Vertex;pos.z = pos.z * (1.0 - 5.0*gray);gl_Position = gl_ModelViewProjectionMatrix * pos;texCoord = gl_MultiTexCoord0.xy;
}//Fragment Program
uniform sampler2D Texture0;
varying vec2 texCoord;void main(void)
{gl_FragColor = texture2D( Texture0, texCoord );
}

这里本来只有一个平整的网格,和一张类似高度图的纹理。运用VTF把顶点对应的纹理坐标的像素值拉出来转化为灰度(转化法同见[基于亮度的图像二值化处理] ),并转化为该网格顶点的“高度”。最后的纹理只是平铺上去(那不是阴影哦)。看,灰度高的地方对应的高度高,灰度低的地方对应的高度低。这就是高度场啊,这就是VTF最典型的应用啊!

在Vertex Shader里面,通过纹理坐标的检取,VTF获取的是真正的“高度值”数据……只是这些数据被储存在一张纹理上罢了。

Vertex Texture Fetch(VTF) Fragment Texture Fetch ( FTF )相关推荐

  1. fetch用英语解释_fetch的搭配、fetch的解释、fetch的翻译、fetch的例句、fetch的短语...

    fetch and carry 打杂,递递拿拿 do a part time job; be assistant ▲fetch and carry Her whole morning was spen ...

  2. fetch 基本用法(fetch 处理后端数据)

    fetch 的基本用法 fetch 的基本用法 fetch 两级then的却别 fetch 的基本用法 await fetch(url, {method: 'POST', // 请求方式headers ...

  3. oracle fetch into语法,Oracle Fetch

    oracle函数 的 Oracle Fetch 在本教程中,将学习如何使用Oracle FETCH子句来限制查询返回的行数. Oracle FETCH子句简介 一些RDBMS(如和)使用子句来检索查询 ...

  4. fetch 服务器不响应,Fetch 常见的使用问题

    Fetch 常见的使用问题 ?fetch 的浏览器兼容 1 fetch 默认不携带 cookie 1fetch 发送请求默认是不发送 cookie 的, 不管是同域还是跨域; 需要设置 : fetch ...

  5. fetch 服务器不响应,fetch的常见问题及其解决办法

    摘要: 玩转fetch. Fundebug经授权转载,版权归原作者所有. 首先声明一下,本文不是要讲解fetch的具体用法,不清楚的可以参考MDN fetch教程. 引言 说道fetch就不得不提XM ...

  6. fetch整个仓库 github_git fetch 的简单用法:更新远程代码到本地仓库

    方式一 1. 查看远程仓库 1 2 3 4 5 6 $ git remote -v eoecn https://github.com/eoecn/android-app.git (fetch) eoe ...

  7. fetch() php,PHP:使用fetch()发送数据

    我试图使用fetch()发送一些数据,但作为回报,我得到 SyntaxError:意外的标记,在JSON中的位置23 这就是我要做的 fetch('/api.php', { method: 'POST ...

  8. php fetch返回false,Php fetch返回字符串而不是布爾值“true / false”值

    I'm using full calender and I have a few events that are all day events. Generally, my php set all ' ...

  9. fetch ajax cros,由 Fetch 跨域 看 CORS

    最近在看 react 获取服务器数据时, 看到了一新的 API fetch, 上手来用了用,觉得十分好用.但是使用的过程中遇到了一些问题,还是决定整体的记录下. fetch 类似于 Ajax, 区别自 ...

最新文章

  1. python 获取打印的内容并保存到记事本里面
  2. 为什么大家都推荐我学Linux
  3. Read correction for non-uniform coverages 读校正非均匀覆盖
  4. Selenium如何通过location和size定位元素坐标?
  5. 拼接图像亮度均匀调整_液晶拼接屏如何才能达到更好的显示效果
  6. 基于React Native和Ethers.js的电子钱包(三):Ethers.js
  7. Sql 中的变量使用
  8. 第五章 条件、循环及其他语句
  9. 算算奖学金(洛谷P1051题题解,Java语言描述)
  10. Rectangles
  11. vue使用laydate.js插件报错laydate.css: Invalid
  12. 关于计算机技术职业资格那些事
  13. 解决串口数据接收,实际值FF,接收却是FFFFFFFF
  14. VB使用API的简明教程
  15. .gen格式文件读取,完成兰伯特和墨卡托投影转换
  16. 动态生成icon图标
  17. facebook登陆ios
  18. Millet谷仓:人人受益的电商
  19. 作为SLAM中最常用的闭环检测方法,视觉词袋模型技术详解来了
  20. vue项目rem 大屏可视化适配

热门文章

  1. mysql常用快速查询修改操作
  2. 物料主数据(MM03)跳转函数
  3. Python中第三方的库(library)、模块(module),包(package)的安装方法以及ImportError: No module named...
  4. luajit日记-FFI库
  5. Gamebryo实例学习之二BackgroundLoad
  6. QAction添加事件响应
  7. linux limit
  8. SBO中的manager用户已锁定
  9. Codeforces 892E Envy
  10. Activity的呼叫转移*(3个Activity之间的跳转)