CocosCreator2.3.3 Effect中换算图集中UV

  • 需求
  • 环境
  • 准备知识(要点)
    • 线性变换
    • spriteFrame在自动图集中的位置
  • 一个Demo
    • 编写Effect (Shader)
    • TS调用
    • 结果截图

需求

CocosCreater中的自动图集可以帮助缩减App运行时的开销,主要是合图之后的DrawCall减少。但是一些图片需要自定义的shader来进行特效处理,此时,shader中的uv使用的是该spriteframe在图集中的uv,正常来说,需要把uv换算到0~1之间,使其便于处理。

环境

  • CocosCreator 2.3.3
  • Android Studio 4.0.1
  • 参考: https://forum.cocos.org/t/demo/95087

准备知识(要点)

线性变换

 // 已知在数轴上的橡皮筋两个端点分别在x0, x1// 拉伸橡皮筋使其两个端点到y0, y1// 那么原始的inputX位置变到了哪里?float linear(float x0, float x1, float y0, float y1, float inputX) {return (y1 - y0) * (inputX - x0) / (x1 - x0) + y0;}

spriteFrame在自动图集中的位置

// uv里面有8个值,分别是左下,右下,左上,右上4个点的x和y坐标,因此,只需要左下和右上的点的xy就可以找到在自身图集中的位置,在uv数组里面索引正好是 0左 6右 1下 7上
//@ts-ignore
let uv: number[] = this._sprite.spriteFrame.uv;
material.setProperty('u_lrbt', [uv[0], uv[6], uv[1], uv[7]]);

一个Demo

这个demo就是希望在自动图集中的一个spriteFrame上面显示出一个白点,和红绿交叉线,基于给定pos参数范围是0~1

编写Effect (Shader)

使用了line函数把图集内uv坐标按照给定的图集内位置线性变换到[0,1]的范围内,后续的计算就通用成单图的计算了。
数组u_lrbt 的0,1,2,3分别对应着图集中的左,右,下,上的[0,1]范围uv。

// 将 图集中的v_uv0扩展到0~1之间
vec2 uv = vec2(linear(u_lrbt[0], u_lrbt[1], 0.0, 1.0, v_uv0.x),linear(u_lrbt[2], u_lrbt[3], 0.0, 1.0, v_uv0.y)
);

完整Effect文件:

// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.  CCEffect %{techniques:- passes:- vert: vsfrag: fsblendState:targets:- blend: truerasterizerState:cullMode: noneproperties:texture: { value: white }alphaThreshold: { value: 0.5 }u_lrbt: { value: [0.0, 1.0, 0.0, 1.0] }u_pos: { value: [0.5, 0.5] }
}%CCProgram vs %{precision highp float;#include <cc-global>#include <cc-local>in vec3 a_position;in vec4 a_color;out vec4 v_color;#if USE_TEXTUREin vec2 a_uv0;out vec2 v_uv0;#endifvoid main () {vec4 pos = vec4(a_position, 1);#if CC_USE_MODELpos = cc_matViewProj * cc_matWorld * pos;#elsepos = cc_matViewProj * pos;#endif#if USE_TEXTUREv_uv0 = a_uv0;#endifv_color = a_color;gl_Position = pos;}
}%CCProgram fs %{precision highp float;#include <alpha-test>#include <texture>in vec4 v_color;#if USE_TEXTUREin vec2 v_uv0;uniform sampler2D texture;uniform User {vec4 u_lrbt;vec2 u_pos;};#endiffloat linear(float x0, float x1, float y0, float y1, float inputX) {return (y1 - y0) * (inputX - x0) / (x1 - x0) + y0;}void main () {vec4 o = vec4(1, 1, 1, 1);#if USE_TEXTURECCTexture(texture, v_uv0, o);#endifo *= v_color;// 将 图集中的v_uv0扩展到0~1之间vec2 uv = vec2(linear(u_lrbt[0], u_lrbt[1], 0.0, 1.0, v_uv0.x),linear(u_lrbt[2], u_lrbt[3], 0.0, 1.0, v_uv0.y));ALPHA_TEST(o);if (abs(uv.x - u_pos.x)< .02) {o = vec4(1.0,0.0,0.0,1.0);}if (abs(uv.y - u_pos.y) < .02) {o = vec4(0.0,1.0,0.0,1.0);}if (distance(uv, u_pos) < .1) {o = vec4(1.0,1.0,1.0,1.0);}gl_FragColor = o;}
}%

TS调用


