思路:

  1. uv.x取模
  2. 使用step处理这个模(也可以用smoothstep,以造成柔和边缘)
  3. 乘上一个旋转矩阵
  4. 根据a通道,控制阴影(透明)部分不要应用这个效果(如果有背景的时候可以看出来)

紧接着,就遇到了九宫格特性与其兼容性问题。

反九宫格变换

当使用了九宫格特性,得到的uv已经是变换之后的,如果希望上面的运算处在一个平直的均匀的坐标中。那么需要对这个变换做反运算。

仔细查询spriteframe的一个属性_capInsets:

和另一个属性uvSliced:(这个属性可以也用node size和上面的capInsets计算比例得到)

显然这跟九宫格的设置是有关系的 Border Top/Bottom/Left/Right

仔细观察,这16个点的与原始图形的关系是这样的
[1213141589101145670123]\begin{bmatrix}12&13&14&15\\8&9&10&11\\4&5&6&7\\0&1&2&3\end{bmatrix}⎣⎢⎢⎡​12840​13951​141062​151173​⎦⎥⎥⎤​
那么需要获取拉伸的信息,只需要把1,2的u坐标和8,4的v坐标传给shader即可。
另外用上面的_capInsets结合node.width/height排出一个这几条线的序列,方便shader使用。
比如上图的4条线在200宽的图像上的实际坐标位:[0,24,176,200]
其中的0,200确实是冗余的,其实只要24和200这两个数据就能算出上面的数组,但是为了shader计算方便,我就这么写了。
最终用一个这样给material传参数:

let uvSliced: { u: number, v: number }[] = this._sprite.spriteFrame.uvSliced;
let capInsets: number[] = this._sprite.spriteFrame._capInsets;
material.setProperty('u_uvs', [uvSliced[1].u, uvSliced[2].u, uvSliced[8].v, uvSliced[4].v]);
material.setProperty('u_ur', [0, capInsets[0], this.node.width - capInsets[2], this.node.width]);
material.setProperty('u_vr', [0, capInsets[1], this.node.height - capInsets[3], this.node.height]);

思路:
1.uv的x,y独立处理
2.linear函数自己可以构造一个,非常方便在原点不为零的两个线段之间做线性变换
3.把标准值[0,1]先按照九宫格的分段,映射到真实长度坐标下[0,width],[0,height]
4.真实坐标后,按真实坐标总长线性变换回标准区间[0,1]即可

  float linear(float x0, float x1, float y0, float y1, float inputX) {return (y1 - y0) * (inputX - x0) / (x1 - x0) + y0;}

而兼容九宫格特性的相关shader代码这样写:

    vec2 uvsc = vec2(v_uv0.x, v_uv0.y);#if USE_SLICED_CONFRONTvec4 un = vec4(0, u_uvs[0], u_uvs[1], 1.0);vec4 vn = vec4(0, u_uvs[2], u_uvs[3], 1.0);float rx = 0.0;float ry = 0.0;if (uvsc.x < u_uvs[0]) {rx = linear(un[0], un[1], u_ur[0], u_ur[1], uvsc.x);} else if (uvsc.x < u_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 < u_uvs[2]) {ry = linear(vn[0], vn[1], u_vr[0], u_vr[1], uvsc.y);} else if (uvsc.y < u_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

计算得到的uvsc在下面代替原本的v_uv0使用即可

图集兼容性问题

如果你用的这张图片是图集中的,那么显示上一定会出问题。
两个原因:

  1. uv是相对大图中的。
  2. uvSliced是相对大图中的。
    因此需要变换回标准区间[0,1]
    详细内容看这下一篇文章:
    CocosCreator Effect (Shader) - 反图集打包(Packable)补偿

