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

修正显示长宽比

先前的例子中,可以看到网格的绘制都是长方形,但是肯定会碰到需要绘制正方形的情况。由于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内建函数篇 :-)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值