CocosCreator Effect (Shader) - 反九宫格就(Sliced)补偿
思路:
- uv.x取模
- 使用step处理这个模(也可以用smoothstep,以造成柔和边缘)
- 乘上一个旋转矩阵
- 根据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}⎣⎢⎢⎡1284013951141062151173⎦⎥⎥⎤
那么需要获取拉伸的信息,只需要把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使用即可
图集兼容性问题
如果你用的这张图片是图集中的,那么显示上一定会出问题。
两个原因:
- uv是相对大图中的。
- uvSliced是相对大图中的。
因此需要变换回标准区间[0,1]
详细内容看这下一篇文章:
CocosCreator Effect (Shader) - 反图集打包(Packable)补偿
CocosCreator Effect (Shader) - 反九宫格就(Sliced)补偿相关推荐
- CocosCreator Effect (Shader) - 斜条纹如何画
左图是原图,没有使用九宫格sliced.也没有在图集中.这篇文章作为基础,只考虑如何画斜条纹.另外两篇文章讨论了如何处理在九宫格和在图集中使用的问题. 注意,所有的改动都在这里: void main ...
- 【转】Silverlight 3 Beta 新特性解析(7)- Child Window和Shader Effect篇
前提条件: 阅读本文之前请确认你已经安装了如下软件 Visual Studio 2008 (Express) SP1 Silverlight 3 Tools For Visual Studio Mic ...
- CocosCreator优化之DrawCall漫谈
本文首发于我的个人Blog阿西BUG,欢迎大家批评指正 前言 在游戏开发中,DrawCall 作为一个非常重要的性能指标,直接影响游戏的整体性能表现. 无论是 Cocos Creator.Unity. ...
- CocosCreator2.3.3 Effect中换算图集中UV
CocosCreator2.3.3 Effect中换算图集中UV 需求 环境 准备知识(要点) 线性变换 spriteFrame在自动图集中的位置 一个Demo 编写Effect (Shader) T ...
- Unity Shader着色器优化
对游戏开发者而言,着色器长久以来就是游戏开发中的重要部分,在Unity中编写并实现着色器的过程直观且高效,优秀的着色器还可以创造非常精美的游戏画面,同时保证极高的性能.今天将由Unity的技术工程师张 ...
- UnityShader2:Shader与材质
前置:Unity3D基础3:贴图与材质球 一.Shader 与材质 贴图 + 着色器(Shader) = 材质球 同一张贴图使用不同的着色器,可以展现出不同的效果: 在下面这个位置设置 Shader, ...
- 1.Unity之Shader新手入门
Unity Shader着色器的基本概念 如何使用Unity Shader着色器 示例:如何使用Unity Shader着色器创建复杂的效果 总结 什么是Unity中的Shader着色器? Shade ...
- Unity学习之Shader
Shader 是用来实现图像渲染的,用来替代固定渲染管线的可编辑程序.其中Vertex Shader(顶点着色器)主要负责顶点的几何关系等的运算,Pixel Shader(像素着色器)主要负责片元颜色 ...
- DirectX11 Effect特效文件
Effect特效文件 1. 什么是Effect特效文件? Direct3D 中,有个 Effect 文件的概念.将所创建的着色器与这些文件捆绑在一起就是所谓的一个效果(特效). 大多数时候,你只是结合 ...
- unity3d UGUI九宫格纹理拉伸的使用
本篇文章我们来学习下在unity new ui即UGUI九宫格纹理拉伸的使用,不论是游戏中的UI,还是应用中的UI,纹理九宫格拉伸都是必不可少的,因为采用这种拉伸方式,可以最大化的节省纹理资源,任意缩 ...
最新文章
- linux系统下常用或有用的系统级命令
- string转换为bigdecimal_SO面试题09:如何将String转换为Int?
- python通过什么来体现逻辑关系_Python语言通过()来体现语句之间的逻辑关系。
- 210120 阶段三 fork与阻塞函数
- 永磁直驱风力发电机结构图_风机越来越大,国内首台10兆瓦海上风力发电机研制成功...
- hive - 自定义函数(超详细步骤,手把手的交)
- Porteus 2.0 RC1 发布,轻量级 Linux 版本
- 2017/09/15
- 运维学习之自动化安装系统的配置
- Android Toast 设置到屏幕中间,自定义Toast的实现方法,及其说明
- 聊聊jQuery is not defined
- CCNP系列之九-----帧中继子接口试验配置
- redis 哨兵的原理
- 论文阅读:(NFM)Neural Factorization Machines for Sparse Predictive Analytics
- MIDI音乐,看这一篇就够了
- 【WIN32APIDAPI】RegisterClass CreateWindowEx UpdateWindow
- python中circle是什么意思_啥是佩奇,让 Python 告诉你!
- 蓝桥杯 拉马车 java_拉马车蓝桥杯(基于Java中的stack和queue)
- FreeMark简介
- 思维导图——秒懂综合布线系统