glsl|glsl gl_FragCoord 与 屏幕关系
【glsl|glsl gl_FragCoord 与 屏幕关系】转载链接:http://blog.csdn.net/jinghouxiang/article/details/50751125
原创
2016年02月26日 17:06:01
[plain]view plain 运行环境:Android opengl es版本: 2.0 3D引擎库 : Rajawali3D
ShaderToy上用的shader语言 为glsl , 效果是用webgl跑的,而webgl封装了opengl es,所以ShaderToy上的例子同样使用于Android端。
ShaderToy基本上 都是用fragment shader 对栅格化后的像素进行处理。大部分会用到纹理来丰富最终渲染结果的形状和质地,有些也会用到声音,键盘等外部输入信息。但是,最终都是归结为对栅格化区域内的每个像素进行处理,因此,我们首先来认识gl_FragCoord这个内置变量以及其与屏幕坐标的关系。
gl_FragCoord根据glsl language spec的解释为: 它是fragment shaders的输入变量,并持有该framgent的屏幕相对坐标(x, y, z, 1/w)
什么是屏幕相对坐标,它的坐标范围是多少,这些都没有告诉我们。需要我们实验
假设我们采用2d ortho projection的方式来渲染,输入的顶点信息为屏幕的4个顶点坐标,这样我们最终渲染出来的是一个 铺满屏幕的图。 由于是2D渲染,最终每个fragment的 gl_FragCoord的z接近0.0, 而w 为1.0, 而它的x, y分量,是相对于屏幕左下角为原点的屏幕坐标。什么意思? 假如,我们设定的viewport的渲染区域为(0, 0, 1280, 574) 这么大,那么,gl_Fragment的x分量 范围就在0~1280之间, y分量就在0~574之间。
我们可以用一下测试用例来进行测试: vertex shader: [plain]view plain copy
- precision mediump float ;
- uniform mat4 uMVPMatrix;
- attribute vec4 aPosition;
- void main(){
- position = vec3 (uMVPMatrix*aPosition);
- gl_Position = uMVPMatrix*aPosition;
- }
fragment shader:
[plain]view plain copy
- precision mediump float ;
- uniform vec2 screenSize; // step1
- void main()
- {
- vec2 uv = vec2(gl_FragCoord.xy/screenSize.xy); // step 2
- //Calculate polar coordinates
- float r = length(uv);
- float c = 0.0;
- if(uv.x>0.98 &&uv.x<1.0 )// step 3
- {
- c = 1.0;
- }
- if(uv.y>0.98 &&uv.y<1.0 )// step 4
- {
- c = 1.0;
- }
- //Calculate the final color mixing lines and backgrounds.
- vec3 bg = mix(vec3(0.93 , 0.71 ,0.62 ),vec3(0.9 , 0.44 , 0.44),r); // step 5
- bg = mix(bg, vec3 (0.9 , 0.91 , 0.62 ), c); //step 6
- gl_FragColor = vec4(bg, 1.0);
- }
运行后,效果图如下:
文章图片
这里主要说下 fragment shader: step 1: 之前说到, gl_FragCoord的坐标范围, 这里screenSize 表示屏幕的宽高。 step 2 :将每个fragment的 每个gl_FragCoord归一化,这是一个惯例,利于后面计算 step3: 和 step4:这两个分别表示,当fragment的坐标(x, y) 的x和y分量分别落在这个范围时(即中间)c 的值会发生变化 step5:step5 和 step6都用到了glsl 的 mix内置函数,考虑到 bg = mix(color1, color2, r)它的意思,就是将color1和color2 两种颜色,按照bg = color1*(1-r)+r*color2的方式混合,其中bg, color1, color2都是表示颜色,有三个分量。 那么,当r=0.0时,表示的是color1颜色,当r = 1.0表示的是color2颜色。 我们利用mix可以在一种背景上标记出另一种颜色。
step3 和 step4 表示,当x, y 分别落在值范围的中间时,c的值从0.0变为1.0, 即在这个范围内,背景色变为我们设置的颜色。
当我们把step3 和 step4 改为: if (uv.x> 0.09 &&uv.x< 0.11 )// step 3 {
c = 1.0;
}
if (uv.y> 0.09 &&uv.y< 0.11 )// step 4
{
c = 1.0;
}
效果图如下:
文章图片
通过,以上的例子我们得出gl_FragCoord的正确表示方式。
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- Docker应用:容器间通信与Mariadb数据库主从复制
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 第326天
- Shell-Bash变量与运算符
- 逻辑回归的理解与python示例
- Guava|Guava RateLimiter与限流算法
- 我和你之前距离
- CGI,FastCGI,PHP-CGI与PHP-FPM
- 原生家庭之痛与超越