StandardMaterial: optimized vectors access

This commit is contained in:
Yaski
2012-05-16 17:52:32 +06:00
parent a90ce894ef
commit 2d989449c4

View File

@@ -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:StandardMaterialProgram, 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]);
@@ -778,7 +777,6 @@ 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.aNormal, normalsBuffer, geometry._attributesOffsets[VertexAttributes.NORMAL], VertexAttributes.FORMATS[VertexAttributes.NORMAL]); drawUnit.setVertexBufferAt(program.aNormal, normalsBuffer, geometry._attributesOffsets[VertexAttributes.NORMAL], VertexAttributes.FORMATS[VertexAttributes.NORMAL]);
@@ -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,37 +1006,32 @@ 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:StandardMaterialProgram; 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
// Form key // Form key
materialKey = (lightMap != null) ? "L" : "l"+ materialKey = (lightMap != null) ? "L" : "l"+
@@ -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,19 +1101,19 @@ 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;
lightGroup.length = 0; lightGroup.length = 0;
} }
if (shadowGroupLength>0){ if (shadowGroupLength > 0){
// Group of ligths with shadow // Group of ligths with shadow
// For each light we will create new drawUnit // For each light we will create new drawUnit
for (j = 0; j < shadowGroupLength; j++) { for (j = 0; j < shadowGroupLength; j++) {
@@ -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;