【cocos creator 3.x】 修改builtin-unlit 加了一个类似流光显示的mask参数

news2025/1/11 22:50:31

效果见图:

shader 代码修改如下, 主要看 USE_MASK_UVY 关键字部分修改:

// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
CCEffect %{
  techniques:
  - name: opaque
    passes:
    - vert: unlit-vs:vert
      frag: unlit-fs:frag
      properties: &props
        mainTexture:    { value: grey }
        tilingOffset:   { value: [1, 1, 0, 0] }
        mainColor:      { value: [1, 1, 1, 1], linear: true, editor: { type: color } }
        colorScale:     { value: [1, 1, 1], target: colorScaleAndCutoff.xyz }
        alphaThreshold: { value: 0.5, target: colorScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } }
        color:          { target: mainColor, linear: true, editor: { visible: false } } # backward compability
        mask_uvpos:     { value: 0.5, target: mask.x, editor: { parent: USE_MASK_UVY } } # uv 采样中心位置
        mask_width:     { value: 0.1, target: mask.y, editor: { parent: USE_MASK_UVY, range: [0, 1] } } # uv 采样上下宽度范围
        mask_lerpwidth:     { value: 0.05, target: mask.z, editor: { parent: USE_MASK_UVY , range: [0, 1]} } # uv 采样边缘平滑宽度
        mask_alpha_strength:     { value: 1, target: mask.w, editor: { parent: USE_MASK_UVY } } # uv 采样透明度强度

      migrations: &migs
        properties:
          mainColor:    { formerlySerializedAs: color }
    - &planar-shadow
      vert: planar-shadow-vs:vert
      frag: planar-shadow-fs:frag
      phase: planar-shadow
      propertyIndex: 0
      depthStencilState:
        depthTest: true
        depthWrite: false
        stencilTestFront: true
        stencilFuncFront: not_equal
        stencilPassOpFront: replace
        stencilRef: 0x80 # only use the leftmost bit
        stencilReadMask: 0x80
        stencilWriteMask: 0x80
      blendState:
        targets:
        - blend: true
          blendSrc: src_alpha
          blendDst: one_minus_src_alpha
          blendDstAlpha: one_minus_src_alpha
    - &deferred-forward
      vert: unlit-vs:vert
      frag: unlit-fs:frag
      phase: deferred-forward
      propertyIndex: 0
  - name: transparent
    passes:
    - vert: unlit-vs:vert
      frag: unlit-fs:frag
      depthStencilState: &d1
        depthTest: true
        depthWrite: false
      blendState: &b1
        targets:
        - blend: true
          blendSrc: src_alpha
          blendDst: one_minus_src_alpha
          blendDstAlpha: one_minus_src_alpha
      properties: *props
      migrations: *migs
    - *planar-shadow
    - &deferred-forward-transparent
      vert: unlit-vs:vert
      frag: unlit-fs:frag
      phase: deferred-forward
      propertyIndex: 0
      migrations: *migs
      depthStencilState: *d1
      blendState: *b1
  - name: add
    passes:
    - vert: unlit-vs:vert
      frag: unlit-fs:frag
      rasterizerState: &r1 { cullMode: none }
      depthStencilState: *d1
      blendState: &b2
        targets:
        - blend: true
          blendSrc: src_alpha
          blendDst: one
          blendSrcAlpha: src_alpha
          blendDstAlpha: one
      properties: *props
      migrations: *migs
    - &deferred-forward-add
      vert: unlit-vs:vert
      frag: unlit-fs:frag
      phase: deferred-forward
      rasterizerState: *r1
      depthStencilState: *d1
      blendState: *b2
      propertyIndex: 0
      migrations: *migs
  - name: alpha-blend
    passes:
    - vert: unlit-vs:vert
      frag: unlit-fs:frag
      rasterizerState: *r1
      depthStencilState: *d1
      blendState: &b3
        targets:
        - blend: true
          blendSrc: src_alpha
          blendDst: one_minus_src_alpha
          blendSrcAlpha: src_alpha
          blendDstAlpha: one_minus_src_alpha
      properties: *props
      migrations: *migs
    - &deferred-forward-alpha-blend
      vert: unlit-vs:vert
      frag: unlit-fs:frag
      phase: deferred-forward
      rasterizerState: *r1
      depthStencilState: *d1
      blendState: *b3
      propertyIndex: 0
      migrations: *migs
}%

