diff --git a/.gitignore b/.gitignore index 4149b49..22b7f70 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ __pycache__/ *.pyc *.DS_Store **/workspace.xml -**/vcs.xml \ No newline at end of file +**/vcs.xml +**/stderr.txt +**/kinc.dmp \ No newline at end of file diff --git a/leenkx/Shaders/std/light.glsl b/leenkx/Shaders/std/light.glsl index 17bb226..c908982 100644 --- a/leenkx/Shaders/std/light.glsl +++ b/leenkx/Shaders/std/light.glsl @@ -148,10 +148,9 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co vec3(1.0, 0.0, t.y), vec3(0.0, t.z, 0.0), vec3(t.w, 0.0, t.x)); - const float PI = 3.1415926535; - float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3) / PI; + float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3); ltcspec *= textureLod(sltcMag, tuv, 0.0).a; - float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3) / PI; + float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3); vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05; #else vec3 direct = lambertDiffuseBRDF(albedo, dotNL) + @@ -244,7 +243,7 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co #ifdef _ShadowMap if (receiveShadow) { #ifdef _SinglePoint - vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 2, 1.0); + vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0); direct *= shadowTest(shadowMapSpot[0], #ifdef _ShadowMapTransparent shadowMapSpotTransparent[0], @@ -256,7 +255,7 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co ); #endif #ifdef _Clusters - vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 2, 1.0); + vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0); #ifdef _ShadowMapAtlas direct *= shadowTest( #ifdef _ShadowMapTransparent @@ -436,10 +435,9 @@ vec3 sampleLightVoxels(const vec3 p, const vec3 n, const vec3 v, const float dot vec3(1.0, 0.0, t.y), vec3(0.0, t.z, 0.0), vec3(t.w, 0.0, t.x)); - const float PI = 3.1415926535; - float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3) / PI; + float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3); ltcspec *= textureLod(sltcMag, tuv, 0.0).a; - float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3) / PI; + float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3); vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05; #else vec3 direct = lambertDiffuseBRDF(albedo, dotNL) + @@ -454,7 +452,7 @@ vec3 sampleLightVoxels(const vec3 p, const vec3 n, const vec3 v, const float dot #ifdef _ShadowMap if (receiveShadow) { #ifdef _SinglePoint - vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 2, 1.0); + vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0); direct *= shadowTest(shadowMapSpot[0], #ifdef _ShadowMapTransparent shadowMapSpotTransparent[0], @@ -466,7 +464,7 @@ vec3 sampleLightVoxels(const vec3 p, const vec3 n, const vec3 v, const float dot ); #endif #ifdef _Clusters - vec4 lPos = LWVPSpot[index] * vec4(p + n * bias * 2, 1.0); + vec4 lPos = LWVPSpot[index] * vec4(p + n * bias * 10, 1.0); if (index == 0) direct *= shadowTest(shadowMapSpot[0], #ifdef _ShadowMapTransparent shadowMapSpotTransparent[0], @@ -516,7 +514,7 @@ vec3 sampleLightVoxels(const vec3 p, const vec3 n, const vec3 v, const float dot #ifdef _ShadowMap if (receiveShadow) { #ifdef _SinglePoint - vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 2, 1.0); + vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0); direct *= shadowTest(shadowMapSpot[0], #ifdef _ShadowMapTransparent shadowMapSpotTransparent[0], @@ -528,7 +526,7 @@ vec3 sampleLightVoxels(const vec3 p, const vec3 n, const vec3 v, const float dot ); #endif #ifdef _Clusters - vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 2, 1.0); + vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0); #ifdef _ShadowMapAtlas direct *= shadowTest( #ifdef _ShadowMapTransparent diff --git a/leenkx/Sources/iron/object/LightObject.hx b/leenkx/Sources/iron/object/LightObject.hx index 0749fab..01b4a6a 100644 --- a/leenkx/Sources/iron/object/LightObject.hx +++ b/leenkx/Sources/iron/object/LightObject.hx @@ -97,12 +97,8 @@ class LightObject extends Object { this.shadowMapScale = 1.0; #end } - else if (type == "point" || type == "area") { + else //if (type == "point" || type == "area" || type == "spot") { P = Mat4.persp(fov, 1, data.raw.near_plane, data.raw.far_plane); - } - else if (type == "spot") { - P = Mat4.persp(fov, 1, data.raw.near_plane, data.raw.far_plane); - } Scene.active.lights.push(this); } diff --git a/leenkx/Sources/leenkx/renderpath/Inc.hx b/leenkx/Sources/leenkx/renderpath/Inc.hx index 5e90488..29b5116 100644 --- a/leenkx/Sources/leenkx/renderpath/Inc.hx +++ b/leenkx/Sources/leenkx/renderpath/Inc.hx @@ -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 diff --git a/leenkx/Sources/leenkx/renderpath/RenderPathDeferred.hx b/leenkx/Sources/leenkx/renderpath/RenderPathDeferred.hx index 9f56277..3c5b778 100644 --- a/leenkx/Sources/leenkx/renderpath/RenderPathDeferred.hx +++ b/leenkx/Sources/leenkx/renderpath/RenderPathDeferred.hx @@ -1104,7 +1104,6 @@ class RenderPathDeferred { } #end path.setTarget(target); - path.clearTarget(0x00000000); path.bindTarget("tex", "tex"); #if rp_compositordepth diff --git a/leenkx/Sources/leenkx/renderpath/RenderPathForward.hx b/leenkx/Sources/leenkx/renderpath/RenderPathForward.hx index 17a3473..2187521 100644 --- a/leenkx/Sources/leenkx/renderpath/RenderPathForward.hx +++ b/leenkx/Sources/leenkx/renderpath/RenderPathForward.hx @@ -754,8 +754,7 @@ class RenderPathForward { } #end path.setTarget(target); - path.clearTarget(0x00000000); - + #if rp_compositordepth { path.bindTarget("_main", "gbufferD"); diff --git a/leenkx/blender/lnx/make_renderpath.py b/leenkx/blender/lnx/make_renderpath.py index 3c92657..12d1023 100644 --- a/leenkx/blender/lnx/make_renderpath.py +++ b/leenkx/blender/lnx/make_renderpath.py @@ -8,6 +8,7 @@ import lnx.assets as assets import lnx.log as log import lnx.make_state as state import lnx.utils +from lnx.props_renderpath import auto_atlas_size if lnx.is_reload(__name__): lnx.api = lnx.reload_module(lnx.api) @@ -68,12 +69,32 @@ def add_world_defs(): if rpdat.rp_shadowmap_atlas_single_map: assets.add_khafile_def('lnx_shadowmap_atlas_single_map') wrd.world_defs += '_SingleAtlas' - assets.add_khafile_def('rp_shadowmap_atlas_max_size_point={0}'.format(int(rpdat.rp_shadowmap_atlas_max_size_point))) - assets.add_khafile_def('rp_shadowmap_atlas_max_size_spot={0}'.format(int(rpdat.rp_shadowmap_atlas_max_size_spot))) - assets.add_khafile_def('rp_shadowmap_atlas_max_size_sun={0}'.format(int(rpdat.rp_shadowmap_atlas_max_size_sun))) - assets.add_khafile_def('rp_shadowmap_atlas_max_size={0}'.format(int(rpdat.rp_shadowmap_atlas_max_size))) - assets.add_khafile_def('rp_max_lights_cluster={0}'.format(int(rpdat.rp_max_lights_cluster))) + if rpdat.rp_shadowmap_atlas_auto: + max_lights = int(rpdat.rp_max_lights) + cube_size = int(rpdat.rp_shadowmap_cube) + cascade_size = int(rpdat.rp_shadowmap_cascade) + cascades = int(rpdat.rp_shadowmap_cascades) + + auto_point = auto_atlas_size(max_lights, cube_size, 6) + auto_spot = auto_atlas_size(max_lights, cascade_size, 1) + auto_sun = auto_atlas_size(max_lights, cascade_size, cascades) + auto_max = max(auto_point, auto_spot, auto_sun) + + assets.add_khafile_def('rp_shadowmap_atlas_max_size_point={0}'.format(auto_point)) + assets.add_khafile_def('rp_shadowmap_atlas_max_size_spot={0}'.format(auto_spot)) + assets.add_khafile_def('rp_shadowmap_atlas_max_size_sun={0}'.format(auto_sun)) + assets.add_khafile_def('rp_shadowmap_atlas_max_size={0}'.format(auto_max)) + else: + assets.add_khafile_def('rp_shadowmap_atlas_max_size_point={0}'.format(int(rpdat.rp_shadowmap_atlas_max_size_point))) + assets.add_khafile_def('rp_shadowmap_atlas_max_size_spot={0}'.format(int(rpdat.rp_shadowmap_atlas_max_size_spot))) + assets.add_khafile_def('rp_shadowmap_atlas_max_size_sun={0}'.format(int(rpdat.rp_shadowmap_atlas_max_size_sun))) + assets.add_khafile_def('rp_shadowmap_atlas_max_size={0}'.format(int(rpdat.rp_shadowmap_atlas_max_size))) + + if rpdat.rp_shadowmap_atlas_auto: + assets.add_khafile_def('rp_max_lights_cluster={0}'.format(int(rpdat.rp_max_lights))) + else: + assets.add_khafile_def('rp_max_lights_cluster={0}'.format(int(rpdat.rp_max_lights_cluster))) assets.add_khafile_def('rp_max_lights={0}'.format(int(rpdat.rp_max_lights))) if rpdat.rp_shadowmap_atlas_lod: assets.add_khafile_def('lnx_shadowmap_atlas_lod') diff --git a/leenkx/blender/lnx/props_renderpath.py b/leenkx/blender/lnx/props_renderpath.py index 90ea357..5da4b1d 100644 --- a/leenkx/blender/lnx/props_renderpath.py +++ b/leenkx/blender/lnx/props_renderpath.py @@ -1,5 +1,6 @@ from typing import Optional +import math import bpy from bpy.props import * @@ -44,6 +45,18 @@ def update_point_atlas_size_options(scene: bpy.types.Scene, context: bpy.types.C return atlas_sizes_from_min(int(rpdat.rp_shadowmap_cube) * 2) +def auto_atlas_size(max_lights: int, tile_size: int, tiles_per_light: int) -> int: + """Automatically calculate the minimum atlas texture size needed to fit max_lights of a given type.""" + tiles_needed = max_lights * tiles_per_light + grid_size = math.ceil(math.sqrt(tiles_needed)) + needed_pixels = grid_size * tile_size + for size_entry in atlas_sizes: + size = int(size_entry[0]) + if size >= needed_pixels: + return size + return int(atlas_sizes[-1][0]) + + def update_preset(self, context): rpdat = self.lnx_rplist[-1] @@ -332,6 +345,7 @@ class LnxRPListItem(bpy.types.PropertyGroup): ('64', '64', '64'),], name="Max Lights Shadows", description="Max number of rendered shadow maps that can be visible in the screen. Always equal or lower than Max Lights", default='16') rp_shadowmap_atlas: BoolProperty(name="Shadow Map Atlasing", description="Group shadow maps of lights of the same type in the same texture", default=False, update=update_renderpath) + rp_shadowmap_atlas_auto: BoolProperty(name="Automatic Atlasing", description="Automatically compute atlas sizes based on max lights and shadow map sizes", default=True, update=update_renderpath) rp_shadowmap_atlas_single_map: BoolProperty(name="Shadow Map Atlas single map", description="Use a single texture for all different light types.", default=False, update=update_renderpath) rp_shadowmap_atlas_lod: BoolProperty(name="Shadow Map Atlas LOD (Experimental)", description="When enabled, the size of the shadow map will be determined on runtime based on the distance of the light to the camera", default=False, update=update_renderpath) rp_shadowmap_transparent: BoolProperty(name="Transparency", description="Enable shadows for transparent objects", default=False, update=update_renderpath) diff --git a/leenkx/blender/lnx/props_ui.py b/leenkx/blender/lnx/props_ui.py index b36be29..1c2dd4c 100644 --- a/leenkx/blender/lnx/props_ui.py +++ b/leenkx/blender/lnx/props_ui.py @@ -1745,92 +1745,113 @@ class LNX_PT_RenderPathShadowsPanel(bpy.types.Panel): layout.prop(rpdat, 'rp_shadowmap_atlas') colatlas = layout.column() colatlas.enabled = rpdat.rp_shadowmap_atlas + + colatlas.prop(rpdat, 'rp_shadowmap_atlas_auto') + colatlas.prop(rpdat, 'rp_max_lights') - colatlas.prop(rpdat, 'rp_max_lights_cluster') + + if not rpdat.rp_shadowmap_atlas_auto: + colatlas.prop(rpdat, 'rp_max_lights_cluster') + + if rpdat.rp_shadowmap_atlas_auto: + # Automatic mode: compute sizes from max lights + max_lights = int(rpdat.rp_max_lights) + cube_size = int(rpdat.rp_shadowmap_cube) + cascade_size = int(rpdat.rp_shadowmap_cascade) + cascades = int(rpdat.rp_shadowmap_cascades) + + auto_point = lnx.props_renderpath.auto_atlas_size(max_lights, cube_size, 6) + auto_spot = lnx.props_renderpath.auto_atlas_size(max_lights, cascade_size, 1) + auto_sun = lnx.props_renderpath.auto_atlas_size(max_lights, cascade_size, cascades) + + if auto_point > 2048 or auto_spot > 2048 or auto_sun > 2048: + size_warning = True + colatlas.prop(rpdat, 'rp_shadowmap_atlas_lod') - colatlas_lod = colatlas.column() - colatlas_lod.enabled = rpdat.rp_shadowmap_atlas_lod - colatlas_lod.prop(rpdat, 'rp_shadowmap_atlas_lod_subdivisions') + if rpdat.rp_shadowmap_atlas_lod: + colatlas_lod = colatlas.column() + colatlas_lod.prop(rpdat, 'rp_shadowmap_atlas_lod_subdivisions') - colatlas_lod_info = colatlas_lod.row() - colatlas_lod_info.alignment = 'RIGHT' - subdivs_list = self.compute_subdivs(int(rpdat.rp_shadowmap_cascade), int(rpdat.rp_shadowmap_atlas_lod_subdivisions)) - subdiv_text = "Subdivisions for spot lights: " + ', '.join(map(str, subdivs_list)) - colatlas_lod_info.label(text=subdiv_text, icon="IMAGE_ZDEPTH") - - if not rpdat.rp_shadowmap_atlas_single_map: colatlas_lod_info = colatlas_lod.row() colatlas_lod_info.alignment = 'RIGHT' - subdivs_list = self.compute_subdivs(int(rpdat.rp_shadowmap_cube), int(rpdat.rp_shadowmap_atlas_lod_subdivisions)) - subdiv_text = "Subdivisions for point lights: " + ', '.join(map(str, subdivs_list)) + subdivs_list = self.compute_subdivs(int(rpdat.rp_shadowmap_cascade), int(rpdat.rp_shadowmap_atlas_lod_subdivisions)) + subdiv_text = "Subdivisions for spot lights: " + ', '.join(map(str, subdivs_list)) colatlas_lod_info.label(text=subdiv_text, icon="IMAGE_ZDEPTH") + if not rpdat.rp_shadowmap_atlas_single_map: + colatlas_lod_info = colatlas_lod.row() + colatlas_lod_info.alignment = 'RIGHT' + subdivs_list = self.compute_subdivs(int(rpdat.rp_shadowmap_cube), int(rpdat.rp_shadowmap_atlas_lod_subdivisions)) + subdiv_text = "Subdivisions for point lights: " + ', '.join(map(str, subdivs_list)) + colatlas_lod_info.label(text=subdiv_text, icon="IMAGE_ZDEPTH") + size_warning = int(rpdat.rp_shadowmap_cascade) > 2048 or int(rpdat.rp_shadowmap_cube) > 2048 colatlas.prop(rpdat, 'rp_shadowmap_atlas_single_map') - # show size for single texture - if rpdat.rp_shadowmap_atlas_single_map: - colatlas_single = colatlas.column() - colatlas_single.prop(rpdat, 'rp_shadowmap_atlas_max_size') - if rpdat.rp_shadowmap_atlas_max_size != '': - atlas_size = int(rpdat.rp_shadowmap_atlas_max_size) - shadowmap_size = int(rpdat.rp_shadowmap_cascade) + if not rpdat.rp_shadowmap_atlas_auto: + # show size for single texture + if rpdat.rp_shadowmap_atlas_single_map: + colatlas_single = colatlas.column() + colatlas_single.prop(rpdat, 'rp_shadowmap_atlas_max_size') + if rpdat.rp_shadowmap_atlas_max_size != '': + atlas_size = int(rpdat.rp_shadowmap_atlas_max_size) + shadowmap_size = int(rpdat.rp_shadowmap_cascade) - if shadowmap_size > 2048: - size_warning = True + if shadowmap_size > 2048: + size_warning = True - point_lights = self.lights_number_atlas(rpdat, atlas_size, shadowmap_size, 'point') - spot_lights = self.lights_number_atlas(rpdat, atlas_size, shadowmap_size, 'spot') - dir_lights = self.lights_number_atlas(rpdat, atlas_size, shadowmap_size, 'sun') + point_lights = self.lights_number_atlas(rpdat, atlas_size, shadowmap_size, 'point') + spot_lights = self.lights_number_atlas(rpdat, atlas_size, shadowmap_size, 'spot') + dir_lights = self.lights_number_atlas(rpdat, atlas_size, shadowmap_size, 'sun') - col = colatlas_single.row() - col.alignment = 'RIGHT' - col.label(text=f'Enough space for { point_lights } point lights or { spot_lights } spot lights or { dir_lights } directional lights.') - else: - # show size for all types - colatlas_mixed = colatlas.column() - colatlas_mixed.prop(rpdat, 'rp_shadowmap_atlas_max_size_spot') + col = colatlas_single.row() + col.alignment = 'RIGHT' + col.label(text=f'Enough space for { point_lights } point lights or { spot_lights } spot lights or { dir_lights } directional lights.') + else: + # show size for all types + colatlas_mixed = colatlas.column() + colatlas_mixed.prop(rpdat, 'rp_shadowmap_atlas_max_size_spot') - if rpdat.rp_shadowmap_atlas_max_size_spot != '': - atlas_size = int(rpdat.rp_shadowmap_atlas_max_size_spot) - shadowmap_size = int(rpdat.rp_shadowmap_cascade) - spot_lights = self.lights_number_atlas(rpdat, atlas_size, shadowmap_size, 'spot') + if rpdat.rp_shadowmap_atlas_max_size_spot != '': + atlas_size = int(rpdat.rp_shadowmap_atlas_max_size_spot) + shadowmap_size = int(rpdat.rp_shadowmap_cascade) + spot_lights = self.lights_number_atlas(rpdat, atlas_size, shadowmap_size, 'spot') - if shadowmap_size > 2048: - size_warning = True + if shadowmap_size > 2048: + size_warning = True - col = colatlas_mixed.row() - col.alignment = 'RIGHT' - col.label(text=f'Enough space for {spot_lights} spot lights.') + col = colatlas_mixed.row() + col.alignment = 'RIGHT' + col.label(text=f'Enough space for {spot_lights} spot lights.') - colatlas_mixed.prop(rpdat, 'rp_shadowmap_atlas_max_size_point') + colatlas_mixed.prop(rpdat, 'rp_shadowmap_atlas_max_size_point') - if rpdat.rp_shadowmap_atlas_max_size_point != '': - atlas_size = int(rpdat.rp_shadowmap_atlas_max_size_point) - shadowmap_size = int(rpdat.rp_shadowmap_cube) - point_lights = self.lights_number_atlas(rpdat, atlas_size, shadowmap_size, 'point') + if rpdat.rp_shadowmap_atlas_max_size_point != '': + atlas_size = int(rpdat.rp_shadowmap_atlas_max_size_point) + shadowmap_size = int(rpdat.rp_shadowmap_cube) + point_lights = self.lights_number_atlas(rpdat, atlas_size, shadowmap_size, 'point') - if shadowmap_size > 2048: - size_warning = True + if shadowmap_size > 2048: + size_warning = True - col = colatlas_mixed.row() - col.alignment = 'RIGHT' - col.label(text=f'Enough space for {point_lights} point lights.') + col = colatlas_mixed.row() + col.alignment = 'RIGHT' + col.label(text=f'Enough space for {point_lights} point lights.') - colatlas_mixed.prop(rpdat, 'rp_shadowmap_atlas_max_size_sun') + colatlas_mixed.prop(rpdat, 'rp_shadowmap_atlas_max_size_sun') - if rpdat.rp_shadowmap_atlas_max_size_sun != '': - atlas_size = int(rpdat.rp_shadowmap_atlas_max_size_sun) - shadowmap_size = int(rpdat.rp_shadowmap_cascade) - dir_lights = self.lights_number_atlas(rpdat, atlas_size, shadowmap_size, 'sun') + if rpdat.rp_shadowmap_atlas_max_size_sun != '': + atlas_size = int(rpdat.rp_shadowmap_atlas_max_size_sun) + shadowmap_size = int(rpdat.rp_shadowmap_cascade) + dir_lights = self.lights_number_atlas(rpdat, atlas_size, shadowmap_size, 'sun') - if shadowmap_size > 2048: - size_warning = True + if shadowmap_size > 2048: + size_warning = True - col = colatlas_mixed.row() - col.alignment = 'RIGHT' - col.label(text=f'Enough space for {dir_lights} directional lights.') + col = colatlas_mixed.row() + col.alignment = 'RIGHT' + col.label(text=f'Enough space for {dir_lights} directional lights.') # show warning when user picks a size higher than 2048 (arbitrary number). if size_warning: