【分享】基于SDF的2D shader

学废了,先插眼

感觉比腊鸭论坛强多了

可以可以。学习了。

优秀啊,大佬

mark!!!

感谢大佬orz

大佬牛皮!!!

mark wwww

大佬~~~

大佬,放到3.0里面,就剩下一条线,有得整不?

image
image

// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
CCEffect %{
  techniques:
  - passes:
    - vert: sprite-vs:vert
      frag: sprite-fs:frag
      depthStencilState:
        depthTest: false
        depthWrite: false
      blendState:
        targets:
        - blend: true
          blendSrc: src_alpha
          blendDst: one_minus_src_alpha
          blendDstAlpha: one_minus_src_alpha
      rasterizerState:
        cullMode: none
      properties:
        alphaThreshold: { value: 0.5 }
        outlineColor: { value: [1., 0., 1., 1.], editor: { type: color, displayName: '颜色' } }
}%

CCProgram sprite-vs %{
  precision highp float;
  #include <cc-global>
  #if USE_LOCAL
    #include <cc-local>
  #endif

  in vec3 a_position;
  in vec2 a_texCoord;
  in vec4 a_color;

  out vec4 color;
  out vec2 uv0;

  vec4 vert () {
    vec4 pos = vec4(a_position, 1);

    #if USE_LOCAL
      pos = cc_matWorld * pos;
    #endif

    #if USE_PIXEL_ALIGNMENT
      pos = cc_matView * pos;
      pos.xyz = floor(pos.xyz);
      pos = cc_matProj * pos;
    #else
      pos = cc_matViewProj * pos;
    #endif

    uv0 = a_texCoord;

    color = a_color;

    return pos;
  }
}%

CCProgram sprite-fs %{
  precision highp float;
  #include <embedded-alpha>
  #include <alpha-test>
  #include <cc-global>

  in vec4 color;
  in vec2 uv0;
  #define PI 3.141592653589793

  #if USE_TEXTURE
    #pragma builtin(local)
    layout(set = 2, binding = 10) uniform sampler2D cc_spriteTexture;
  #endif

  #if USE_OUTLINE
    uniform ARGS {
      vec4 outlineColor;
    };
  #endif

  
  float Remap01(float a, float b, float t) {
    return (t-a) / (b-a);
  }

  float Remap(float a, float b, float c, float d, float t) {
    return Remap01(a, b, t) * (d-c) + c;
  }
 
  // 脉冲函数
  // X,Y区间都是[0,1],X=0.5位置Y=1
  // https://www.iquilezles.org/www/articles/functions/functions.htm
  float Pulse(float x) {
    return pow(4.0 * x * (1.0 - x), 16.0);
  }

  vec4 frag () {
    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE
      o *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0);
      //o *= texture(cc_spriteTexture, uv0) * color;
      #if IS_GRAY
        float gray  = 0.2126 * o.r + 0.7152 * o.g + 0.0722 * o.b;
        o.r = o.g = o.b = gray;
      #endif
    #endif

    #if USE_OUTLINE

      float alpha = o.a;
    
      // 轮廓宽度(0.0, 1.0), 对应alpha区域
      float offset = Remap(-1., 1., 0., 0.2, sin(cc_time.x * 2.0 * PI + uv0.y * 3.0));
      float outlineWidth = 0.3 + offset * (uv0.y);

      // 选择一个alpha值做为轮廓的中线
      float centerAlpha = 0.5;

      float alphaDist = abs(alpha - centerAlpha);
      float mask = smoothstep(outlineWidth, 0., alphaDist);

      // 外发光颜色
      //vec4 outlineColor = outlineColorvec4(1., 0.5, 0., mask);
      vec4 oc = outlineColor;
      oc.a = mask;
      
      // 底色基础上叠加一个亮度,叠加后中心位置变白
      float brightness = 0.3;
      oc.rgb += Pulse((alphaDist + 0.5)) * brightness;

      // 原图的轮廓alpha平滑处理
      o.a = smoothstep(0.48, 0.49, alpha);
      o.rgb *= o.a;

      // 外发光和原图混合
      o = mix(oc, o, smoothstep(0.49, 0.5, alpha));
      //o = oc;

    #endif

    //o *= color;
    //ALPHA_TEST(o);
    return o;
  }
}%

shader是配合SDF使用的,你用的纹理不是SDF

大佬能请教下吗,我搜了网上有很多生成 sdf 字体纹理的工具,但是有啥好的生成任何图片的 sdf 纹理的工具能推荐下吗,谢谢了

哦哦,我是用demo里你的那个头像素材也不行,是哪里操作不正确吗?

我也没有现成的推荐哦。你可以试试吧DEMO里的SDF模块提取出来。字体计算SDF也是需要先绘制字体图像然后计算SDF的,可以直接以你自己的图像作为输入

看来3.0不支持哦,有空我再整整:)

谢谢大佬 :slight_smile:

优秀。。。

膜拜大佬!

大佬,这个一定要用摄像机才能获取到像素数据么…