CCProgram unlit-vs %{
  precision highp float;
  #include <legacy/input>
  #include <builtin/uniforms/cc-global>
  #include <legacy/decode-base>
  #include <legacy/local-batch>
  #include <legacy/input>
  #include <legacy/fog-vs>

  #if USE_VERTEX_COLOR
    in lowp vec4 a_color;
    out lowp vec4 v_color;
  #endif

  #if USE_TEXTURE
    out vec2 v_uv;
    uniform TexCoords {
      vec4 tilingOffset;
    };
  #endif

  vec4 vert () {
    vec4 position;
    CCVertInput(position);

    mat4 matWorld;
    CCGetWorldMatrix(matWorld);

    #if USE_TEXTURE
      v_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;
      #if SAMPLE_FROM_RT
        CC_HANDLE_RT_SAMPLE_FLIP(v_uv);
      #endif
    #endif

    #if USE_VERTEX_COLOR
      v_color = a_color;
    #endif

    CC_TRANSFER_FOG(matWorld * position);
    return cc_matProj * (cc_matView * matWorld) * position;
  }
}%

CCProgram unlit-fs %{
  precision highp float;
  #include <legacy/output-standard>
  #include <legacy/fog-fs>

  #if USE_ALPHA_TEST
    #pragma define-meta ALPHA_TEST_CHANNEL options([a, r, g, b])
  #endif

  #if USE_TEXTURE
    in vec2 v_uv;
    uniform sampler2D mainTexture;
  #endif

  uniform Constant {
    vec4 mainColor;
    vec4 colorScaleAndCutoff;
    vec4 mask;  // USE_MASK_UVY
  };

  #if USE_VERTEX_COLOR
    in lowp vec4 v_color;
  #endif

  #if USE_MASK_UVY
  // float LerpMask(float uv_y, vec4 mask) {
  //   float d = abs(uv_y - mask.x);  // uv y 与中心点的距离
  //   float a = mask.w;
  //   float d2 = d - mask.y;        // 距离小于 mask.y(mask宽度范围) 则显示全值
  //   if(d2 > 0.0) {
  //     if(d2 <= mask.z && mask.z > 0.0) {
  //       a *= (1.0 - (d2 /mask.z)); // 距离大于 mask.y 且 小于 mask.z(mask边缘平滑宽度) 则开始衰减
  //     } else {
  //       a = 0.0;
  //     }
  //   }
  //   return a;
  // }
  float LinearStep(float t1, float t2, float x)
  {
      x = clamp((x-t1)/(t2-t1),0.0,1.0);
      // return x*x*(3-2*x);  // smoothstep
      return x;
  }
  #endif

  vec4 frag () {
    vec4 o = mainColor;
    o.rgb *= colorScaleAndCutoff.xyz;

    #if USE_VERTEX_COLOR
      o.rgb *= SRGBToLinear(v_color.rgb);//use linear
      o.a *= v_color.a;
    #endif


    #if USE_TEXTURE
      vec4 texColor = texture(mainTexture, v_uv);
      texColor.rgb = SRGBToLinear(texColor.rgb);
      o *= texColor;
    #endif

  #if USE_MASK_UVY
    // o.a *= LerpMask(v_uv.y, mask);
    o.a *= LinearStep(mask.z, 0.0, abs(v_uv.y - mask.x) - mask.y) * mask.w;
  #endif

    #if USE_ALPHA_TEST
      if (o.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard;
    #endif

    CC_APPLY_FOG(o);
    return CCFragOutput(o);
  }
}%

CCProgram planar-shadow-vs %{
  precision highp float;
  #include <legacy/input>
  #include <builtin/uniforms/cc-global>
  #include <legacy/decode-base>
  #include <legacy/local-batch>
  #include <builtin/uniforms/cc-shadow>
  #include <common/lighting/functions>

  out float v_dist;

  vec4 vert () {
    vec4 position;
    CCVertInput(position);
    // World Space
    mat4 matWorld, matWorldIT;
    CCGetWorldMatrixFull(matWorld, matWorldIT);
    vec3 worldPos = (matWorld * position).xyz;
    vec4 shadowPos = CalculatePlanarShadowPos(worldPos, cc_cameraPos.xyz, cc_mainLitDir.xyz, cc_planarNDInfo);
    position = CalculatePlanarShadowClipPos(shadowPos, cc_cameraPos.xyz, cc_matView, cc_matProj, cc_nearFar, cc_shadowWHPBInfo.w);
    v_dist = shadowPos.w;
    return position;
  }
}%

CCProgram planar-shadow-fs %{
  precision highp float;
  #include <builtin/uniforms/cc-shadow>
  #include <legacy/output>

  in float v_dist;

  vec4 frag () {
    if(v_dist < 0.0)
      discard;
    return CCFragOutput(cc_shadowColor);
  }
}%

即加了4个参数:


        mask_uvpos:     { value: 0.5, target: mask.x, editor: { parent: USE_MASK_UVY } } # uv 采样中心位置
        mask_width:     { value: 0.1, target: mask.y, editor: { parent: USE_MASK_UVY, range: [0, 1] } } # uv 采样上下宽度范围
        mask_lerpwidth:     { value: 0.05, target: mask.z, editor: { parent: USE_MASK_UVY , range: [0, 1]} } # uv 采样边缘平滑宽度
        mask_alpha_strength:     { value: 1, target: mask.w, editor: { parent: USE_MASK_UVY } } # uv 采样透明度强度



核心算法就一句:
    o.a *= smoothstep(mask.z, 0.0, abs(v_uv.y - mask.x) - mask.y) * mask.w; 

感觉平滑过渡反而不好,所以自己实现了一个函数 LinearStep:
    o.a *= LinearStep(mask.z, 0.0, abs(v_uv.y - mask.x) - mask.y) * mask.w;

注释掉的 LerpMask 是等价这个算法的,只不过用了 if else来实现的。


算法思路如下: 靠近 pos width内的 全部显示, 接着lerpwidth内的渐变显示, 超过这个距离的不显示:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1820156.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据可视化:Seaborn

安装Seaborn 进入虚拟环境&#xff0c;在终端中键入 pip install seaborn 即可安装。 初步使用Seaborn 在使用seaborn之前&#xff0c;我们先了解一下seaborn是什么&#xff0c;seaborn是以matplotlib为底层的更简便的python第三方库&#xff0c;它可以更快捷地去设置图形的一…

为CAP面板添加简单的Authentication登录验证功能 C#|.net

终于搞定了CAP Dashboard的登录验证功能! 因为网上找不到简单的CAP Dashboard的登录验证功能,所以这个功能摸索着开发了好久。 这个Authentication认证功能,不仅适用于CAP面板,也适用于懒得开发登录页面,但是又需要简单用户名密码登录的网页。 做过后端的比较熟悉,CAP面…

【SCAU数据挖掘】数据挖掘期末总复习题库简答题及解析——上

1.K-Means 假定我们对A、B、C、D四个样品分别测量两个变量&#xff0c;得到的结果见下表。 样品 变量 X1X2 A 5 3 B -1 1 C 1 -2 D -3 -2 利用K-Means方法将以上的样品聚成两类。为了实施均值法(K-Means)聚类&#xff0c;首先将这些样品随意分成两类(A、B)和(C、…

MYSQL 查看SQL执行计划

一、explain explain select id,db,user,host,command,time,state,info from information_schema.processlist order by time desc; id: 查询的标记&#xff0c;可以查看不同查询的执行顺序。 select_type: 查询的类型&#xff0c;如SIMPLE、SUBQUERY、PRIMARY等。 table: …

深入理解指针(二)

目录 1. 数组名的理解 2. 使用指针访问数组 3. ⼀维数组传参的本质 4. 冒泡排序 5. 二级指针 6. 指针数组 7. 指针数组模拟二维数组 1. 数组名的理解 有下面一段代码: #include <stdio.h> int main() {int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int* p &arr[…

【python】通行网格地图四叉树化 (leeccode 427)

【python】通行网格地图四叉树化 受到Leecode 427题的启发&#xff0c;427. 建立四叉树 想将由0和1组成的网格地图绘制为四叉树地图&#xff0c;0表示可通行网格&#xff0c;1表示不可通行网格。 import matplotlib.pyplot as plt import matplotlib.patches as patches …

一文教会你静态住宅代理IP的优势和选择技巧,跨境小白收好这份指南!

一、什么是静态住宅代理IP&#xff1f; 静态住宅代理IP是指分配给个人住宅网络的IP地址&#xff0c;这些IP地址在长时间内保持不变。它们是从互联网服务提供商&#xff08;ISP&#xff09;获取的&#xff0c;因此拥有更高的可信度和较低的被封禁风险。静态住宅代理IP因其独特的…

SpringBoot3 常用的第三方接口调用十种方式

环境&#xff1a;SpringBoot.3.3.0 简介 在项目中调用第三方接口是日常开发中非常常见的。调用方式的选择通常遵循公司既定的技术栈和架构规范&#xff0c;以确保项目的一致性和可维护性。无论是RESTful API调用、Feign声明式HTTP客户端、Apache HttpClient等调用方式&#x…

Word同行内的文字如何左右分别对齐

先打开标尺&#xff08;视图-标尺&#xff09; 开右边&#xff0c;选一个制表位置&#xff0c;比如我选34 切回开始&#xff0c;点段落段落右下角 然后 然后 我修改为35&#xff08;因为“6月13日”总共3个字符&#xff09; 在文字中间按下Tab键&#xff0c;效果如下

Spring Boot 自定义校验注解

1.创建注解&#xff0c;可参考其他检验注解进行创建 2.创建校验类&#xff0c;需实现ContraintValidator并重写isValid方法,注意范型中表示给那个注解(State)提供校验及校验类型&#xff08;String&#xff09;,然后自行编写校验规则true为检验成功&#xff0c;false为失败 3.使…

网工内推 | 外企、上市公司运维工程师,有软考中高项证书优先

01 优尼派特&#xff08;苏州&#xff09;物流有限公司 &#x1f537;招聘岗位&#xff1a;软件运维测试工程师 &#x1f537;任职要求&#xff1a; 1、负责公司自主研发的软件售后服务工作, 包括软件的安装, 调试, 升级,培训, 参数配置, 需求与Bug的处理; 2、负责数据库升级及…

unDraw —— 免费且可定制的插画库,为您的设计注入灵魂

&#x1f3a8; unDraw —— 免费且可定制的插画库&#xff0c;为您的设计注入灵魂 在寻找能够完美融入您品牌风格的插画吗&#xff1f;unDraw&#xff0c;一个提供大量免费插画资源的网站&#xff0c;可能是您的理想选择&#xff01; &#x1f310; 网站特色 免费且开源 unDraw…

Doris集群管理工具Doris Manager安装使用(已踩坑)

背景&#xff1a;Doris集群管理、监控相对复杂&#xff0c;就想着有没有免费的、好用的管理工具&#xff0c;就发现了Doris Manager&#xff0c;给大家分享一下。 官网&#xff1a;https://docs.selectdb.com/docs/enterprise/cluster-manager-guide/deployment-guide/deployme…

【算法训练记录——Day28】

Day28——回溯算法Ⅳ 1.复原IP地址2.[全排列](https://leetcode.cn/problems/permutations/submissions/539240290/)3.[全排列Ⅱ](https://leetcode.cn/problems/permutations-ii/description/) ● 93.复原IP地址 ● 78.子集 ● 90.子集II 1.复原IP地址 思路&#xff1a;相当于…

【OceanBase DBA早下班系列】—— 性能问题如何 “拍CT“ (一键获取火焰图和扁鹊图)

1. 前言 最近接连遇到几个客户的环境在排查集群性能问题&#xff0c;总结了一下&#xff0c;直接教大家如何去获取火焰图、扁鹊图&#xff08;调用关系图&#xff09;&#xff0c;直击要害&#xff0c;就像是内脏的疾病去医院看病&#xff0c;上来先照一个CT&#xff0c;通过分…

HarmonyOS Next 系列之HTTP请求封装和Token持久化存储(四)

系列文章目录 HarmonyOS Next 系列之省市区弹窗选择器实现&#xff08;一&#xff09; HarmonyOS Next 系列之验证码输入组件实现&#xff08;二&#xff09; HarmonyOS Next 系列之底部标签栏TabBar实现&#xff08;三&#xff09; HarmonyOS Next 系列之HTTP请求封装和Token…

家用洗地机排行榜前十名:2024十大王牌机型精准种草

最近很多人都在问我洗地机相关的问题&#xff0c;不愧是改善家庭生活品质的“三神器”之一。洗地机依靠其清洁力和清洁效率吸引了越来越多的平时需要做家务人群的兴趣&#xff0c;为了解答大家关于洗地机的各种疑问&#xff0c;我把市面上目前非常火爆的洗地机型号和参数都进行…

探索未来通信的新边界:AQChat一款融合AI的在线匿名聊天

探索未来通信的新边界&#xff1a;AQChat一款融合AI的在线匿名聊天 在数字时代&#xff0c;即时通讯变得无处不在&#xff0c;但隐私和性能仍旧是许多用户和开发者关注的焦点。今天&#xff0c;我要介绍一个开创性的开源项目 —— AQChat&#xff0c;它不仅重定义了在线匿名聊…

Spring IoC注解

一、回顾反射机制 反射的调用三步&#xff1a;1&#xff09;获取类。2&#xff09;获取方法。3&#xff09;调用方法 调用方法&#xff1a;调用哪个对象&#xff0c;哪个方法&#xff0c;传什么参数&#xff0c;返回什么值。 方法&#xff08;Do&#xff09;类&#xff1a; …

eFuse电子保险丝,需要了解的技术干货来啦

热保险丝作为一种基本的电路保护器件&#xff0c;已经成功使用了150多年。热保险丝有效可靠、易用&#xff0c;具有各种不同的数值和版本&#xff0c;能够满足不同的设计目标。然而&#xff0c;对于寻求以极快的速度切断电流的设计人员来说&#xff0c;热保险丝不可避免的缺点就…