|
|
|
|
@ -10,6 +10,8 @@ class Inc {
|
|
|
|
|
static var path: RenderPath;
|
|
|
|
|
public static var superSample = 1.0;
|
|
|
|
|
|
|
|
|
|
static var pointIndex = 0;
|
|
|
|
|
static var spotIndex = 0;
|
|
|
|
|
static var lastFrame = -1;
|
|
|
|
|
|
|
|
|
|
#if lnx_shadowmap_atlas
|
|
|
|
|
@ -164,7 +166,7 @@ class Inc {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
for(k in 0...6) {
|
|
|
|
|
LightObject.pointLightsData[j ] = light.tileOffsetX[k]; // posx
|
|
|
|
|
LightObject.pointLightsData[j ] = light.tileOffsetX[k]; // posx
|
|
|
|
|
LightObject.pointLightsData[j + 1] = light.tileOffsetY[k]; // posy
|
|
|
|
|
LightObject.pointLightsData[j + 2] = light.tileScale[k]; // tile scale factor relative to atlas
|
|
|
|
|
LightObject.pointLightsData[j + 3] = 0; // padding
|
|
|
|
|
@ -177,39 +179,12 @@ class Inc {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function bindShadowMapAtlas() {
|
|
|
|
|
var hasAtlas = false;
|
|
|
|
|
|
|
|
|
|
for (atlas in ShadowMapAtlas.shadowMapAtlases) {
|
|
|
|
|
path.bindTarget(atlas.target, atlas.target);
|
|
|
|
|
hasAtlas = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!hasAtlas) {
|
|
|
|
|
#if lnx_shadowmap_atlas_single_map
|
|
|
|
|
path.bindTarget("empty_shadowmap", "shadowMapAtlas");
|
|
|
|
|
#else
|
|
|
|
|
path.bindTarget("empty_shadowmap", "shadowMapAtlasSun");
|
|
|
|
|
path.bindTarget("empty_shadowmap", "shadowMapAtlasPoint");
|
|
|
|
|
path.bindTarget("empty_shadowmap", "shadowMapAtlasSpot");
|
|
|
|
|
#end
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if rp_shadowmap_transparent
|
|
|
|
|
var hasAtlasT = false;
|
|
|
|
|
|
|
|
|
|
for (atlas in ShadowMapAtlas.shadowMapAtlasesTransparent) {
|
|
|
|
|
path.bindTarget(atlas.target, atlas.target);
|
|
|
|
|
hasAtlasT = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!hasAtlasT) {
|
|
|
|
|
#if lnx_shadowmap_atlas_single_map
|
|
|
|
|
path.bindTarget("empty_shadowmap_transparent", "shadowMapAtlasTransparent");
|
|
|
|
|
#else
|
|
|
|
|
path.bindTarget("empty_shadowmap_transparent", "shadowMapAtlasSunTransparent");
|
|
|
|
|
path.bindTarget("empty_shadowmap_transparent", "shadowMapAtlasPointTransparent");
|
|
|
|
|
path.bindTarget("empty_shadowmap_transparent", "shadowMapAtlasSpotTransparent");
|
|
|
|
|
#end
|
|
|
|
|
}
|
|
|
|
|
#end
|
|
|
|
|
}
|
|
|
|
|
@ -271,11 +246,6 @@ class Inc {
|
|
|
|
|
}
|
|
|
|
|
#end
|
|
|
|
|
}
|
|
|
|
|
// update point light data before rendering
|
|
|
|
|
updatePointLightAtlasData(false);
|
|
|
|
|
#if rp_shadowmap_transparent
|
|
|
|
|
updatePointLightAtlasData(true);
|
|
|
|
|
#end
|
|
|
|
|
|
|
|
|
|
for (atlas in ShadowMapAtlas.shadowMapAtlases) {
|
|
|
|
|
tilesToRemove.resize(0);
|
|
|
|
|
@ -352,6 +322,24 @@ class Inc {
|
|
|
|
|
}
|
|
|
|
|
path.endStream();
|
|
|
|
|
path.currentG = null;
|
|
|
|
|
|
|
|
|
|
updatePointLightAtlasData(false);
|
|
|
|
|
|
|
|
|
|
#if lnx_shadowmap_atlas_lod
|
|
|
|
|
for (tile in tilesToChangeSize) {
|
|
|
|
|
tilesToRemove.push(tile);
|
|
|
|
|
|
|
|
|
|
var newTile = ShadowMapTile.assignTiles(tile.light, atlas, tile);
|
|
|
|
|
if (newTile != null)
|
|
|
|
|
atlas.activeTiles.push(newTile);
|
|
|
|
|
}
|
|
|
|
|
updatePointLightAtlasData(false);
|
|
|
|
|
#end
|
|
|
|
|
|
|
|
|
|
for (tile in tilesToRemove) {
|
|
|
|
|
atlas.activeTiles.remove(tile);
|
|
|
|
|
tile.freeTile();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if rp_shadowmap_transparent
|
|
|
|
|
@ -432,6 +420,8 @@ class Inc {
|
|
|
|
|
|
|
|
|
|
path.currentG = null;
|
|
|
|
|
|
|
|
|
|
updatePointLightAtlasData(true);
|
|
|
|
|
|
|
|
|
|
#if lnx_shadowmap_atlas_lod
|
|
|
|
|
for (tile in tilesToChangeSize) {
|
|
|
|
|
tilesToRemove.push(tile);
|
|
|
|
|
@ -461,39 +451,33 @@ class Inc {
|
|
|
|
|
path.bindTarget(n, n);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
var lightIndex = 0;
|
|
|
|
|
for (l in iron.Scene.active.lights) {
|
|
|
|
|
if (iron.object.LightObject.discardLightCulled(l)) continue;
|
|
|
|
|
|
|
|
|
|
if (l.data.raw.type == "point") {
|
|
|
|
|
var n = "shadowMapPoint[" + lightIndex + "]";
|
|
|
|
|
path.bindTarget(n, n);
|
|
|
|
|
var n = "shadowMapPointTransparent[" + lightIndex + "]";
|
|
|
|
|
path.bindTarget(n, n);
|
|
|
|
|
}
|
|
|
|
|
else if (l.data.raw.type == "spot" || l.data.raw.type == "area") {
|
|
|
|
|
var n = "shadowMapSpot[" + lightIndex + "]";
|
|
|
|
|
path.bindTarget(n, n);
|
|
|
|
|
var n = "shadowMapSpotTransparent[" + lightIndex + "]";
|
|
|
|
|
path.bindTarget(n, n);
|
|
|
|
|
}
|
|
|
|
|
lightIndex++;
|
|
|
|
|
for (i in 0...pointIndex) {
|
|
|
|
|
var n = "shadowMapPoint[" + i + "]";
|
|
|
|
|
path.bindTarget(n, n);
|
|
|
|
|
var n = "shadowMapPointTransparent[" + i + "]";
|
|
|
|
|
path.bindTarget(n, n);
|
|
|
|
|
}
|
|
|
|
|
for (i in 0...spotIndex) {
|
|
|
|
|
var n = "shadowMapSpot[" + i + "]";
|
|
|
|
|
path.bindTarget(n, n);
|
|
|
|
|
var n = "shadowMapSpotTransparent[" + i + "]";
|
|
|
|
|
path.bindTarget(n, n);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static function shadowMapName(light: LightObject, index: Int, transparent: Bool): String {
|
|
|
|
|
static function shadowMapName(light: LightObject, transparent: Bool): String {
|
|
|
|
|
switch (light.data.raw.type) {
|
|
|
|
|
case "sun":
|
|
|
|
|
return transparent ? "shadowMapTransparent" : "shadowMap";
|
|
|
|
|
case "point":
|
|
|
|
|
return transparent ? "shadowMapPointTransparent[" + index + "]" : "shadowMapPoint[" + index + "]";
|
|
|
|
|
return transparent ? "shadowMapPointTransparent[" + pointIndex + "]" : "shadowMapPoint[" + pointIndex + "]";
|
|
|
|
|
default:
|
|
|
|
|
return transparent ? "shadowMapSpotTransparent[" + index + "]" : "shadowMapSpot[" + index + "]";
|
|
|
|
|
return transparent ? "shadowMapSpotTransparent[" + spotIndex + "]" : "shadowMapSpot[" + spotIndex + "]";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static function getShadowMap(l: iron.object.LightObject, index: Int, transparent: Bool): String {
|
|
|
|
|
var target = shadowMapName(l, index, transparent);
|
|
|
|
|
static function getShadowMap(l: iron.object.LightObject, transparent: Bool): String {
|
|
|
|
|
var target = shadowMapName(l, transparent);
|
|
|
|
|
var rt = path.renderTargets.get(target);
|
|
|
|
|
// Create shadowmap on the fly
|
|
|
|
|
if (rt == null) {
|
|
|
|
|
@ -536,12 +520,13 @@ class Inc {
|
|
|
|
|
lastFrame = RenderPath.active.frame;
|
|
|
|
|
#end
|
|
|
|
|
|
|
|
|
|
var lightIndex = 0;
|
|
|
|
|
pointIndex = 0;
|
|
|
|
|
spotIndex = 0;
|
|
|
|
|
for (l in iron.Scene.active.lights) {
|
|
|
|
|
if (!l.visible) continue;
|
|
|
|
|
|
|
|
|
|
path.light = l;
|
|
|
|
|
var shadowmap = Inc.getShadowMap(l, lightIndex, false);
|
|
|
|
|
var shadowmap = Inc.getShadowMap(l, false);
|
|
|
|
|
var faces = l.data.raw.shadowmap_cube ? 6 : 1;
|
|
|
|
|
for (i in 0...faces) {
|
|
|
|
|
if (faces > 1) path.currentFace = i;
|
|
|
|
|
@ -553,18 +538,18 @@ class Inc {
|
|
|
|
|
}
|
|
|
|
|
path.currentFace = -1;
|
|
|
|
|
|
|
|
|
|
if (!iron.object.LightObject.discardLightCulled(l)) {
|
|
|
|
|
lightIndex++;
|
|
|
|
|
}
|
|
|
|
|
if (l.data.raw.type == "point") pointIndex++;
|
|
|
|
|
else if (l.data.raw.type == "spot" || l.data.raw.type == "area") spotIndex++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if rp_shadowmap_transparent
|
|
|
|
|
lightIndex = 0;
|
|
|
|
|
pointIndex = 0;
|
|
|
|
|
spotIndex = 0;
|
|
|
|
|
for (l in iron.Scene.active.lights) {
|
|
|
|
|
if (!l.visible) continue;
|
|
|
|
|
|
|
|
|
|
path.light = l;
|
|
|
|
|
var shadowmap_transparent = Inc.getShadowMap(l, lightIndex, true);
|
|
|
|
|
var shadowmap_transparent = Inc.getShadowMap(l, true);
|
|
|
|
|
var faces = l.data.raw.shadowmap_cube ? 6 : 1;
|
|
|
|
|
for (i in 0...faces) {
|
|
|
|
|
if (faces > 1) path.currentFace = i;
|
|
|
|
|
@ -576,9 +561,8 @@ class Inc {
|
|
|
|
|
}
|
|
|
|
|
path.currentFace = -1;
|
|
|
|
|
|
|
|
|
|
if (!iron.object.LightObject.discardLightCulled(l)) {
|
|
|
|
|
lightIndex++;
|
|
|
|
|
}
|
|
|
|
|
if (l.data.raw.type == "point") pointIndex++;
|
|
|
|
|
else if (l.data.raw.type == "spot" || l.data.raw.type == "area") spotIndex++;
|
|
|
|
|
}
|
|
|
|
|
#end
|
|
|
|
|
#end // rp_shadowmap
|
|
|
|
|
|