pubgv3/assets/scripts/tools/ShaderMaterial.js
zhuguoqing 53febf2dc4 update
2022-05-28 10:31:45 +08:00

415 lines
12 KiB
JavaScript

var renderEngine = cc.renderer.renderEngine;
var Material = renderEngine.Material;
const MVP = `
uniform mat4 viewProj;
#ifdef use2DPos
attribute vec2 a_position;
#else
attribute vec3 a_position;
#endif
attribute lowp vec4 a_color;
#ifdef useModel
uniform mat4 model;
#endif
#ifdef useTexture
attribute mediump vec2 a_uv0;
varying mediump vec2 uv0;
#endif
#ifndef useColor
varying lowp vec4 v_fragmentColor;
#endif
attribute mediump vec2 a_uv1;
attribute mediump vec2 a_uv2;
attribute mediump vec2 a_uv3;
varying mediump vec2 uv1;
varying mediump vec2 uv2;
varying mediump vec2 uv3;
void main () {
mat4 mvp;
#ifdef useModel
mvp = viewProj * model;
#else
mvp = viewProj;
#endif
#ifdef use2DPos
vec4 pos = mvp * vec4(a_position, 0, 1);
#else
vec4 pos = mvp * vec4(a_position, 1);
#endif
#ifndef useColor
v_fragmentColor = a_color;
#endif
#ifdef useTexture
uv0 = a_uv0;
#endif
uv1 = a_uv1;
uv2 = a_uv2;
uv3 = a_uv3;
gl_Position = pos;
}`
var ShaderMaterial = cc.Class({
extends: Material,
properties: {
},
setUVoffset(frame,sp)
{
let rect = frame.getRect();
let texture = frame.getTexture();
let texw = texture.width;
let texh = texture.height;
let l = 0, r = 0, b = 1, t = 1;
l = texw && rect.x / texw;
t = texh && rect.y / texh;
if(frame.isRotated())
{
r = texw && (rect.x+rect.height)/texw;
b = texh && (rect.y+rect.width)/texh;
}
else
{
r = texw && (rect.x+rect.width)/texw;
b = texh && (rect.y+rect.height)/texh;
}
this._UVoffset={}
this._UVoffset.x = l;
this._UVoffset.y = t;
this._UVoffset.z = r;
this._UVoffset.w = b;
// this._rotated = frame.isRotated() ? 1.0 : 0.0;
this._effect.setProperty('UVoffset', this._UVoffset);
this._effect.setProperty('rotated', frame.isRotated() ? 1.0 : 0.0);
sp.srotated = frame.isRotated() ? 1.0 : 0.0
sp.sUVoffset = {x:l,y:t,z:r,w:b}
},
initspine(shaderName,params){
var renderer = renderEngine.renderer;
var gfx = renderEngine.gfx;
var pass = new renderer.Pass(shaderName);
pass.setDepth(false, false);
pass.setCullMode(gfx.CULL_NONE);
pass.setBlend(
gfx.BLEND_FUNC_ADD,
gfx.BLEND_SRC_ALPHA, gfx.BLEND_ONE_MINUS_SRC_ALPHA,
gfx.BLEND_FUNC_ADD,
gfx.BLEND_SRC_ALPHA, gfx.BLEND_ONE_MINUS_SRC_ALPHA
);
var techParams = [
{ name: 'texture', type: renderer.PARAM_TEXTURE_2D },
];
if (params) {
techParams = techParams.concat(params);
}
var mainTech = new renderer.Technique(
['transparent'],
techParams,
[pass]
);
this.effect = this._effect = new renderer.Effect(
[mainTech ],
{},
[
{ name: 'useModel', value: true },
{ name: 'alphaTest', value: false },
{ name: 'use2DPos', value: true },
{ name: 'useTint', value: false } ]
);
this.name = shaderName;
this._mainTech = mainTech;
this._texture = null;
},
init (shaderName,params,defines,passdata) {
var renderer = renderEngine.renderer;
var gfx = renderEngine.gfx;
var pass = new renderer.Pass(shaderName);
pass.setDepth(false, false);
pass.setCullMode(gfx.CULL_NONE);
if(passdata == null){
pass.setBlend(
gfx.BLEND_FUNC_ADD,
gfx.BLEND_SRC_ALPHA, gfx.BLEND_ONE_MINUS_SRC_ALPHA,
gfx.BLEND_FUNC_ADD,
gfx.BLEND_SRC_ALPHA, gfx.BLEND_ONE_MINUS_SRC_ALPHA
);
}
else{
pass.setBlend(
passdata[0],
passdata[1], passdata[2],
passdata[3],
passdata[4], passdata[5]
);
}
var techParams = [
{ name: 'texture', type: renderer.PARAM_TEXTURE_2D },
{ name: 'color', type: renderer.PARAM_COLOR4 },
{ name:'UVoffset', type: renderer.PARAM_FLOAT4 },
{ name:'rotated', type: renderer.PARAM_FLOAT },
];
if (params) {
techParams = techParams.concat(params);
}
var mainTech = new renderer.Technique(
['transparent'],
techParams,
[pass]
);
this.name = shaderName;
this.effect = this._effect = new renderer.Effect(
[ mainTech ],
{},
[
{ name: 'useTexture', value: true },
{ name: 'useModel', value: false },
{ name: 'alphaTest', value: false },
{ name: 'use2DPos', value: true },
{ name: 'useColor', value: true }
],
);
this._texture = null;
this._color = { r: 1, g: 1, b: 1, a: 1 };
this._mainTech = mainTech;
},
setParamValue(name, value) {
this._effect.setProperty(name, value);
},
getParamValue(name) {
return this._effect.getProperty(name);
},
setDefine(name, value) {
this._effect.define(name, value);
},
setTexture(texture) {
this._texture = texture;
this._texture.update({ flipY: false, mipmap: false });
this._effect.setProperty('texture', texture.getImpl());
this._texIds['texture'] = texture.getId();
},
bindShader(name,parmas,pass){
var sconfig = ShaderMaterial.getShader(name);
this.init(name,sconfig.params,sconfig.defines||[],pass);
sconfig.start&&sconfig.start(this,parmas);
if(sconfig.update){
this.needUpdate = true;
this.isAni = true
ShaderMaterial.pushUpdate(this);
}
},
bindShader2(name,parmas,pass){
var sconfig = ShaderMaterial.getShader(name);
this.initspine(name,sconfig.params);
sconfig.start&&sconfig.start(this,parmas);
if(sconfig.update){
this.needUpdate = true;
this.shadercfg = sconfig
}
},
restartShadre(){
if(this.isAni){
ShaderMaterial.pushUpdate(this);
}
},
applaySpine(sp,name,parmas){
var texture = sp._material._texture
parmas = parmas||{}
sp._shaderMeterial = this
sp._updateMaterial(this)
this.bindShader2(name,parmas);
this.setTexture(texture);
this.updateHash();
},
applaySprite(sp,name,parmas){
// if(sp.node.active ==false){
// return;
// }
if(!sp._renderData){
return;
}
parmas = parmas||{}
if(sp.node){
parmas.width = sp.node.width;
parmas.height = sp.node.height;
parmas.color = sp.node.color;
parmas.color.r = parmas.color.r/255;
parmas.color.g = parmas.color.g/255;
parmas.color.b = parmas.color.b/255;
parmas.color.a = parmas.color.a/255;
}
this.bindShader(name,parmas);
var texture = sp.spriteFrame.getTexture();
this.setTexture(texture);
this.updateHash();
if(sp._shaderMeterial&&sp._shaderMeterial.needUpdate){
ShaderMaterial.cleanUpdate(sp._shaderMeterial);
}
sp._state = 2;
sp._material = this;
sp._renderData.material = this;
sp._shaderMeterial = this
//this.setUVoffset(sp._spriteFrame,sp)
},
applaySpriteOnce(sp,name,parmas){
if(!this.hasinit){
this.applaySprite(sp,name,parmas)
}else{
sp._state = 2;
sp._material = this;
sp._renderData.material = this;
sp._shaderMeterial = this
}
this.hasinit = true
},
applayLabel(sp,name,parmas){
if(sp.node.active ==false||!sp._frame||!sp._frame._texture){
return;
}
parmas = parmas||{}
if(sp.node){
parmas.width = sp.node.width;
parmas.height = sp.node.height;
parmas.color = sp.node.color;
parmas.color.r = parmas.color.r/255;
parmas.color.g = parmas.color.g/255;
parmas.color.b = parmas.color.b/255;
parmas.color.a = parmas.color.a/255;
}
this.bindShader(name,parmas);
var texture = sp._frame._texture;
this.setTexture(texture);
this.updateHash();
if(sp._material&&sp._material.needUpdate){
ShaderMaterial.cleanUpdate(sp._material);
}
sp._material = this;
sp._renderData.material = this;
sp._shaderMeterial = this
},
applayButton(btn,name,parmas){
if(btn.node.active ==false){
return;
}
this.applaySprite(btn._sprite,name,parmas)
btn.useShader = true
},
cleanUp(){
if(this.needUpdate){
ShaderMaterial.cleanUpdate(this);
this.needUpdate = false;
}
},
reset(parmas){
var sconfig = ShaderMaterial.getShader(this.name);
sconfig.reset&&sconfig.reset(this,parmas);
},
});
var g_shaders = {};
var mtArr =[];
ShaderMaterial.addShader = function(shader){
if (g_shaders[shader.name]) {
console.log("addShader - shader already exist: ", shader.name);
return;
}
var def=[
{ name: 'useTexture', value: true },
{ name: 'useModel', value: false },
{ name: 'alphaTest', value: false },
{ name: 'use2DPos', value: true },
{ name: 'useColor', value: true }
]
if (cc.renderer._forward) {
cc.renderer._forward._programLib.define(shader.name, shader.vert||MVP, shader.frag, def);
g_shaders[shader.name] = shader;
} else {
cc.game.once(cc.game.EVENT_ENGINE_INITED, function () {
cc.renderer._forward._programLib.define(shader.name, shader.vert||MVP, shader.frag, def);
g_shaders[shader.name] = shader;
});
}
}
ShaderMaterial.getShader = function(name) {
return g_shaders[name];
};
ShaderMaterial.pushUpdate = function(mat){
mtArr.push(mat);
};
ShaderMaterial.cleanUpdate = function(mat){
for(var i = 0;i<mtArr.length;i++){
if(mtArr[i] == mat){
mtArr.splice(i,1);
break;
}
}
};
ShaderMaterial.cleanAll= function(){
mtArr.length = 0
}
ShaderMaterial.update = function(dt){
for(var i = 0;i<mtArr.length;i++){
var sconfig = this.getShader(mtArr[i].name);
sconfig.update(mtArr[i],dt);
}
}
ShaderMaterial.spinevert = '\n \nuniform mat4 viewProj;\n\n#ifdef use2DPos\n attribute vec2 a_position;\n#else\n attribute vec3 a_position;\n#endif\n\nattribute lowp vec4 a_color;\n#ifdef useTint\n attribute lowp vec4 a_color0;\n#endif\n\n#ifdef useModel\n uniform mat4 model;\n#endif\n\nattribute mediump vec2 a_uv0;\nvarying mediump vec2 uv0;\n\nvarying lowp vec4 v_light;\n#ifdef useTint\n varying lowp vec4 v_dark;\n#endif\n\nvoid main () {\n mat4 mvp;\n #ifdef useModel\n mvp = viewProj * model;\n #else\n mvp = viewProj;\n #endif\n\n #ifdef use2DPos\n vec4 pos = mvp * vec4(a_position, 0, 1);\n #else\n vec4 pos = mvp * vec4(a_position, 1);\n #endif\n\n v_light = a_color;\n #ifdef useTint\n v_dark = a_color0;\n #endif\n\n uv0 = a_uv0;\n\n gl_Position = pos;\n}'
module.exports = ShaderMaterial;