ASDoc for shadows

This commit is contained in:
artem pecheny
2012-07-30 14:57:28 +06:00
parent cf4ad582f1
commit cffd3bf50d
2 changed files with 1102 additions and 1088 deletions

View File

@@ -43,9 +43,9 @@ package alternativa.engine3d.shadows {
use namespace alternativa3d;
/**
* Class of shadow, that is created by one source of light(<code>DirectionalLight</code>). Shadow is rendered in fixed volume.
* Class of the shadow, that is created by one source of light(<code>DirectionalLight</code>). Shadow is rendered in fixed volume.
* For binding of shadow to light source you need:
* 1) to set <code>DirectionalLightShadow</code> as a value of property <code>shadow</code> of light source;
* 1) to set instance of the <code>DirectionalLightShadow</code> as a value of property <code>shadow</code> of light source;
* 2) to add <code>Object3D</code> to corresponding list, using the method <code>addCaster()</code>.
*
* @see #addCaster()
@@ -820,7 +820,7 @@ package alternativa.engine3d.shadows {
}
/**
* Clears the list of objects, that cast shadow.
* Clears the list of objects, which cast shadow.
*/
public function clearCasters():void {
_casters.length = 0;

View File

@@ -40,7 +40,18 @@ package alternativa.engine3d.shadows {
use namespace alternativa3d;
public class OmniLightShadow extends Shadow{
/**
* Class of the shadow, that is created by one source of light(<code>OmniLight</code>). Shadow is rendered in fixed volume.
* For binding of shadow to light source you need:
* 1) to set instance of the <code>OmniLight</code> as a value of property <code>shadow</code> of light source;
* 2) to add <code>Object3D</code> to corresponding list, using the method <code>addCaster()</code>.
*
* @see #addCaster()
* @see alternativa.engine3d.lights.OmniLight#shadow
* @see #farBoundPosition
*/
public class OmniLightShadow extends Shadow {
// TODO: calculate bias automaticaly
/**
@@ -111,26 +122,26 @@ package alternativa.engine3d.shadows {
debugMaterial.alpha = 0.3;
for (var i:int = 0; i < 6; i++) {
var cam:Camera3D = new Camera3D(radius/1000, radius);
var cam:Camera3D = new Camera3D(radius / 1000, radius);
cam.fov = 1.910633237;
cameras[i] = cam;
}
// Left
cameras[1].rotationY = -Math.PI/2;
cameras[1].rotationY = -Math.PI / 2;
cameras[1].scaleY = -1;
cameras[1].composeTransforms();
// Right
cameras[0].rotationY = Math.PI/2;
cameras[0].rotationY = Math.PI / 2;
cameras[0].scaleY = -1;
cameras[0].composeTransforms();
// Back
cameras[3].rotationX = -Math.PI/2;
cameras[3].rotationX = -Math.PI / 2;
cameras[3].rotationZ = Math.PI;
cameras[3].scaleX = -1;
cameras[3].composeTransforms();
// Front
cameras[2].rotationX = -Math.PI/2;
cameras[2].rotationX = -Math.PI / 2;
cameras[2].scaleY = -1;
cameras[2].composeTransforms();
// Bottom
@@ -143,7 +154,7 @@ package alternativa.engine3d.shadows {
cameras[4].composeTransforms();
}
private function createDebugObject(material:Material, context:Context3D):Mesh{
private function createDebugObject(material:Material, context:Context3D):Mesh {
var geometry:Geometry;
var mesh:Mesh;
if (DEBUG_TYPE == "Box") {
@@ -186,7 +197,7 @@ package alternativa.engine3d.shadows {
triangles.push(c, b, a);
}
mesh.geometry.indices = triangles;
mesh.getSurface(0).numTriangles = triangles.length/3;
mesh.getSurface(0).numTriangles = triangles.length / 3;
mesh.setMaterialToAllSurfaces(material);
}
mesh.geometry.upload(context);
@@ -218,7 +229,7 @@ package alternativa.engine3d.shadows {
radius = OmniLight(_light).attenuationEnd;
for (i = 0; i < 6; i++) {
var cam:Camera3D = cameras[i];
cam.nearClipping = radius/1000;
cam.nearClipping = radius / 1000;
cam.farClipping = radius;
cam.calculateProjection(1, 1);
}
@@ -242,7 +253,7 @@ package alternativa.engine3d.shadows {
caster.localToLightTransform.combine(_light.cameraToLocalTransform, caster.localToCameraTransform);
// collect actualCasters for light
if (caster.boundBox == null || OmniLight(_light).checkBound(caster)){
if (caster.boundBox == null || OmniLight(_light).checkBound(caster)) {
actualCasters[actualCastersCount] = caster;
actualCastersCount++;
@@ -280,7 +291,7 @@ package alternativa.engine3d.shadows {
// Cube side camera
var edgeCamera:Camera3D = cameras[i];
var edgeBit:int = (1<<i);
var edgeBit:int = (1 << i);
if (actualCastersCount > 0) {
// Настройка параметров рендеринга:
renderer.camera = camera;
@@ -306,10 +317,10 @@ package alternativa.engine3d.shadows {
renderer.render(context);
prevActualCastersMask |= edgeBit;
}
else{
else {
// Если относительно одной из камер ничего не менялось, не вызываем отрисовочный вызов
if ((prevActualCastersMask & edgeBit)){
if ((prevActualCastersMask & edgeBit)) {
context.setRenderToTexture(cubeShadowMap, false, 0, i);
context.clear(1, 0, 0, 0);
@@ -331,7 +342,7 @@ package alternativa.engine3d.shadows {
if (debugObject == null) {
debugObject = createDebugObject(debugMaterial, camera.context3D);
}
debugObject.scaleX = debugObject.scaleY = debugObject.scaleZ = radius*debugRadiusScale;
debugObject.scaleX = debugObject.scaleY = debugObject.scaleZ = radius * debugRadiusScale;
debugObject.composeTransforms();
// Формируем матрицу трансформации для debugObject
@@ -344,15 +355,15 @@ package alternativa.engine3d.shadows {
actualCasters.length = 0;
}
private function collectActualChildren(root:Object3D):void{
private function collectActualChildren(root:Object3D):void {
for (var child:Object3D = root.childrenList; child != null; child = child.next) {
if (child.visible){
if (child.visible) {
// calculate transform matrices
_light.lightToObjectTransform.combine(child.cameraToLocalTransform, _light.localToCameraTransform);
child.localToLightTransform.combine(_light.cameraToLocalTransform, child.localToCameraTransform);
// collect actualCasters for light
if (child.boundBox == null || OmniLight(_light).checkBound(child)){
if (child.boundBox == null || OmniLight(_light).checkBound(child)) {
actualCasters[actualCastersCount] = child;
actualCastersCount++;
@@ -508,41 +519,40 @@ package alternativa.engine3d.shadows {
if (plane.x >= 0)
if (plane.y >= 0)
if (plane.z >= 0) {
if (bb.maxX*plane.x + bb.maxY*plane.y + bb.maxZ*plane.z >= plane.offset) result = plane.frontCameras;
if (bb.minX*plane.x + bb.minY*plane.y + bb.minZ*plane.z < plane.offset) result |= plane.backCameras;
if (bb.maxX * plane.x + bb.maxY * plane.y + bb.maxZ * plane.z >= plane.offset) result = plane.frontCameras;
if (bb.minX * plane.x + bb.minY * plane.y + bb.minZ * plane.z < plane.offset) result |= plane.backCameras;
} else {
if (bb.maxX*plane.x + bb.maxY*plane.y + bb.minZ*plane.z >= plane.offset) result = plane.frontCameras;
if (bb.minX*plane.x + bb.minY*plane.y + bb.maxZ*plane.z < plane.offset) result |= plane.backCameras;
if (bb.maxX * plane.x + bb.maxY * plane.y + bb.minZ * plane.z >= plane.offset) result = plane.frontCameras;
if (bb.minX * plane.x + bb.minY * plane.y + bb.maxZ * plane.z < plane.offset) result |= plane.backCameras;
}
else
if (plane.z >= 0) {
if (bb.maxX*plane.x + bb.minY*plane.y + bb.maxZ*plane.z >= plane.offset) result = plane.frontCameras;
if (bb.minX*plane.x + bb.maxY*plane.y + bb.minZ*plane.z < plane.offset) result |= plane.backCameras;
else if (plane.z >= 0) {
if (bb.maxX * plane.x + bb.minY * plane.y + bb.maxZ * plane.z >= plane.offset) result = plane.frontCameras;
if (bb.minX * plane.x + bb.maxY * plane.y + bb.minZ * plane.z < plane.offset) result |= plane.backCameras;
} else {
if (bb.maxX*plane.x + bb.minY*plane.y + bb.minZ*plane.z >= plane.offset) result = plane.frontCameras;
if (bb.minX*plane.x + bb.maxY*plane.y + bb.maxZ*plane.z < plane.offset) result |= plane.backCameras;
if (bb.maxX * plane.x + bb.minY * plane.y + bb.minZ * plane.z >= plane.offset) result = plane.frontCameras;
if (bb.minX * plane.x + bb.maxY * plane.y + bb.maxZ * plane.z < plane.offset) result |= plane.backCameras;
}
else if (plane.y >= 0)
if (plane.z >= 0) {
if (bb.minX*plane.x + bb.maxY*plane.y + bb.maxZ*plane.z >= plane.offset) result = plane.frontCameras;
if (bb.maxX*plane.x + bb.minY*plane.y + bb.minZ*plane.z < plane.offset) result |= plane.backCameras;
if (bb.minX * plane.x + bb.maxY * plane.y + bb.maxZ * plane.z >= plane.offset) result = plane.frontCameras;
if (bb.maxX * plane.x + bb.minY * plane.y + bb.minZ * plane.z < plane.offset) result |= plane.backCameras;
} else {
if (bb.minX*plane.x + bb.maxY*plane.y + bb.minZ*plane.z >= plane.offset) result = plane.frontCameras;
if (bb.maxX*plane.x + bb.minY*plane.y + bb.maxZ*plane.z < plane.offset) result |= plane.backCameras;
if (bb.minX * plane.x + bb.maxY * plane.y + bb.minZ * plane.z >= plane.offset) result = plane.frontCameras;
if (bb.maxX * plane.x + bb.minY * plane.y + bb.maxZ * plane.z < plane.offset) result |= plane.backCameras;
}
else if (plane.z >= 0) {
if (bb.minX*plane.x + bb.minY*plane.y + bb.maxZ*plane.z >= plane.offset) result = plane.frontCameras;
if (bb.maxX*plane.x + bb.maxY*plane.y + bb.minZ*plane.z < plane.offset) result |= plane.backCameras;
if (bb.minX * plane.x + bb.minY * plane.y + bb.maxZ * plane.z >= plane.offset) result = plane.frontCameras;
if (bb.maxX * plane.x + bb.maxY * plane.y + bb.minZ * plane.z < plane.offset) result |= plane.backCameras;
} else {
if (bb.minX*plane.x + bb.minY*plane.y + bb.minZ*plane.z >= plane.offset) result = plane.frontCameras;
if (bb.maxX*plane.x + bb.maxY*plane.y + bb.maxZ*plane.z < plane.offset) result |= plane.backCameras;
if (bb.minX * plane.x + bb.minY * plane.y + bb.minZ * plane.z >= plane.offset) result = plane.frontCameras;
if (bb.maxX * plane.x + bb.maxY * plane.y + bb.maxZ * plane.z < plane.offset) result |= plane.backCameras;
}
culling &= result | plane.unusedBits;
}
return culling;
}
private function collectDraws(context:Context3D, caster:Object3D, edgeCamera:Camera3D):void{
private function collectDraws(context:Context3D, caster:Object3D, edgeCamera:Camera3D):void {
// если объект является мешем, собираем для него дроуколы
var mesh:Mesh = caster as Mesh;
if (mesh != null && mesh.geometry != null) {
@@ -617,7 +627,7 @@ package alternativa.engine3d.shadows {
drawUnit.setProjectionConstants(edgeCamera, program.vertexShader.getVariableIndex("cProjMatrix"), casterToEdgedCameraTransform);
drawUnit.setVertexConstantsFromTransform(program.vertexShader.getVariableIndex("cCasterToOmni"), caster.localToLightTransform);
drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cConstants"), 1 / 255, 0, 255/radius, 1);
drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cConstants"), 1 / 255, 0, 255 / radius, 1);
renderer.addDrawUnit(drawUnit, Renderer.OPAQUE);
}
@@ -721,7 +731,6 @@ package alternativa.engine3d.shadows {
}
//------------- ShadowMap Shader in material----------
/**
@@ -737,12 +746,12 @@ package alternativa.engine3d.shadows {
// Устанавливаем коеффициенты
if (_pcfOffset > 0) {
var offset:Number = Math.tan(_pcfOffset/180*Math.PI)/3;
drawUnit.setFragmentConstantsFromNumbers(fragmentLinker.getVariableIndex("cPCFOffsets"), -3/2, 1/16, 0, 0);
var offset:Number = Math.tan(_pcfOffset / 180 * Math.PI) / 3;
drawUnit.setFragmentConstantsFromNumbers(fragmentLinker.getVariableIndex("cPCFOffsets"), -3 / 2, 1 / 16, 0, 0);
drawUnit.setFragmentConstantsFromNumbers(fragmentLinker.getVariableIndex("cConstants"), -1, 1, 0, offset);
drawUnit.setFragmentConstantsFromNumbers(fragmentLinker.getVariableIndex("cDecode"), -DIFFERENCE_MULTIPLIER, -DIFFERENCE_MULTIPLIER/255, biasMultiplier*DIFFERENCE_MULTIPLIER/radius, 10);
drawUnit.setFragmentConstantsFromNumbers(fragmentLinker.getVariableIndex("cDecode"), -DIFFERENCE_MULTIPLIER, -DIFFERENCE_MULTIPLIER / 255, biasMultiplier * DIFFERENCE_MULTIPLIER / radius, 10);
} else {
drawUnit.setFragmentConstantsFromNumbers(fragmentLinker.getVariableIndex("cConstants"), -DIFFERENCE_MULTIPLIER, -DIFFERENCE_MULTIPLIER/255, biasMultiplier*DIFFERENCE_MULTIPLIER/radius, 1.0);
drawUnit.setFragmentConstantsFromNumbers(fragmentLinker.getVariableIndex("cConstants"), -DIFFERENCE_MULTIPLIER, -DIFFERENCE_MULTIPLIER / 255, biasMultiplier * DIFFERENCE_MULTIPLIER / radius, 1.0);
}
}
@@ -834,7 +843,7 @@ package alternativa.engine3d.shadows {
// shaderArr[line++] = "mov t3.z, t0.w";
shaderArr[line++] = "tex t3.xy, t2.xyz, s0 <cube, nearest>";
shaderArr[line++] = "dp3 o0." +componentByIndex[0] + ", t3.xyz, c0.xyz"; // декодируем, вычитаем, умножаем на большое число
shaderArr[line++] = "dp3 o0." + componentByIndex[0] + ", t3.xyz, c0.xyz"; // декодируем, вычитаем, умножаем на большое число
//-----
@@ -842,7 +851,7 @@ package alternativa.engine3d.shadows {
shaderArr[line++] = "add t2.xyz, t2.xyz, t1.xyz";
shaderArr[line++] = "tex t3.xy, t2.xyz, s0 <cube, nearest>";
shaderArr[line++] = "dp3 o0." +componentByIndex[j] + ", t3.xyz, c0.xyz"; // декодируем, вычитаем, умножаем на большое число
shaderArr[line++] = "dp3 o0." + componentByIndex[j] + ", t3.xyz, c0.xyz"; // декодируем, вычитаем, умножаем на большое число
}
shaderArr[line++] = "sat o0, o0";
@@ -854,13 +863,13 @@ package alternativa.engine3d.shadows {
shaderArr[line++] = "add t2.xyz, t2.xyz, t0.xyz";
shaderArr[line++] = "tex t3.xy, t2.xyz, s0 <cube, nearest>";
shaderArr[line++] = "dp3 o0." +componentByIndex[0] + ", t3.xyz, c0.xyz"; // декодируем, вычитаем, умножаем на большое число
shaderArr[line++] = "dp3 o0." + componentByIndex[0] + ", t3.xyz, c0.xyz"; // декодируем, вычитаем, умножаем на большое число
for (j = 1; j < 4; j++){
shaderArr[line++] = (i%2 == 1)?("add t2.xyz, t2.xyz, t1.xyz"):("sub t2.xyz, t2.xyz, t1.xyz");
for (j = 1; j < 4; j++) {
shaderArr[line++] = (i % 2 == 1) ? ("add t2.xyz, t2.xyz, t1.xyz") : ("sub t2.xyz, t2.xyz, t1.xyz");
shaderArr[line++] = "tex t3.xy, t2.xyz, s0 <cube, nearest>";
shaderArr[line++] = "dp3 o0." +componentByIndex[j] + ", t3.xyz, c0.xyz"; // декодируем, вычитаем, умножаем на большое число
shaderArr[line++] = "dp3 o0." + componentByIndex[j] + ", t3.xyz, c0.xyz"; // декодируем, вычитаем, умножаем на большое число
}
shaderArr[line++] = "sat o0, o0";
shaderArr[line++] = "dp4 o0.x, o0, c2.y";
@@ -876,8 +885,8 @@ package alternativa.engine3d.shadows {
private static const componentByIndex:Array = ["x", "y", "z", "w"];
/**
* Добавляет <code>object</code> в список объектов, отбрасывающих тень.
* @param object Добавляемый объект.
* Adds given object to list of objects, that cast shadow.
* @param object Added object.
*/
public function addCaster(object:Object3D):void {
if (_casters.indexOf(object) < 0) {
@@ -885,6 +894,10 @@ package alternativa.engine3d.shadows {
}
}
/**
* Removes given object from shadow casters list.
* @param object Object which should be removed from shadow casters list.
*/
public function removeCaster(object:Object3D):void {
var index:int = _casters.indexOf(object);
if (index < 0) throw new Error("Caster not found");
@@ -892,14 +905,15 @@ package alternativa.engine3d.shadows {
}
/**
* Очищает список объектов, отбрасывающих тень.
* Clears the list of objects, that cast shadow.
*/
public function clearCasters():void {
_casters.length = 0;
}
/**
* Качество тени. Задает разрешение shadowmap. Может принимать значения от <code>2</code> до <code>11</code>.
* Set resolution of shadow map. This property can get value of power of 2 (up to 2048).
* OmniLightShadow uses 6 shadow maps.
*/
public function get mapSize():int {
return _mapSize;
@@ -916,7 +930,7 @@ package alternativa.engine3d.shadows {
} else if (value > 1024) {
throw new ArgumentError("Map size exceeds maximum value 1024.");
}
if ((Math.log(value)/Math.LN2 % 1) != 0) {
if ((Math.log(value) / Math.LN2 % 1) != 0) {
throw new ArgumentError("Map size must be power of two.");
}
if (cubeShadowMap != null) {
@@ -927,8 +941,7 @@ package alternativa.engine3d.shadows {
}
/**
* Смещение Percentage Closer Filtering. Этот способ фильтрации используется для смягчения границ тени.
* 1 pcfOffset equivalent 1 degree for all blur
* Offset of Percentage Closer Filtering. This way of filtering is used for mitigation of shadow bounds.
*/
public function get pcfOffset():Number {
return _pcfOffset;
@@ -971,6 +984,7 @@ import flash.utils.Dictionary;
class ShadowDebugMaterial extends Material {
use namespace alternativa3d;
/**
* Прозрачность.
* Является дополнительным множителем к прозрачности текстуры.
@@ -1015,7 +1029,7 @@ class ShadowDebugMaterial extends Material {
drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aPosition"), positionBuffer, geometry._attributesOffsets[VertexAttributes.POSITION], VertexAttributes.FORMATS[VertexAttributes.POSITION]);
// Установка констант
drawUnit.setProjectionConstants(camera, program.vertexShader.getVariableIndex("cProjMatrix"), object.localToCameraTransform);
drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cDecode"), 1, 1/255, 0, alpha);
drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cDecode"), 1, 1 / 255, 0, alpha);
drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sCubeMap"), cubeMap);
// Отправка на отрисовку