Loading...
墨滴

四五戒

2021/08/26  阅读:24  主题:默认主题

creator shader:从零开始,用shader画个彩虹

creator shader:从零开始,用shader画个彩虹

1. 从创建shader和材质开始

分别创建名为 rainbow的effect和material,创建一个场景,新建一张Sprite精灵,使用我们创建出来的rainbow材质,替换掉Sprite精灵的默认材质。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

点击新建的材质,这里的effect 选择改为 新建的rainbow

在这里插入图片描述
在这里插入图片描述

此时应用按钮高亮,点击应用

在这里插入图片描述
在这里插入图片描述

使用我们创建出来的rainbow材质,替换掉Sprite精灵的默认材质。

在这里插入图片描述
在这里插入图片描述

2. 给图片上色

修改片元着色器的代码,

  void main () {
    vec4 o = vec4(1111);

    #if USE_TEXTURE
      CCTexture(texture, v_uv0, o);
    #endif

    o *= v_color;

    ALPHA_TEST(o);

    gl_FragColor = o;
  }

删掉,改成


  void main () {
    // color 是三个浮点数的向量,三个分量可以使用color.x color.y color.z分别访问
    // 也可以color.xy color.xz 作为 vec2 随意组合访问
    // xyz访问的分别是第1,2,3个分量,也可以使用rgb分别访问1,2,3三个分量,没有区别
    // 作为color使用,1,2,3三个分量带别的分别是颜色的红绿蓝三色,三个颜色组合成任意颜色
    // 0.,1.,0. 是红色0 绿色1 蓝色0,最终色是 红色
    vec3 color = vec3(0.,1.,0.);

 // gl_FragColor是最终决定每个像素的颜色的值,
 // vec4.xyz 使用上面的color的值,vec4.w 是1.,这个值得意义是透明度,设为1
    vec4 o = vec4(color, 1);
    gl_FragColor = o;
  }

切换到creator面板,看一下我们上色的结果

在这里插入图片描述
在这里插入图片描述

3. 图片画个圆

  void main () {
    // color 是三个浮点数的向量,三个分量可以使用color.x color.y color.z分别访问
    // 也可以color.xy color.xz 作为 vec2 随意组合访问
    // xyz访问的分别是第1,2,3个分量,也可以使用rgb分别访问1,2,3三个分量,没有区别
    // 作为color使用,1,2,3三个分量带别的分别是颜色的红绿蓝三色,三个颜色组合成任意颜色
    // 0.,1.,0. 是红色0 绿色1 蓝色0,最终色是 红色
    vec3 color = vec3(0.,1.,0.);

    vec2 point = vec2(.5,0.);

    // distance 计算两点距离 这里的point事边缘的中心点,v_uv0是每个像素对应的uv坐标
    float mul = distance(v_uv0,point);
    // step函数,参数1 > 参数2 返回0,否则返回1
    // 这里用step来处理mul,使距离小于0.5的返回值1,大于0.5返回值0
    mul = step(mul,.5);

    // color * mul 对距离在0.5内的像素点,*= 1,颜色值不变,>0.5 时*= 0,使颜色变黑色
    // 结果就是一个圆
    color *= mul;

    // gl_FragColor是最终决定每个像素的颜色的值,
 // vec4.xyz 使用上面的color的值,vec4.w 是1.,这个值得意义是透明度,设为1
    vec4 o = vec4(color, 1);
    gl_FragColor = o;
  }
在这里插入图片描述
在这里插入图片描述

mul = step(mul,.5)改成mul=step(mul,.4) 嘿嘿,画个半径0.4的圆

在这里插入图片描述
在这里插入图片描述

后面的套路你已经猜出来了!mul = step(distance(v_uv0,point),.5) - step(distance(v_uv0,point),.4); 大圆-小圆=

在这里插入图片描述
在这里插入图片描述

4. 把画半圆封装成一个函数吧

  float drawHalfCircle(vec2 center,vec2 uv,float radius) {

    float mul = distance(uv,center);
    mul = step(mul,radius);

    return mul;
  }
  
  
  // 参数: center 圆心
  // uv 像素点坐标
  // radius 圆半径
  // width 线宽
  float drawHalfCircleLine(vec2 center,vec2 uv,float radius,float width) {
    float c1 = drawHalfCircle(center,uv,radius);
    float c2 = drawHalfCircle(center,uv,radius - width);
    return c1 - c2;
  }
  
  void main () {
// 省略重复的代码  .......
    float circleline = drawHalfCircleLine(point,v_uv0,0.5,0.05);
    float ret = circleline;
    color = vec3(0.,1.,0.) * ret;
// 省略重复的代码  .......
  }  
在这里插入图片描述
在这里插入图片描述

5. 画彩虹?

    float circleline1 = drawHalfCircleLine(point,v_uv0,0.5,0.05);
    float circleline2 = drawHalfCircleLine(point,v_uv0,0.45,0.05);
    float circleline3 = drawHalfCircleLine(point,v_uv0,0.4,0.05);

    vec3 colorred = vec3(1.,0.,0.);
    vec3 colorgreen = vec3(0.,1.,0.);
    vec3 colorblue = vec3(0.,0.,1.);
    
    vec3 ret = circleline1 * colorred
      + circleline2 * colorgreen
      + circleline3 * colorblue;
    
    color = ret;
在这里插入图片描述
在这里插入图片描述

颜色你再调调吧。

6. 边缘有锯齿?

  float drawHalfCircle(vec2 center,vec2 uv,float radius) {

    float dis = distance(uv,center);
    // dis = step(dis,radius);
    dis = smoothstep(radius,radius -.005,dis);

    return dis;
  }

drawHalfCircle函数换成上面的再看下。

在这里插入图片描述
在这里插入图片描述

挺好。smoothstep下回再聊。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

哎转一下转两下,调调圆心坐标试一下。


7. 补充几句

别把这当做对图片范围上色啊,片元着色器是对每一个片元进行计算的,例如 渲染区域为(0, 0, 1280, 574) 这么大,那么,gl_Fragment 的x分量 范围就在0~1280之间, y分量就在0~574之间 对一个像素点来说,如gl_Fragment.xy = 200,200 v_uv0就是 vec2(200./1280.,200./574.) 对一个像素点的计算,

    float circleline1 = drawHalfCircleLine(point,v_uv0,0.5,0.05);
    float circleline2 = drawHalfCircleLine(point,v_uv0,0.45,0.05);
    float circleline3 = drawHalfCircleLine(point,v_uv0,0.4,0.05);

    vec3 colorred = vec3(1.,0.,0.);
    vec3 colorgreen = vec3(0.,1.,0.);
    vec3 colorblue = vec3(0.,0.,1.);
    
    vec3 ret = circleline1 * colorred
      + circleline2 * colorgreen
      + circleline3 * colorblue;

对一个点来说,上面的三条线计算中,只可能有一条线的值是1,其他的都是0,或没有1全0 比如计算出点在line1范围内,circleline1值1.,其他lin2 line3 值都是0 结果就是 red * 1 + green * 0 + blue * 0,最终200,200的点的颜色值为 red * 1 + 0 + 0红色

如果计算出点不在三条线任一范围内,结果就是 red0+green0+blue*0 = 0 黑色 贴个帖子 glsl gl_FragCoord 与 屏幕关系

四五戒

2021/08/26  阅读:24  主题:默认主题

作者介绍

四五戒