萌新求教,夜晚2D光照该怎么实现

GIF
我是用graphics实现这种,画到一个贴图上如何给贴图做快速模糊。

引擎的各种公测贴不是j 发的吗,不是官方的人?

好帖,评论区各显神通,码了

2D全局雾效和Uniform优化

Cocos Store | 2D全局雾效和Uniform优化

1赞

没错,这种效果就完全满足了~这个是用3.x做的吗?

确实,必须给大佬们点个赞 :smile:

居然还能这样,效果很不错啊,非常感谢~~

没,这是之前2.x做的,3.x估计得稍微改下shader吧,不过我这种方法感觉还是绕了点,我是每个需要光源的节点挂个自定义的光源脚本和碰撞脚本,因为配置脚本可以编辑形状,直接读节点下挂的所有碰撞脚本,创建对应的圆、方和多边形。然后在一个光源管理的脚本统一把这些形状的数据绘制到一个graphics上,这个graphics绘制到一个单独的sprite上面,最后写了一个shader挂在这个sprite上,大概逻辑是有颜色绘制过的部分直接改为透明,其余未绘制的是环境色比如纯黑。最后再来一个快速模糊。

// 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.7 }
        size: { value: [160.0, 90.0], editor: { tooltip: '节点尺寸' } }
        lightColor: { value: [0.0, 0.0, 0.1, 0.1], inspector: { type: color } }
}%


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>
  #include <texture>

  in vec4 v_color;

  #if USE_TEXTURE
  in vec2 v_uv0;
  uniform sampler2D texture;
  #endif
  uniform Properties {
    vec4 lightColor;
    vec2 size;
  };

  vec4 getC(vec2 pos){
    vec4 color = texture2D(texture, pos);
    //透明直接返回阴影色, 否则返回透明
    if(color.a == 0.){
      return lightColor;
    }else {
      return vec4(0.,0.,0.,0.);
    }
  }
  //快速模糊
  vec4 blur13color(vec2 pos, vec2 direction){
    vec4 color = vec4(0.0);
    vec2 off1 = vec2(1.411764705882353) * direction;
    vec2 off2 = vec2(3.2941176470588234) * direction;
    vec2 off3 = vec2(5.176470588235294) * direction;
    color += getC(pos) * 0.1964825501511404;
    color += getC(pos + (off1 / size)) * 0.2969069646728344;
    color += getC(pos - (off1 / size)) * 0.2969069646728344;
    color += getC(pos + (off2 / size)) * 0.09447039785044732;
    color += getC(pos - (off2 / size)) * 0.09447039785044732;
    color += getC(pos + (off3 / size)) * 0.010381362401148057;
    color += getC(pos - (off3 / size)) * 0.010381362401148057;
    return color;
  }

  void main () {
    vec4 o = blur13color(v_uv0,vec2(1.0,0.0));
    ALPHA_TEST(o);
    gl_FragColor = o;
  }
}%
1赞

卧槽,感觉还挺复杂的。得好好研究一下了 :joy:

这个单独的sprite相当于是一个遮罩一样的东西吗?

image
说简单可以很简单,就是一个mask,不停绘制中间的镂空即可;
但是如果只是用image做,会很耗时;
一般还是用shader做;
。。。。。
我最后是用Unity做的

是的,就是个图片全屏覆盖在最上面

所以。。。最终你还是败给了现实

主要是mask只能镂空一个圆圈,要是同一个黑幕上要镂空多个圆圈出来,就麻烦了

:rofl: :rofl:

你的名字是rustGo,你怎么不用c++呢

那这个图片是覆盖当前屏幕可视区域吗,还是说其实是覆盖了整个场景?

我是用一个比屏幕大一点的sprite,然后这个sprite始终跟着主摄像头移动 :rofl:

因为cpp不香

原来如此,思路好棒~~