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

好的,感谢大佬~

太感谢了~~~

:+1: :+1: :+1:

大佬威武~ :+1:雪中送炭啊,不过我用的3.x做2d游戏,是不是该换成2.x比较好? :joy:

不不不,我只需要最简单的一个光亮就行了,不需要什么阴影或者烘焙之类的,游戏嘛,玩法大于一切,特效什么的及格就可以了 :smile:

:+1:原来还是有部分代码可以通用的啊

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相当于是一个遮罩一样的东西吗?


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