CocosCreator Effect (Shader) - 反九宫格就(Sliced)补偿相关推荐

  1. CocosCreator Effect (Shader) - 斜条纹如何画

    左图是原图,没有使用九宫格sliced.也没有在图集中.这篇文章作为基础,只考虑如何画斜条纹.另外两篇文章讨论了如何处理在九宫格和在图集中使用的问题. 注意,所有的改动都在这里: void main ...

  2. 【转】Silverlight 3 Beta 新特性解析(7)- Child Window和Shader Effect篇

    前提条件: 阅读本文之前请确认你已经安装了如下软件 Visual Studio 2008 (Express) SP1 Silverlight 3 Tools For Visual Studio Mic ...

  3. CocosCreator优化之DrawCall漫谈

    本文首发于我的个人Blog阿西BUG,欢迎大家批评指正 前言 在游戏开发中,DrawCall 作为一个非常重要的性能指标,直接影响游戏的整体性能表现. 无论是 Cocos Creator.Unity. ...

  4. CocosCreator2.3.3 Effect中换算图集中UV

    CocosCreator2.3.3 Effect中换算图集中UV 需求 环境 准备知识(要点) 线性变换 spriteFrame在自动图集中的位置 一个Demo 编写Effect (Shader) T ...

  5. Unity Shader着色器优化

    对游戏开发者而言,着色器长久以来就是游戏开发中的重要部分,在Unity中编写并实现着色器的过程直观且高效,优秀的着色器还可以创造非常精美的游戏画面,同时保证极高的性能.今天将由Unity的技术工程师张 ...

  6. UnityShader2:Shader与材质

    前置:Unity3D基础3:贴图与材质球 一.Shader 与材质 贴图 + 着色器(Shader) = 材质球 同一张贴图使用不同的着色器,可以展现出不同的效果: 在下面这个位置设置 Shader, ...

  7. 1.Unity之Shader新手入门

    Unity Shader着色器的基本概念 如何使用Unity Shader着色器 示例:如何使用Unity Shader着色器创建复杂的效果 总结 什么是Unity中的Shader着色器? Shade ...

  8. Unity学习之Shader

    Shader 是用来实现图像渲染的,用来替代固定渲染管线的可编辑程序.其中Vertex Shader(顶点着色器)主要负责顶点的几何关系等的运算,Pixel Shader(像素着色器)主要负责片元颜色 ...

  9. DirectX11 Effect特效文件

    Effect特效文件 1. 什么是Effect特效文件? Direct3D 中,有个 Effect 文件的概念.将所创建的着色器与这些文件捆绑在一起就是所谓的一个效果(特效). 大多数时候,你只是结合 ...

  10. unity3d UGUI九宫格纹理拉伸的使用

    本篇文章我们来学习下在unity new ui即UGUI九宫格纹理拉伸的使用,不论是游戏中的UI,还是应用中的UI,纹理九宫格拉伸都是必不可少的,因为采用这种拉伸方式,可以最大化的节省纹理资源,任意缩 ...

最新文章

  1. linux系统下常用或有用的系统级命令
  2. string转换为bigdecimal_SO面试题09:如何将String转换为Int?
  3. python通过什么来体现逻辑关系_Python语言通过()来体现语句之间的逻辑关系。
  4. 210120 阶段三 fork与阻塞函数
  5. 永磁直驱风力发电机结构图_风机越来越大,国内首台10兆瓦海上风力发电机研制成功...
  6. hive - 自定义函数(超详细步骤,手把手的交)
  7. Porteus 2.0 RC1 发布,轻量级 Linux 版本
  8. 2017/09/15
  9. 运维学习之自动化安装系统的配置
  10. Android Toast 设置到屏幕中间,自定义Toast的实现方法,及其说明
  11. 聊聊jQuery is not defined
  12. CCNP系列之九-----帧中继子接口试验配置
  13. redis 哨兵的原理
  14. 论文阅读:(NFM)Neural Factorization Machines for Sparse Predictive Analytics
  15. MIDI音乐,看这一篇就够了
  16. 【WIN32APIDAPI】RegisterClass CreateWindowEx UpdateWindow
  17. python中circle是什么意思_啥是佩奇,让 Python 告诉你!
  18. 蓝桥杯 拉马车 java_拉马车蓝桥杯(基于Java中的stack和queue)
  19. FreeMark简介
  20. 思维导图——秒懂综合布线系统

热门文章

  1. 对行场、带宽很好解析的一文章
  2. 最新yar扩展安装和使用
  3. 实测对比:2层和4层板的干扰和辐射差异
  4. Window串口编程
  5. java短信验证码功能发送的验证码如何校验_如何实现java手机短信验证功能
  6. 时间计算题100道_数学大作战!小学13000道计算题+20000道口算题立即领!
  7. 《Storm实时数据处理》一2.3 创建日志Spout
  8. Linux学习笔记——Linux基本命令篇
  9. 网络表情NLP(二)︱特殊表情包+emoji识别
  10. 关注虚拟财富“.ME”域名的投资价值