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);

 

 

 

 

posted @ 2012-05-02 17:20  peony3d  阅读(1051)  评论(0)    收藏  举报