const { ccclass, property, executeInEditMode } = cc._decorator;@ccclass
@executeInEditMode
export default class Sprite_OneDot extends cc.Component {@property(cc.Sprite)_sprite: cc.Sprite = null;@propertyprivate _pos: cc.Vec2 = cc.v2(.5, .5);@property(cc.Vec2)public get pos(): cc.Vec2 { return this._pos; }public set pos(v: cc.Vec2) { this._pos = v; };refreshMaterial() {if (this._sprite == null) this._sprite = this.node.getComponent(cc.Sprite);let material = this._sprite.getMaterial(0);//@ts-ignoreif (material && material.effectAsset.name == 'Effect_OneDot') {//@ts-ignorelet uv: number[] = this._sprite.spriteFrame.uv;material.setProperty('u_lrbt', [uv[0], uv[6], uv[1], uv[7]]);material.setProperty('u_pos', [this.pos.x, this.pos.y]);this._sprite.setMaterial(0, material);}}_lastX: number = null;_lastY: number = null;update() {if (this._lastX != this.pos.x || this._lastY != this.pos.y) {this.refreshMaterial();this._lastX = this.pos.x;this._lastY = this.pos.y;}}
}

结果截图

第一个是原图
第二个是发光shader
第三个是画的上面的Shader所画的

CocosCreator2.3.3 Effect中换算图集中UV相关推荐

  1. 日志统计中的PV UV IP

    我们在统计访问日志的时候,经常要提及到三个概念:UV   PV   IP ,其中UV与IP的区别有时让初学者摸不着头脑,简单的聊一下这些概念: 一.Cookie.UV和IP的概念 要区别UV和IP,就 ...

  2. echarts-gl中3d曲面UV参数详解

    文章目录 前言 什么是UV echarts中的UV解析 利用UV创建模型 利用UV确定贴图位置 前言 在echart-gl中3D曲面的数据除曲面方程及普通数据[x,y,z]外,还有一个带有UV坐标系的 ...

  3. php uv pv,SEO中IP、UV和PV的定义与区别?

    [名词解释]IP(独立IP): 即Internet Protocol,指独立IP数.00:00-24:00内相同IP地址之被计算一次. PV(访问量): 即Page View,即页面浏览量或点击量,用 ...

  4. 【Cocos Creator 3.x】ShaderToy 中的 iTime 对应 Cocos Effect 中是什么?

    前言 在网上 ShaderToy 中找了很久的一个 Shader 效果,不知道怎么移至到 Cocos Creator 中. 介绍 ShaderToy 中的 iTime 是 Shader 着色器播放时间 ...

  5. 网站中PV、UV、IP的区别

    网站推广需要一个网站访问统计工具,常用的统计工具有百度统计.51la.量子恒道统计等.网站访问量常用的指标为PV.UV.IP.那么什么是PV.UV和IP,PV.UV.IP的区别是什么? 首先来看看ip ...

  6. 在片段着色器中通过对uv进行多重变换实现丰富的纹理表现效果(GLSL源码)示例

    请见demo:http://www.artvily.com/renderCase?sample=uvMultCalc / 着色器glsl代码示例(由编辑器生成) ///// ** vshd_str: ...

  7. 解决AE模板提示:类“Effect”中名为“Color”的属性或方法缺失或不存在

    1.出现该错误提示原因为很多AE模板都是国外引进过来的,是使用英文版AE存储的. 2.使用汉化版打开外国模板会出现因汉化问题而导致某些属性解析错误. 3.解决办法有两个 (1)使用英文版AE编辑 (2 ...

  8. Spark中pv和uv计算的流程图【图片】

  9. Threejs中 Blender建模的问题 ------ uv贴图中修改贴图的方向和uv贴图材质重复不起作用

    修改贴图的方向(只有一个面) 数字键盘/来在3D视图中控制视野中选中对象的显示切换 首先确保添加了uv的数据,不然会在最终的显示材质时有问题 直接在Blender建模,添加材质,添加纹理 在three ...

最新文章

  1. 声音匹配_如何调节人声音色方法如下
  2. Keras入门(一)搭建深度神经网络(DNN)解决多分类问题 1
  3. Linux 文件大小 文件夹大小 磁盘大小
  4. 基于eureka如何使用spring cloud zuul 网关
  5. VTK修炼之道20:图像基本操作_图像类型转换
  6. Python之Django框架开发博客
  7. 【codevs3732】【BZOJ3751】解方程,hash+秦九韶算法
  8. CentOS7 下安装telnet服务
  9. 15分钟破解保险箱!美国小哥200美元自制开锁机器人
  10. oppo9s刷机教程_oppor9s怎么自己刷机很简单的技巧
  11. 二叉树求解前序序列、中序序列、后序序列
  12. 高中数学立体几何证明套路高考试题(附答案)
  13. pvr格式的用什么打开_cocos2d 查看pvr图片的详细格式
  14. python实现DEAMON守护进程
  15. Unity UGUI实现王者荣耀版多格血条
  16. app pour android,Comment configurer Dell Mobile Connect pour Android
  17. 论文解读:NSGA-II, EFR, EFR-RR
  18. 技能入户广州需要符合什么条件
  19. css超过一定长度显示省略号
  20. HTB_Weak RSA

热门文章

  1. MySQL查询优化系列文章
  2. 我才23岁,我要去追太阳了
  3. 线性代数-思维导图(5)
  4. 门面(facade)模式
  5. htonl htons ntohl ntohs inet_pton inet_ntop
  6. SSI服务端包含技术
  7. Linux 开发环境工具 下载网址大全 --转
  8. 14-HBase的介绍、数据模型以及架构模型
  9. C++ Virtual详解
  10. VSCode安装及配置