ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CocosCreator Effect (Shader) - 反图集打包(Packable)补偿

2021-12-11 18:59:22  阅读:285  来源: 互联网

标签:Packable linear 0.0 uvs Effect Shader lrbt uv uvsc


在这里插入图片描述
这是一个在九宫格基础上使用shader画出的半透明亮线。至于如何在九宫格特性sprite上面进行均匀画线,请看另一篇文章:
CocosCreator Effect (Shader) - 反九宫格补偿

当然,这张图如果没有经过打包,所取得的结果是正常的。但是一旦进入图集打包,则会得到左图的错误结果。
处理方式1:
把这张图的Packable取消勾选,就是这张图不会进入打包即可得到正确结果。 至于在图集反正是一个effect去处理的,对DrawCall反正都要+1,在图集去除这张图也没什么不好的。
但是这个图的大部分多数情况仍需按常规显示。好吧。那我复制一个图呗。shader的用独立复制出来的额外一张小图去除packable勾选即可。
那这里我就钻个牛角尖,我就要直接使用在图集中的这张图去做effect,那么,我就需要来个针对图集中位置的反变换,把图集范围内的uv坐标还原到只表示这张图的uv [0,1]内。
如果看过反九宫格补偿这篇文章。那么应该对反变换有一定的感觉了。

反Packable变换

这次使用spriteframe的属性uv:
如果直接在start里面查询:
在这里插入图片描述
看这里的全是0或者1,没有表示出来其在大图中的位置。而实际上,你是需要把它放进图集才可以看见。如果是动态图集。引擎运行时会生成这个图集,因此这个图在大图中的位置会随着大图的变化而变化。那么我是在启动后等了10帧再去拿这个数组的(而且在实际使用时,你也需要等整个大图固定出来了之后才能拿这些数据进行计算,一般来说这个大图确实已经固定了,除非是动态图集要注意一下,稳定才能拿,或者动态图集中的图就不要用这个变换):
在这里插入图片描述
同样的这8个值同样也是表示的4个点,这4个点恰好是一个长方形,围出了小图在大图中的标准位置(我习惯把[0,1]之间的值叫做标准值,标准位置)
这里直接说结论:
其中的uv[0],uv[6]就是小图在大图中的左右两边界位置
其中的uv[7],uv[1]就是小图在大图中的上下两边界位置
那么对应给material这样传值:

let uv: number[] = this._sprite.spriteFrame.uv;
material.setProperty('u_lrbt', [uv[0], uv[6], uv[7], uv[1]]);

进入effect文件中这样去处理:

vec2 uvsc = vec2(v_uv0.x, v_uv0.y);
#if USE_PACKABLE_CONFRONT
uvsc.x = linear(u_lrbt[0], u_lrbt[1], 0.0, 1.0, uvsc.x);
uvsc.y = linear(u_lrbt[2], u_lrbt[3], 0.0, 1.0, uvsc.y);
#endif

到此,普通的一个在图集中的图就如同不打包的单图一样去处理uv,使用uvsc即可。

同时兼容反九宫格的补偿

由于有反九宫格补偿那篇文章,会发现图集中的图放进来做九宫格就会产生问题。
即使是如上使用了uv的反packable变换。
原因在于:
uvSliced,也就是传入的uvs,也会收到图集的影响。那篇文章讲的是单图。
解决方式很简单,针对传入的uvs,也如同uv一样做一次反packable变换。
改造后的代码:就是把u_uvs变换为uvs。
不做这个操作会是这样的:
在这里插入图片描述

vec2 uvsc = vec2(v_uv0.x, v_uv0.y);

    #if USE_PACKABLE_CONFRONT
    uvsc.x = linear(u_lrbt[0], u_lrbt[1], 0.0, 1.0, uvsc.x);
    uvsc.y = linear(u_lrbt[2], u_lrbt[3], 0.0, 1.0, uvsc.y);
    #endif

    #if USE_SLICED_CONFRONT

    vec4 uvs = vec4(u_uvs[0], u_uvs[1], u_uvs[2], u_uvs[3]);

    #if USE_PACKABLE_CONFRONT
    uvs[0] = linear(u_lrbt[0], u_lrbt[1], 0.0, 1.0, uvs[0]);
    uvs[1] = linear(u_lrbt[0], u_lrbt[1], 0.0, 1.0, uvs[1]);
    uvs[2] = linear(u_lrbt[2], u_lrbt[3], 0.0, 1.0, uvs[2]);
    uvs[3] = linear(u_lrbt[2], u_lrbt[3], 0.0, 1.0, uvs[3]);
    #endif

    vec4 un = vec4(0, uvs[0], uvs[1], 1.0);
    vec4 vn = vec4(0, uvs[2], uvs[3], 1.0);

    float rx = 0.0;
    float ry = 0.0;

    if (uvsc.x < uvs[0]) {
      rx = linear(un[0], un[1], u_ur[0], u_ur[1], uvsc.x);
    } else if (uvsc.x < uvs[1]) {
      rx = linear(un[1], un[2], u_ur[1], u_ur[2], uvsc.x);
    } else {
      rx = linear(un[2], un[3], u_ur[2], u_ur[3], uvsc.x);
    }

    if (uvsc.y < uvs[2]) {
      ry = linear(vn[0], vn[1], u_vr[0], u_vr[1], uvsc.y);
    } else if (uvsc.y < uvs[3]) {
      ry = linear(vn[1], vn[2], u_vr[1], u_vr[2], uvsc.y);
    } else {
      ry = linear(vn[2], vn[3], u_vr[2], u_vr[3], uvsc.y);
    }

    uvsc.x = rx / u_ur[3]; // linear(0.0, u_ur[3], 0.0, 1.0, rx);
    uvsc.y = ry / u_vr[3]; // linear(0.0, u_vr[3], 0.0, 1.0, ry);
    #endif

标签:Packable,linear,0.0,uvs,Effect,Shader,lrbt,uv,uvsc
来源: https://blog.csdn.net/Yishionwang/article/details/121877326

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有