mirror of
https://github.com/MapMakersAndProgrammers/Alternativa3D.git
synced 2025-10-26 18:09:14 -07:00
Merge branch '8.30.MaterialsGetVariableOptimized' of github.com:AlternativaPlatform/Alternativa3D
This commit is contained in:
@@ -77,7 +77,7 @@ package alternativa.engine3d.materials {
|
|||||||
this.alpha = alpha;
|
this.alpha = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setupProgram(object:Object3D):ShaderProgram {
|
private function setupProgram(object:Object3D):FillMaterialProgram {
|
||||||
var vertexLinker:Linker = new Linker(Context3DProgramType.VERTEX);
|
var vertexLinker:Linker = new Linker(Context3DProgramType.VERTEX);
|
||||||
var positionVar:String = "aPosition";
|
var positionVar:String = "aPosition";
|
||||||
vertexLinker.declareVariable(positionVar, VariableType.ATTRIBUTE);
|
vertexLinker.declareVariable(positionVar, VariableType.ATTRIBUTE);
|
||||||
@@ -90,7 +90,7 @@ package alternativa.engine3d.materials {
|
|||||||
var fragmentLinker:Linker = new Linker(Context3DProgramType.FRAGMENT);
|
var fragmentLinker:Linker = new Linker(Context3DProgramType.FRAGMENT);
|
||||||
fragmentLinker.addProcedure(outColorProcedure);
|
fragmentLinker.addProcedure(outColorProcedure);
|
||||||
fragmentLinker.varyings = vertexLinker.varyings;
|
fragmentLinker.varyings = vertexLinker.varyings;
|
||||||
return new ShaderProgram(vertexLinker, fragmentLinker);
|
return new FillMaterialProgram(vertexLinker, fragmentLinker);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -114,7 +114,7 @@ package alternativa.engine3d.materials {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var program:ShaderProgram = programsCache[object.transformProcedure];
|
var program:FillMaterialProgram = programsCache[object.transformProcedure];
|
||||||
if (program == null) {
|
if (program == null) {
|
||||||
program = setupProgram(object);
|
program = setupProgram(object);
|
||||||
program.upload(camera.context3D);
|
program.upload(camera.context3D);
|
||||||
@@ -123,11 +123,11 @@ package alternativa.engine3d.materials {
|
|||||||
// Drawcall
|
// Drawcall
|
||||||
var drawUnit:DrawUnit = camera.renderer.createDrawUnit(object, program.program, geometry._indexBuffer, surface.indexBegin, surface.numTriangles, program);
|
var drawUnit:DrawUnit = camera.renderer.createDrawUnit(object, program.program, geometry._indexBuffer, surface.indexBegin, surface.numTriangles, program);
|
||||||
// Streams
|
// Streams
|
||||||
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aPosition"), positionBuffer, geometry._attributesOffsets[VertexAttributes.POSITION], VertexAttributes.FORMATS[VertexAttributes.POSITION]);
|
drawUnit.setVertexBufferAt(program.aPosition, positionBuffer, geometry._attributesOffsets[VertexAttributes.POSITION], VertexAttributes.FORMATS[VertexAttributes.POSITION]);
|
||||||
// Constants
|
// Constants
|
||||||
object.setTransformConstants(drawUnit, surface, program.vertexShader, camera);
|
object.setTransformConstants(drawUnit, surface, program.vertexShader, camera);
|
||||||
drawUnit.setProjectionConstants(camera, program.vertexShader.getVariableIndex("cProjMatrix"), object.localToCameraTransform);
|
drawUnit.setProjectionConstants(camera, program.cProjMatrix, object.localToCameraTransform);
|
||||||
drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cColor"), red, green, blue, alpha);
|
drawUnit.setFragmentConstantsFromNumbers(program.cColor, red, green, blue, alpha);
|
||||||
// Send to render
|
// Send to render
|
||||||
if (alpha < 1) {
|
if (alpha < 1) {
|
||||||
drawUnit.blendSource = Context3DBlendFactor.SOURCE_ALPHA;
|
drawUnit.blendSource = Context3DBlendFactor.SOURCE_ALPHA;
|
||||||
@@ -149,3 +149,27 @@ package alternativa.engine3d.materials {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import alternativa.engine3d.materials.ShaderProgram;
|
||||||
|
import alternativa.engine3d.materials.compiler.Linker;
|
||||||
|
|
||||||
|
import flash.display3D.Context3D;
|
||||||
|
|
||||||
|
class FillMaterialProgram extends ShaderProgram {
|
||||||
|
|
||||||
|
public var aPosition:int = -1;
|
||||||
|
public var cProjMatrix:int = -1;
|
||||||
|
public var cColor:int = -1;
|
||||||
|
|
||||||
|
public function FillMaterialProgram(vertex:Linker, fragment:Linker) {
|
||||||
|
super(vertex, fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function upload(context3D:Context3D):void {
|
||||||
|
super.upload(context3D);
|
||||||
|
|
||||||
|
aPosition = vertexShader.findVariable("aPosition");
|
||||||
|
cProjMatrix = vertexShader.findVariable("cProjMatrix");
|
||||||
|
cColor = fragmentShader.findVariable("cColor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -112,9 +112,9 @@ package alternativa.engine3d.materials {
|
|||||||
* @param alphaTest 0 - disabled, 1 - opaque, 2 - contours
|
* @param alphaTest 0 - disabled, 1 - opaque, 2 - contours
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private function getProgram(object:Object3D, programs:Vector.<ShaderProgram>, camera:Camera3D, opacityMap:TextureResource, alphaTest:int):ShaderProgram {
|
private function getProgram(object:Object3D, programs:Vector.<LightMapMaterialProgram>, camera:Camera3D, opacityMap:TextureResource, alphaTest:int):LightMapMaterialProgram {
|
||||||
var key:int = (opacityMap != null ? 3 : 0) + alphaTest;
|
var key:int = (opacityMap != null ? 3 : 0) + alphaTest;
|
||||||
var program:ShaderProgram = programs[key];
|
var program:LightMapMaterialProgram = programs[key];
|
||||||
if (program == null) {
|
if (program == null) {
|
||||||
// Make program
|
// Make program
|
||||||
// Vertex shader
|
// Vertex shader
|
||||||
@@ -147,7 +147,7 @@ package alternativa.engine3d.materials {
|
|||||||
|
|
||||||
fragmentLinker.varyings = vertexLinker.varyings;
|
fragmentLinker.varyings = vertexLinker.varyings;
|
||||||
|
|
||||||
program = new ShaderProgram(vertexLinker, fragmentLinker);
|
program = new LightMapMaterialProgram(vertexLinker, fragmentLinker);
|
||||||
|
|
||||||
program.upload(camera.context3D);
|
program.upload(camera.context3D);
|
||||||
programs[key] = program;
|
programs[key] = program;
|
||||||
@@ -155,7 +155,7 @@ package alternativa.engine3d.materials {
|
|||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getDrawUnit(program:ShaderProgram, camera:Camera3D, surface:Surface, geometry:Geometry, opacityMap:TextureResource):DrawUnit {
|
private function getDrawUnit(program:LightMapMaterialProgram, camera:Camera3D, surface:Surface, geometry:Geometry, opacityMap:TextureResource):DrawUnit {
|
||||||
var positionBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.POSITION);
|
var positionBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.POSITION);
|
||||||
var uvBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.TEXCOORDS[0]);
|
var uvBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.TEXCOORDS[0]);
|
||||||
var lightMapUVBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.TEXCOORDS[lightMapChannel]);
|
var lightMapUVBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.TEXCOORDS[lightMapChannel]);
|
||||||
@@ -166,18 +166,18 @@ package alternativa.engine3d.materials {
|
|||||||
var drawUnit:DrawUnit = camera.renderer.createDrawUnit(object, program.program, geometry._indexBuffer, surface.indexBegin, surface.numTriangles, program);
|
var drawUnit:DrawUnit = camera.renderer.createDrawUnit(object, program.program, geometry._indexBuffer, surface.indexBegin, surface.numTriangles, program);
|
||||||
|
|
||||||
// Streams
|
// Streams
|
||||||
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aPosition"), positionBuffer, geometry._attributesOffsets[VertexAttributes.POSITION], VertexAttributes.FORMATS[VertexAttributes.POSITION]);
|
drawUnit.setVertexBufferAt(program.aPosition, positionBuffer, geometry._attributesOffsets[VertexAttributes.POSITION], VertexAttributes.FORMATS[VertexAttributes.POSITION]);
|
||||||
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aUV"), uvBuffer, geometry._attributesOffsets[VertexAttributes.TEXCOORDS[0]], VertexAttributes.FORMATS[VertexAttributes.TEXCOORDS[0]]);
|
drawUnit.setVertexBufferAt(program.aUV, uvBuffer, geometry._attributesOffsets[VertexAttributes.TEXCOORDS[0]], VertexAttributes.FORMATS[VertexAttributes.TEXCOORDS[0]]);
|
||||||
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aUV1"), lightMapUVBuffer, geometry._attributesOffsets[VertexAttributes.TEXCOORDS[lightMapChannel]], VertexAttributes.FORMATS[VertexAttributes.TEXCOORDS[lightMapChannel]]);
|
drawUnit.setVertexBufferAt(program.aUV1, lightMapUVBuffer, geometry._attributesOffsets[VertexAttributes.TEXCOORDS[lightMapChannel]], VertexAttributes.FORMATS[VertexAttributes.TEXCOORDS[lightMapChannel]]);
|
||||||
// Constants
|
// Constants
|
||||||
object.setTransformConstants(drawUnit, surface, program.vertexShader, camera);
|
object.setTransformConstants(drawUnit, surface, program.vertexShader, camera);
|
||||||
drawUnit.setProjectionConstants(camera, program.vertexShader.getVariableIndex("cProjMatrix"), object.localToCameraTransform);
|
drawUnit.setProjectionConstants(camera, program.cProjMatrix, object.localToCameraTransform);
|
||||||
drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cThresholdAlpha"), alphaThreshold, 0, 0, alpha);
|
drawUnit.setFragmentConstantsFromNumbers(program.cThresholdAlpha, alphaThreshold, 0, 0, alpha);
|
||||||
// Textures
|
// Textures
|
||||||
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sDiffuse"), diffuseMap._texture);
|
drawUnit.setTextureAt(program.sDiffuse, diffuseMap._texture);
|
||||||
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sLightMap"), lightMap._texture);
|
drawUnit.setTextureAt(program.sLightMap, lightMap._texture);
|
||||||
if (opacityMap != null) {
|
if (opacityMap != null) {
|
||||||
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sOpacity"), opacityMap._texture);
|
drawUnit.setTextureAt(program.sOpacity, opacityMap._texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
return drawUnit;
|
return drawUnit;
|
||||||
@@ -208,13 +208,13 @@ package alternativa.engine3d.materials {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var optionsPrograms:Vector.<ShaderProgram> = programsCache[object.transformProcedure];
|
var optionsPrograms:Vector.<LightMapMaterialProgram> = programsCache[object.transformProcedure];
|
||||||
if(optionsPrograms == null) {
|
if(optionsPrograms == null) {
|
||||||
optionsPrograms = new Vector.<ShaderProgram>(6, true);
|
optionsPrograms = new Vector.<LightMapMaterialProgram>(6, true);
|
||||||
programsCache[object.transformProcedure] = optionsPrograms;
|
programsCache[object.transformProcedure] = optionsPrograms;
|
||||||
}
|
}
|
||||||
|
|
||||||
var program:ShaderProgram;
|
var program:LightMapMaterialProgram;
|
||||||
var drawUnit:DrawUnit;
|
var drawUnit:DrawUnit;
|
||||||
// Opaque pass
|
// Opaque pass
|
||||||
if (opaquePass && alphaThreshold <= alpha) {
|
if (opaquePass && alphaThreshold <= alpha) {
|
||||||
@@ -252,3 +252,38 @@ package alternativa.engine3d.materials {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import alternativa.engine3d.materials.ShaderProgram;
|
||||||
|
import alternativa.engine3d.materials.compiler.Linker;
|
||||||
|
|
||||||
|
import flash.display3D.Context3D;
|
||||||
|
|
||||||
|
class LightMapMaterialProgram extends ShaderProgram {
|
||||||
|
|
||||||
|
public var aPosition:int = -1;
|
||||||
|
public var aUV:int = -1;
|
||||||
|
public var aUV1:int = -1;
|
||||||
|
public var cProjMatrix:int = -1;
|
||||||
|
public var cThresholdAlpha:int = -1;
|
||||||
|
public var sDiffuse:int = -1;
|
||||||
|
public var sLightMap:int = -1;
|
||||||
|
public var sOpacity:int = -1;
|
||||||
|
|
||||||
|
public function LightMapMaterialProgram(vertex:Linker, fragment:Linker) {
|
||||||
|
super(vertex, fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function upload(context3D:Context3D):void {
|
||||||
|
super.upload(context3D);
|
||||||
|
|
||||||
|
aPosition = vertexShader.findVariable("aPosition");
|
||||||
|
aUV = vertexShader.findVariable("aUV");
|
||||||
|
aUV1 = vertexShader.findVariable("aUV1");
|
||||||
|
cProjMatrix = vertexShader.findVariable("cProjMatrix");
|
||||||
|
cThresholdAlpha = fragmentShader.findVariable("cThresholdAlpha");
|
||||||
|
sDiffuse = fragmentShader.findVariable("sDiffuse");
|
||||||
|
sLightMap = fragmentShader.findVariable("sLightMap");
|
||||||
|
sOpacity = fragmentShader.findVariable("sOpacity");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,11 +27,6 @@ package alternativa.engine3d.materials {
|
|||||||
*/
|
*/
|
||||||
public class Material {
|
public class Material {
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
alternativa3d function get canDrawInShadowMap():Boolean {return true}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of the material
|
* Name of the material
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -515,9 +515,9 @@ package alternativa.engine3d.materials {
|
|||||||
* @param directionalLight
|
* @param directionalLight
|
||||||
* @param lightsLength
|
* @param lightsLength
|
||||||
*/
|
*/
|
||||||
private function getProgram(object:Object3D, programs:Dictionary, camera:Camera3D, materialKey:String, opacityMap:TextureResource, alphaTest:int, lightsGroup:Vector.<Light3D>, lightsLength:int, isFirstGroup:Boolean, shadowedLight:Light3D):ShaderProgram {
|
private function getProgram(object:Object3D, programs:Dictionary, camera:Camera3D, materialKey:String, opacityMap:TextureResource, alphaTest:int, lightsGroup:Vector.<Light3D>, lightsLength:int, isFirstGroup:Boolean, shadowedLight:Light3D):StandardMaterialProgram {
|
||||||
var key:String = materialKey + (opacityMap != null ? "O" : "o") + alphaTest.toString();
|
var key:String = materialKey + (opacityMap != null ? "O" : "o") + alphaTest.toString();
|
||||||
var program:ShaderProgram = programs[key];
|
var program:StandardMaterialProgram = programs[key];
|
||||||
if (program == null) {
|
if (program == null) {
|
||||||
var vertexLinker:Linker = new Linker(Context3DProgramType.VERTEX);
|
var vertexLinker:Linker = new Linker(Context3DProgramType.VERTEX);
|
||||||
var fragmentLinker:Linker = new Linker(Context3DProgramType.FRAGMENT);
|
var fragmentLinker:Linker = new Linker(Context3DProgramType.FRAGMENT);
|
||||||
@@ -737,7 +737,7 @@ package alternativa.engine3d.materials {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
fragmentLinker.varyings = vertexLinker.varyings;
|
fragmentLinker.varyings = vertexLinker.varyings;
|
||||||
program = new ShaderProgram(vertexLinker, fragmentLinker);
|
program = new StandardMaterialProgram(vertexLinker, fragmentLinker);
|
||||||
|
|
||||||
program.upload(camera.context3D);
|
program.upload(camera.context3D);
|
||||||
programs[key] = program;
|
programs[key] = program;
|
||||||
@@ -745,8 +745,7 @@ package alternativa.engine3d.materials {
|
|||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: return not neccessary more
|
private function addDrawUnits(program:StandardMaterialProgram, camera:Camera3D, surface:Surface, geometry:Geometry, opacityMap:TextureResource, lights:Vector.<Light3D>, lightsLength:int, isFirstGroup:Boolean, shadowedLight:Light3D, opaqueOption:Boolean, transparentOption:Boolean, objectRenderPriority:int):void {
|
||||||
private function getDrawUnit(program:ShaderProgram, camera:Camera3D, surface:Surface, geometry:Geometry, opacityMap:TextureResource, lights:Vector.<Light3D>, lightsLength:int, isFirstGroup:Boolean, shadowedLight:Light3D, opaqueOption:Boolean, transparentOption:Boolean, objectRenderPriority:int):DrawUnit {
|
|
||||||
// Buffers
|
// Buffers
|
||||||
var positionBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.POSITION);
|
var positionBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.POSITION);
|
||||||
var uvBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.TEXCOORDS[0]);
|
var uvBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.TEXCOORDS[0]);
|
||||||
@@ -759,15 +758,15 @@ package alternativa.engine3d.materials {
|
|||||||
var drawUnit:DrawUnit = camera.renderer.createDrawUnit(object, program.program, geometry._indexBuffer, surface.indexBegin, surface.numTriangles, program);
|
var drawUnit:DrawUnit = camera.renderer.createDrawUnit(object, program.program, geometry._indexBuffer, surface.indexBegin, surface.numTriangles, program);
|
||||||
|
|
||||||
// Streams
|
// Streams
|
||||||
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aPosition"), positionBuffer, geometry._attributesOffsets[VertexAttributes.POSITION], VertexAttributes.FORMATS[VertexAttributes.POSITION]);
|
drawUnit.setVertexBufferAt(program.aPosition, positionBuffer, geometry._attributesOffsets[VertexAttributes.POSITION], VertexAttributes.FORMATS[VertexAttributes.POSITION]);
|
||||||
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aUV"), uvBuffer, geometry._attributesOffsets[VertexAttributes.TEXCOORDS[0]], VertexAttributes.FORMATS[VertexAttributes.TEXCOORDS[0]]);
|
drawUnit.setVertexBufferAt(program.aUV, uvBuffer, geometry._attributesOffsets[VertexAttributes.TEXCOORDS[0]], VertexAttributes.FORMATS[VertexAttributes.TEXCOORDS[0]]);
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
object.setTransformConstants(drawUnit, surface, program.vertexShader, camera);
|
object.setTransformConstants(drawUnit, surface, program.vertexShader, camera);
|
||||||
drawUnit.setProjectionConstants(camera, program.vertexShader.getVariableIndex("cProjMatrix"), object.localToCameraTransform);
|
drawUnit.setProjectionConstants(camera, program.cProjMatrix, object.localToCameraTransform);
|
||||||
// Set options for a surface. X should be 0.
|
// Set options for a surface. X should be 0.
|
||||||
drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cSurface"), 0, glossiness, specularPower, 1);
|
drawUnit.setFragmentConstantsFromNumbers(program.cSurface, 0, glossiness, specularPower, 1);
|
||||||
drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cThresholdAlpha"), alphaThreshold, 0, 0, alpha);
|
drawUnit.setFragmentConstantsFromNumbers(program.cThresholdAlpha, alphaThreshold, 0, 0, alpha);
|
||||||
|
|
||||||
var light:Light3D;
|
var light:Light3D;
|
||||||
var len:Number;
|
var len:Number;
|
||||||
@@ -778,16 +777,15 @@ package alternativa.engine3d.materials {
|
|||||||
var falloff:Number;
|
var falloff:Number;
|
||||||
var hotspot:Number;
|
var hotspot:Number;
|
||||||
|
|
||||||
|
|
||||||
if (lightsLength > 0 || shadowedLight) {
|
if (lightsLength > 0 || shadowedLight) {
|
||||||
if (_normalMapSpace == NormalMapSpace.TANGENT_RIGHT_HANDED || _normalMapSpace == NormalMapSpace.TANGENT_LEFT_HANDED) {
|
if (_normalMapSpace == NormalMapSpace.TANGENT_RIGHT_HANDED || _normalMapSpace == NormalMapSpace.TANGENT_LEFT_HANDED) {
|
||||||
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aNormal"), normalsBuffer, geometry._attributesOffsets[VertexAttributes.NORMAL], VertexAttributes.FORMATS[VertexAttributes.NORMAL]);
|
drawUnit.setVertexBufferAt(program.aNormal, normalsBuffer, geometry._attributesOffsets[VertexAttributes.NORMAL], VertexAttributes.FORMATS[VertexAttributes.NORMAL]);
|
||||||
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aTangent"), tangentsBuffer, geometry._attributesOffsets[VertexAttributes.TANGENT4], VertexAttributes.FORMATS[VertexAttributes.TANGENT4]);
|
drawUnit.setVertexBufferAt(program.aTangent, tangentsBuffer, geometry._attributesOffsets[VertexAttributes.TANGENT4], VertexAttributes.FORMATS[VertexAttributes.TANGENT4]);
|
||||||
}
|
}
|
||||||
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sBump"), normalMap._texture);
|
drawUnit.setTextureAt(program.sBump, normalMap._texture);
|
||||||
|
|
||||||
var camTransform:Transform3D = object.cameraToLocalTransform;
|
var camTransform:Transform3D = object.cameraToLocalTransform;
|
||||||
drawUnit.setVertexConstantsFromNumbers(program.vertexShader.getVariableIndex("cCameraPosition"), camTransform.d, camTransform.h, camTransform.l);
|
drawUnit.setVertexConstantsFromNumbers(program.cCameraPosition, camTransform.d, camTransform.h, camTransform.l);
|
||||||
|
|
||||||
for (var i:int = 0; i < lightsLength; i++) {
|
for (var i:int = 0; i < lightsLength; i++) {
|
||||||
light = lights[i];
|
light = lights[i];
|
||||||
@@ -861,32 +859,32 @@ package alternativa.engine3d.materials {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Textures
|
// Textures
|
||||||
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sDiffuse"), diffuseMap._texture);
|
drawUnit.setTextureAt(program.sDiffuse, diffuseMap._texture);
|
||||||
if (opacityMap != null) {
|
if (opacityMap != null) {
|
||||||
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sOpacity"), opacityMap._texture);
|
drawUnit.setTextureAt(program.sOpacity, opacityMap._texture);
|
||||||
}
|
}
|
||||||
if (glossinessMap != null) {
|
if (glossinessMap != null) {
|
||||||
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sGlossiness"), glossinessMap._texture);
|
drawUnit.setTextureAt(program.sGlossiness, glossinessMap._texture);
|
||||||
}
|
}
|
||||||
if (specularMap != null) {
|
if (specularMap != null) {
|
||||||
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sSpecular"), specularMap._texture);
|
drawUnit.setTextureAt(program.sSpecular, specularMap._texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isFirstGroup){
|
if (isFirstGroup){
|
||||||
if (lightMap != null) {
|
if (lightMap != null) {
|
||||||
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aUV1"),
|
drawUnit.setVertexBufferAt(program.aUV1,
|
||||||
geometry.getVertexBuffer(VertexAttributes.TEXCOORDS[lightMapChannel]),
|
geometry.getVertexBuffer(VertexAttributes.TEXCOORDS[lightMapChannel]),
|
||||||
geometry._attributesOffsets[VertexAttributes.TEXCOORDS[lightMapChannel]],
|
geometry._attributesOffsets[VertexAttributes.TEXCOORDS[lightMapChannel]],
|
||||||
Context3DVertexBufferFormat.FLOAT_2);
|
Context3DVertexBufferFormat.FLOAT_2);
|
||||||
drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cAmbientColor"), 0,0,0, 1);
|
drawUnit.setFragmentConstantsFromNumbers(program.cAmbientColor, 0,0,0, 1);
|
||||||
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sLightMap"), lightMap._texture);
|
drawUnit.setTextureAt(program.sLightMap, lightMap._texture);
|
||||||
} else {
|
} else {
|
||||||
drawUnit.setFragmentConstantsFromVector(program.fragmentShader.getVariableIndex("cAmbientColor"), camera.ambient, 1);
|
drawUnit.setFragmentConstantsFromVector(program.cAmbientColor, camera.ambient, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cAmbientColor"), 0,0,0, 1);
|
drawUnit.setFragmentConstantsFromNumbers(program.cAmbientColor, 0,0,0, 1);
|
||||||
}
|
}
|
||||||
setPassUVProcedureConstants(drawUnit, program.vertexShader);
|
setPassUVProcedureConstants(drawUnit, program.vertexShader);
|
||||||
|
|
||||||
@@ -894,7 +892,6 @@ package alternativa.engine3d.materials {
|
|||||||
shadowedLight.shadow.setup(drawUnit, program.vertexShader, program.fragmentShader, surface);
|
shadowedLight.shadow.setup(drawUnit, program.vertexShader, program.fragmentShader, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Inititalizing render properties
|
// Inititalizing render properties
|
||||||
if (opaqueOption)
|
if (opaqueOption)
|
||||||
// Use z-buffer within DrawCall, draws without blending
|
// Use z-buffer within DrawCall, draws without blending
|
||||||
@@ -963,9 +960,11 @@ package alternativa.engine3d.materials {
|
|||||||
// drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cFogConsts"), 0.5*uScale, 0.5 - uRight, 0);
|
// drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cFogConsts"), 0.5*uScale, 0.5 - uRight, 0);
|
||||||
// drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sFogTexture"), fogTexture._texture);
|
// drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sFogTexture"), fogTexture._texture);
|
||||||
// }
|
// }
|
||||||
return drawUnit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static var lightGroup:Vector.<Light3D> = new Vector.<Light3D>();
|
||||||
|
private static var shadowGroup:Vector.<Light3D> = new Vector.<Light3D>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
@@ -1007,35 +1006,30 @@ package alternativa.engine3d.materials {
|
|||||||
programsCache[object.transformProcedure] = optionsPrograms;
|
programsCache[object.transformProcedure] = optionsPrograms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Form groups of lights
|
||||||
// Form groups
|
var groupsCount:int = 0;
|
||||||
var groupsCount:int = groups.length = 0;
|
var lightGroupLength:int = 0;
|
||||||
var firstGroup:Vector.<Light3D> = new Vector.<Light3D>();
|
var shadowGroupLength:int = 0;
|
||||||
var shadowGroup:Vector.<Light3D> = new Vector.<Light3D>();
|
|
||||||
var firstGroupLength:int = 0;
|
|
||||||
for (i = 0; i < lightsLength; i++) {
|
for (i = 0; i < lightsLength; i++) {
|
||||||
light = lights[i];
|
light = lights[i];
|
||||||
if (light.shadow != null && useShadow) {
|
if (light.shadow != null && useShadow) {
|
||||||
shadowGroup.push(light);
|
shadowGroup[int(shadowGroupLength++)] = light;
|
||||||
|
} else {
|
||||||
|
if (lightGroupLength == 6) {
|
||||||
|
groups[int(groupsCount++)] = lightGroup;
|
||||||
|
lightGroup = new Vector.<Light3D>();
|
||||||
|
lightGroupLength = 0;
|
||||||
}
|
}
|
||||||
else{
|
lightGroup[int(lightGroupLength++)] = light;
|
||||||
if (firstGroupLength==6){
|
|
||||||
groups[groupsCount++] = firstGroup;
|
|
||||||
firstGroup = new Vector.<Light3D>();
|
|
||||||
firstGroupLength = 0;
|
|
||||||
}
|
|
||||||
firstGroup[firstGroupLength++] = light;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (firstGroupLength!=0){
|
if (lightGroupLength != 0) {
|
||||||
groups[groupsCount++] = firstGroup;
|
groups[int(groupsCount++)] = lightGroup;
|
||||||
}
|
}
|
||||||
var shadowGroupLength:int = shadowGroup.length;
|
|
||||||
|
|
||||||
// Iterate groups
|
// Iterate groups
|
||||||
var materialKey:String;
|
var materialKey:String;
|
||||||
var program:ShaderProgram;
|
var program:StandardMaterialProgram;
|
||||||
var drawUnit:DrawUnit;
|
|
||||||
|
|
||||||
if (groupsCount == 0 && shadowGroupLength == 0) {
|
if (groupsCount == 0 && shadowGroupLength == 0) {
|
||||||
// There is only Ambient light on the scene
|
// There is only Ambient light on the scene
|
||||||
@@ -1049,11 +1043,11 @@ package alternativa.engine3d.materials {
|
|||||||
// Alpha test
|
// Alpha test
|
||||||
// use opacityMap if it is presented
|
// use opacityMap if it is presented
|
||||||
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 1, null, 0, true, null);
|
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 1, null, 0, true, null);
|
||||||
drawUnit = getDrawUnit(program, camera, surface, geometry, opacityMap, null, 0, true, null, true, false, objectRenderPriority);
|
addDrawUnits(program, camera, surface, geometry, opacityMap, null, 0, true, null, true, false, objectRenderPriority);
|
||||||
} else {
|
} else {
|
||||||
// do not use opacityMap at all
|
// do not use opacityMap at all
|
||||||
program = getProgram(object, optionsPrograms, camera, materialKey, null, 0, null, 0, true, null);
|
program = getProgram(object, optionsPrograms, camera, materialKey, null, 0, null, 0, true, null);
|
||||||
drawUnit = getDrawUnit(program, camera, surface, geometry, null, null, 0, true, null, true, false, objectRenderPriority);
|
addDrawUnits(program, camera, surface, geometry, null, null, 0, true, null, true, false, objectRenderPriority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Transparent pass
|
// Transparent pass
|
||||||
@@ -1062,20 +1056,19 @@ package alternativa.engine3d.materials {
|
|||||||
if (alphaThreshold <= alpha && !opaquePass) {
|
if (alphaThreshold <= alpha && !opaquePass) {
|
||||||
// Alpha threshold
|
// Alpha threshold
|
||||||
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 2, null, 0, true, null);
|
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 2, null, 0, true, null);
|
||||||
drawUnit = getDrawUnit(program, camera, surface, geometry, opacityMap, null, 0, true, null, false, true, objectRenderPriority);
|
addDrawUnits(program, camera, surface, geometry, opacityMap, null, 0, true, null, false, true, objectRenderPriority);
|
||||||
} else {
|
} else {
|
||||||
// There is no Alpha threshold or check z-buffer by previous pass
|
// There is no Alpha threshold or check z-buffer by previous pass
|
||||||
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 0, null, 0, true, null);
|
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 0, null, 0, true, null);
|
||||||
drawUnit = getDrawUnit(program, camera, surface, geometry, opacityMap, null, 0, true, null, false, true, objectRenderPriority);
|
addDrawUnits(program, camera, surface, geometry, opacityMap, null, 0, true, null, false, true, objectRenderPriority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var j:int;
|
var j:int;
|
||||||
var lightLengthInGroup:int;
|
|
||||||
var isFirstGroup:Boolean = true;
|
var isFirstGroup:Boolean = true;
|
||||||
for (i = 0; i < groupsCount; i++) {
|
for (i = 0; i < groupsCount; i++) {
|
||||||
var lightGroup:Vector.<Light3D> = groups[i];
|
lightGroup = groups[i];
|
||||||
lightLengthInGroup = lightGroup.length;
|
lightGroupLength = lightGroup.length;
|
||||||
|
|
||||||
// Group of lights without shadow
|
// Group of lights without shadow
|
||||||
// Form key
|
// Form key
|
||||||
@@ -1084,7 +1077,7 @@ package alternativa.engine3d.materials {
|
|||||||
(_normalMapSpace.toString()) +
|
(_normalMapSpace.toString()) +
|
||||||
((glossinessMap != null) ? "G" : "g") +
|
((glossinessMap != null) ? "G" : "g") +
|
||||||
((specularMap != null) ? "S" : "s");
|
((specularMap != null) ? "S" : "s");
|
||||||
for (j = 0; j < lightLengthInGroup; j++) {
|
for (j = 0; j < lightGroupLength; j++) {
|
||||||
light = lightGroup[j];
|
light = lightGroup[j];
|
||||||
materialKey += light.lightID;
|
materialKey += light.lightID;
|
||||||
}
|
}
|
||||||
@@ -1095,12 +1088,12 @@ package alternativa.engine3d.materials {
|
|||||||
if (alphaThreshold > 0) {
|
if (alphaThreshold > 0) {
|
||||||
// Alpha test
|
// Alpha test
|
||||||
// use opacityMap if it is presented
|
// use opacityMap if it is presented
|
||||||
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 1, lightGroup, lightLengthInGroup, isFirstGroup, null);
|
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 1, lightGroup, lightGroupLength, isFirstGroup, null);
|
||||||
drawUnit = getDrawUnit(program, camera, surface, geometry, opacityMap, lightGroup, lightLengthInGroup, isFirstGroup, null, true, false, objectRenderPriority);
|
addDrawUnits(program, camera, surface, geometry, opacityMap, lightGroup, lightGroupLength, isFirstGroup, null, true, false, objectRenderPriority);
|
||||||
} else {
|
} else {
|
||||||
// do not use opacityMap at all
|
// do not use opacityMap at all
|
||||||
program = getProgram(object, optionsPrograms, camera, materialKey, null, 0, lightGroup, lightLengthInGroup, isFirstGroup, null);
|
program = getProgram(object, optionsPrograms, camera, materialKey, null, 0, lightGroup, lightGroupLength, isFirstGroup, null);
|
||||||
drawUnit = getDrawUnit(program, camera, surface, geometry, null, lightGroup, lightLengthInGroup, isFirstGroup, null, true, false, objectRenderPriority);
|
addDrawUnits(program, camera, surface, geometry, null, lightGroup, lightGroupLength, isFirstGroup, null, true, false, objectRenderPriority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Transparent pass
|
// Transparent pass
|
||||||
@@ -1108,12 +1101,12 @@ package alternativa.engine3d.materials {
|
|||||||
// use opacityMap if it is presented
|
// use opacityMap if it is presented
|
||||||
if (alphaThreshold <= alpha && !opaquePass) {
|
if (alphaThreshold <= alpha && !opaquePass) {
|
||||||
// Alpha threshold
|
// Alpha threshold
|
||||||
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 2, lightGroup, lightLengthInGroup, isFirstGroup, null);
|
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 2, lightGroup, lightGroupLength, isFirstGroup, null);
|
||||||
drawUnit = getDrawUnit(program, camera, surface, geometry, opacityMap, lightGroup, lightLengthInGroup, isFirstGroup, null, false, true, objectRenderPriority);
|
addDrawUnits(program, camera, surface, geometry, opacityMap, lightGroup, lightGroupLength, isFirstGroup, null, false, true, objectRenderPriority);
|
||||||
} else {
|
} else {
|
||||||
// There is no Alpha threshold or check z-buffer by previous pass
|
// There is no Alpha threshold or check z-buffer by previous pass
|
||||||
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 0, lightGroup, lightLengthInGroup, isFirstGroup, null);
|
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 0, lightGroup, lightGroupLength, isFirstGroup, null);
|
||||||
drawUnit = getDrawUnit(program, camera, surface, geometry, opacityMap, lightGroup, lightLengthInGroup, isFirstGroup, null, false, true, objectRenderPriority);
|
addDrawUnits(program, camera, surface, geometry, opacityMap, lightGroup, lightGroupLength, isFirstGroup, null, false, true, objectRenderPriority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isFirstGroup = false;
|
isFirstGroup = false;
|
||||||
@@ -1142,15 +1135,12 @@ package alternativa.engine3d.materials {
|
|||||||
// Alpha test
|
// Alpha test
|
||||||
// use opacityMap if it is presented
|
// use opacityMap if it is presented
|
||||||
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 1, null, 0, isFirstGroup, light);
|
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 1, null, 0, isFirstGroup, light);
|
||||||
drawUnit = getDrawUnit(program, camera, surface, geometry, opacityMap, null, 0, isFirstGroup, light, true, false, objectRenderPriority);
|
addDrawUnits(program, camera, surface, geometry, opacityMap, null, 0, isFirstGroup, light, true, false, objectRenderPriority);
|
||||||
} else {
|
} else {
|
||||||
// do not use opacityMap at all
|
// do not use opacityMap at all
|
||||||
program = getProgram(object, optionsPrograms, camera, materialKey, null, 0, null, 0, isFirstGroup, light);
|
program = getProgram(object, optionsPrograms, camera, materialKey, null, 0, null, 0, isFirstGroup, light);
|
||||||
drawUnit = getDrawUnit(program, camera, surface, geometry, null, null, 0, isFirstGroup, light, true, false, objectRenderPriority);
|
addDrawUnits(program, camera, surface, geometry, null, null, 0, isFirstGroup, light, true, false, objectRenderPriority);
|
||||||
}
|
}
|
||||||
// trace(program.vertexShader.describeLinkageInfo());
|
|
||||||
// trace(program.fragmentShader.describeLinkageInfo());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// Transparent pass
|
// Transparent pass
|
||||||
if (transparentPass && alphaThreshold > 0 && alpha > 0) {
|
if (transparentPass && alphaThreshold > 0 && alpha > 0) {
|
||||||
@@ -1158,11 +1148,11 @@ package alternativa.engine3d.materials {
|
|||||||
if (alphaThreshold <= alpha && !opaquePass) {
|
if (alphaThreshold <= alpha && !opaquePass) {
|
||||||
// Alpha threshold
|
// Alpha threshold
|
||||||
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 2, null, 0, isFirstGroup, light);
|
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 2, null, 0, isFirstGroup, light);
|
||||||
drawUnit = getDrawUnit(program, camera, surface, geometry, opacityMap, null, 0, isFirstGroup, light, false, true, objectRenderPriority);
|
addDrawUnits(program, camera, surface, geometry, opacityMap, null, 0, isFirstGroup, light, false, true, objectRenderPriority);
|
||||||
} else {
|
} else {
|
||||||
// There is no Alpha threshold or check z-buffer by previous pass
|
// There is no Alpha threshold or check z-buffer by previous pass
|
||||||
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 0, null, 0, isFirstGroup, light);
|
program = getProgram(object, optionsPrograms, camera, materialKey, opacityMap, 0, null, 0, isFirstGroup, light);
|
||||||
drawUnit = getDrawUnit(program, camera, surface, geometry, opacityMap, null, 0, isFirstGroup, light, false, true, objectRenderPriority);
|
addDrawUnits(program, camera, surface, geometry, opacityMap, null, 0, isFirstGroup, light, false, true, objectRenderPriority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isFirstGroup = false;
|
isFirstGroup = false;
|
||||||
@@ -1197,3 +1187,55 @@ package alternativa.engine3d.materials {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import alternativa.engine3d.materials.ShaderProgram;
|
||||||
|
import alternativa.engine3d.materials.compiler.Linker;
|
||||||
|
|
||||||
|
import flash.display3D.Context3D;
|
||||||
|
|
||||||
|
class StandardMaterialProgram extends ShaderProgram {
|
||||||
|
|
||||||
|
public var aPosition:int = -1;
|
||||||
|
public var aUV:int = -1;
|
||||||
|
public var aUV1:int = -1;
|
||||||
|
public var aNormal:int = -1;
|
||||||
|
public var aTangent:int = -1;
|
||||||
|
public var cProjMatrix:int = -1;
|
||||||
|
public var cCameraPosition:int = -1;
|
||||||
|
public var cAmbientColor:int = -1;
|
||||||
|
public var cSurface:int = -1;
|
||||||
|
public var cThresholdAlpha:int = -1;
|
||||||
|
public var sDiffuse:int = -1;
|
||||||
|
public var sOpacity:int = -1;
|
||||||
|
public var sBump:int = -1;
|
||||||
|
public var sGlossiness:int = -1;
|
||||||
|
public var sSpecular:int = -1;
|
||||||
|
public var sLightMap:int = -1;
|
||||||
|
|
||||||
|
public function StandardMaterialProgram(vertex:Linker, fragment:Linker) {
|
||||||
|
super(vertex, fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function upload(context3D:Context3D):void {
|
||||||
|
super.upload(context3D);
|
||||||
|
|
||||||
|
aPosition = vertexShader.findVariable("aPosition");
|
||||||
|
aUV = vertexShader.findVariable("aUV");
|
||||||
|
aUV1 = vertexShader.findVariable("aUV1");
|
||||||
|
aNormal = vertexShader.findVariable("aNormal");
|
||||||
|
aTangent = vertexShader.findVariable("aTangent");
|
||||||
|
cProjMatrix = vertexShader.findVariable("cProjMatrix");
|
||||||
|
cCameraPosition = vertexShader.findVariable("cCameraPosition");
|
||||||
|
|
||||||
|
cAmbientColor = fragmentShader.findVariable("cAmbientColor");
|
||||||
|
cSurface = fragmentShader.findVariable("cSurface");
|
||||||
|
cThresholdAlpha = fragmentShader.findVariable("cThresholdAlpha");
|
||||||
|
sDiffuse = fragmentShader.findVariable("sDiffuse");
|
||||||
|
sOpacity = fragmentShader.findVariable("sOpacity");
|
||||||
|
sBump = fragmentShader.findVariable("sBump");
|
||||||
|
sGlossiness = fragmentShader.findVariable("sGlossiness");
|
||||||
|
sSpecular = fragmentShader.findVariable("sSpecular");
|
||||||
|
sLightMap = fragmentShader.findVariable("sLightMap");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -42,13 +42,6 @@ package alternativa.engine3d.materials {
|
|||||||
*/
|
*/
|
||||||
public class TextureMaterial extends Material {
|
public class TextureMaterial extends Material {
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
alternativa3d override function get canDrawInShadowMap():Boolean {
|
|
||||||
return opaquePass && alphaThreshold == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static var caches:Dictionary = new Dictionary(true);
|
private static var caches:Dictionary = new Dictionary(true);
|
||||||
private var cachedContext3D:Context3D;
|
private var cachedContext3D:Context3D;
|
||||||
private var programsCache:Dictionary;
|
private var programsCache:Dictionary;
|
||||||
@@ -176,9 +169,9 @@ package alternativa.engine3d.materials {
|
|||||||
* @param alphaTest 0 - disabled, 1 - opaque, 2 - contours
|
* @param alphaTest 0 - disabled, 1 - opaque, 2 - contours
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private function getProgram(object:Object3D, programs:Vector.<ShaderProgram>, camera:Camera3D, opacityMap:TextureResource, alphaTest:int):ShaderProgram {
|
private function getProgram(object:Object3D, programs:Vector.<TextureMaterialProgram>, camera:Camera3D, opacityMap:TextureResource, alphaTest:int):TextureMaterialProgram {
|
||||||
var key:int = (opacityMap != null ? 3 : 0) + alphaTest;
|
var key:int = (opacityMap != null ? 3 : 0) + alphaTest;
|
||||||
var program:ShaderProgram = programs[key];
|
var program:TextureMaterialProgram = programs[key];
|
||||||
if (program == null) {
|
if (program == null) {
|
||||||
// Make program
|
// Make program
|
||||||
// Vertex shader
|
// Vertex shader
|
||||||
@@ -208,7 +201,7 @@ package alternativa.engine3d.materials {
|
|||||||
}
|
}
|
||||||
fragmentLinker.varyings = vertexLinker.varyings;
|
fragmentLinker.varyings = vertexLinker.varyings;
|
||||||
|
|
||||||
program = new ShaderProgram(vertexLinker, fragmentLinker);
|
program = new TextureMaterialProgram(vertexLinker, fragmentLinker);
|
||||||
|
|
||||||
program.upload(camera.context3D);
|
program.upload(camera.context3D);
|
||||||
programs[key] = program;
|
programs[key] = program;
|
||||||
@@ -216,7 +209,7 @@ package alternativa.engine3d.materials {
|
|||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getDrawUnit(program:ShaderProgram, camera:Camera3D, surface:Surface, geometry:Geometry, opacityMap:TextureResource):DrawUnit {
|
private function getDrawUnit(program:TextureMaterialProgram, camera:Camera3D, surface:Surface, geometry:Geometry, opacityMap:TextureResource):DrawUnit {
|
||||||
var positionBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.POSITION);
|
var positionBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.POSITION);
|
||||||
var uvBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.TEXCOORDS[0]);
|
var uvBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.TEXCOORDS[0]);
|
||||||
|
|
||||||
@@ -226,16 +219,16 @@ package alternativa.engine3d.materials {
|
|||||||
var drawUnit:DrawUnit = camera.renderer.createDrawUnit(object, program.program, geometry._indexBuffer, surface.indexBegin, surface.numTriangles, program);
|
var drawUnit:DrawUnit = camera.renderer.createDrawUnit(object, program.program, geometry._indexBuffer, surface.indexBegin, surface.numTriangles, program);
|
||||||
|
|
||||||
// Streams
|
// Streams
|
||||||
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aPosition"), positionBuffer, geometry._attributesOffsets[VertexAttributes.POSITION], VertexAttributes.FORMATS[VertexAttributes.POSITION]);
|
drawUnit.setVertexBufferAt(program.aPosition, positionBuffer, geometry._attributesOffsets[VertexAttributes.POSITION], VertexAttributes.FORMATS[VertexAttributes.POSITION]);
|
||||||
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aUV"), uvBuffer, geometry._attributesOffsets[VertexAttributes.TEXCOORDS[0]], VertexAttributes.FORMATS[VertexAttributes.TEXCOORDS[0]]);
|
drawUnit.setVertexBufferAt(program.aUV, uvBuffer, geometry._attributesOffsets[VertexAttributes.TEXCOORDS[0]], VertexAttributes.FORMATS[VertexAttributes.TEXCOORDS[0]]);
|
||||||
//Constants
|
//Constants
|
||||||
object.setTransformConstants(drawUnit, surface, program.vertexShader, camera);
|
object.setTransformConstants(drawUnit, surface, program.vertexShader, camera);
|
||||||
drawUnit.setProjectionConstants(camera, program.vertexShader.getVariableIndex("cProjMatrix"), object.localToCameraTransform);
|
drawUnit.setProjectionConstants(camera, program.cProjMatrix, object.localToCameraTransform);
|
||||||
drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cThresholdAlpha"), alphaThreshold, 0, 0, alpha);
|
drawUnit.setFragmentConstantsFromNumbers(program.cThresholdAlpha, alphaThreshold, 0, 0, alpha);
|
||||||
// Textures
|
// Textures
|
||||||
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sDiffuse"), diffuseMap._texture);
|
drawUnit.setTextureAt(program.sDiffuse, diffuseMap._texture);
|
||||||
if (opacityMap != null) {
|
if (opacityMap != null) {
|
||||||
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sOpacity"), opacityMap._texture);
|
drawUnit.setTextureAt(program.sOpacity, opacityMap._texture);
|
||||||
}
|
}
|
||||||
return drawUnit;
|
return drawUnit;
|
||||||
}
|
}
|
||||||
@@ -262,13 +255,13 @@ package alternativa.engine3d.materials {
|
|||||||
caches[cachedContext3D] = programsCache;
|
caches[cachedContext3D] = programsCache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var optionsPrograms:Vector.<ShaderProgram> = programsCache[object.transformProcedure];
|
var optionsPrograms:Vector.<TextureMaterialProgram> = programsCache[object.transformProcedure];
|
||||||
if(optionsPrograms == null) {
|
if(optionsPrograms == null) {
|
||||||
optionsPrograms = new Vector.<ShaderProgram>(6, true);
|
optionsPrograms = new Vector.<TextureMaterialProgram>(6, true);
|
||||||
programsCache[object.transformProcedure] = optionsPrograms;
|
programsCache[object.transformProcedure] = optionsPrograms;
|
||||||
}
|
}
|
||||||
|
|
||||||
var program:ShaderProgram;
|
var program:TextureMaterialProgram;
|
||||||
var drawUnit:DrawUnit;
|
var drawUnit:DrawUnit;
|
||||||
// Opaque pass
|
// Opaque pass
|
||||||
if (opaquePass && alphaThreshold <= alpha) {
|
if (opaquePass && alphaThreshold <= alpha) {
|
||||||
@@ -329,3 +322,34 @@ package alternativa.engine3d.materials {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import alternativa.engine3d.materials.ShaderProgram;
|
||||||
|
import alternativa.engine3d.materials.compiler.Linker;
|
||||||
|
|
||||||
|
import flash.display3D.Context3D;
|
||||||
|
|
||||||
|
class TextureMaterialProgram extends ShaderProgram {
|
||||||
|
|
||||||
|
public var aPosition:int = -1;
|
||||||
|
public var aUV:int = -1;
|
||||||
|
public var cProjMatrix:int = -1;
|
||||||
|
public var cThresholdAlpha:int = -1;
|
||||||
|
public var sDiffuse:int = -1;
|
||||||
|
public var sOpacity:int = -1;
|
||||||
|
|
||||||
|
public function TextureMaterialProgram(vertex:Linker, fragment:Linker) {
|
||||||
|
super(vertex, fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function upload(context3D:Context3D):void {
|
||||||
|
super.upload(context3D);
|
||||||
|
|
||||||
|
aPosition = vertexShader.findVariable("aPosition");
|
||||||
|
aUV = vertexShader.findVariable("aUV");
|
||||||
|
cProjMatrix = vertexShader.findVariable("cProjMatrix");
|
||||||
|
cThresholdAlpha = fragmentShader.findVariable("cThresholdAlpha");
|
||||||
|
sDiffuse = fragmentShader.findVariable("sDiffuse");
|
||||||
|
sOpacity = fragmentShader.findVariable("sOpacity");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -126,9 +126,9 @@ package alternativa.engine3d.materials {
|
|||||||
* @param directionalLight
|
* @param directionalLight
|
||||||
* @param lightsLength
|
* @param lightsLength
|
||||||
*/
|
*/
|
||||||
private function getProgram(object:Object3D, programs:Dictionary, camera:Camera3D, materialKey:String, opacityMap:TextureResource, alphaTest:int, lights:Vector.<Light3D>, lightsLength:int):ShaderProgram {
|
private function getProgram(object:Object3D, programs:Dictionary, camera:Camera3D, materialKey:String, opacityMap:TextureResource, alphaTest:int, lights:Vector.<Light3D>, lightsLength:int):VertexLightTextureMaterialProgram {
|
||||||
var key:String = materialKey + (opacityMap != null ? "O" : "o") + alphaTest.toString();
|
var key:String = materialKey + (opacityMap != null ? "O" : "o") + alphaTest.toString();
|
||||||
var program:ShaderProgram = programs[key];
|
var program:VertexLightTextureMaterialProgram = programs[key];
|
||||||
if (program == null) {
|
if (program == null) {
|
||||||
var vertexLinker:Linker = new Linker(Context3DProgramType.VERTEX);
|
var vertexLinker:Linker = new Linker(Context3DProgramType.VERTEX);
|
||||||
vertexLinker.declareVariable("tTotalLight");
|
vertexLinker.declareVariable("tTotalLight");
|
||||||
@@ -200,7 +200,7 @@ package alternativa.engine3d.materials {
|
|||||||
fragmentLinker.addProcedure(_mulLightingProcedure, "tColor");
|
fragmentLinker.addProcedure(_mulLightingProcedure, "tColor");
|
||||||
|
|
||||||
fragmentLinker.varyings = vertexLinker.varyings;
|
fragmentLinker.varyings = vertexLinker.varyings;
|
||||||
program = new ShaderProgram(vertexLinker, fragmentLinker);
|
program = new VertexLightTextureMaterialProgram(vertexLinker, fragmentLinker);
|
||||||
|
|
||||||
program.upload(camera.context3D);
|
program.upload(camera.context3D);
|
||||||
programs[key] = program;
|
programs[key] = program;
|
||||||
@@ -208,7 +208,7 @@ package alternativa.engine3d.materials {
|
|||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getDrawUnit(program:ShaderProgram, camera:Camera3D, surface:Surface, geometry:Geometry, opacityMap:TextureResource, lights:Vector.<Light3D>, lightsLength:int):DrawUnit {
|
private function getDrawUnit(program:VertexLightTextureMaterialProgram, camera:Camera3D, surface:Surface, geometry:Geometry, opacityMap:TextureResource, lights:Vector.<Light3D>, lightsLength:int):DrawUnit {
|
||||||
// Buffers
|
// Buffers
|
||||||
var object:Object3D = surface.object;
|
var object:Object3D = surface.object;
|
||||||
|
|
||||||
@@ -220,17 +220,17 @@ package alternativa.engine3d.materials {
|
|||||||
var drawUnit:DrawUnit = camera.renderer.createDrawUnit(object, program.program, geometry._indexBuffer, surface.indexBegin, surface.numTriangles, program);
|
var drawUnit:DrawUnit = camera.renderer.createDrawUnit(object, program.program, geometry._indexBuffer, surface.indexBegin, surface.numTriangles, program);
|
||||||
|
|
||||||
// Streams
|
// Streams
|
||||||
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aPosition"), positionBuffer, geometry._attributesOffsets[VertexAttributes.POSITION], VertexAttributes.FORMATS[VertexAttributes.POSITION]);
|
drawUnit.setVertexBufferAt(program.aPosition, positionBuffer, geometry._attributesOffsets[VertexAttributes.POSITION], VertexAttributes.FORMATS[VertexAttributes.POSITION]);
|
||||||
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aUV"), uvBuffer, geometry._attributesOffsets[VertexAttributes.TEXCOORDS[0]], VertexAttributes.FORMATS[VertexAttributes.TEXCOORDS[0]]);
|
drawUnit.setVertexBufferAt(program.aUV, uvBuffer, geometry._attributesOffsets[VertexAttributes.TEXCOORDS[0]], VertexAttributes.FORMATS[VertexAttributes.TEXCOORDS[0]]);
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
object.setTransformConstants(drawUnit, surface, program.vertexShader, camera);
|
object.setTransformConstants(drawUnit, surface, program.vertexShader, camera);
|
||||||
drawUnit.setProjectionConstants(camera, program.vertexShader.getVariableIndex("cProjMatrix"), object.localToCameraTransform);
|
drawUnit.setProjectionConstants(camera, program.cProjMatrix, object.localToCameraTransform);
|
||||||
drawUnit.setVertexConstantsFromVector(program.vertexShader.getVariableIndex("cAmbientColor"), camera.ambient, 1);
|
drawUnit.setVertexConstantsFromVector(program.cAmbientColor, camera.ambient, 1);
|
||||||
drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cThresholdAlpha"), alphaThreshold, 0, 0, alpha);
|
drawUnit.setFragmentConstantsFromNumbers(program.cThresholdAlpha, alphaThreshold, 0, 0, alpha);
|
||||||
|
|
||||||
if (lightsLength > 0) {
|
if (lightsLength > 0) {
|
||||||
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aNormal"), normalsBuffer, geometry._attributesOffsets[VertexAttributes.NORMAL], VertexAttributes.FORMATS[VertexAttributes.NORMAL]);
|
drawUnit.setVertexBufferAt(program.aNormal, normalsBuffer, geometry._attributesOffsets[VertexAttributes.NORMAL], VertexAttributes.FORMATS[VertexAttributes.NORMAL]);
|
||||||
|
|
||||||
var i:int;
|
var i:int;
|
||||||
var light:Light3D;
|
var light:Light3D;
|
||||||
@@ -269,9 +269,9 @@ package alternativa.engine3d.materials {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Textures
|
// Textures
|
||||||
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sDiffuse"), diffuseMap._texture);
|
drawUnit.setTextureAt(program.sDiffuse, diffuseMap._texture);
|
||||||
if (opacityMap != null) {
|
if (opacityMap != null) {
|
||||||
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sOpacity"), opacityMap._texture);
|
drawUnit.setTextureAt(program.sOpacity, opacityMap._texture);
|
||||||
}
|
}
|
||||||
return drawUnit;
|
return drawUnit;
|
||||||
}
|
}
|
||||||
@@ -294,6 +294,7 @@ package alternativa.engine3d.materials {
|
|||||||
// Program
|
// Program
|
||||||
var light:Light3D;
|
var light:Light3D;
|
||||||
var materialKey:String = "";
|
var materialKey:String = "";
|
||||||
|
// TODO: Form key by each light types count, not id
|
||||||
for (var i:int = 0; i < lightsLength; i++) {
|
for (var i:int = 0; i < lightsLength; i++) {
|
||||||
light = lights[i];
|
light = lights[i];
|
||||||
materialKey += light.lightID;
|
materialKey += light.lightID;
|
||||||
@@ -315,7 +316,7 @@ package alternativa.engine3d.materials {
|
|||||||
programsCache[object.transformProcedure] = optionsPrograms;
|
programsCache[object.transformProcedure] = optionsPrograms;
|
||||||
}
|
}
|
||||||
|
|
||||||
var program:ShaderProgram;
|
var program:VertexLightTextureMaterialProgram;
|
||||||
var drawUnit:DrawUnit;
|
var drawUnit:DrawUnit;
|
||||||
// Opaque passOpaque pass
|
// Opaque passOpaque pass
|
||||||
if (opaquePass && alphaThreshold <= alpha) {
|
if (opaquePass && alphaThreshold <= alpha) {
|
||||||
@@ -353,3 +354,38 @@ package alternativa.engine3d.materials {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import alternativa.engine3d.materials.ShaderProgram;
|
||||||
|
import alternativa.engine3d.materials.compiler.Linker;
|
||||||
|
|
||||||
|
import flash.display3D.Context3D;
|
||||||
|
|
||||||
|
class VertexLightTextureMaterialProgram extends ShaderProgram {
|
||||||
|
|
||||||
|
public var aPosition:int = -1;
|
||||||
|
public var aUV:int = -1;
|
||||||
|
public var aNormal:int = -1;
|
||||||
|
public var cProjMatrix:int = -1;
|
||||||
|
public var cAmbientColor:int = -1;
|
||||||
|
public var cThresholdAlpha:int = -1;
|
||||||
|
public var sDiffuse:int = -1;
|
||||||
|
public var sOpacity:int = -1;
|
||||||
|
|
||||||
|
public function VertexLightTextureMaterialProgram(vertex:Linker, fragment:Linker) {
|
||||||
|
super(vertex, fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function upload(context3D:Context3D):void {
|
||||||
|
super.upload(context3D);
|
||||||
|
|
||||||
|
aPosition = vertexShader.findVariable("aPosition");
|
||||||
|
aUV = vertexShader.findVariable("aUV");
|
||||||
|
aNormal = vertexShader.findVariable("aNormal");
|
||||||
|
cProjMatrix = vertexShader.findVariable("cProjMatrix");
|
||||||
|
cAmbientColor = vertexShader.findVariable("cAmbientColor");
|
||||||
|
cThresholdAlpha = fragmentShader.findVariable("cThresholdAlpha");
|
||||||
|
sDiffuse = fragmentShader.findVariable("sDiffuse");
|
||||||
|
sOpacity = fragmentShader.findVariable("sOpacity");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user