[LayaAirIDE 2.0]Shader预编译解决方案
ver2.5.0
{laya.d3.js} 源码分析
BaseRender.material : Laya.Material
material._shaderValues : Laya.ShaderData
material._shaderValues._defineDatas :Laya.DefineDatas
参考接口
_render(context) {
...
this._material._shaderValues._defineDatas.cloneTo(comDef);
var shader = context.shader = this._material._shader.getSubShaderAt(0)._passes[0].withCompile(comDef);
...
}
Laya.ShaderPass -> withCompile(compileDefine) {
if (Shader3D.debugMode)//开启debug编译shader时生成打印shader参数
this._addDebugShaderVariantCollection(compileDefine);
}
debugShader : Laya.Shader
debugShader : Laya.SubShader
Laya.ShaderPass -> _addDebugShaderVariantCollection(compileDefine) {
var dbugShaderVariantInfo = Shader3D._debugShaderVariantInfo;
var debugSubShader = this._owner;
var debugShader = debugSubShader._owner;
var deugDefines = ShaderPass._debugDefineString;
//将defineDatas抓换成宏定义数组
Shader3D._getNamesByDefineData(compileDefine, deugDefines);
if (!Config3D._config._multiLighting) {
var index = deugDefines.indexOf("LEGACYSINGLELIGHTING");
(index !== -1) && (deugDefines.splice(index, 1));
}
//保存参数
if (dbugShaderVariantInfo)
dbugShaderVariantInfo.setValue(debugShader, debugShader._subShaders.indexOf(debugSubShader), debugSubShader._passes.indexOf(this), deugDefines);
else
Shader3D._debugShaderVariantInfo = dbugShaderVariantInfo = new ShaderVariant(debugShader, debugShader._subShaders.indexOf(debugSubShader), debugSubShader._passes.indexOf(this), deugDefines);
Shader3D.debugShaderVariantCollection.add(dbugShaderVariantInfo);
}
Laya预编译 shader 接口
Laya.Shader3D.compileShaderByDefineNames(shaderName:string,subShaderIndex:number,passIndex:number,defines:Laya.):void;
material : BaseRender.material
shader : material._shader
shaderName :shader.name
subShaders : shader._subShaders : Laya.SubShader
subShaderIndex : shader._subShaders.indexOf(subShader) : number
shaderPassses : subShader._passes : Laya.ShaderPass
passIndex : subShader._passes.indexOf(shaderPass) : number
defineNames :宏定义名称
static compileShaderByDefineNames(shaderName, subShaderIndex, passIndex, defineNames) {
var shader = Shader3D.find(shaderName);
if (shader) {
var subShader = shader.getSubShaderAt(subShaderIndex);
if (subShader) {
var pass = subShader._passes[passIndex];
if (pass) {
var compileDefineDatas = Shader3D._compileDefineDatas;
compileDefineDatas.clear();
for (var i = 0, n = defineNames.length; i < n; i++)
//将宏定义名称转换为 Laya.DefineDatas
compileDefineDatas.add(Shader3D.getDefineByName(defineNames));
(Config3D._config._multiLighting) || (compileDefineDatas.add(Shader3D.SHADERDEFINE_LEGACYSINGALLIGHTING));
//预编译shader compileDefineDatas : Laya.DefineDatas
pass.withCompile(compileDefineDatas);
}
else {
console.warn("Shader3D: unknown passIndex.");
}
}
else {
console.warn("Shader3D: unknown subShaderIndex.");
}
}
else {
console.warn("Shader3D: unknown shader name.");
}
}
}
===============================================
方案1:官方接口编译
private $compileShader(model: Laya.Sprite3D) {
if (model instanceof Laya.ShuriKenParticle3D) {
var shuriKenParticle3D: Laya.ShuriKenParticle3D = model as Laya.ShuriKenParticle3D;
var render: Laya.ShurikenParticleRenderer = shuriKenParticle3D.particleRenderer;
var materials: Array<Laya.Material> = render.materials;
for (var i: number = 0; i < materials.length; i++) {
var mater: Laya.Material = materials[i] as Laya.Material;
let defineDatas: Laya.DefineDatas = mater._defineDatas;
var deugDefines = Laya.ShaderPass["_debugDefineString"];
if (!deugDefines) { deugDefines = ; }
//将defineDatas转换成宏定义数组
Laya.Shader3D["_getNamesByDefineData"](defineDatas, deugDefines);
if (!Config3D["_config"] && Config3D["_config"]["_multiLighting"]) {
var index = deugDefines.indexOf("LEGACYSINGLELIGHTING");
(index !== -1) && (deugDefines.splice(index, 1));
}
let shader: Laya.Shader3D = mater["_shader"];
if (!shader) continue;
let subShaders: Laya.SubShader[] = shader["_subShaders"];
if (subShaders && subShaders.length > 0) {
for (let j = 0; j< subShaders.length; j++) {
let subShader: Laya.SubShader = subShaders[i];
let passes: Laya.ShaderPass[] = subShader["_passes"];
if (passes && passes.length > 0) {
for (let k = 0; k < passes.length; k++) {
let pass: Laya.ShaderPass = passes[i];
pass && Laya.Shader3D.compileShaderByDefineNames(shader.name, j, k, deugDefines);
}
}
}
}
}
}
//递归获取子对象
if (model.numChildren) {
let len: number = model.numChildren;
for (var i: number = 0; i < len; i++) {
this.$compileShader(model.getChildAt(i) as Laya.Sprite3D);
}
}
}[/i][/i][/i]
===============================================
[i][i][i]方案2:绕过宏定义名称转换直接编译
private $compileShader2(model: Laya.Sprite3D) {
if (model instanceof Laya.ShuriKenParticle3D) {
var shuriKenParticle3D: Laya.ShuriKenParticle3D = model as Laya.ShuriKenParticle3D;
var render: Laya.ShurikenParticleRenderer = shuriKenParticle3D.particleRenderer;
var materials: Array<Laya.Material> = render.materials;
for (var i: number = 0; i < materials.length; i++) {
var mater: Laya.Material = materials[i] as Laya.Material;
let defineDatas: Laya.DefineDatas = mater._defineDatas;
let shader: Laya.Shader3D = mater["_shader"];
if (!shader) continue;
let subShaders: Laya.SubShader[] = shader["_subShaders"];
if (!subShaders || subShaders.length <= 0) continue;
subShaders.forEach((subShader: Laya.SubShader) => {
if (subShader) {
let passes: Laya.ShaderPass[] = subShader["_passes"];
if (passes && passes.length > 0) {
passes.forEach((pass: Laya.ShaderPass) => { pass && pass["withCompile"](defineDatas); })
}
}
});
}
}
//递归获取子对象
if (model.numChildren) {
let len: number = model.numChildren;
for (var i: number = 0; i < len; i++) {
this.$compileShader(model.getChildAt(i) as Laya.Sprite3D);
}
}
}
[/i][/i][/i][/i]
没有找到相关结果
已邀请:
要回复问题请先登录
0 个回复