This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/release/scripts/startup/bl_ui/properties_data_camera.py
Clément Foucault f4fe3fb09b EEVEE-Next: Depth Of Field: Port implementation to compute shader
This is a port of the previous implementation but using compute
shaders instead of using the raster pipeline for every steps.

Only the scatter passes is kept as a raster pass for obvious performance
reasons.

Many steps have been rewritten to take advantage of LDS which allows faster
and simpler downsampling and filtering for some passes.

A new stabilize phase has been separated from another setup pass in order
to improve it in the future with better stabilization.

The scatter pass shaders and pipeline also changed. We now use indirect
drawcall to draw quads using triangle strips primitives. This reduces
fragment shader invocation count & overdraw compared to a bounding
triangle. This also reduces the amount of vertex shader invocation
drastically to the bare minimum instead of having always 3 verts per
4 pixels (for each ground).
2022-08-02 21:53:17 +02:00

525 lines
18 KiB
Python

# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bpy.types import Panel
from rna_prop_ui import PropertyPanel
from bl_ui.utils import PresetPanel
class CameraButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
@classmethod
def poll(cls, context):
engine = context.engine
return context.camera and (engine in cls.COMPAT_ENGINES)
class CAMERA_PT_presets(PresetPanel, Panel):
bl_label = "Camera Presets"
preset_subdir = "camera"
preset_operator = "script.execute_preset"
preset_add_operator = "camera.preset_add"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
class SAFE_AREAS_PT_presets(PresetPanel, Panel):
bl_label = "Camera Presets"
preset_subdir = "safe_areas"
preset_operator = "script.execute_preset"
preset_add_operator = "safe_areas.preset_add"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
class DATA_PT_context_camera(CameraButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
def draw(self, context):
layout = self.layout
ob = context.object
cam = context.camera
space = context.space_data
if ob:
layout.template_ID(ob, "data")
elif cam:
layout.template_ID(space, "pin_id")
class DATA_PT_lens(CameraButtonsPanel, Panel):
bl_label = "Lens"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
cam = context.camera
layout.prop(cam, "type")
col = layout.column()
col.separator()
if cam.type == 'PERSP':
if cam.lens_unit == 'MILLIMETERS':
col.prop(cam, "lens")
elif cam.lens_unit == 'FOV':
col.prop(cam, "angle")
col.prop(cam, "lens_unit")
elif cam.type == 'ORTHO':
col.prop(cam, "ortho_scale")
elif cam.type == 'PANO':
engine = context.engine
if engine == 'CYCLES':
ccam = cam.cycles
col.prop(ccam, "panorama_type")
if ccam.panorama_type == 'FISHEYE_EQUIDISTANT':
col.prop(ccam, "fisheye_fov")
elif ccam.panorama_type == 'FISHEYE_EQUISOLID':
col.prop(ccam, "fisheye_lens", text="Lens")
col.prop(ccam, "fisheye_fov")
elif ccam.panorama_type == 'EQUIRECTANGULAR':
sub = col.column(align=True)
sub.prop(ccam, "latitude_min", text="Latitude Min")
sub.prop(ccam, "latitude_max", text="Max")
sub = col.column(align=True)
sub.prop(ccam, "longitude_min", text="Longitude Min")
sub.prop(ccam, "longitude_max", text="Max")
elif ccam.panorama_type == 'FISHEYE_LENS_POLYNOMIAL':
col.prop(ccam, "fisheye_fov")
col.prop(ccam, "fisheye_polynomial_k0", text="K0")
col.prop(ccam, "fisheye_polynomial_k1", text="K1")
col.prop(ccam, "fisheye_polynomial_k2", text="K2")
col.prop(ccam, "fisheye_polynomial_k3", text="K3")
col.prop(ccam, "fisheye_polynomial_k4", text="K4")
elif engine in {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}:
if cam.lens_unit == 'MILLIMETERS':
col.prop(cam, "lens")
elif cam.lens_unit == 'FOV':
col.prop(cam, "angle")
col.prop(cam, "lens_unit")
col = layout.column()
col.separator()
sub = col.column(align=True)
sub.prop(cam, "shift_x", text="Shift X")
sub.prop(cam, "shift_y", text="Y")
col.separator()
sub = col.column(align=True)
sub.prop(cam, "clip_start", text="Clip Start")
sub.prop(cam, "clip_end", text="End")
class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel):
bl_label = "Stereoscopy"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
@classmethod
def poll(cls, context):
render = context.scene.render
return (super().poll(context) and render.use_multiview and
render.views_format == 'STEREO_3D')
def draw(self, context):
layout = self.layout
layout.use_property_split = True
render = context.scene.render
st = context.camera.stereo
cam = context.camera
is_spherical_stereo = cam.type != 'ORTHO' and render.use_spherical_stereo
use_spherical_stereo = is_spherical_stereo and st.use_spherical_stereo
layout.prop(st, "convergence_mode")
col = layout.column()
sub = col.column()
sub.active = st.convergence_mode != 'PARALLEL'
sub.prop(st, "convergence_distance")
col.prop(st, "interocular_distance")
if is_spherical_stereo:
col.separator()
col.prop(st, "use_spherical_stereo")
sub = col.column()
sub.active = st.use_spherical_stereo
sub.prop(st, "use_pole_merge")
sub = col.column(align=True)
sub.active = st.use_pole_merge
sub.prop(st, "pole_merge_angle_from", text="Pole Merge Angle Start")
sub.prop(st, "pole_merge_angle_to", text="End")
col = layout.column()
col.active = not use_spherical_stereo
col.separator()
col.prop(st, "pivot")
class DATA_PT_camera(CameraButtonsPanel, Panel):
bl_label = "Camera"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
def draw_header_preset(self, _context):
CAMERA_PT_presets.draw_panel_header(self.layout)
def draw(self, context):
layout = self.layout
cam = context.camera
layout.use_property_split = True
col = layout.column()
col.prop(cam, "sensor_fit")
if cam.sensor_fit == 'AUTO':
col.prop(cam, "sensor_width", text="Size")
else:
sub = col.column(align=True)
sub.active = cam.sensor_fit == 'HORIZONTAL'
sub.prop(cam, "sensor_width", text="Width")
sub = col.column(align=True)
sub.active = cam.sensor_fit == 'VERTICAL'
sub.prop(cam, "sensor_height", text="Height")
class DATA_PT_camera_dof(CameraButtonsPanel, Panel):
bl_label = "Depth of Field"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
def draw_header(self, context):
cam = context.camera
dof = cam.dof
self.layout.prop(dof, "use_dof", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
cam = context.camera
dof = cam.dof
layout.active = dof.use_dof
col = layout.column()
col.prop(dof, "focus_object", text="Focus on Object")
if dof.focus_object and dof.focus_object.type == 'ARMATURE':
col.prop_search(dof, "focus_subtarget", dof.focus_object.data, "bones", text="Focus on Bone")
sub = col.column()
sub.active = (dof.focus_object is None)
sub.prop(dof, "focus_distance", text="Focus Distance")
class DATA_PT_camera_dof_aperture(CameraButtonsPanel, Panel):
bl_label = "Aperture"
bl_parent_id = "DATA_PT_camera_dof"
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
cam = context.camera
dof = cam.dof
layout.active = dof.use_dof
flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
col = flow.column()
col.prop(dof, "aperture_fstop")
col = flow.column()
col.prop(dof, "aperture_blades")
col.prop(dof, "aperture_rotation")
col.prop(dof, "aperture_ratio")
class DATA_PT_camera_background_image(CameraButtonsPanel, Panel):
bl_label = "Background Images"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
def draw_header(self, context):
cam = context.camera
self.layout.prop(cam, "show_background_images", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
cam = context.camera
use_multiview = context.scene.render.use_multiview
col = layout.column()
col.operator("view3d.background_image_add", text="Add Image")
for i, bg in enumerate(cam.background_images):
layout.active = cam.show_background_images
box = layout.box()
row = box.row(align=True)
row.prop(bg, "show_expanded", text="", emboss=False)
if bg.source == 'IMAGE' and bg.image:
row.prop(bg.image, "name", text="", emboss=False)
elif bg.source == 'MOVIE_CLIP' and bg.clip:
row.prop(bg.clip, "name", text="", emboss=False)
elif bg.source and bg.use_camera_clip:
row.label(text="Active Clip")
else:
row.label(text="Not Set")
row.prop(
bg,
"show_background_image",
text="",
emboss=False,
icon='RESTRICT_VIEW_OFF' if bg.show_background_image else 'RESTRICT_VIEW_ON',
)
row.operator("view3d.background_image_remove", text="", emboss=False, icon='X').index = i
if bg.show_expanded:
row = box.row()
row.prop(bg, "source", expand=True)
has_bg = False
if bg.source == 'IMAGE':
row = box.row()
row.template_ID(bg, "image", open="image.open")
if bg.image is not None:
box.template_image(bg, "image", bg.image_user, compact=True)
has_bg = True
if use_multiview:
box.prop(bg.image, "use_multiview")
column = box.column()
column.active = bg.image.use_multiview
column.label(text="Views Format:")
column.row().prop(bg.image, "views_format", expand=True)
sub = column.box()
sub.active = bg.image.views_format == 'STEREO_3D'
sub.template_image_stereo_3d(bg.image.stereo_3d_format)
elif bg.source == 'MOVIE_CLIP':
box.prop(bg, "use_camera_clip", text="Active Clip")
column = box.column()
column.active = not bg.use_camera_clip
column.template_ID(bg, "clip", open="clip.open")
if bg.clip:
column.template_movieclip(bg, "clip", compact=True)
if bg.use_camera_clip or bg.clip:
has_bg = True
column = box.column()
column.active = has_bg
column.prop(bg.clip_user, "use_render_undistorted")
column.prop(bg.clip_user, "proxy_render_size")
if has_bg:
col = box.column()
col.prop(bg, "alpha", slider=True)
col.row().prop(bg, "display_depth", expand=True)
col.row().prop(bg, "frame_method", expand=True)
row = box.row()
row.prop(bg, "offset")
col = box.column()
col.prop(bg, "rotation")
col.prop(bg, "scale")
col = box.column(heading="Flip")
col.prop(bg, "use_flip_x", text="X")
col.prop(bg, "use_flip_y", text="Y")
class DATA_PT_camera_display(CameraButtonsPanel, Panel):
bl_label = "Viewport Display"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
cam = context.camera
col = layout.column(align=True)
col.prop(cam, "display_size", text="Size")
col = layout.column(heading="Show")
col.prop(cam, "show_limits", text="Limits")
col.prop(cam, "show_mist", text="Mist")
col.prop(cam, "show_sensor", text="Sensor")
col.prop(cam, "show_name", text="Name")
col = layout.column(align=False, heading="Passepartout")
col.use_property_decorate = False
row = col.row(align=True)
sub = row.row(align=True)
sub.prop(cam, "show_passepartout", text="")
sub = sub.row(align=True)
sub.active = cam.show_passepartout
sub.prop(cam, "passepartout_alpha", text="")
row.prop_decorator(cam, "passepartout_alpha")
class DATA_PT_camera_display_composition_guides(CameraButtonsPanel, Panel):
bl_label = "Composition Guides"
bl_parent_id = "DATA_PT_camera_display"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
cam = context.camera
layout.prop(cam, "show_composition_thirds")
col = layout.column(heading="Center", align=True)
col.prop(cam, "show_composition_center")
col.prop(cam, "show_composition_center_diagonal", text="Diagonal")
col = layout.column(heading="Golden", align=True)
col.prop(cam, "show_composition_golden", text="Ratio")
col.prop(cam, "show_composition_golden_tria_a", text="Triangle A")
col.prop(cam, "show_composition_golden_tria_b", text="Triangle B")
col = layout.column(heading="Harmony", align=True)
col.prop(cam, "show_composition_harmony_tri_a", text="Triangle A")
col.prop(cam, "show_composition_harmony_tri_b", text="Triangle B")
class DATA_PT_camera_safe_areas(CameraButtonsPanel, Panel):
bl_label = "Safe Areas"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
def draw_header(self, context):
cam = context.camera
self.layout.prop(cam, "show_safe_areas", text="")
def draw_header_preset(self, _context):
SAFE_AREAS_PT_presets.draw_panel_header(self.layout)
def draw(self, context):
layout = self.layout
safe_data = context.scene.safe_areas
camera = context.camera
layout.use_property_split = True
layout.active = camera.show_safe_areas
col = layout.column()
sub = col.column()
sub.prop(safe_data, "title", slider=True)
sub.prop(safe_data, "action", slider=True)
class DATA_PT_camera_safe_areas_center_cut(CameraButtonsPanel, Panel):
bl_label = "Center-Cut Safe Areas"
bl_parent_id = "DATA_PT_camera_safe_areas"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
def draw_header(self, context):
cam = context.camera
layout = self.layout
layout.active = cam.show_safe_areas
layout.prop(cam, "show_safe_center", text="")
def draw(self, context):
layout = self.layout
safe_data = context.scene.safe_areas
camera = context.camera
layout.use_property_split = True
layout.active = camera.show_safe_areas and camera.show_safe_center
col = layout.column()
col.prop(safe_data, "title_center", slider=True)
col.prop(safe_data, "action_center", slider=True)
class DATA_PT_custom_props_camera(CameraButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
_context_path = "object.data"
_property_type = bpy.types.Camera
def draw_display_safe_settings(layout, safe_data, settings):
show_safe_areas = settings.show_safe_areas
show_safe_center = settings.show_safe_center
layout.use_property_split = True
col = layout.column()
col.active = show_safe_areas
sub = col.column()
sub.prop(safe_data, "title", slider=True)
sub.prop(safe_data, "action", slider=True)
col.separator()
col.prop(settings, "show_safe_center", text="Center-Cut Safe Areas")
sub = col.column()
sub.active = show_safe_areas and show_safe_center
sub.prop(safe_data, "title_center", slider=True)
sub.prop(safe_data, "action_center", slider=True)
classes = (
CAMERA_PT_presets,
SAFE_AREAS_PT_presets,
DATA_PT_context_camera,
DATA_PT_lens,
DATA_PT_camera_dof,
DATA_PT_camera_dof_aperture,
DATA_PT_camera,
DATA_PT_camera_stereoscopy,
DATA_PT_camera_safe_areas,
DATA_PT_camera_safe_areas_center_cut,
DATA_PT_camera_background_image,
DATA_PT_camera_display,
DATA_PT_camera_display_composition_guides,
DATA_PT_custom_props_camera,
)
if __name__ == "__main__": # only for live edit.
from bpy.utils import register_class
for cls in classes:
register_class(cls)