Shader学习笔记(4)- 基本概念与基础效果(3)

来源:互联网 发布:淘宝商家直播入口 编辑:程序博客网 时间:2024/06/06 20:05

修正显示长宽比

先前的例子中,可以看到网格的绘制都是长方形,但是肯定会碰到需要绘制正方形的情况。由于width和height都被映射到了[0,1],而实际上显示范围的width一般是大于height(手机上就不一样),所以需要把width映射至正确的区间。

思路(我的显示器1920*1080做例子)

首先2*fragCoord,xy分别为[0,1920*2]和[0,1080*2]
然后2*fragCoord-iResolution.xy,xy分别为[-1920,1920]和[-1080,1080]
最后(2*fragCoord-iResolution.xy)/min(iResolution.x,iResolution.y),xy分别为[-1.7,1.7]和[-1,1],成功映射。

void mainImage( out vec4 fragColor, in vec2 fragCoord ){    vec2 uv = (2.*fragCoord-iResolution.xy)/min(iResolution.x,iResolution.y);//将屏幕空间映射至[-1.xx,1.xx]x[-1,1](width大于height)    vec3 BGcolor = vec3(1.);        vec3 axisColor = HexTo01Color(22.,147.,165.);   //坐标轴颜色    vec3 gridColor = vec3(.5);  //网格颜色    vec3 color = BGcolor;    const float gridGap = 0.1;  //网格间距    //取模运算不会绘制双倍宽度    if(mod(uv.x,gridGap)<0.008) color = gridColor;//此处以取模运算代替for循环    if(mod(uv.y,gridGap)<0.008) color = gridColor;    if(abs(uv.x)<0.006) color = axisColor;    if(abs(uv.y)<0.007) color = axisColor;    fragColor = vec4(color,1.);}

这里写图片描述

绘制圆盘

想要绘制图形的思路都一样,那就是将在一定范围里面的坐标位置都用我们指定的颜色填充就ok。
这里画圆用上大家都学过的公式:x^2+y^2=r^2。(r是半径)

void mainImage( out vec4 fragColor, in vec2 fragCoord ){    vec2 uv = (2.*fragCoord-iResolution.xy)/min(iResolution.x,iResolution.y);    vec3 BGcolor = vec3(1.);    vec3 color_1 = HexTo01Color(22.,147.,165.);    vec3 color_2 = HexTo01Color(173.,216.,199.);    vec3 color_3 = HexTo01Color(251.,184.,41.);    vec3 color = BGcolor;    float radius = 0.6; //半径    if(uv.x*uv.x+uv.y*uv.y<radius) color = color_1; //x^2+y^2 = r^2 大家都学过    //使用内建函数    if(length(uv)<0.4) color = color_2; //和上面等价    //指定圆心位置    vec2 circlePosition = vec2(0.2,-0.5);    if(length(uv-circlePosition)<0.3) color = color_3;    //这里的颜色叠加顺序大家可以想象成ps中的图层,最先绘制显示在下,同时之后绘制的会    //覆盖先前的绘制    fragColor = vec4(color,1.);}

这里写图片描述

使用自定义函数封装绘制

将绘制过程封装起来,c语言会的这个都会。这里说一个变量的修饰符“inout”。

in修饰的变量:将实参赋值给形参,相当于传进,默认就是这样。
out修饰的变量:将形参的值传给实参,相当于传出。(如果想要将变量传出,不加out得不到效果)

//封装void DrawCircle(vec2 pos,vec2 center,float radius,vec3 color,out vec3 targetColor){    if(length(pos-center)<radius) targetColor = color;}
void mainImage( out vec4 fragColor, in vec2 fragCoord ){    vec2 uv = (2.*fragCoord-iResolution.xy)/min(iResolution.x,iResolution.y);    vec3 BGcolor = vec3(1.);    vec3 color_1 = HexTo01Color(22.,147.,165.);    vec3 color_2 = HexTo01Color(173.,216.,199.);    vec3 color_3 = HexTo01Color(251.,184.,41.);    vec3 color = BGcolor;    //使用自定义函数绘制    DrawCircle(uv,vec2(0.,0.),0.6,color_1,color);    DrawCircle(uv,vec2(0.,0.),0.3,color_2,color);    DrawCircle(uv,vec2(-0.3,-0.5),0.2,color_3,color);    fragColor = vec4(color,1.);}

这里写图片描述

基本概念与基础效果到此结束
接下来会开始GLSL内建函数篇 :-)

原创粉丝点击