cocos creator 利用shader 实现探照灯效果

探照灯实现效果如下:

看看怎么实现的吧:

light.effect

// 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;
  uniform ARGS {
    float width;
    float height;
    vec2 center;
  };
  #if USE_TEXTURE
  in vec2 v_uv0;
  uniform sampler2D texture;
  #endif
  void mainImage(out vec4 color,vec2 uv,vec4 s) {
    vec2 realCenter;
    realCenter.x = uv.x / width;
    realCenter.y = uv.y / height;
    float radius = 3.;
    float dis = sqrt(pow((realCenter.x - uv.x),2.) + pow((realCenter.y - uv.y),2.));
    if(dis < 1.) {
      color = vec4(0.3,0.4,0.5,1.);
    } else {
      color = s;
      // color = color * vec4(1.,0.,0.,0.5);
    }
  }
  void circle(out vec4 color,vec2 uv,vec2 cen,float radius,vec4 s) {
    float ratio = width / height;
    /* 所有像素点到中心点的距离*/
    float dis = sqrt(pow((cen.x - uv.x),2.) + pow((cen.y - uv.y),2.));
    if(dis < radius) {
      color = s;
    } else {
      color = vec4(s.r * s.g * s.b,s.b * s.r * s.g,s.b * s.r * s.g ,0.5);
    }
  }
  void main () {
    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE
    o *= texture(texture, v_uv0);
      #if CC_USE_ALPHA_ATLAS_TEXTURE
      o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;
      #endif
    #endif

    o *= v_color;

    ALPHA_TEST(o);
    
    gl_FragColor = o;
    vec2 resolution = vec2(width,height);
    vec2 uv = v_uv0;
    float ratio;
    vec2 realCenter = vec2(0.5,0.5);
    if(height > width) {
      ratio = height / width;
      uv.y *= ratio;
      realCenter.y = center.y * ratio;
      realCenter.x = center.x;

    } else {
      ratio = width / height;
      uv.x *= ratio;
      realCenter.x = center.x * ratio;
      realCenter.y = center.y;
    }
    // uv.y *= 1.77;
    // vec2 uv = (-resolution.xy + 2. * v_uv0.xy) / resolution.y;
    circle(gl_FragColor,uv,realCenter,0.2,o);
    // mainImage(gl_FragColor,uv,o);
  }
}%

对应setUniform的ts文件:

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    

    // LIFE-CYCLE CALLBACKS:
    _material: cc.Material;
    @property({
        type: cc.Integer,
        step: 1,
        displayName: '横向格子的数量',
        slide: true,
        min: 10,
        max: 200
    })
    width: number = 0;
    @property({
        type: cc.Integer,
        step: 1,
        displayName: '纵向格子的数量',
        slide: true,
        min: 20,
        max: 300
    })
    height: number = 0;

    onLoad () {
        this._material = this.node.getComponent(cc.RenderComponent).getMaterial(0);
        let sprite: cc.Sprite = this.node.getComponent(cc.Sprite);
        let spriteFrame: cc.SpriteFrame = sprite.spriteFrame;

        let texture: cc.Texture2D = spriteFrame.getTexture();
        let textureWidth: number = texture.width;
        let textureHeight: number = texture.height;

        console.log("width is ",textureWidth," and height is ",textureHeight);

        // for(let i = 0; i < textureWidth; i++) {
        //     for(let j = 0; j < textureHeight; j++) {
                
        //     }
        // }
        
        this.node.on(cc.Node.EventType.TOUCH_MOVE,this.move,this);
        console.log("width is ",this.node.width," and height is ",this.node.height);
        // this._material.setProperty('width')
        this._material.setProperty('width',this.node.width);
        this._material.setProperty('height',this.node.height);
        this._material.setProperty('center',cc.v2(0.5,0.5));

    }
    move(event: cc.Event.EventMouse): void {
        let ratio = this.node.height / this.node.width;

        let location: cc.Vec2 = event.getLocation();
        console.log("location.y is ",location.y);
        let x = location.x / cc.winSize.width;
        let y = (location.y / cc.winSize.height);
        /**
         * x [-1,1]
         * y [-1,1]
         */

        console.log("x is ",x);
        console.log("y is ",y);

        let center = cc.v2(x,1 - y);
        this._material.setProperty('center',center);
    }
    start () {

    }

    update (dt) {
        
    }
}

鼠标移动到哪哪个地方就会有个探照灯

 

### 回答1: Cocos Creator是一个面向游戏和应用程序开发的跨平台游戏引擎,它提供了丰富的功能和工具,可以帮助开发者轻松创建游戏和应用程序。 在Cocos Creator中,可以使用自定义的shader实现各种特效和效果,包括圆形shader。圆形shader是一种可以在一个元素或画面上创建圆形渐变效果的技术。 要实现圆形shader,首先需要创建一个新的shader脚本。在这个脚本中,我们需要定义一些变量,例如圆形的中心点坐标、半径、渐变颜色等。然后,我们需要在shader的主体部分中使用这些变量来计算每个像素的颜色。 在计算像素的颜色时,我们可以使用距离中心点的距离来确定该像素的位置。然后,根据这个距离来计算出该像素的颜色。通常,离中心点越近的像素颜色越浅,离中心点越远的像素颜色越深,这样就形成了一个圆形的渐变效果。 在Cocos Creator中,可以通过将自定义的shader脚本添加到Sprite节点的材质上来应用该shader效果。只需要在脚本中指定shader文件的路径,然后将其赋值给节点的材质,即可使节点显示出圆形渐变的样式。 通过使用Cocos Creator提供的自定义shader功能,我们可以轻松地实现各种各样的特效和效果,使游戏和应用程序更加丰富多样化。 ### 回答2: Cocos Creator是一款游戏开发引擎,它支持使用Shader实现各种特效效果,包括圆形Shader。 在Cocos Creator中,我们可以通过编写自定义Shader实现圆形特效。首先,我们需要创建一个新的Shader文件。在Shader文件中,我们可以使用GLSL语言来编写着色器代码。 对于圆形Shader,我们可以使用圆的数学方程来实现。在vertex shader中,我们需要将顶点位置传递给fragment shader,并根据顶点位置计算出圆心距离。然后,在fragment shader中,我们可以根据圆心距离来确定像素的颜色值,从而实现圆形效果。 具体的实现代码可能如下所示: Vertex Shader: ``` attribute vec4 a_position; void main() { gl_Position = a_position; } ``` Fragment Shader: ``` uniform vec2 u_resolution; void main() { // 计算像素位置 vec2 st = gl_FragCoord.xy / u_resolution; // 计算圆心距离 float d = distance(st, vec2(0.5)); // 如果距离小于0.5(半径),则为圆形内部,否则为圆形外部 if(d < 0.5) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 设置为红色 } else { gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); // 设置为透明 } } ``` 以上代码简单实现了一个圆形Shader,在圆内部显示为红色,圆外部显示为透明。当然,你也可以根据自己的需求来修改这段代码,实现更加丰富的圆形特效效果。 在Cocos Creator中,你可以将这段Shader代码应用到你的游戏对象上,从而实现圆形特效。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值