如何实现图片的阴影/投影的效果?

只是单纯的图片阴影效果,像这样。


目前只有2个思路
开始想用这种方法,通过把子节点的zIndex设置成负的来达成这个效果,然鹅查了下好像只有同节点设置zIndex才有效
还有一种方法就是另外再加一个节点层来管理添加阴影的,不过这样就又得做个阴影层的pool…,这样逻辑就更复杂了。。。,目前还未梳理清逻辑
大佬们能给个建议么?在线等急(
ps:实在不行就只能用把阴影画在图片上了。不过这样工作量就会大很多,而且坐标也得根据阴影重新调整了。。

好像这里有人搞过模拟的点光源实现阴影,可惜Shader不懂,不知道怎么改到creator 2的版本上来
github地址:https://github.com/nhljh1234/MyProject/tree/master/2DLight

简单实现就是阴影做父节点。

感谢分享,可惜我也是用2.0的,官方说是 shader 的使用改为了 material,但是提供的例子完全看不懂:joy:

求一个 2.3 的 2D 阴影shader

vec2 shadowOffset = vec2(-0.03, 0.02);
vec4 textureColor = texture2D(texture, v_uv0);
textureColor += texture2D(texture, v_uv0  + shadowOffset) * vec4(0., 0., 0., 1.);
gl_FragColor = textureColor;
可以满足楼主这种阴影的需求
1赞

// 给你个shader ,create effect + Metarial ,挂到sprite上。
但是只支持native,浏览器下看不到阴影。同时求大神指点

CCEffect %{
techniques:

  • passes:
    • vert: vs
      frag: fs
      blendState:
      targets:
      • blend: true
        rasterizerState:
        cullMode: none
        properties:
        texture: { value: white }
        alphaThreshold: { value: 0.5 }
        shadowAlpha: { value: 0.5 }
        offset: {
        value: [-0.2, -0.2],
        editor: {
        tooltip: “阴影偏移量”
        }
        }

      阴影颜色

      shadowColor: {
      value: [1.0, 1.0, 1.0, 1.0],
      editor: {
      type: color,
      tooltip: “阴影颜色”,
      }
      }
      }%

CCProgram vs %{
precision highp float;

#include
#include

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

in vec4 v_color;

#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D texture;
#endif
uniform shadowP {
// 颜色
vec4 shadowColor;
// 发光范围
vec2 offset;
// 阈值
float shadowAlpha;

};

vec4 getTextureColor(sampler2D texture, vec2 v_uv0) {
  if (v_uv0.x > 1.0 || v_uv0.x < 0.0 || v_uv0.y > 1.0 || v_uv0.y < 0.0) {
    return vec4(0.0, 0.0, 0.0, 0.0);
  }
  return texture(texture, v_uv0);
}

/**

  • 获取指定角度方向,距离为xxx的像素的透明度
  • @param angle 角度 [0.0, 360.0]
  • @param dist 距离 [0.0, 1.0]
  • @return alpha [0.0, 1.0]
    */
    float getColorAlpha(float angle, float dist) {
    // 角度转弧度,公式为:弧度 = 角度 * (pi / 180)
    float radian = angle * 0.01745329252; // 这个浮点数是 pi / 180
    vec4 color = getTextureColor(texture, v_uv0 + vec2(dist * cos(radian), dist * sin(radian)));
    return color.a;
    }

/**

  • 获取指定距离的周边像素的透明度平均值
  • @param dist 距离 [0.0, 1.0]
  • @return average alpha [0.0, 1.0]
    */
    float getAverageAlpha(float dist) {
    float totalAlpha = 0.0;
    const float count = 30.0;
    const float angle = 360.0 / count;
    for (float i = 0.0; i < count; i += 1.0) {
    totalAlpha += getColorAlpha(angle * i, dist) ;
    }
    return totalAlpha / count;
    }

/**

  • 获取发光的透明度
    */
    float getGlowAlpha() {
    float glowColorSize = 0.1;
    // 如果发光宽度为0,直接返回0.0透明度,减少计算量
    if (glowColorSize == 0.0) {
    return 0.0;
    }
// 将传入的指定距离,平均分成10圈,求出每一圈的平均透明度,
// 然后求和取平均值,那么就可以得到该点的平均透明度
float totalAlpha = 0.0;
totalAlpha += getAverageAlpha(glowColorSize * 0.1);
totalAlpha += getAverageAlpha(glowColorSize * 0.2);
totalAlpha += getAverageAlpha(glowColorSize * 0.3);
totalAlpha += getAverageAlpha(glowColorSize * 0.4);
totalAlpha += getAverageAlpha(glowColorSize * 0.5);
totalAlpha += getAverageAlpha(glowColorSize * 0.6);
totalAlpha += getAverageAlpha(glowColorSize * 0.7);
totalAlpha += getAverageAlpha(glowColorSize * 0.8);
totalAlpha += getAverageAlpha(glowColorSize * 0.9);
totalAlpha += getAverageAlpha(glowColorSize * 1.0);
return totalAlpha * 0.1;

}

void main () {
vec4 o = vec4(1, 1, 1, 1);

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

o *= v_color;

ALPHA_TEST(o);

if(o.a<shadowAlpha){
  vec4 shadow = vec4(0.0);
  vec2 v = v_uv0  + offset;
  if(v.x> 0.0 && v.x<1.0 && v.y>0.0 && v.y<1.0){
    shadow = texture2D(texture, v_uv0  + offset) * vec4(0., 0., 0.,o.a);
  }
  if(shadow.a>0.0){
    o = shadowColor;
  }
}

gl_FragColor = o;

}
}%

把材质直接拖到精灵上吗?啥效果都没有,怎么回事呢

可以看一下这个

https://store.cocos.com/app/detail/6668

我看是3.x的版本,2.4版本可以用吗?

可以参考 3.x 的 effect 迁移一下,或者直接联系我

这个应该就只有方块的效果吧,如果是多边形会有效果吗?

像商店里面的示例动图,其实是实时渲染的

preview

注意:左上角的那个方块,它一直在自转,其实想表达的是,这里的投影是可以实现计算处理

一些补充

  1. 项目里,应该不是所有的东西都需要生成投影,大部分可能都是仅限一些节点需要生成投影
  2. 仅仅 将需要生成投影的节点,先渲染到一个 RT(实时每帧渲染到RT)
  3. 将 RT 重新用一个 Sprite 组件去渲染,然后这个 Sprite 应用投影材质

最后就可以做到示例动图的效果

经过这几个说明,我感觉应该可以满足你的疑问

用3d摄像机 和 3d object

两张图叠一起不就好了,阴影图片就是把原图调成黑色。