forked from LeenkxTeam/LNXSDK
Update
This commit is contained in:
@ -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')
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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:
|
||||
|
||||
Reference in New Issue
Block a user