cocos creator shader 方形头像变为圆形头像

将方形头像转变为圆形头像我起初的思路就是,先在一个图片上绘制一个在中心点带颜色的圆:

1:如果uv坐标在圆内的话就会和图片的颜色进行混合只不过混合的时候,带颜色的圆的插值为0,图片的插值为1

2:如果uv坐标不在圆内的话就将图片颜色的插值设置为0并且将圆的颜色的插值也设置为0

用到的数学知识是:r <  d = \sqrt{{(x'-x) * (x'-x) + (y'-y)*(y'-y)}}   在圆内,否则在圆外

// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.  

CCEffect %{
  techniques:
  - passes:
    - vert: vs
      frag: fs
      blendState:
        targets:
        - blend: true
      rasterizerState:
        cullMode: none
      properties:
        texture: { value: white }
        alphaThreshold: { value: 0.5 }
}%


CCProgram vs %{
  precision highp float;

  #include <cc-global>
  #include <cc-local>

  in vec3 a_position;
  in vec4 a_color;
  out vec4 v_color;

  #if USE_TEXTURE
  in vec2 a_uv0;
  out vec2 v_uv0;
  #endif

  void main () {
    vec4 pos = vec4(a_position, 1);

    #if CC_USE_MODEL
    pos = cc_matViewProj * cc_matWorld * pos;
    #else
    pos = cc_matViewProj * pos;
    #endif

    #if USE_TEXTURE
    v_uv0 = a_uv0;
    #endif

    v_color = a_color;

    gl_Position = pos;
  }
}%


CCProgram fs %{
  precision highp float;
  
  #include <alpha-test>

  in vec4 v_color;

  in vec2 v_uv0;
  uniform sampler2D texture;
  uniform ARGS {
    vec2 iResolution;
    float time;
  }
  void drawCircle(vec2 curUV,vec2 center,float radius,out vec4 color) {
    float res;
    // 圆周运动
    // curUV.x += 0.1 * sin(curUV.x * 0.2 + time);
    // curUV.y += 0.1 * cos(curUV.x * 0.2 + time);
    // 求出任意像素坐标到中心点的距离
    res = sqrt(pow((curUV.x - center.x),2.)+pow((curUV.y - center.y),2.));
    vec4 cirColor = vec4(1.0,1.,0.,1.);
    vec4 texColor = texture2D(texture,curUV);
    if(res < radius) {
      color = cirColor * 0. + texColor * 1.;
    } else {
      color = cirColor * 0. + texColor * 0.;      
    }
  }
  void mainImage(out vec4 fragColor,in vec2 uv,vec2 res) {
    vec2 tempUV = uv.xy / res.xy;
    vec2 center = vec2(0.5,0.5);
    float r = 0.5;
    drawCircle(tempUV,center,r,fragColor);
  }
  void main () {
    vec2 res = vec2(200.,200.);
    mainImage(gl_FragColor,v_uv0.xy * res.xy,res);
  }
}%

当然需要在该shader对应的节点上挂上对应的脚本传递对应的参数,上面的res 可以在外面进行传递,我这里就是简单的处理了一下子,最后处理结果为:

对应的脚本文件为:

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {
    // LIFE-CYCLE CALLBACKS:
    @property(cc.Node)
    spriteNode: cc.Node = null;
    // onLoad () {}
    private spriteComponent: cc.Sprite;
    private mat: cc.Material;
    private time: number = 0;
    private resolution: cc.Vec2;
    private tex: cc.Texture2D;
    start () {
        this.spriteComponent = this.spriteNode.getComponent(cc.Sprite);
        this.tex = this.spriteComponent.spriteFrame.getTexture()
        let a = cc.v2(2,2);
        let b = cc.v2(2,2);
        let res = a.dot(b);
        console.log("res is ",res);
        this.resolution = cc.v2(this.node.width,this.node.height);
    }

    update (dt) {
        this.time += dt;
        this.mat = this.spriteComponent.sharedMaterials[0];
        this.mat.setProperty("iResolution",this.resolution);
        this.mat.setProperty("time",this.time);
        // this.mat.setProperty("tex",);
        if(this.tex) {
            // this.mat.setProperty("tex",this.tex);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/lck8989/article/details/103733020