Alternativa3D系列 --着色系统
Alternativa3D 着色系统在一定意义上克服了AGAL汇编级代码的编写难度,实现了自己的一套编写规则,能进行寄存器变量声明和汇编命令行操作,
其着色语言 基本形式为:
"#v0=vUV", //v0为UV输入 "#s0=sDiffuse", //s0贴图输入,名字定义为sDiffuse "#c0=cThresholdAlpha",//透明度 "tex t0, v0, s0 <2d, linear,repeat, miplinear>", "mul t0.w, t0.w, c0.w",//w -alpha xyz - color "mov o0, t0"
"#"对变量进行声明,后会依据这个变量名 进行数据输入。 这样就不用去考虑寄存器索引的问题。
Alternativa3D 着色系统重要类:
ShaderProgram : 着色程序, 负责将着色代码传入到program.
vertexShader.link();//连接顶点着色器 fragmentShader.link();//链接片段着色器 program = context3D.createProgram();//创建着色程序 program.upload(vertexShader.data, fragmentShader.data);//上传着色器二进制代码
Linker: 着色链接器,可以加入不同的程序片断Procedure。声明寄存器,设置输入输出。
addProcedure:加入着色程序片断,可输入设置参数
declareVariable/declareSampler 声明寄存器
setInputParams/setOutputParams 声明输入输出
getVariableIndex 获取寄存器索引
link() 将Procedures 链接成一个 shader 将agal编译成二进制
1.编译头文件,2,解析各pass中的寄存器,3.写入各pass二进制代码
4.解析输入,输出寄存器,并设置输入输出寄存器索引,offset。
Procedure: 负责编译着色代码, 编译 声明及着色方法.
compileFromArray: 解析声明,编译命令,注入声明(供linker调用).
Variable: 寄存器基类, 子类定义各类寄存器,源寄存器,目标寄存器等等..
其主要用法:(源代码参见 TextureMaterial.collectDraws()方法)
一.获取program着色程序。(有,用缓存,无新建)
1. 设置着色程序,并上传到GPU中。
//建立顶点着色器
//声明属性寄存器 aPosition 并将其当成_projectProcedure的输入
//连接投影pass, positionVar为输入。
//关于projectProcedure
//c0放入cProjMatrix 投影矩阵,输出为转换后的顶点。
//_projectProcedure = new Procedure(["m44 o0, i0, c0"], "projectProcedure");
//_projectProcedure.assignVariableName(VariableType.CONSTANT, 0, "cProjMatrix", 4);
//数据输入:drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aPosition"), positionBuffer....);
//连接uv Pass
//new Procedure(["#v0=vUV", "#a0=aUV", "mov v0, a0"], "passUVProcedure");
//v0定义为vUV为片段着色器使用,a0定义为aUV,为顶点着色器输入UV数据
//数据输入:drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aUV"), uvBuffer,...);
//数据输入: drawUnit.setProjectionConstants(camera, program.vertexShader.getVariableIndex("cProjMatrix"),....);
var vertexLinker:Linker = new Linker(Context3DProgramType.VERTEX);
var positionVar:String = "aPosition";
vertexLinker.declareVariable(positionVar, VariableType.ATTRIBUTE);
//链接投影
vertexLinker.addProcedure(_projectProcedure);
vertexLinker.setInputParams(_projectProcedure, positionVar);
vertexLinker.addProcedure(_passUVProcedure);
//声明片段着色器
//添加片段着色pass
//new Procedure([
// "#v0=vUV", v0为UV输入
// "#s0=sDiffuse", //s0贴图输入,名字定义为sDiffuse
// "#c0=cThresholdAlpha",//透明度
// "tex t0, v0, s0 <2d, linear,repeat, miplinear>",
// "mul t0.w, t0.w, c0.w",//w -alpha xyz - color
// "mov o0, t0"
// ], "getDiffuseProcedure"); 片段着色代码
var fragmentLinker:Linker = new Linker(Context3DProgramType.FRAGMENT);
fragmentLinker.addProcedure(getDiffuseProcedure);
//将变寄存器对应
fragmentLinker.varyings = vertexLinker.varyings;
//生成着色程序,并上传。
program = new ShaderProgram(vertexLinker, fragmentLinker);
//upload时,会编译着色代码,此时会自动生成定义变量所对应的索引值。
program.upload(camera.context3D);
2.向GPU设置数据,向上面定义的变量中设置
//获取顶点 UV 缓冲数据
var positionBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.POSITION);
var uvBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.TEXCOORDS[0]);
//建立此surface 下的drawUnit
var drawUnit:DrawUnit = camera.renderer.createDrawUnit(.....);
//设置顶点缓冲数据
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aPosition"), positionBuffer....);
//设置UV缓冲数据
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aUV"), uvBuffer...);
//设置变换矩阵
drawUnit.setProjectionConstants(camera, program.vertexShader.getVariableIndex("cProjMatrix"), object.localToCameraTransform);
//设置透明度
drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cThresholdAlpha"), alphaThreshold....);
//设置贴图数据
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sDiffuse"), diffuseMap._texture);

浙公网安备 33010602011771号