Files
test2/scripts/startup/bl_ui/properties_data_lightprobe.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

270 lines
7.9 KiB
Python
Raw Normal View History

# SPDX-FileCopyrightText: 2009-2023 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
from bpy.types import Panel
class DataButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
@classmethod
def poll(cls, context):
engine = context.engine
return context.lightprobe and (engine in cls.COMPAT_ENGINES)
class DATA_PT_context_lightprobe(DataButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT'}
def draw(self, context):
layout = self.layout
ob = context.object
probe = context.lightprobe
space = context.space_data
if ob:
layout.template_ID(ob, "data")
elif probe:
layout.template_ID(space, "pin_id")
class DATA_PT_lightprobe(DataButtonsPanel, Panel):
bl_label = "Probe"
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_RENDER'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
probe = context.lightprobe
# layout.prop(probe, "type")
if probe.type == 'VOLUME':
col = layout.column()
col.prop(probe, "influence_distance", text="Distance")
col.prop(probe, "falloff")
col.prop(probe, "intensity")
sub = col.column(align=True)
sub.prop(probe, "grid_resolution_x", text="Resolution X")
sub.prop(probe, "grid_resolution_y", text="Y")
sub.prop(probe, "grid_resolution_z", text="Z")
elif probe.type == 'PLANE':
col = layout.column()
col.prop(probe, "influence_distance", text="Distance")
col.prop(probe, "falloff")
else:
col = layout.column()
col.prop(probe, "influence_type")
2017-06-13 15:56:04 +02:00
if probe.influence_type == 'ELIPSOID':
col.prop(probe, "influence_distance", text="Radius")
2017-06-13 15:56:04 +02:00
else:
col.prop(probe, "influence_distance", text="Size")
2017-06-13 15:56:04 +02:00
col.prop(probe, "falloff")
col.prop(probe, "intensity")
sub = col.column(align=True)
if probe.type != 'PLANE':
sub.prop(probe, "clip_start", text="Clipping Start")
else:
sub.prop(probe, "clip_start", text="Clipping Offset")
if probe.type != 'PLANE':
sub.prop(probe, "clip_end", text="End")
class DATA_PT_lightprobe_eevee_next(DataButtonsPanel, Panel):
bl_label = "Probe"
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
probe = context.lightprobe
if probe.type == 'VOLUME':
col = layout.column()
sub = col.column(align=True)
sub.prop(probe, "grid_resolution_x", text="Resolution X")
sub.prop(probe, "grid_resolution_y", text="Y")
sub.prop(probe, "grid_resolution_z", text="Z")
col.separator()
col.prop(probe, "intensity")
col.separator()
2023-09-13 13:36:00 +10:00
col.operator("object.lightprobe_cache_bake").subset = 'ACTIVE'
col.operator("object.lightprobe_cache_free").subset = 'ACTIVE'
col.separator()
col.prop(probe, "grid_bake_samples")
col.prop(probe, "surfel_density")
col.prop(probe, "clip_end", text="Capture Distance")
col.separator()
col.prop(probe, "grid_clamp_direct")
col.prop(probe, "grid_clamp_indirect")
col.separator()
col.prop(probe, "grid_normal_bias")
col.prop(probe, "grid_view_bias")
col.prop(probe, "grid_irradiance_smoothing")
col.prop(probe, "grid_validity_threshold")
col.separator()
col.prop(probe, "grid_surface_bias")
col.prop(probe, "grid_escape_bias")
col.separator()
col.prop(probe, "grid_dilation_threshold")
col.prop(probe, "grid_dilation_radius")
col.separator()
col.prop(probe, "grid_capture_world")
col.prop(probe, "grid_capture_indirect")
col.prop(probe, "grid_capture_emission")
elif probe.type == 'SPHERE':
col = layout.column()
col.prop(probe, "influence_type")
if probe.influence_type == 'ELIPSOID':
influence_text = "Radius"
else:
influence_text = "Size"
col.prop(probe, "influence_distance", text=influence_text)
col.prop(probe, "falloff")
sub = layout.column(align=True)
sub.prop(probe, "clip_start", text="Clipping Start")
sub.prop(probe, "clip_end", text="End")
Eevee-next: Reflection Probe Packing All probes (including the world background probe) are stored in a single texture. Each probe can be of any resolution as long as it is a power of 2 and not larger than 2048. So valid options are (2048x2048, 1024x1024, 512x512, etc). Each probe can be stored in their own resolution and can be set by the user. > NOTE: Eventually we would like to add automatic resolution selection. The probes are packed in an 2d texture array with the dimension of 2048*2048. The number of layers depends on the actual needed layers. If more layers are needed the texture will be recreated. This can happen when a new reflection probe is added, or an existing reflection probe is made visible to the scene or its resolution is changed. ### Octahedral mapping Probes are rendered into a cubemap. To reduce memory needs and improve sampling performance the cubemap is stored in octahedral mapping space. This is done in `eevee_reflection_probe_remap_comp.glsl`. The regular octahedral mapping has been extended to fix leakages at the edges of the texture and to be able to be used on an atlas texture and by sampling the texture once. To reduce sampling cost and improve the quality we add an border around the octahedral map and extend the octahedral coordinates. This also allows us to generate lower resolution mipmaps of the atlas texture using 2x2 box filtering from a higher resolution. ### Subdivisions and areas Probes data are stored besides the texture. The data is used to find out where the probe is stored in the texture. It is also used to find free space to store new probes. This approach ensures that we can be flexible at storing probes with different resolutions on the same layer. Lets see an example how that works Code-wise this is implemented by `ProbeLocationFinder`. ProbeLocationFinder can view a texture in a given subdivision level and mark areas that are covered by probes. When finding a free spot it returns the first empty area. **Notes** * Currently the cubemap is rendered with a fixed resolution and mipmaps are generated in order to increase the quality of the atlas. Eventually we should use dynamic resolution and no mipmaps. This will be done as part of the light probe baking change. Pull Request: https://projects.blender.org/blender/blender/pulls/109688
2023-07-07 15:37:26 +02:00
elif probe.type == 'PLANE':
col = layout.column()
row = col.row()
col.prop(probe, "clip_start", text="Clipping Offset")
col.prop(probe, "influence_distance", text="Distance")
pass
else:
# Currently unsupported
pass
class DATA_PT_lightprobe_visibility(DataButtonsPanel, Panel):
bl_label = "Visibility"
bl_parent_id = "DATA_PT_lightprobe"
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_RENDER'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
probe = context.lightprobe
col = layout.column()
if probe.type == 'VOLUME':
col.prop(probe, "visibility_buffer_bias", text="Bias")
col.prop(probe, "visibility_bleed_bias", text="Bleed Bias")
col.prop(probe, "visibility_blur", text="Blur")
row = col.row(align=True)
row.prop(probe, "visibility_collection")
row.prop(probe, "invert_visibility_collection", text="", icon='ARROW_LEFTRIGHT')
class DATA_PT_lightprobe_parallax(DataButtonsPanel, Panel):
bl_label = "Custom Parallax"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT'}
2017-06-13 15:56:04 +02:00
@classmethod
def poll(cls, context):
engine = context.engine
return context.lightprobe and context.lightprobe.type == 'SPHERE' and (engine in cls.COMPAT_ENGINES)
2017-06-13 15:56:04 +02:00
def draw_header(self, context):
probe = context.lightprobe
self.layout.prop(probe, "use_custom_parallax", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
probe = context.lightprobe
col = layout.column()
col.active = probe.use_custom_parallax
col.prop(probe, "parallax_type")
if probe.parallax_type == 'ELIPSOID':
col.prop(probe, "parallax_distance", text="Radius")
else:
col.prop(probe, "parallax_distance", text="Size")
class DATA_PT_lightprobe_display(DataButtonsPanel, Panel):
bl_label = "Viewport Display"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_RENDER'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
ob = context.object
probe = context.lightprobe
col = layout.column()
if probe.type == 'PLANE':
col.prop(ob, "empty_display_size", text="Arrow Size")
Overlay Engine: Refactor & Cleanup This is the unification of all overlays into one overlay engine as described in T65347. I went over all the code making it more future proof with less hacks and removing old / not relevent parts. Goals / Acheivements: - Remove internal shader usage (only drw shaders) - Remove viewportSize and viewportSizeInv and put them in gloabl ubo - Fixed some drawing issues: Missing probe option and Missing Alt+B clipping of some shader - Remove old (legacy) shaders dependancy (not using view UBO). - Less shader variation (less compilation time at first load and less patching needed for vulkan) - removed some geom shaders when I could - Remove static e_data (except shaders storage where it is OK) - Clear the way to fix some anoying limitations (dithered transparency, background image compositing etc...) - Wireframe drawing now uses the same batching capabilities as workbench & eevee (indirect drawing). - Reduced complexity, removed ~3000 Lines of code in draw (also removed a lot of unused shader in GPU). - Post AA to avoid complexity and cost of MSAA. Remaining issues: - ~~Armature edits, overlay toggles, (... others?) are not refreshing viewport after AA is complete~~ - FXAA is not the best for wires, maybe investigate SMAA - Maybe do something more temporally stable for AA. - ~~Paint overlays are not working with AA.~~ - ~~infront objects are difficult to select.~~ - ~~the infront wires sometimes goes through they solid counterpart (missing clear maybe?) (toggle overlays on-off when using infront+wireframe overlay in solid shading)~~ Note: I made some decision to change slightly the appearance of some objects to simplify their drawing. Namely the empty arrows end (which is now hollow/wire) and distance points of the cameras/spots being done by lines. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D6296
2019-12-02 01:40:58 +01:00
col.prop(probe, "show_influence")
col.prop(probe, "show_data")
2017-10-01 01:23:48 +02:00
if probe.type in {'VOLUME', 'SPHERE'}:
2017-10-01 01:23:48 +02:00
col.prop(probe, "show_influence")
col.prop(probe, "show_clip")
if probe.type == 'SPHERE':
sub = col.column()
sub.active = probe.use_custom_parallax
sub.prop(probe, "show_parallax")
2017-10-01 01:23:48 +02:00
classes = (
DATA_PT_context_lightprobe,
DATA_PT_lightprobe,
DATA_PT_lightprobe_eevee_next,
DATA_PT_lightprobe_visibility,
DATA_PT_lightprobe_parallax,
DATA_PT_lightprobe_display,
)
if __name__ == "__main__": # only for live edit.
from bpy.utils import register_class
for cls in classes:
register_class(cls)