Its a long class but it has 2 main functions that are relevant one is called each frame to render all the objects (RenderToTexture), and one is uploading the registers needed for the object or deleting the registers not needed for the object (drawItem):
public function RenderToTexture(NonTransparentObjects:Array,TransparentObjects:Array,NeedsLightDirctionUpdate:Boolean):void
{
context3D.setRenderToTexture(tex1,true,4);
context3D.clear(Background.skyColor[0],Background.skyColor[1],Background.skyColor[2]);
// Draw objects
var worldToClip:Matrix3D = camera.worldToClipMatrix;
//NonTransparentObjects.sortOn("Distance_From_0Z",Array.DESCENDING|Array.NUMERIC); //,Array.CASEINSENSITIVE|Array.NUMERIC
TransparentObjects.sortOn("Distance_From_0Z",Array.DESCENDING|Array.NUMERIC); //,Array.CASEINSENSITIVE|Array.NUMERIC
var i:int = 0;
for (i=0; i < NonTransparentObjects.length; i++)
{
drawItem(NonTransparentObjects[i],worldToClip,NeedsLightDirctionUpdate);
}
for (var j:int=0; j < TransparentObjects.length; j++)
{
drawItem(TransparentObjects[j],worldToClip,NeedsLightDirctionUpdate);
}
}
private function drawItem(obj:Object3D,worldToClip:Matrix3D,NeedsLightDirctionUpdate:Boolean):void
{
if (!obj.visible)
return;
obj.modelToWorld.copyToMatrix3D(drawMatrix);
var tmp:Object3D = obj;
while (tmp.Parent)
{
drawMatrix.prepend(tmp.Parent.modelToWorld);
tmp = tmp.Parent;
}
drawMatrix.prepend(worldToClip);
obj.update_BBox_Rotation_and_Absolute_Position();
if (NeedsLightDirctionUpdate)
{
/*
what I do in my code is turn the light position, into the light direction
to the current rendered object, that is why I have to reduce the object
position from the light position, because then the position vector of the
light becomes a direction vector from the light to the currently rendered
object, because a direction vector is simply a vector that is originating
from the 0,0,0 point, that is why I have to reduce the object position from
the light position, to have the the light position point to the center of
the world, then it becomes a direction, then I rotate the position to
neutralize the object orientation, and then I'm left with the direction
of the light to the object. only then I can normalize it, not at the stage
where it is still a position, otherwise my calculation will be wrong.
*/
var m:Vector.<Number> = obj.modelToWorld.rawData;
/*
the next 3 lines are mixting between a directional ligh
and a point light, either you send a direction
for directional light or a position for point light
so if you want to directional light just do this:
*/
obj.LightPos.x = -(sceneLight.Position.x);
obj.LightPos.y = -(sceneLight.Position.y);
obj.LightPos.z = sceneLight.Position.z;
//obj.LightPos.x = -(sceneLight.Position.x - m[3]);
//obj.LightPos.y = -(sceneLight.Position.y - m[7]);
//obj.LightPos.z = sceneLight.Position.z - m[11];
//specular is always a directional light, because the
//reflection is always reletive to the camera
SpecularLightDirection.x = obj.LightPos.x - (camera.positionX - m[3]);
SpecularLightDirection.y = obj.LightPos.y - (camera.positionY - m[7]);
SpecularLightDirection.z = obj.LightPos.z + camera.positionZ - m[11];
//this is turning a position into a direction
//for directional ligh, if you do point light
//you don't need this (except for
//the specular light direction calculation)
//just pass to the shader LightPos
obj.LightDir.identity();
drawMatrix.copyToMatrix3D(obj.LightDir);
//obj.LightDir.appendRotation(180, Vector3D.Y_AXIS);
obj.LightDir.appendRotation(180, Vector3D.X_AXIS);
obj.LightDir.appendRotation(180, Vector3D.Z_AXIS);
obj.LightPos = obj.LightDir.transformVector(obj.LightPos);
obj.LightPos.normalize();
//obj.LightPos.negate();
obj.LightPos.scaleBy(sceneLight.intensity);
SpecularLightDirection = obj.LightDir.transformVector(SpecularLightDirection);
SpecularLightDirection.normalize();
}
if (obj.texture)
{
context3D.setProgram(program01);
context3D.setTextureAt(0, obj.texture);
context3D.setVertexBufferAt(1, obj.texCoords, 0, Context3DVertexBufferFormat.FLOAT_3);
if (1) //&& normalmap//obj.normalmap
{
//context3D.setVertexBufferAt(3, obj.normals, 0, Context3DVertexBufferFormat.FLOAT_3);
//context3D.setVertexBufferAt(3, obj.tangents, 0, Context3DVertexBufferFormat.FLOAT_3);
//context3D.setVertexBufferAt(4, obj.bitangents, 0, Context3DVertexBufferFormat.FLOAT_3);
}
}
else
{
context3D.setProgram(program02);
context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 4, obj.DiffuseColor ); // meshe color
context3D.setTextureAt(0, null);
context3D.setVertexBufferAt(1, null, null, null);
context3D.setVertexBufferAt(3, null, null, null);
context3D.setVertexBufferAt(4, null, null, null);
}
context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, clamping); //fc0, for clamping negative values to zero
context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, obj.EmbientColor); //fc1, ambient lighting (1/4 of full intensity)
context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 2, Vector.<Number>([obj.LightPos.x,obj.LightPos.y,obj.LightPos.z,1])); // Light Direction
context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 3, sceneLight.color); // Light Color
//for shininess
context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 5, Vector.<Number>([SpecularLightDirection.x,SpecularLightDirection.y,SpecularLightDirection.z,1])); // specular Light Direction
context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 6, obj.Shininess); // specular amount
context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 7, obj.SpecularColor); // specular light color
//selection material
context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 8, obj.SelectionColor); // selection color
//transparency
context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 9, obj.Transparency);
//offset for bump map
context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 10, sOffset);
context3D.setVertexBufferAt(0, obj.positions, 0, Context3DVertexBufferFormat.FLOAT_3);
context3D.setVertexBufferAt(2, obj.normals, 0, Context3DVertexBufferFormat.FLOAT_3);
//context3D.setVertexBufferAt(3, obj.normals, 0, Context3DVertexBufferFormat.FLOAT_3);
context3D.setProgramConstantsFromMatrix(
Context3DProgramType.VERTEX,
0,
drawMatrix,
false
);
//trace(obj.Name+" -------<<");
context3D.drawTriangles(obj.tris);
}
in case you want to see the complete class:
https://drive.google.com/file/d/1dsw1scjpvcqBnoFaJlVb28i9p71njMj-/view?usp=sharing