[]分享一个Shader版的CoolDown实现
Laya的Pie做Mask在native下有bug,不能正常显示。就研究了下laya的custom shader,在没有详细文档的情况下搞出来了,但又发现无法在Native下使用。。。真是X了
既然无法使用,就分享出来,大家有兴趣的看看
正常渲染效果
alpha遮罩
用法:
var texture: Laya.Texture = Laya.Loader.getRes("progress.png");
this.spe = new coolDownSprite();
this.spe.init(texture);
//this.spe.initWithoutTexture(128, 128);
this.spe.pos(300, 350);
this.spe.setProgress(this.progress);
Laya.stage.addChild(this.spe);
----------------------源码--------------------------
import Shader = laya.webgl.shader.Shader;
export class coolDownShader extends Shader {
/**
* 当前着色器的一个实例对象。
*/
public static shader: coolDownShader = new coolDownShader();
constructor() {
var vs: string = " \
attribute vec2 position; \
attribute vec2 texcoord; \
attribute vec4 color; \
uniform vec2 size; \
uniform mat4 mmat; \
varying vec2 v_texcoord; \
varying vec4 v_color; \
void main(){ \
vec4 pos =mmat*vec4(position.x,position.y,0,1);\
gl_Position = vec4((pos.x / size.x - 0.5) * 2.0, (0.5 - pos.y / size.y) * 2.0, pos.z, 1.0);\
v_color = color;\
v_texcoord = texcoord;\
} \
";
var ps: string = " \
precision mediump float; \
varying vec2 v_texcoord; \
varying vec4 v_color; \
uniform sampler2D texture; \
uniform float progress;\
uniform vec4 uv_info; \
void main(){ \
vec2 pos = ((v_texcoord-uv_info.xy)/uv_info.zw - vec2(0.5,0.5))*256.0;\
float radius = length(pos.xy);\
float angle = -degrees(atan(pos.x, pos.y)) + 180.0;\
float fa = radians(angle - progress * 360.0) * radius + 1.0;\
fa = clamp(fa, 0.0, 1.0);\
vec4 t_color = texture2D(texture, v_texcoord); \
gl_FragColor = t_color.rgba * v_color.rgba * vec4(1,1,1,fa); \
}\
";
/*
var ps: string = " \
precision mediump float; \
varying vec2 v_texcoord; \
varying vec4 v_color; \
uniform float progress;\
uniform vec4 uv_info; \
void main(){ \
vec2 pos = ((v_texcoord-uv_info.xy)/uv_info.zw - vec2(0.5,0.5))*256.0;\
float radius = length(pos.xy);\
float angle = -degrees(atan(pos.x, pos.y)) + 180.0;\
float fa = radians(angle - progress * 360.0) * radius + 1.0;\
fa = clamp(fa, 0.0, 1.0);\
gl_FragColor = v_color.rgba * vec4(1,1,1,fa); \
}\
";
*/
super(vs, ps, "coolDownShader");
}
}
import WebGLContext = laya.webgl.WebGLContext;
import Value2D = laya.webgl.shader.d2.value.Value2D;
import CONST3D2D = laya.webgl.utils.CONST3D2D;
export class coolDownShaderValue extends Value2D {
public texcoord: any;
public progress: number;
public uv_info: Array<any>;
constructor() {
super(0, 0);
this.progress = 0.0;
this.uv_info = [0.0, 0.0, 1.0, 1.0];
var len: number = 8 * CONST3D2D.BYTES_PE;
//设置在shader程序文件里定义的属性的相关描述:[属性长度, 属性类型,false, 属性起始位置索引 * CONST3D2D.BYTES_PE];
this.position = [2, WebGLContext.FLOAT, false, len, 0];
this.texcoord = [2, WebGLContext.FLOAT, false, len, 2 * CONST3D2D.BYTES_PE];
this.color = [4, WebGLContext.FLOAT, false, len, 4 * CONST3D2D.BYTES_PE];
}
}
import Sprite = Laya.Sprite;
export class coolDownSprite extends Sprite {
/** 顶点缓冲区。 */
private vBuffer: Laya.VertexBuffer2D;
/** 片元缓冲区。 */
private iBuffer: Laya.IndexBuffer2D;
private vbData: Float32Array;
private ibData: Uint16Array;
private iNum: number = 0;
/** 着色器变量。 */
private shaderValue: coolDownShaderValue;
constructor() {
super();
}
/**
* 初始化此类。
* @param texture 纹理对象。
* @param vb 顶点数组。
* @param ib 顶点索引数组。
*/
public init(texture: Laya.Texture, vb: Array<number> = null, ib: Array<number> = null): void {
this.vBuffer = Laya.VertexBuffer2D.create();
this.iBuffer = Laya.IndexBuffer2D.create();
this.ibData = null;
var vbArray: Array<number>;
var ibArray: Array<number>;
if (vb) {
vbArray = vb;
}
else {
vbArray = new Array<number>();
var texWidth: number = texture.width;
var texHeight: number = texture.height;
//定义颜色值,取值范围0~1 浮点。
const red: number = 1;
const greed: number = 1;
const blue: number = 1;
const alpha: number = 1;
//在顶点数组中放入4个顶点
//每个顶点的数据:(坐标X,坐标Y,u,v,R,G,B,A)
vbArray.push(0, 0, texture.uv[0], texture.uv[1], red, greed, blue, alpha);
vbArray.push(texWidth, 0, texture.uv[2], texture.uv[3], red, greed, blue, alpha);
vbArray.push(texWidth, texHeight, texture.uv[4], texture.uv[5], red, greed, blue, alpha);
vbArray.push(0, texHeight, texture.uv[6], texture.uv[7], red, greed, blue, alpha);
// vbArray.push(0, 0, 0, 0, red, greed, blue, alpha);
// vbArray.push(texWidth, 0, 1, 0, red, greed, blue, alpha);
// vbArray.push(texWidth, texHeight, 1, 1, red, greed, blue, alpha);
// vbArray.push(0, texHeight, 0, 1, red, greed, blue, alpha);
}
if (ib) {
ibArray = ib;
}
else {
ibArray = new Array<number>();
//在顶点索引数组中放入组成三角形的顶点索引。
//三角形的顶点索引对应顶点数组vbArray 里的点索引,索引从0开始。
ibArray.push(0, 1, 3);//第一个三角形的顶点索引。
ibArray.push(3, 1, 2);//第二个三角形的顶点索引。
}
this.iNum = ibArray.length;
this.vbData = new Float32Array(vbArray);
this.ibData = new Uint16Array(ibArray);
this.vBuffer.append(this.vbData);
this.iBuffer.append(this.ibData);
this.shaderValue = new coolDownShaderValue();
this.shaderValue.textureHost = texture;
this._renderType |= Laya.RenderSprite.CUSTOM;//设置当前显示对象的渲染模式为自定义渲染模式。
this.setUVInfo(texture.uv[0], texture.uv[1], texture.uv[4] - texture.uv[0], texture.uv[5] - texture.uv[1]);
this.setProgress(0);
}
public initWithoutTexture(width: number, height: number, vb: Array<number> = null, ib: Array<number> = null): void {
this.vBuffer = Laya.VertexBuffer2D.create();
this.iBuffer = Laya.IndexBuffer2D.create();
this.ibData = null;
var vbArray: Array<number>;
var ibArray: Array<number>;
if (vb) {
vbArray = vb;
}
else {
vbArray = new Array<number>();
var texWidth: number = width;
var texHeight: number = height;
//定义颜色值,取值范围0~1 浮点。
const red: number = 1;
const greed: number = 1;
const blue: number = 1;
const alpha: number = 1;
//在顶点数组中放入4个顶点
//每个顶点的数据:(坐标X,坐标Y,u,v,R,G,B,A)
vbArray.push(0, 0, 0, 0, red, greed, blue, alpha);
vbArray.push(texWidth, 0, 1, 0, red, greed, blue, alpha);
vbArray.push(texWidth, texHeight, 1, 1, red, greed, blue, alpha);
vbArray.push(0, texHeight, 0, 1, red, greed, blue, alpha);
}
if (ib) {
ibArray = ib;
}
else {
ibArray = new Array<number>();
//在顶点索引数组中放入组成三角形的顶点索引。
//三角形的顶点索引对应顶点数组vbArray 里的点索引,索引从0开始。
ibArray.push(0, 1, 3);//第一个三角形的顶点索引。
ibArray.push(3, 1, 2);//第二个三角形的顶点索引。
}
this.iNum = ibArray.length;
this.vbData = new Float32Array(vbArray);
this.ibData = new Uint16Array(ibArray);
this.vBuffer.append(this.vbData);
this.iBuffer.append(this.ibData);
this.shaderValue = new coolDownShaderValue();
this.shaderValue.textureHost = null;
this._renderType |= Laya.RenderSprite.CUSTOM;//设置当前显示对象的渲染模式为自定义渲染模式。
this.setUVInfo(0, 0, 1, 1);
this.setProgress(0);
}
public setProgress(val: number) {
if (val < 0.0) {
val = 0.0;
}
else if (val > 1.0) {
val = 1.0;
}
this.shaderValue.progress = val;
}
/**
* 设置uv信息
* 单位 0~1
* @private
* @param {number} su 起始 u
* @param {number} sv 起始 v
* @param {number} w uv的实际宽
* @param {number} h uv的实际高
*
* @memberof coolDownSprite
*/
private setUVInfo(su: number, sv: number, w: number, h: number) {
this.shaderValue.uv_info = [su, sv, w, h];
}
//重写渲染函数。
public customRender(context: Laya.RenderContext, x: number, y: number): void {
(context.ctx as Laya.WebGLContext2D).setIBVB(x, y, this.iBuffer, this.vBuffer, this.iNum, null,
coolDownShader.shader, this.shaderValue, 0, 0);
}
既然无法使用,就分享出来,大家有兴趣的看看
正常渲染效果
alpha遮罩
用法:
var texture: Laya.Texture = Laya.Loader.getRes("progress.png");
this.spe = new coolDownSprite();
this.spe.init(texture);
//this.spe.initWithoutTexture(128, 128);
this.spe.pos(300, 350);
this.spe.setProgress(this.progress);
Laya.stage.addChild(this.spe);
----------------------源码--------------------------
import Shader = laya.webgl.shader.Shader;
export class coolDownShader extends Shader {
/**
* 当前着色器的一个实例对象。
*/
public static shader: coolDownShader = new coolDownShader();
constructor() {
var vs: string = " \
attribute vec2 position; \
attribute vec2 texcoord; \
attribute vec4 color; \
uniform vec2 size; \
uniform mat4 mmat; \
varying vec2 v_texcoord; \
varying vec4 v_color; \
void main(){ \
vec4 pos =mmat*vec4(position.x,position.y,0,1);\
gl_Position = vec4((pos.x / size.x - 0.5) * 2.0, (0.5 - pos.y / size.y) * 2.0, pos.z, 1.0);\
v_color = color;\
v_texcoord = texcoord;\
} \
";
var ps: string = " \
precision mediump float; \
varying vec2 v_texcoord; \
varying vec4 v_color; \
uniform sampler2D texture; \
uniform float progress;\
uniform vec4 uv_info; \
void main(){ \
vec2 pos = ((v_texcoord-uv_info.xy)/uv_info.zw - vec2(0.5,0.5))*256.0;\
float radius = length(pos.xy);\
float angle = -degrees(atan(pos.x, pos.y)) + 180.0;\
float fa = radians(angle - progress * 360.0) * radius + 1.0;\
fa = clamp(fa, 0.0, 1.0);\
vec4 t_color = texture2D(texture, v_texcoord); \
gl_FragColor = t_color.rgba * v_color.rgba * vec4(1,1,1,fa); \
}\
";
/*
var ps: string = " \
precision mediump float; \
varying vec2 v_texcoord; \
varying vec4 v_color; \
uniform float progress;\
uniform vec4 uv_info; \
void main(){ \
vec2 pos = ((v_texcoord-uv_info.xy)/uv_info.zw - vec2(0.5,0.5))*256.0;\
float radius = length(pos.xy);\
float angle = -degrees(atan(pos.x, pos.y)) + 180.0;\
float fa = radians(angle - progress * 360.0) * radius + 1.0;\
fa = clamp(fa, 0.0, 1.0);\
gl_FragColor = v_color.rgba * vec4(1,1,1,fa); \
}\
";
*/
super(vs, ps, "coolDownShader");
}
}
import WebGLContext = laya.webgl.WebGLContext;
import Value2D = laya.webgl.shader.d2.value.Value2D;
import CONST3D2D = laya.webgl.utils.CONST3D2D;
export class coolDownShaderValue extends Value2D {
public texcoord: any;
public progress: number;
public uv_info: Array<any>;
constructor() {
super(0, 0);
this.progress = 0.0;
this.uv_info = [0.0, 0.0, 1.0, 1.0];
var len: number = 8 * CONST3D2D.BYTES_PE;
//设置在shader程序文件里定义的属性的相关描述:[属性长度, 属性类型,false, 属性起始位置索引 * CONST3D2D.BYTES_PE];
this.position = [2, WebGLContext.FLOAT, false, len, 0];
this.texcoord = [2, WebGLContext.FLOAT, false, len, 2 * CONST3D2D.BYTES_PE];
this.color = [4, WebGLContext.FLOAT, false, len, 4 * CONST3D2D.BYTES_PE];
}
}
import Sprite = Laya.Sprite;
export class coolDownSprite extends Sprite {
/** 顶点缓冲区。 */
private vBuffer: Laya.VertexBuffer2D;
/** 片元缓冲区。 */
private iBuffer: Laya.IndexBuffer2D;
private vbData: Float32Array;
private ibData: Uint16Array;
private iNum: number = 0;
/** 着色器变量。 */
private shaderValue: coolDownShaderValue;
constructor() {
super();
}
/**
* 初始化此类。
* @param texture 纹理对象。
* @param vb 顶点数组。
* @param ib 顶点索引数组。
*/
public init(texture: Laya.Texture, vb: Array<number> = null, ib: Array<number> = null): void {
this.vBuffer = Laya.VertexBuffer2D.create();
this.iBuffer = Laya.IndexBuffer2D.create();
this.ibData = null;
var vbArray: Array<number>;
var ibArray: Array<number>;
if (vb) {
vbArray = vb;
}
else {
vbArray = new Array<number>();
var texWidth: number = texture.width;
var texHeight: number = texture.height;
//定义颜色值,取值范围0~1 浮点。
const red: number = 1;
const greed: number = 1;
const blue: number = 1;
const alpha: number = 1;
//在顶点数组中放入4个顶点
//每个顶点的数据:(坐标X,坐标Y,u,v,R,G,B,A)
vbArray.push(0, 0, texture.uv[0], texture.uv[1], red, greed, blue, alpha);
vbArray.push(texWidth, 0, texture.uv[2], texture.uv[3], red, greed, blue, alpha);
vbArray.push(texWidth, texHeight, texture.uv[4], texture.uv[5], red, greed, blue, alpha);
vbArray.push(0, texHeight, texture.uv[6], texture.uv[7], red, greed, blue, alpha);
// vbArray.push(0, 0, 0, 0, red, greed, blue, alpha);
// vbArray.push(texWidth, 0, 1, 0, red, greed, blue, alpha);
// vbArray.push(texWidth, texHeight, 1, 1, red, greed, blue, alpha);
// vbArray.push(0, texHeight, 0, 1, red, greed, blue, alpha);
}
if (ib) {
ibArray = ib;
}
else {
ibArray = new Array<number>();
//在顶点索引数组中放入组成三角形的顶点索引。
//三角形的顶点索引对应顶点数组vbArray 里的点索引,索引从0开始。
ibArray.push(0, 1, 3);//第一个三角形的顶点索引。
ibArray.push(3, 1, 2);//第二个三角形的顶点索引。
}
this.iNum = ibArray.length;
this.vbData = new Float32Array(vbArray);
this.ibData = new Uint16Array(ibArray);
this.vBuffer.append(this.vbData);
this.iBuffer.append(this.ibData);
this.shaderValue = new coolDownShaderValue();
this.shaderValue.textureHost = texture;
this._renderType |= Laya.RenderSprite.CUSTOM;//设置当前显示对象的渲染模式为自定义渲染模式。
this.setUVInfo(texture.uv[0], texture.uv[1], texture.uv[4] - texture.uv[0], texture.uv[5] - texture.uv[1]);
this.setProgress(0);
}
public initWithoutTexture(width: number, height: number, vb: Array<number> = null, ib: Array<number> = null): void {
this.vBuffer = Laya.VertexBuffer2D.create();
this.iBuffer = Laya.IndexBuffer2D.create();
this.ibData = null;
var vbArray: Array<number>;
var ibArray: Array<number>;
if (vb) {
vbArray = vb;
}
else {
vbArray = new Array<number>();
var texWidth: number = width;
var texHeight: number = height;
//定义颜色值,取值范围0~1 浮点。
const red: number = 1;
const greed: number = 1;
const blue: number = 1;
const alpha: number = 1;
//在顶点数组中放入4个顶点
//每个顶点的数据:(坐标X,坐标Y,u,v,R,G,B,A)
vbArray.push(0, 0, 0, 0, red, greed, blue, alpha);
vbArray.push(texWidth, 0, 1, 0, red, greed, blue, alpha);
vbArray.push(texWidth, texHeight, 1, 1, red, greed, blue, alpha);
vbArray.push(0, texHeight, 0, 1, red, greed, blue, alpha);
}
if (ib) {
ibArray = ib;
}
else {
ibArray = new Array<number>();
//在顶点索引数组中放入组成三角形的顶点索引。
//三角形的顶点索引对应顶点数组vbArray 里的点索引,索引从0开始。
ibArray.push(0, 1, 3);//第一个三角形的顶点索引。
ibArray.push(3, 1, 2);//第二个三角形的顶点索引。
}
this.iNum = ibArray.length;
this.vbData = new Float32Array(vbArray);
this.ibData = new Uint16Array(ibArray);
this.vBuffer.append(this.vbData);
this.iBuffer.append(this.ibData);
this.shaderValue = new coolDownShaderValue();
this.shaderValue.textureHost = null;
this._renderType |= Laya.RenderSprite.CUSTOM;//设置当前显示对象的渲染模式为自定义渲染模式。
this.setUVInfo(0, 0, 1, 1);
this.setProgress(0);
}
public setProgress(val: number) {
if (val < 0.0) {
val = 0.0;
}
else if (val > 1.0) {
val = 1.0;
}
this.shaderValue.progress = val;
}
/**
* 设置uv信息
* 单位 0~1
* @private
* @param {number} su 起始 u
* @param {number} sv 起始 v
* @param {number} w uv的实际宽
* @param {number} h uv的实际高
*
* @memberof coolDownSprite
*/
private setUVInfo(su: number, sv: number, w: number, h: number) {
this.shaderValue.uv_info = [su, sv, w, h];
}
//重写渲染函数。
public customRender(context: Laya.RenderContext, x: number, y: number): void {
(context.ctx as Laya.WebGLContext2D).setIBVB(x, y, this.iBuffer, this.vBuffer, this.iNum, null,
coolDownShader.shader, this.shaderValue, 0, 0);
}
没有找到相关结果
已邀请:
要回复问题请先登录
2 个回复
cuixueying
赞同来自:
chunjine
赞同来自: