Compare commits
129 Commits
blender-pr
...
tmp-worben
Author | SHA1 | Date | |
---|---|---|---|
2da005902f | |||
693dffb7b7 | |||
aef43d1461 | |||
2c432baad0 | |||
99e5f4000c | |||
1b5a594a05 | |||
a9d716fa0f | |||
6f28259ea3 | |||
a6b383bd69 | |||
c2022d6d36 | |||
15f8b6bbef | |||
3a06bb5e45 | |||
2c547fc7b1 | |||
15b2caab21 | |||
0ea4baa94d | |||
49e9d105f0 | |||
89e114fa70 | |||
b061ace748 | |||
f1a90deb13 | |||
47a629b972 | |||
0b013d8873 | |||
8cbbfa8c29 | |||
ee51f6b3e9 | |||
b17578a943 | |||
128d4104bf | |||
8f165c390d | |||
b87ae86e3c | |||
f8eb85d910 | |||
ed69fbadf7 | |||
5627c8acea | |||
9594be5eef | |||
fdb4abc36d | |||
8213d1735d | |||
4aec99931b | |||
a53e560ca5 | |||
64b87737d6 | |||
b33634f8fa | |||
1b20a9d383 | |||
c6ce4eed5e | |||
5c4a5c637c | |||
646613c23d | |||
45103e3a88 | |||
87482b8a9e | |||
6b7160ed3b | |||
c76d4ddf0b | |||
c38bdceb68 | |||
7bc00aeabf | |||
dcdf29d936 | |||
97b0719f7d | |||
bc73c1cd16 | |||
8cbd045a82 | |||
6fd43f10d7 | |||
d20b672e01 | |||
b81e6ab2f0 | |||
eec714350f | |||
c5ef9fc5ec | |||
179eadc91f | |||
ae192ececd | |||
31cdeed916 | |||
cf1863d990 | |||
77d3cd35b9 | |||
58b26198d2 | |||
13573fd22c | |||
d4cfdc6c2c | |||
cfc730e612 | |||
c394ad246d | |||
2ea0ba8854 | |||
9fd51e16ed | |||
657d36c8b7 | |||
0b33068a2f | |||
4e0076daca | |||
739b3abc47 | |||
c69b304129 | |||
862fbf1ab2 | |||
dc0300178f | |||
c6e42a5723 | |||
9fdf1074d9 | |||
429bb7a4fd | |||
7a56cb0e8a | |||
9725b83415 | |||
109b1a717a | |||
d518dc411e | |||
2a1ad72d20 | |||
cd67fde848 | |||
5be7f872c4 | |||
f1038bb8ea | |||
114ccbccf9 | |||
aa3a485e9d | |||
97874b0f41 | |||
a3055b75fb | |||
5abcd8c8fb | |||
a29d9debe4 | |||
f90272b650 | |||
af447def21 | |||
b6dd660903 | |||
695ce56e06 | |||
47e8fc113b | |||
562783a9a9 | |||
7e754023a7 | |||
ef836b2222 | |||
4b4ae0900d | |||
bb0d1781cb | |||
6c1647a96e | |||
2e6c5b3075 | |||
4e895f0a3a | |||
dc5fb28c27 | |||
71c1266921 | |||
40945fc283 | |||
439dfabaeb | |||
70a39f484f | |||
1f64fa75e1 | |||
5a10182a70 | |||
7c59b0b836 | |||
4b65c0ad54 | |||
8501e93dea | |||
219d5a9530 | |||
ce54a09cdd | |||
65a069b539 | |||
79f15f68c5 | |||
dfd61be20e | |||
cde0faf4dd | |||
106c6db1b5 | |||
2739e186b6 | |||
f1851fa35c | |||
71c9746ec6 | |||
d6457310d8 | |||
db6665813b | |||
bc28bf3681 | |||
43dad4d9b1 |
@@ -248,7 +248,7 @@ class DATA_PT_motion_paths_display(MotionPathButtonsPanel_display, Panel):
|
||||
|
||||
|
||||
class DATA_PT_custom_props_arm(ArmatureButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "object.data"
|
||||
_property_type = bpy.types.Armature
|
||||
|
||||
|
@@ -444,7 +444,7 @@ class BONE_PT_deform(BoneButtonsPanel, Panel):
|
||||
|
||||
|
||||
class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_property_type = bpy.types.Bone, bpy.types.EditBone, bpy.types.PoseBone
|
||||
|
||||
@property
|
||||
|
@@ -21,7 +21,7 @@ class CAMERA_PT_presets(PresetPanel, Panel):
|
||||
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'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
|
||||
class SAFE_AREAS_PT_presets(PresetPanel, Panel):
|
||||
@@ -29,13 +29,13 @@ class SAFE_AREAS_PT_presets(PresetPanel, Panel):
|
||||
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'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
|
||||
class DATA_PT_context_camera(CameraButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -52,7 +52,7 @@ class DATA_PT_context_camera(CameraButtonsPanel, Panel):
|
||||
|
||||
class DATA_PT_lens(CameraButtonsPanel, Panel):
|
||||
bl_label = "Lens"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -100,7 +100,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel):
|
||||
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'}:
|
||||
elif engine in {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}:
|
||||
if cam.lens_unit == 'MILLIMETERS':
|
||||
col.prop(cam, "lens")
|
||||
elif cam.lens_unit == 'FOV':
|
||||
@@ -122,7 +122,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel):
|
||||
|
||||
class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel):
|
||||
bl_label = "Stereoscopy"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -171,7 +171,7 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel):
|
||||
class DATA_PT_camera(CameraButtonsPanel, Panel):
|
||||
bl_label = "Camera"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header_preset(self, _context):
|
||||
CAMERA_PT_presets.draw_panel_header(self.layout)
|
||||
@@ -201,7 +201,7 @@ class DATA_PT_camera(CameraButtonsPanel, Panel):
|
||||
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'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
cam = context.camera
|
||||
@@ -228,7 +228,7 @@ class DATA_PT_camera_dof(CameraButtonsPanel, Panel):
|
||||
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'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -252,7 +252,7 @@ class DATA_PT_camera_dof_aperture(CameraButtonsPanel, Panel):
|
||||
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'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
cam = context.camera
|
||||
@@ -359,7 +359,7 @@ class DATA_PT_camera_background_image(CameraButtonsPanel, Panel):
|
||||
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'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -392,7 +392,7 @@ 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'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -419,7 +419,7 @@ class DATA_PT_camera_display_composition_guides(CameraButtonsPanel, Panel):
|
||||
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'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
cam = context.camera
|
||||
@@ -449,7 +449,7 @@ 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'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
cam = context.camera
|
||||
@@ -473,7 +473,7 @@ class DATA_PT_camera_safe_areas_center_cut(CameraButtonsPanel, Panel):
|
||||
|
||||
|
||||
class DATA_PT_custom_props_camera(CameraButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "object.data"
|
||||
_property_type = bpy.types.Camera
|
||||
|
||||
|
@@ -116,7 +116,7 @@ class DATA_PT_shape_curve(CurveButtonsPanel, Panel):
|
||||
class DATA_PT_curve_texture_space(CurveButtonsPanel, Panel):
|
||||
bl_label = "Texture Space"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -475,7 +475,7 @@ class DATA_PT_text_boxes(CurveButtonsPanelText, Panel):
|
||||
|
||||
|
||||
class DATA_PT_custom_props_curve(CurveButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "object.data"
|
||||
_property_type = bpy.types.Curve
|
||||
|
||||
|
@@ -18,7 +18,7 @@ class DataButtonsPanel:
|
||||
class DATA_PT_context_curves(DataButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -35,7 +35,7 @@ class DATA_PT_context_curves(DataButtonsPanel, Panel):
|
||||
|
||||
class DATA_PT_curves_surface(DataButtonsPanel, Panel):
|
||||
bl_label = "Surface"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -118,7 +118,7 @@ class CURVES_UL_attributes(UIList):
|
||||
|
||||
class DATA_PT_CURVES_attributes(DataButtonsPanel, Panel):
|
||||
bl_label = "Attributes"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
curves = context.curves
|
||||
@@ -143,7 +143,7 @@ class DATA_PT_CURVES_attributes(DataButtonsPanel, Panel):
|
||||
|
||||
|
||||
class DATA_PT_custom_props_curves(DataButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "object.data"
|
||||
_property_type = bpy.types.Curves if hasattr(bpy.types, "Curves") else None
|
||||
|
||||
|
@@ -64,7 +64,7 @@ class DATA_PT_lattice(DataButtonsPanel, Panel):
|
||||
|
||||
|
||||
class DATA_PT_custom_props_lattice(DataButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "object.data"
|
||||
_property_type = bpy.types.Lattice
|
||||
|
||||
|
@@ -18,7 +18,7 @@ class DataButtonsPanel:
|
||||
class DATA_PT_context_light(DataButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -44,7 +44,7 @@ class DATA_PT_preview(DataButtonsPanel, Panel):
|
||||
|
||||
class DATA_PT_light(DataButtonsPanel, Panel):
|
||||
bl_label = "Light"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -230,7 +230,7 @@ class DATA_PT_EEVEE_shadow_contact(DataButtonsPanel, Panel):
|
||||
class DATA_PT_spot(DataButtonsPanel, Panel):
|
||||
bl_label = "Spot Shape"
|
||||
bl_parent_id = "DATA_PT_EEVEE_light"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -275,7 +275,7 @@ class DATA_PT_falloff_curve(DataButtonsPanel, Panel):
|
||||
|
||||
|
||||
class DATA_PT_custom_props_light(DataButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "object.data"
|
||||
_property_type = bpy.types.Light
|
||||
|
||||
|
@@ -171,7 +171,7 @@ class MeshButtonsPanel:
|
||||
class DATA_PT_context_mesh(MeshButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -189,7 +189,7 @@ class DATA_PT_context_mesh(MeshButtonsPanel, Panel):
|
||||
class DATA_PT_normals(MeshButtonsPanel, Panel):
|
||||
bl_label = "Normals"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -211,7 +211,7 @@ class DATA_PT_normals(MeshButtonsPanel, Panel):
|
||||
class DATA_PT_texture_space(MeshButtonsPanel, Panel):
|
||||
bl_label = "Texture Space"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -231,7 +231,7 @@ class DATA_PT_texture_space(MeshButtonsPanel, Panel):
|
||||
|
||||
class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
|
||||
bl_label = "Vertex Groups"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -288,7 +288,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
|
||||
class DATA_PT_face_maps(MeshButtonsPanel, Panel):
|
||||
bl_label = "Face Maps"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -331,7 +331,7 @@ class DATA_PT_face_maps(MeshButtonsPanel, Panel):
|
||||
|
||||
class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
|
||||
bl_label = "Shape Keys"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -428,7 +428,7 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
|
||||
class DATA_PT_uv_texture(MeshButtonsPanel, Panel):
|
||||
bl_label = "UV Maps"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -448,7 +448,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel):
|
||||
class DATA_PT_remesh(MeshButtonsPanel, Panel):
|
||||
bl_label = "Remesh"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -478,7 +478,7 @@ class DATA_PT_remesh(MeshButtonsPanel, Panel):
|
||||
class DATA_PT_customdata(MeshButtonsPanel, Panel):
|
||||
bl_label = "Geometry Data"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -519,7 +519,7 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
|
||||
|
||||
|
||||
class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "object.data"
|
||||
_property_type = bpy.types.Mesh
|
||||
|
||||
@@ -568,7 +568,7 @@ class MESH_UL_attributes(UIList):
|
||||
class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel):
|
||||
bl_label = "Attributes"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
mesh = context.mesh
|
||||
@@ -692,7 +692,7 @@ class MESH_UL_color_attributes_selector(UIList, ColorAttributesListBase):
|
||||
class DATA_PT_vertex_colors(DATA_PT_mesh_attributes, Panel):
|
||||
bl_label = "Color Attributes"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
mesh = context.mesh
|
||||
|
@@ -56,7 +56,7 @@ class DATA_PT_metaball(DataButtonsPanel, Panel):
|
||||
class DATA_PT_mball_texture_space(DataButtonsPanel, Panel):
|
||||
bl_label = "Texture Space"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -111,7 +111,7 @@ class DATA_PT_metaball_element(DataButtonsPanel, Panel):
|
||||
|
||||
|
||||
class DATA_PT_custom_props_metaball(DataButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "object.data"
|
||||
_property_type = bpy.types.MetaBall
|
||||
|
||||
|
@@ -18,7 +18,7 @@ class DataButtonsPanel:
|
||||
class DATA_PT_context_pointcloud(DataButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -97,7 +97,7 @@ class POINTCLOUD_UL_attributes(UIList):
|
||||
|
||||
class DATA_PT_pointcloud_attributes(DataButtonsPanel, Panel):
|
||||
bl_label = "Attributes"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
pointcloud = context.pointcloud
|
||||
@@ -122,7 +122,7 @@ class DATA_PT_pointcloud_attributes(DataButtonsPanel, Panel):
|
||||
|
||||
|
||||
class DATA_PT_custom_props_pointcloud(DataButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "object.data"
|
||||
_property_type = bpy.types.PointCloud if hasattr(bpy.types, "PointCloud") else None
|
||||
|
||||
|
@@ -18,7 +18,7 @@ class DataButtonsPanel:
|
||||
class DATA_PT_context_speaker(DataButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -35,7 +35,7 @@ class DATA_PT_context_speaker(DataButtonsPanel, Panel):
|
||||
|
||||
class DATA_PT_speaker(DataButtonsPanel, Panel):
|
||||
bl_label = "Sound"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -57,7 +57,7 @@ class DATA_PT_speaker(DataButtonsPanel, Panel):
|
||||
class DATA_PT_distance(DataButtonsPanel, Panel):
|
||||
bl_label = "Distance"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -81,7 +81,7 @@ class DATA_PT_distance(DataButtonsPanel, Panel):
|
||||
class DATA_PT_cone(DataButtonsPanel, Panel):
|
||||
bl_label = "Cone"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -103,7 +103,7 @@ class DATA_PT_cone(DataButtonsPanel, Panel):
|
||||
|
||||
|
||||
class DATA_PT_custom_props_speaker(DataButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "object.data"
|
||||
_property_type = bpy.types.Speaker
|
||||
|
||||
|
@@ -18,7 +18,7 @@ class DataButtonsPanel:
|
||||
class DATA_PT_context_volume(DataButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -35,7 +35,7 @@ class DATA_PT_context_volume(DataButtonsPanel, Panel):
|
||||
|
||||
class DATA_PT_volume_file(DataButtonsPanel, Panel):
|
||||
bl_label = "OpenVDB File"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -80,7 +80,7 @@ class VOLUME_UL_grids(UIList):
|
||||
|
||||
class DATA_PT_volume_grids(DataButtonsPanel, Panel):
|
||||
bl_label = "Grids"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -93,7 +93,7 @@ class DATA_PT_volume_grids(DataButtonsPanel, Panel):
|
||||
|
||||
class DATA_PT_volume_render(DataButtonsPanel, Panel):
|
||||
bl_label = "Render"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -125,7 +125,7 @@ class DATA_PT_volume_render(DataButtonsPanel, Panel):
|
||||
|
||||
class DATA_PT_volume_viewport_display(DataButtonsPanel, Panel):
|
||||
bl_label = "Viewport Display"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -149,7 +149,7 @@ class DATA_PT_volume_viewport_display(DataButtonsPanel, Panel):
|
||||
class DATA_PT_volume_viewport_display_slicing(DataButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_parent_id = 'DATA_PT_volume_viewport_display'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
@@ -175,7 +175,7 @@ class DATA_PT_volume_viewport_display_slicing(DataButtonsPanel, Panel):
|
||||
|
||||
|
||||
class DATA_PT_custom_props_volume(DataButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "object.data"
|
||||
_property_type = bpy.types.Volume
|
||||
|
||||
|
@@ -21,7 +21,7 @@ class RENDER_PT_freestyle(RenderFreestyleButtonsPanel, Panel):
|
||||
bl_label = "Freestyle"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_order = 10
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
rd = context.scene.render
|
||||
@@ -79,7 +79,7 @@ class ViewLayerFreestyleEditorButtonsPanel(ViewLayerFreestyleButtonsPanel):
|
||||
|
||||
class ViewLayerFreestyleLineStyle(ViewLayerFreestyleEditorButtonsPanel):
|
||||
# Freestyle Linestyle Panels
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -123,7 +123,7 @@ class RENDER_MT_lineset_context_menu(Menu):
|
||||
|
||||
class VIEWLAYER_PT_freestyle(ViewLayerFreestyleButtonsPanel, Panel):
|
||||
bl_label = "Freestyle"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
view_layer = context.view_layer
|
||||
@@ -153,7 +153,7 @@ class VIEWLAYER_PT_freestyle(ViewLayerFreestyleButtonsPanel, Panel):
|
||||
class VIEWLAYER_PT_freestyle_edge_detection(ViewLayerFreestyleButtonsPanel, Panel):
|
||||
bl_label = "Edge Detection"
|
||||
bl_parent_id = "VIEWLAYER_PT_freestyle"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -183,7 +183,7 @@ class VIEWLAYER_PT_freestyle_edge_detection(ViewLayerFreestyleButtonsPanel, Pane
|
||||
class VIEWLAYER_PT_freestyle_style_modules(ViewLayerFreestyleButtonsPanel, Panel):
|
||||
bl_label = "Style Modules"
|
||||
bl_parent_id = "VIEWLAYER_PT_freestyle"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -219,7 +219,7 @@ class VIEWLAYER_PT_freestyle_style_modules(ViewLayerFreestyleButtonsPanel, Panel
|
||||
|
||||
class VIEWLAYER_PT_freestyle_lineset(ViewLayerFreestyleEditorButtonsPanel, Panel):
|
||||
bl_label = "Freestyle Line Set"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_edge_type_buttons(self, box, lineset, edge_type):
|
||||
# property names
|
||||
@@ -282,7 +282,7 @@ class VIEWLAYER_PT_freestyle_lineset(ViewLayerFreestyleEditorButtonsPanel, Panel
|
||||
class VIEWLAYER_PT_freestyle_lineset_visibilty(ViewLayerFreestyleLineStyle, Panel):
|
||||
bl_label = "Visibility"
|
||||
bl_parent_id = "VIEWLAYER_PT_freestyle_lineset"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
@@ -316,7 +316,7 @@ class VIEWLAYER_PT_freestyle_lineset_visibilty(ViewLayerFreestyleLineStyle, Pane
|
||||
class VIEWLAYER_PT_freestyle_lineset_edgetype(ViewLayerFreestyleLineStyle, Panel):
|
||||
bl_label = "Edge Type"
|
||||
bl_parent_id = "VIEWLAYER_PT_freestyle_lineset"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
@@ -366,7 +366,7 @@ class VIEWLAYER_PT_freestyle_lineset_edgetype(ViewLayerFreestyleLineStyle, Panel
|
||||
class VIEWLAYER_PT_freestyle_lineset_facemarks(ViewLayerFreestyleLineStyle, Panel):
|
||||
bl_label = "Face Marks"
|
||||
bl_parent_id = "VIEWLAYER_PT_freestyle_lineset"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw_header(self, context):
|
||||
@@ -395,7 +395,7 @@ class VIEWLAYER_PT_freestyle_lineset_facemarks(ViewLayerFreestyleLineStyle, Pane
|
||||
class VIEWLAYER_PT_freestyle_lineset_collection(ViewLayerFreestyleLineStyle, Panel):
|
||||
bl_label = "Collection"
|
||||
bl_parent_id = "VIEWLAYER_PT_freestyle_lineset"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw_header(self, context):
|
||||
@@ -1236,7 +1236,7 @@ class MaterialFreestyleButtonsPanel:
|
||||
class MATERIAL_PT_freestyle_line(MaterialFreestyleButtonsPanel, Panel):
|
||||
bl_label = "Freestyle Line"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@@ -60,7 +60,7 @@ class MATERIAL_PT_preview(MaterialButtonsPanel, Panel):
|
||||
|
||||
|
||||
class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "material"
|
||||
_property_type = bpy.types.Material
|
||||
|
||||
@@ -69,7 +69,7 @@ class EEVEE_MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_context = "material"
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
@@ -228,7 +228,7 @@ class MATERIAL_PT_gpencil_preview(GPMaterialButtonsPanel, Panel):
|
||||
|
||||
|
||||
class MATERIAL_PT_gpencil_custom_props(GPMaterialButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "object.active_material"
|
||||
_property_type = bpy.types.Material
|
||||
|
||||
|
@@ -366,7 +366,7 @@ class OBJECT_PT_motion_paths_display(MotionPathButtonsPanel_display, Panel):
|
||||
class OBJECT_PT_visibility(ObjectButtonsPanel, Panel):
|
||||
bl_label = "Visibility"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -395,7 +395,7 @@ class OBJECT_PT_visibility(ObjectButtonsPanel, Panel):
|
||||
|
||||
|
||||
class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "object"
|
||||
_property_type = bpy.types.Object
|
||||
|
||||
|
@@ -42,7 +42,7 @@ class RenderOutputButtonsPanel:
|
||||
|
||||
class RENDER_PT_format(RenderOutputButtonsPanel, Panel):
|
||||
bl_label = "Format"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
_frame_rate_args_prev = None
|
||||
_preset_class = None
|
||||
@@ -120,7 +120,7 @@ class RENDER_PT_format(RenderOutputButtonsPanel, Panel):
|
||||
|
||||
class RENDER_PT_frame_range(RenderOutputButtonsPanel, Panel):
|
||||
bl_label = "Frame Range"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -139,7 +139,7 @@ class RENDER_PT_time_stretching(RenderOutputButtonsPanel, Panel):
|
||||
bl_label = "Time Stretching"
|
||||
bl_parent_id = "RENDER_PT_frame_range"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -156,7 +156,7 @@ class RENDER_PT_time_stretching(RenderOutputButtonsPanel, Panel):
|
||||
class RENDER_PT_post_processing(RenderOutputButtonsPanel, Panel):
|
||||
bl_label = "Post Processing"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -174,7 +174,7 @@ class RENDER_PT_post_processing(RenderOutputButtonsPanel, Panel):
|
||||
class RENDER_PT_stamp(RenderOutputButtonsPanel, Panel):
|
||||
bl_label = "Metadata"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -208,7 +208,7 @@ class RENDER_PT_stamp_note(RenderOutputButtonsPanel, Panel):
|
||||
bl_label = "Note"
|
||||
bl_parent_id = "RENDER_PT_stamp"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
rd = context.scene.render
|
||||
@@ -228,7 +228,7 @@ class RENDER_PT_stamp_burn(RenderOutputButtonsPanel, Panel):
|
||||
bl_label = "Burn Into Image"
|
||||
bl_parent_id = "RENDER_PT_stamp"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
rd = context.scene.render
|
||||
@@ -252,7 +252,7 @@ class RENDER_PT_stamp_burn(RenderOutputButtonsPanel, Panel):
|
||||
|
||||
class RENDER_PT_output(RenderOutputButtonsPanel, Panel):
|
||||
bl_label = "Output"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -281,7 +281,7 @@ class RENDER_PT_output(RenderOutputButtonsPanel, Panel):
|
||||
class RENDER_PT_output_views(RenderOutputButtonsPanel, Panel):
|
||||
bl_label = "Views"
|
||||
bl_parent_id = "RENDER_PT_output"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -301,7 +301,7 @@ class RENDER_PT_output_color_management(RenderOutputButtonsPanel, Panel):
|
||||
bl_label = "Color Management"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_parent_id = "RENDER_PT_output"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
@@ -336,7 +336,7 @@ class RENDER_PT_encoding(RenderOutputButtonsPanel, Panel):
|
||||
bl_label = "Encoding"
|
||||
bl_parent_id = "RENDER_PT_output"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header_preset(self, _context):
|
||||
RENDER_PT_ffmpeg_presets.draw_panel_header(self.layout)
|
||||
@@ -361,7 +361,7 @@ class RENDER_PT_encoding(RenderOutputButtonsPanel, Panel):
|
||||
class RENDER_PT_encoding_video(RenderOutputButtonsPanel, Panel):
|
||||
bl_label = "Video"
|
||||
bl_parent_id = "RENDER_PT_encoding"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -437,7 +437,7 @@ class RENDER_PT_encoding_video(RenderOutputButtonsPanel, Panel):
|
||||
class RENDER_PT_encoding_audio(RenderOutputButtonsPanel, Panel):
|
||||
bl_label = "Audio"
|
||||
bl_parent_id = "RENDER_PT_encoding"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -479,7 +479,7 @@ class RENDER_UL_renderviews(UIList):
|
||||
|
||||
class RENDER_PT_stereoscopy(RenderOutputButtonsPanel, Panel):
|
||||
bl_label = "Stereoscopy"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw_header(self, context):
|
||||
|
@@ -52,7 +52,7 @@ def particle_get_settings(context):
|
||||
|
||||
class PARTICLE_MT_context_menu(Menu):
|
||||
bl_label = "Particle Specials"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -92,7 +92,7 @@ class PARTICLE_PT_hair_dynamics_presets(PresetPanel, Panel):
|
||||
preset_subdir = "hair_dynamics"
|
||||
preset_operator = "script.execute_preset"
|
||||
preset_add_operator = "particle.hair_dynamics_preset_add"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
|
||||
class ParticleButtonsPanel:
|
||||
@@ -146,7 +146,7 @@ class PARTICLE_UL_particle_systems(bpy.types.UIList):
|
||||
class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -240,7 +240,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_emission(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Emission"
|
||||
bl_translation_context = i18n_contexts.id_particlesettings
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -292,7 +292,7 @@ class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Source"
|
||||
bl_parent_id = "PARTICLE_PT_emission"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -329,7 +329,7 @@ class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Hair Dynamics"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -412,7 +412,7 @@ class PARTICLE_PT_hair_dynamics_collision(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Collisions"
|
||||
bl_parent_id = "PARTICLE_PT_hair_dynamics"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -444,7 +444,7 @@ class PARTICLE_PT_hair_dynamics_structure(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Structure"
|
||||
bl_parent_id = "PARTICLE_PT_hair_dynamics"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -475,7 +475,7 @@ class PARTICLE_PT_hair_dynamics_volume(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Volume"
|
||||
bl_parent_id = "PARTICLE_PT_hair_dynamics"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -506,7 +506,7 @@ class PARTICLE_PT_hair_dynamics_volume(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_cache(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Cache"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -539,7 +539,7 @@ class PARTICLE_PT_cache(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Velocity"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -588,7 +588,7 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Rotation"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -643,7 +643,7 @@ class PARTICLE_PT_rotation_angular_velocity(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Angular Velocity"
|
||||
bl_parent_id = "PARTICLE_PT_rotation"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -668,7 +668,7 @@ class PARTICLE_PT_rotation_angular_velocity(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Physics"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -721,7 +721,7 @@ class PARTICLE_PT_physics_fluid_advanced(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Advanced"
|
||||
bl_parent_id = "PARTICLE_PT_physics"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -766,7 +766,7 @@ class PARTICLE_PT_physics_fluid_springs(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Springs"
|
||||
bl_parent_id = "PARTICLE_PT_physics"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -790,7 +790,7 @@ class PARTICLE_PT_physics_fluid_springs_viscoelastic(ParticleButtonsPanel, Panel
|
||||
bl_label = "Viscoelastic Springs"
|
||||
bl_parent_id = "PARTICLE_PT_physics_fluid_springs"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -826,7 +826,7 @@ class PARTICLE_PT_physics_fluid_springs_advanced(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Advanced"
|
||||
bl_parent_id = "PARTICLE_PT_physics_fluid_springs"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -850,7 +850,7 @@ class PARTICLE_PT_physics_boids_movement(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Movement"
|
||||
bl_parent_id = "PARTICLE_PT_physics"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -903,7 +903,7 @@ class PARTICLE_PT_physics_boids_battle(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Battle"
|
||||
bl_parent_id = "PARTICLE_PT_physics"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -930,7 +930,7 @@ class PARTICLE_PT_physics_boids_misc(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Misc"
|
||||
bl_parent_id = "PARTICLE_PT_physics"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -955,7 +955,7 @@ class PARTICLE_PT_physics_relations(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Relations"
|
||||
bl_parent_id = "PARTICLE_PT_physics"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1010,7 +1010,7 @@ class PARTICLE_PT_physics_fluid_interaction(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Fluid Interaction"
|
||||
bl_parent_id = "PARTICLE_PT_physics"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1051,7 +1051,7 @@ class PARTICLE_PT_physics_deflection(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Deflection"
|
||||
bl_parent_id = "PARTICLE_PT_physics"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1077,7 +1077,7 @@ class PARTICLE_PT_physics_deflection(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_physics_forces(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Forces"
|
||||
bl_parent_id = "PARTICLE_PT_physics"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1104,7 +1104,7 @@ class PARTICLE_PT_physics_integration(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Integration"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_parent_id = "PARTICLE_PT_physics"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1138,7 +1138,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel):
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_parent_id = "PARTICLE_PT_physics"
|
||||
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1236,7 +1236,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Render"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1283,7 +1283,7 @@ class PARTICLE_PT_render_extra(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Extra"
|
||||
bl_parent_id = "PARTICLE_PT_render"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1307,7 +1307,7 @@ class PARTICLE_PT_render_extra(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_render_path(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Path"
|
||||
bl_parent_id = "PARTICLE_PT_render"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1329,7 +1329,7 @@ class PARTICLE_PT_render_path_timing(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Timing"
|
||||
bl_parent_id = "PARTICLE_PT_render"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1357,7 +1357,7 @@ class PARTICLE_PT_render_path_timing(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_render_object(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Object"
|
||||
bl_parent_id = "PARTICLE_PT_render"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1382,7 +1382,7 @@ class PARTICLE_PT_render_object(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_render_collection(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Collection"
|
||||
bl_parent_id = "PARTICLE_PT_render"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1412,7 +1412,7 @@ class PARTICLE_PT_render_collection_use_count(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Use Count"
|
||||
bl_parent_id = "PARTICLE_PT_render_collection"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1460,7 +1460,7 @@ class PARTICLE_PT_render_collection_use_count(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_draw(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Viewport Display"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1519,7 +1519,7 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Children"
|
||||
bl_translation_context = i18n_contexts.id_particlesettings
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1572,7 +1572,7 @@ class PARTICLE_PT_children_parting(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Parting"
|
||||
bl_parent_id = "PARTICLE_PT_children"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1603,7 +1603,7 @@ class PARTICLE_PT_children_clumping(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Clumping"
|
||||
bl_parent_id = "PARTICLE_PT_children"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1639,7 +1639,7 @@ class PARTICLE_PT_children_clumping_noise(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Clump Noise"
|
||||
bl_parent_id = "PARTICLE_PT_children_clumping"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
|
||||
@@ -1663,7 +1663,7 @@ class PARTICLE_PT_children_roughness(ParticleButtonsPanel, Panel):
|
||||
bl_translation_context = i18n_contexts.id_particlesettings
|
||||
bl_parent_id = "PARTICLE_PT_children"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1704,7 +1704,7 @@ class PARTICLE_PT_children_kink(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Kink"
|
||||
bl_parent_id = "PARTICLE_PT_children"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1754,7 +1754,7 @@ class PARTICLE_PT_children_kink(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Field Weights"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1775,7 +1775,7 @@ class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Force Field Settings"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -1791,7 +1791,7 @@ class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_force_fields_type1(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Type 1"
|
||||
bl_parent_id = "PARTICLE_PT_force_fields"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -1808,7 +1808,7 @@ class PARTICLE_PT_force_fields_type1(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_force_fields_type2(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Type 2"
|
||||
bl_parent_id = "PARTICLE_PT_force_fields"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -1826,7 +1826,7 @@ class PARTICLE_PT_force_fields_type1_falloff(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Falloff"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_parent_id = "PARTICLE_PT_force_fields_type1"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -1842,7 +1842,7 @@ class PARTICLE_PT_force_fields_type2_falloff(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Falloff"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_parent_id = "PARTICLE_PT_force_fields_type2"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -1857,7 +1857,7 @@ class PARTICLE_PT_force_fields_type2_falloff(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Vertex Groups"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1946,7 +1946,7 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_textures(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Textures"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1978,7 +1978,7 @@ class PARTICLE_PT_textures(ParticleButtonsPanel, Panel):
|
||||
class PARTICLE_PT_hair_shape(ParticleButtonsPanel, Panel):
|
||||
bl_label = "Hair Shape"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -2006,7 +2006,7 @@ class PARTICLE_PT_hair_shape(ParticleButtonsPanel, Panel):
|
||||
|
||||
|
||||
class PARTICLE_PT_custom_props(ParticleButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "particle_system.settings"
|
||||
_property_type = bpy.types.ParticleSettings
|
||||
|
||||
|
@@ -35,7 +35,7 @@ class PhysicButtonsPanel:
|
||||
|
||||
class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Cloth"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header_preset(self, _context):
|
||||
CLOTH_PT_presets.draw_panel_header(self.layout)
|
||||
@@ -60,7 +60,7 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_cloth_physical_properties(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Physical Properties"
|
||||
bl_parent_id = 'PHYSICS_PT_cloth'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -84,7 +84,7 @@ class PHYSICS_PT_cloth_physical_properties(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Stiffness"
|
||||
bl_parent_id = 'PHYSICS_PT_cloth_physical_properties'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -115,7 +115,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_cloth_damping(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Damping"
|
||||
bl_parent_id = 'PHYSICS_PT_cloth_physical_properties'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -146,7 +146,7 @@ class PHYSICS_PT_cloth_damping(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_cloth_internal_springs(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Internal Springs"
|
||||
bl_parent_id = 'PHYSICS_PT_cloth_physical_properties'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
cloth = context.cloth.settings
|
||||
@@ -188,7 +188,7 @@ class PHYSICS_PT_cloth_internal_springs(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_cloth_pressure(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Pressure"
|
||||
bl_parent_id = 'PHYSICS_PT_cloth_physical_properties'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
cloth = context.cloth.settings
|
||||
@@ -232,7 +232,7 @@ class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Cache"
|
||||
bl_parent_id = 'PHYSICS_PT_cloth'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
md = context.cloth
|
||||
@@ -243,7 +243,7 @@ class PHYSICS_PT_cloth_shape(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Shape"
|
||||
bl_parent_id = 'PHYSICS_PT_cloth'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -293,7 +293,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Collisions"
|
||||
bl_parent_id = 'PHYSICS_PT_cloth'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -313,7 +313,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_cloth_object_collision(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Object Collisions"
|
||||
bl_parent_id = 'PHYSICS_PT_cloth_collision'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
cloth = context.cloth.collision_settings
|
||||
@@ -349,7 +349,7 @@ class PHYSICS_PT_cloth_object_collision(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_cloth_self_collision(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Self Collisions"
|
||||
bl_parent_id = 'PHYSICS_PT_cloth_collision'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
cloth = context.cloth.collision_settings
|
||||
@@ -386,7 +386,7 @@ class PHYSICS_PT_cloth_property_weights(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Property Weights"
|
||||
bl_parent_id = 'PHYSICS_PT_cloth'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -440,7 +440,7 @@ class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Field Weights"
|
||||
bl_parent_id = 'PHYSICS_PT_cloth'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
cloth = context.cloth.settings
|
||||
|
@@ -50,7 +50,7 @@ def physics_add_special(layout, data, name, addop, removeop, typeicon):
|
||||
class PHYSICS_PT_add(PhysicButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@@ -83,7 +83,7 @@ class PhysicButtonsPanel:
|
||||
|
||||
class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Dynamic Paint"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -104,7 +104,7 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_dynamic_paint_settings(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Settings"
|
||||
bl_parent_id = 'PHYSICS_PT_dynamic_paint'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -188,7 +188,7 @@ class PHYSICS_PT_dynamic_paint_settings(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_dp_surface_canvas(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Surface"
|
||||
bl_parent_id = "PHYSICS_PT_dynamic_paint"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -251,7 +251,7 @@ class PHYSICS_PT_dp_surface_canvas_paint_dry(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Dry"
|
||||
bl_parent_id = "PHYSICS_PT_dp_surface_canvas"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -287,7 +287,7 @@ class PHYSICS_PT_dp_surface_canvas_paint_dissolve(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Dissolve"
|
||||
bl_parent_id = "PHYSICS_PT_dp_surface_canvas"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -324,7 +324,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Output"
|
||||
bl_parent_id = "PHYSICS_PT_dynamic_paint"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -400,7 +400,7 @@ class PHYSICS_PT_dp_canvas_output_paintmaps(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Paintmaps"
|
||||
bl_parent_id = "PHYSICS_PT_dp_canvas_output"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -430,7 +430,7 @@ class PHYSICS_PT_dp_canvas_output_wetmaps(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Wetmaps"
|
||||
bl_parent_id = "PHYSICS_PT_dp_canvas_output"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -460,7 +460,7 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Initial Color"
|
||||
bl_parent_id = "PHYSICS_PT_dynamic_paint"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -500,7 +500,7 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Effects"
|
||||
bl_parent_id = 'PHYSICS_PT_dynamic_paint'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -517,7 +517,7 @@ class PHYSICS_PT_dp_effects_spread(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Spread"
|
||||
bl_parent_id = "PHYSICS_PT_dp_effects"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -552,7 +552,7 @@ class PHYSICS_PT_dp_effects_drip(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Drip"
|
||||
bl_parent_id = "PHYSICS_PT_dp_effects"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -588,7 +588,7 @@ class PHYSICS_PT_dp_effects_drip_weights(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Weights"
|
||||
bl_parent_id = "PHYSICS_PT_dp_effects_drip"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -612,7 +612,7 @@ class PHYSICS_PT_dp_effects_shrink(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Shrink"
|
||||
bl_parent_id = "PHYSICS_PT_dp_effects"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -642,7 +642,7 @@ class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Cache"
|
||||
bl_parent_id = "PHYSICS_PT_dynamic_paint"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -662,7 +662,7 @@ class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Source"
|
||||
bl_parent_id = "PHYSICS_PT_dynamic_paint"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -725,7 +725,7 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_dp_brush_source_color_ramp(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Falloff Ramp"
|
||||
bl_parent_id = "PHYSICS_PT_dp_brush_source"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -752,7 +752,7 @@ class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Velocity"
|
||||
bl_parent_id = "PHYSICS_PT_dynamic_paint"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -783,7 +783,7 @@ class PHYSICS_PT_dp_brush_velocity_color_ramp(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Ramp"
|
||||
bl_parent_id = "PHYSICS_PT_dp_brush_velocity"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -804,7 +804,7 @@ class PHYSICS_PT_dp_brush_velocity_smudge(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Smudge"
|
||||
bl_parent_id = "PHYSICS_PT_dp_brush_velocity"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -832,7 +832,7 @@ class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Waves"
|
||||
bl_parent_id = "PHYSICS_PT_dynamic_paint"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
@@ -27,7 +27,7 @@ class PhysicButtonsPanel:
|
||||
|
||||
class PHYSICS_PT_field(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Force Fields"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -49,7 +49,7 @@ class PHYSICS_PT_field(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Settings"
|
||||
bl_parent_id = 'PHYSICS_PT_field'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -136,7 +136,7 @@ class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_field_settings_kink(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Kink"
|
||||
bl_parent_id = 'PHYSICS_PT_field_settings'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -170,7 +170,7 @@ class PHYSICS_PT_field_settings_kink(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_field_settings_texture_select(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Texture"
|
||||
bl_parent_id = 'PHYSICS_PT_field_settings'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -192,7 +192,7 @@ class PHYSICS_PT_field_settings_texture_select(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_field_falloff(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Falloff"
|
||||
bl_parent_id = "PHYSICS_PT_field"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -217,7 +217,7 @@ class PHYSICS_PT_field_falloff(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Angular"
|
||||
bl_parent_id = "PHYSICS_PT_field_falloff"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -256,7 +256,7 @@ class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_field_falloff_radial(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Radial"
|
||||
bl_parent_id = "PHYSICS_PT_field_falloff"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -300,7 +300,7 @@ def collision_warning(layout):
|
||||
|
||||
class PHYSICS_PT_collision(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Collision"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -331,7 +331,7 @@ class PHYSICS_PT_collision(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Particle"
|
||||
bl_parent_id = "PHYSICS_PT_collision"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -377,7 +377,7 @@ class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_collision_softbody(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Softbody & Cloth"
|
||||
bl_parent_id = "PHYSICS_PT_collision"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
@@ -98,7 +98,7 @@ class PhysicButtonsPanel:
|
||||
|
||||
class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Fluid"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -122,7 +122,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_settings(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Settings"
|
||||
bl_parent_id = 'PHYSICS_PT_fluid'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -285,7 +285,7 @@ class PHYSICS_PT_settings(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_borders(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Border Collisions"
|
||||
bl_parent_id = 'PHYSICS_PT_settings'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -318,7 +318,7 @@ class PHYSICS_PT_borders(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Gas"
|
||||
bl_parent_id = 'PHYSICS_PT_fluid'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -351,7 +351,7 @@ class PHYSICS_PT_smoke_dissolve(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Dissolve"
|
||||
bl_parent_id = 'PHYSICS_PT_smoke'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -395,7 +395,7 @@ class PHYSICS_PT_fire(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Fire"
|
||||
bl_parent_id = 'PHYSICS_PT_smoke'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -434,7 +434,7 @@ class PHYSICS_PT_fire(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_liquid(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Liquid"
|
||||
bl_parent_id = 'PHYSICS_PT_fluid'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -497,7 +497,7 @@ class PHYSICS_PT_flow_source(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Flow Source"
|
||||
bl_parent_id = 'PHYSICS_PT_settings'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -538,7 +538,7 @@ class PHYSICS_PT_flow_source(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_flow_initial_velocity(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Initial Velocity"
|
||||
bl_parent_id = 'PHYSICS_PT_settings'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -580,7 +580,7 @@ class PHYSICS_PT_flow_texture(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Texture"
|
||||
bl_parent_id = 'PHYSICS_PT_settings'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -631,7 +631,7 @@ class PHYSICS_PT_adaptive_domain(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Adaptive Domain"
|
||||
bl_parent_id = 'PHYSICS_PT_settings'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -683,7 +683,7 @@ class PHYSICS_PT_noise(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Noise"
|
||||
bl_parent_id = 'PHYSICS_PT_smoke'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -763,7 +763,7 @@ class PHYSICS_PT_mesh(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Mesh"
|
||||
bl_parent_id = 'PHYSICS_PT_liquid'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -858,7 +858,7 @@ class PHYSICS_PT_particles(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Particles"
|
||||
bl_parent_id = 'PHYSICS_PT_liquid'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -989,7 +989,7 @@ class PHYSICS_PT_viscosity(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Viscosity"
|
||||
bl_parent_id = 'PHYSICS_PT_liquid'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1029,7 +1029,7 @@ class PHYSICS_PT_diffusion(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Diffusion"
|
||||
bl_parent_id = 'PHYSICS_PT_liquid'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1076,7 +1076,7 @@ class PHYSICS_PT_guide(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Guides"
|
||||
bl_parent_id = 'PHYSICS_PT_fluid'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1142,7 +1142,7 @@ class PHYSICS_PT_collections(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Collections"
|
||||
bl_parent_id = 'PHYSICS_PT_fluid'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1169,7 +1169,7 @@ class PHYSICS_PT_collections(PhysicButtonsPanel, Panel):
|
||||
class PHYSICS_PT_cache(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Cache"
|
||||
bl_parent_id = 'PHYSICS_PT_fluid'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1253,7 +1253,7 @@ class PHYSICS_PT_export(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Advanced"
|
||||
bl_parent_id = 'PHYSICS_PT_cache'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1298,7 +1298,7 @@ class PHYSICS_PT_field_weights(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Field Weights"
|
||||
bl_parent_id = 'PHYSICS_PT_fluid'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1487,7 +1487,7 @@ class PHYSICS_PT_fluid_domain_render(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Render"
|
||||
bl_parent_id = 'PHYSICS_PT_fluid'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
@@ -19,7 +19,7 @@ class PHYSICS_PT_rigidbody_panel:
|
||||
|
||||
class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel):
|
||||
bl_label = "Rigid Body"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -54,7 +54,7 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel):
|
||||
class PHYSICS_PT_rigid_body_settings(PHYSICS_PT_rigidbody_panel, Panel):
|
||||
bl_label = "Settings"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -86,7 +86,7 @@ class PHYSICS_PT_rigid_body_settings(PHYSICS_PT_rigidbody_panel, Panel):
|
||||
class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel):
|
||||
bl_label = "Collisions"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -136,7 +136,7 @@ class PHYSICS_PT_rigid_body_collisions_surface(PHYSICS_PT_rigidbody_panel, Panel
|
||||
bl_label = "Surface Response"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_collisions'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -164,7 +164,7 @@ class PHYSICS_PT_rigid_body_collisions_sensitivity(PHYSICS_PT_rigidbody_panel, P
|
||||
bl_label = "Sensitivity"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_collisions'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -201,7 +201,7 @@ class PHYSICS_PT_rigid_body_collisions_collections(PHYSICS_PT_rigidbody_panel, P
|
||||
bl_label = "Collections"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_collisions'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -223,7 +223,7 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel):
|
||||
bl_label = "Dynamics"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -256,7 +256,7 @@ class PHYSICS_PT_rigid_body_dynamics_deactivation(PHYSICS_PT_rigidbody_panel, Pa
|
||||
bl_label = "Deactivation"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_dynamics'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
@@ -13,7 +13,7 @@ class PHYSICS_PT_rigidbody_constraint_panel:
|
||||
|
||||
class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Panel):
|
||||
bl_label = "Rigid Body Constraint"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -33,7 +33,7 @@ class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Pa
|
||||
class PHYSICS_PT_rigid_body_constraint_settings(PHYSICS_PT_rigidbody_constraint_panel, Panel):
|
||||
bl_label = "Settings"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_constraint'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -64,7 +64,7 @@ class PHYSICS_PT_rigid_body_constraint_settings(PHYSICS_PT_rigidbody_constraint_
|
||||
class PHYSICS_PT_rigid_body_constraint_objects(PHYSICS_PT_rigidbody_constraint_panel, Panel):
|
||||
bl_label = "Objects"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_constraint'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -85,7 +85,7 @@ class PHYSICS_PT_rigid_body_constraint_objects(PHYSICS_PT_rigidbody_constraint_p
|
||||
class PHYSICS_PT_rigid_body_constraint_override_iterations(PHYSICS_PT_rigidbody_constraint_panel, Panel):
|
||||
bl_label = "Override Iterations"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_constraint'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -111,7 +111,7 @@ class PHYSICS_PT_rigid_body_constraint_override_iterations(PHYSICS_PT_rigidbody_
|
||||
class PHYSICS_PT_rigid_body_constraint_limits(PHYSICS_PT_rigidbody_constraint_panel, Panel):
|
||||
bl_label = "Limits"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_constraint'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -128,7 +128,7 @@ class PHYSICS_PT_rigid_body_constraint_limits(PHYSICS_PT_rigidbody_constraint_pa
|
||||
class PHYSICS_PT_rigid_body_constraint_limits_linear(PHYSICS_PT_rigidbody_constraint_panel, Panel):
|
||||
bl_label = "Linear"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_limits'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -185,7 +185,7 @@ class PHYSICS_PT_rigid_body_constraint_limits_linear(PHYSICS_PT_rigidbody_constr
|
||||
class PHYSICS_PT_rigid_body_constraint_limits_angular(PHYSICS_PT_rigidbody_constraint_panel, Panel):
|
||||
bl_label = "Angular"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_limits'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -251,7 +251,7 @@ class PHYSICS_PT_rigid_body_constraint_limits_angular(PHYSICS_PT_rigidbody_const
|
||||
class PHYSICS_PT_rigid_body_constraint_motor(PHYSICS_PT_rigidbody_constraint_panel, Panel):
|
||||
bl_label = "Motor"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_constraint'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -268,7 +268,7 @@ class PHYSICS_PT_rigid_body_constraint_motor(PHYSICS_PT_rigidbody_constraint_pan
|
||||
class PHYSICS_PT_rigid_body_constraint_motor_angular(PHYSICS_PT_rigidbody_constraint_panel, Panel):
|
||||
bl_label = "Angular"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_motor'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -304,7 +304,7 @@ class PHYSICS_PT_rigid_body_constraint_motor_angular(PHYSICS_PT_rigidbody_constr
|
||||
class PHYSICS_PT_rigid_body_constraint_motor_linear(PHYSICS_PT_rigidbody_constraint_panel, Panel):
|
||||
bl_label = "Linear"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_motor'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -340,7 +340,7 @@ class PHYSICS_PT_rigid_body_constraint_motor_linear(PHYSICS_PT_rigidbody_constra
|
||||
class PHYSICS_PT_rigid_body_constraint_springs(PHYSICS_PT_rigidbody_constraint_panel, Panel):
|
||||
bl_label = "Springs"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_constraint'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -364,7 +364,7 @@ class PHYSICS_PT_rigid_body_constraint_springs(PHYSICS_PT_rigidbody_constraint_p
|
||||
class PHYSICS_PT_rigid_body_constraint_springs_angular(PHYSICS_PT_rigidbody_constraint_panel, Panel):
|
||||
bl_label = "Angular"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_springs'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -412,7 +412,7 @@ class PHYSICS_PT_rigid_body_constraint_springs_angular(PHYSICS_PT_rigidbody_cons
|
||||
class PHYSICS_PT_rigid_body_constraint_springs_linear(PHYSICS_PT_rigidbody_constraint_panel, Panel):
|
||||
bl_label = "Linear"
|
||||
bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_springs'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
@@ -28,7 +28,7 @@ class PhysicButtonsPanel:
|
||||
|
||||
class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Soft Body"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -44,7 +44,7 @@ class PHYSICS_PT_softbody_object(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Object"
|
||||
bl_parent_id = 'PHYSICS_PT_softbody'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -72,7 +72,7 @@ class PHYSICS_PT_softbody_simulation(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Simulation"
|
||||
bl_parent_id = 'PHYSICS_PT_softbody'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -90,7 +90,7 @@ class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Cache"
|
||||
bl_parent_id = 'PHYSICS_PT_softbody'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
md = context.soft_body
|
||||
@@ -101,7 +101,7 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Goal"
|
||||
bl_parent_id = 'PHYSICS_PT_softbody'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
softbody = context.soft_body.settings
|
||||
@@ -126,7 +126,7 @@ class PHYSICS_PT_softbody_goal_strengths(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Strengths"
|
||||
bl_parent_id = 'PHYSICS_PT_softbody_goal'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -152,7 +152,7 @@ class PHYSICS_PT_softbody_goal_settings(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Settings"
|
||||
bl_parent_id = 'PHYSICS_PT_softbody_goal'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -175,7 +175,7 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Edges"
|
||||
bl_parent_id = 'PHYSICS_PT_softbody'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
softbody = context.soft_body.settings
|
||||
@@ -226,7 +226,7 @@ class PHYSICS_PT_softbody_edge_aerodynamics(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Aerodynamics"
|
||||
bl_parent_id = 'PHYSICS_PT_softbody_edge'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -249,7 +249,7 @@ class PHYSICS_PT_softbody_edge_stiffness(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Stiffness"
|
||||
bl_parent_id = 'PHYSICS_PT_softbody_edge'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
softbody = context.soft_body.settings
|
||||
@@ -273,7 +273,7 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Self Collision"
|
||||
bl_parent_id = 'PHYSICS_PT_softbody'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
softbody = context.soft_body.settings
|
||||
@@ -308,7 +308,7 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Solver"
|
||||
bl_parent_id = 'PHYSICS_PT_softbody'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -333,7 +333,7 @@ class PHYSICS_PT_softbody_solver_diagnostics(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Diagnostics"
|
||||
bl_parent_id = 'PHYSICS_PT_softbody_solver'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -352,7 +352,7 @@ class PHYSICS_PT_softbody_solver_helpers(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Helpers"
|
||||
bl_parent_id = 'PHYSICS_PT_softbody_solver'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -375,7 +375,7 @@ class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel, Panel):
|
||||
bl_label = "Field Weights"
|
||||
bl_parent_id = 'PHYSICS_PT_softbody'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
md = context.soft_body
|
||||
|
@@ -47,7 +47,7 @@ class RENDER_PT_color_management(RenderButtonsPanel, Panel):
|
||||
bl_label = "Color Management"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_order = 100
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -80,7 +80,7 @@ class RENDER_PT_color_management_curves(RenderButtonsPanel, Panel):
|
||||
bl_label = "Use Curves"
|
||||
bl_parent_id = "RENDER_PT_color_management"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
|
||||
@@ -640,7 +640,7 @@ class RENDER_PT_eevee_hair(RenderButtonsPanel, Panel):
|
||||
class RENDER_PT_eevee_performance(RenderButtonsPanel, Panel):
|
||||
bl_label = "Performance"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -661,7 +661,7 @@ class RENDER_PT_gpencil(RenderButtonsPanel, Panel):
|
||||
bl_label = "Grease Pencil"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_order = 10
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -677,7 +677,7 @@ class RENDER_PT_gpencil(RenderButtonsPanel, Panel):
|
||||
|
||||
class RENDER_PT_opengl_sampling(RenderButtonsPanel, Panel):
|
||||
bl_label = "Sampling"
|
||||
COMPAT_ENGINES = {'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -699,7 +699,7 @@ class RENDER_PT_opengl_sampling(RenderButtonsPanel, Panel):
|
||||
class RENDER_PT_opengl_film(RenderButtonsPanel, Panel):
|
||||
bl_label = "Film"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -712,7 +712,7 @@ class RENDER_PT_opengl_film(RenderButtonsPanel, Panel):
|
||||
|
||||
class RENDER_PT_opengl_lighting(RenderButtonsPanel, Panel):
|
||||
bl_label = "Lighting"
|
||||
COMPAT_ENGINES = {'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -724,7 +724,7 @@ class RENDER_PT_opengl_lighting(RenderButtonsPanel, Panel):
|
||||
|
||||
class RENDER_PT_opengl_color(RenderButtonsPanel, Panel):
|
||||
bl_label = "Color"
|
||||
COMPAT_ENGINES = {'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -736,7 +736,7 @@ class RENDER_PT_opengl_color(RenderButtonsPanel, Panel):
|
||||
|
||||
class RENDER_PT_opengl_options(RenderButtonsPanel, Panel):
|
||||
bl_label = "Options"
|
||||
COMPAT_ENGINES = {'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -749,7 +749,7 @@ class RENDER_PT_opengl_options(RenderButtonsPanel, Panel):
|
||||
class RENDER_PT_simplify(RenderButtonsPanel, Panel):
|
||||
bl_label = "Simplify"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
rd = context.scene.render
|
||||
@@ -762,7 +762,7 @@ class RENDER_PT_simplify(RenderButtonsPanel, Panel):
|
||||
class RENDER_PT_simplify_viewport(RenderButtonsPanel, Panel):
|
||||
bl_label = "Viewport"
|
||||
bl_parent_id = "RENDER_PT_simplify"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -787,7 +787,7 @@ class RENDER_PT_simplify_viewport(RenderButtonsPanel, Panel):
|
||||
class RENDER_PT_simplify_render(RenderButtonsPanel, Panel):
|
||||
bl_label = "Render"
|
||||
bl_parent_id = "RENDER_PT_simplify"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -815,7 +815,7 @@ class RENDER_PT_simplify_greasepencil(RenderButtonsPanel, Panel, GreasePencilSim
|
||||
'BLENDER_CLAY',
|
||||
'BLENDER_EEVEE',
|
||||
'BLENDER_EEVEE_NEXT',
|
||||
'BLENDER_WORKBENCH',
|
||||
'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT',
|
||||
}
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
|
@@ -67,7 +67,7 @@ class TextureButtonsPanel:
|
||||
|
||||
class TEXTURE_PT_preview(TextureButtonsPanel, Panel):
|
||||
bl_label = "Preview"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -96,7 +96,7 @@ class TEXTURE_PT_context(TextureButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_context = "texture"
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -135,7 +135,7 @@ class TEXTURE_PT_context(TextureButtonsPanel, Panel):
|
||||
class TEXTURE_PT_node(TextureButtonsPanel, Panel):
|
||||
bl_label = "Node"
|
||||
bl_context = "texture"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -164,7 +164,7 @@ class TextureTypePanel(TextureButtonsPanel):
|
||||
class TEXTURE_PT_clouds(TextureTypePanel, Panel):
|
||||
bl_label = "Clouds"
|
||||
tex_type = 'CLOUDS'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -196,7 +196,7 @@ class TEXTURE_PT_clouds(TextureTypePanel, Panel):
|
||||
class TEXTURE_PT_wood(TextureTypePanel, Panel):
|
||||
bl_label = "Wood"
|
||||
tex_type = 'WOOD'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -233,7 +233,7 @@ class TEXTURE_PT_wood(TextureTypePanel, Panel):
|
||||
class TEXTURE_PT_marble(TextureTypePanel, Panel):
|
||||
bl_label = "Marble"
|
||||
tex_type = 'MARBLE'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -267,7 +267,7 @@ class TEXTURE_PT_marble(TextureTypePanel, Panel):
|
||||
class TEXTURE_PT_magic(TextureTypePanel, Panel):
|
||||
bl_label = "Magic"
|
||||
tex_type = 'MAGIC'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -286,7 +286,7 @@ class TEXTURE_PT_magic(TextureTypePanel, Panel):
|
||||
class TEXTURE_PT_blend(TextureTypePanel, Panel):
|
||||
bl_label = "Blend"
|
||||
tex_type = 'BLEND'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -308,7 +308,7 @@ class TEXTURE_PT_blend(TextureTypePanel, Panel):
|
||||
class TEXTURE_PT_stucci(TextureTypePanel, Panel):
|
||||
bl_label = "Stucci"
|
||||
tex_type = 'STUCCI'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -339,7 +339,7 @@ class TEXTURE_PT_stucci(TextureTypePanel, Panel):
|
||||
class TEXTURE_PT_image(TextureTypePanel, Panel):
|
||||
bl_label = "Image"
|
||||
tex_type = 'IMAGE'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, _context):
|
||||
# TODO: maybe expose the template_ID from the template image here.
|
||||
@@ -351,7 +351,7 @@ class TEXTURE_PT_image_settings(TextureTypePanel, Panel):
|
||||
bl_label = "Settings"
|
||||
bl_parent_id = 'TEXTURE_PT_image'
|
||||
tex_type = 'IMAGE'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -506,7 +506,7 @@ class TEXTURE_PT_image_mapping_crop(TextureTypePanel, Panel):
|
||||
class TEXTURE_PT_musgrave(TextureTypePanel, Panel):
|
||||
bl_label = "Musgrave"
|
||||
tex_type = 'MUSGRAVE'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -551,7 +551,7 @@ class TEXTURE_PT_musgrave(TextureTypePanel, Panel):
|
||||
class TEXTURE_PT_voronoi(TextureTypePanel, Panel):
|
||||
bl_label = "Voronoi"
|
||||
tex_type = 'VORONOI'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -584,7 +584,7 @@ class TEXTURE_PT_voronoi_feature_weights(TextureTypePanel, Panel):
|
||||
bl_label = "Feature Weights"
|
||||
bl_parent_id = "TEXTURE_PT_voronoi"
|
||||
tex_type = 'VORONOI'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -605,7 +605,7 @@ class TEXTURE_PT_voronoi_feature_weights(TextureTypePanel, Panel):
|
||||
class TEXTURE_PT_distortednoise(TextureTypePanel, Panel):
|
||||
bl_label = "Distorted Noise"
|
||||
tex_type = 'DISTORTED_NOISE'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -630,7 +630,7 @@ class TEXTURE_PT_distortednoise(TextureTypePanel, Panel):
|
||||
|
||||
|
||||
class TextureSlotPanel(TextureButtonsPanel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -642,7 +642,7 @@ class TextureSlotPanel(TextureButtonsPanel):
|
||||
|
||||
class TEXTURE_PT_mapping(TextureSlotPanel, Panel):
|
||||
bl_label = "Mapping"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -710,7 +710,7 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel):
|
||||
class TEXTURE_PT_influence(TextureSlotPanel, Panel):
|
||||
bl_label = "Influence"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -792,7 +792,7 @@ class TextureColorsPoll:
|
||||
class TEXTURE_PT_colors(TextureButtonsPanel, TextureColorsPoll, Panel):
|
||||
bl_label = "Colors"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -821,7 +821,7 @@ class TEXTURE_PT_colors_ramp(TextureButtonsPanel, TextureColorsPoll, Panel):
|
||||
bl_label = "Color Ramp"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_parent_id = 'TEXTURE_PT_colors'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
tex = context.texture
|
||||
@@ -842,7 +842,7 @@ class TEXTURE_PT_colors_ramp(TextureButtonsPanel, TextureColorsPoll, Panel):
|
||||
|
||||
|
||||
class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "texture"
|
||||
_property_type = Texture
|
||||
|
||||
|
@@ -26,7 +26,7 @@ class ViewLayerButtonsPanel:
|
||||
|
||||
class VIEWLAYER_PT_layer(ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "View Layer"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -44,7 +44,7 @@ class VIEWLAYER_PT_layer(ViewLayerButtonsPanel, Panel):
|
||||
|
||||
class VIEWLAYER_PT_layer_passes(ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "Passes"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
@@ -94,6 +94,23 @@ class VIEWLAYER_PT_eevee_next_layer_passes_data(ViewLayerButtonsPanel, Panel):
|
||||
sub.active = not scene.eevee.use_motion_blur
|
||||
sub.prop(view_layer, "use_pass_vector")
|
||||
|
||||
class VIEWLAYER_PT_eevee_next_layer_passes_data(ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "Data"
|
||||
bl_parent_id = "VIEWLAYER_PT_layer_passes"
|
||||
|
||||
COMPAT_ENGINES = {'BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
view_layer = context.view_layer
|
||||
|
||||
col = layout.column()
|
||||
col.prop(view_layer, "use_pass_combined")
|
||||
col.prop(view_layer, "use_pass_z")
|
||||
|
||||
|
||||
class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "Light"
|
||||
|
@@ -19,7 +19,7 @@ class WorldButtonsPanel:
|
||||
class WORLD_PT_context_world(WorldButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -63,7 +63,7 @@ class EEVEE_WORLD_PT_mist(WorldButtonsPanel, Panel):
|
||||
|
||||
|
||||
class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "world"
|
||||
_property_type = bpy.types.World
|
||||
|
||||
|
@@ -670,7 +670,7 @@ class NODE_PT_texture_mapping(Panel):
|
||||
bl_category = "Node"
|
||||
bl_label = "Texture Mapping"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
@@ -2607,7 +2607,7 @@ class SEQUENCER_PT_annotation_onion(AnnotationOnionSkin, SequencerButtonsPanel_O
|
||||
|
||||
|
||||
class SEQUENCER_PT_custom_props(SequencerButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}
|
||||
_context_path = "active_sequence_strip"
|
||||
_property_type = (bpy.types.Sequence,)
|
||||
bl_category = "Strip"
|
||||
|
@@ -2339,6 +2339,7 @@ class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel):
|
||||
({"property": "use_sculpt_texture_paint"}, "T96225"),
|
||||
({"property": "use_full_frame_compositor"}, "T88150"),
|
||||
({"property": "enable_eevee_next"}, "T93220"),
|
||||
({"property": "enable_workbench_next"}, "T101619"),
|
||||
),
|
||||
)
|
||||
|
||||
|
@@ -158,15 +158,26 @@ set(SRC
|
||||
engines/eevee_next/eevee_world.cc
|
||||
engines/workbench/workbench_data.c
|
||||
engines/workbench/workbench_effect_antialiasing.c
|
||||
engines/workbench/workbench_effect_antialiasing.cc
|
||||
engines/workbench/workbench_effect_cavity.c
|
||||
engines/workbench/workbench_effect_cavity.cc
|
||||
engines/workbench/workbench_effect_dof.c
|
||||
engines/workbench/workbench_effect_dof.cc
|
||||
engines/workbench/workbench_effect_outline.c
|
||||
engines/workbench/workbench_effect_outline.cc
|
||||
engines/workbench/workbench_engine.c
|
||||
engines/workbench/workbench_engine.cc
|
||||
engines/workbench/workbench_materials.cc
|
||||
engines/workbench/workbench_materials_next.cc
|
||||
engines/workbench/workbench_mesh_passes.cc
|
||||
engines/workbench/workbench_opaque.c
|
||||
engines/workbench/workbench_render.c
|
||||
engines/workbench/workbench_resources.cc
|
||||
engines/workbench/workbench_shader.cc
|
||||
engines/workbench/workbench_shader_cache.cc
|
||||
engines/workbench/workbench_shadow.c
|
||||
engines/workbench/workbench_shadow.cc
|
||||
engines/workbench/workbench_state.cc
|
||||
engines/workbench/workbench_transparent.c
|
||||
engines/workbench/workbench_volume.c
|
||||
engines/external/external_engine.c
|
||||
@@ -290,8 +301,11 @@ set(SRC
|
||||
engines/image/image_space_node.hh
|
||||
engines/image/image_texture_info.hh
|
||||
engines/image/image_usage.hh
|
||||
engines/workbench/workbench_defines.hh
|
||||
engines/workbench/workbench_engine.h
|
||||
engines/workbench/workbench_enums.hh
|
||||
engines/workbench/workbench_private.h
|
||||
engines/workbench/workbench_private.hh
|
||||
engines/workbench/workbench_shader_shared.h
|
||||
engines/select/select_engine.h
|
||||
engines/select/select_private.h
|
||||
@@ -462,6 +476,7 @@ set(GLSL_SRC
|
||||
engines/workbench/shaders/workbench_cavity_lib.glsl
|
||||
engines/workbench/shaders/workbench_common_lib.glsl
|
||||
engines/workbench/shaders/workbench_composite_frag.glsl
|
||||
engines/workbench/shaders/workbench_next_composite_frag.glsl
|
||||
engines/workbench/shaders/workbench_curvature_lib.glsl
|
||||
engines/workbench/shaders/workbench_effect_cavity_frag.glsl
|
||||
engines/workbench/shaders/workbench_effect_dof_frag.glsl
|
||||
@@ -473,6 +488,7 @@ set(GLSL_SRC
|
||||
engines/workbench/shaders/workbench_matcap_lib.glsl
|
||||
engines/workbench/shaders/workbench_material_lib.glsl
|
||||
engines/workbench/shaders/workbench_merge_infront_frag.glsl
|
||||
engines/workbench/shaders/workbench_next_merge_depth_frag.glsl
|
||||
engines/workbench/shaders/workbench_prepass_frag.glsl
|
||||
engines/workbench/shaders/workbench_prepass_hair_vert.glsl
|
||||
engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl
|
||||
@@ -482,6 +498,7 @@ set(GLSL_SRC
|
||||
engines/workbench/shaders/workbench_shadow_debug_frag.glsl
|
||||
engines/workbench/shaders/workbench_shadow_geom.glsl
|
||||
engines/workbench/shaders/workbench_shadow_vert.glsl
|
||||
engines/workbench/shaders/workbench_shadow_visibility_comp.glsl
|
||||
engines/workbench/shaders/workbench_shadow_vert_no_geom.glsl
|
||||
engines/workbench/shaders/workbench_transparent_accum_frag.glsl
|
||||
engines/workbench/shaders/workbench_transparent_resolve_frag.glsl
|
||||
@@ -689,6 +706,7 @@ set(GLSL_SRC
|
||||
)
|
||||
|
||||
set(GLSL_C)
|
||||
|
||||
foreach(GLSL_FILE ${GLSL_SRC})
|
||||
data_to_c_simple(${GLSL_FILE} GLSL_C)
|
||||
endforeach()
|
||||
@@ -700,6 +718,7 @@ list(APPEND LIB
|
||||
)
|
||||
|
||||
set(GLSL_SOURCE_CONTENT "")
|
||||
|
||||
foreach(GLSL_FILE ${GLSL_SRC})
|
||||
get_filename_component(GLSL_FILE_NAME ${GLSL_FILE} NAME)
|
||||
string(REPLACE "." "_" GLSL_FILE_NAME_UNDERSCORES ${GLSL_FILE_NAME})
|
||||
@@ -746,11 +765,13 @@ endif()
|
||||
|
||||
if(WITH_TBB)
|
||||
add_definitions(-DWITH_TBB)
|
||||
|
||||
if(WIN32)
|
||||
# TBB includes Windows.h which will define min/max macros
|
||||
# that will collide with the stl versions.
|
||||
add_definitions(-DNOMINMAX)
|
||||
endif()
|
||||
|
||||
list(APPEND INC_SYS
|
||||
${TBB_INCLUDE_DIRS}
|
||||
)
|
||||
|
@@ -1,15 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
#include "workbench_defines.hh"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Base Composite
|
||||
* \{ */
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_composite)
|
||||
.sampler(0, ImageType::FLOAT_2D, "normalBuffer", Frequency::PASS)
|
||||
.sampler(1, ImageType::FLOAT_2D, "materialBuffer", Frequency::PASS)
|
||||
.uniform_buf(4, "WorldData", "world_data", Frequency::PASS)
|
||||
.sampler(0, ImageType::FLOAT_2D, "normalBuffer")
|
||||
.sampler(1, ImageType::FLOAT_2D, "materialBuffer")
|
||||
.uniform_buf(WB_WORLD_SLOT, "WorldData", "world_data")
|
||||
.push_constant(Type::BOOL, "forceShadowing")
|
||||
.fragment_out(0, Type::VEC4, "fragColor")
|
||||
.typedef_source("workbench_shader_shared.h")
|
||||
@@ -23,20 +24,88 @@ GPU_SHADER_CREATE_INFO(workbench_composite)
|
||||
* \{ */
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_composite_studio)
|
||||
.define("V3D_LIGHTING_STUDIO")
|
||||
.define("WORKBENCH_LIGHTING_STUDIO")
|
||||
.additional_info("workbench_composite")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_composite_matcap)
|
||||
.define("V3D_LIGHTING_MATCAP")
|
||||
.sampler(2, ImageType::FLOAT_2D, "matcap_diffuse_tx", Frequency::PASS)
|
||||
.sampler(3, ImageType::FLOAT_2D, "matcap_specular_tx", Frequency::PASS)
|
||||
.define("WORKBENCH_LIGHTING_MATCAP")
|
||||
.sampler(2, ImageType::FLOAT_2D, "matcap_diffuse_tx")
|
||||
.sampler(3, ImageType::FLOAT_2D, "matcap_specular_tx")
|
||||
.additional_info("workbench_composite")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_composite_flat)
|
||||
.define("V3D_LIGHTING_FLAT")
|
||||
.define("WORKBENCH_LIGHTING_FLAT")
|
||||
.additional_info("workbench_composite")
|
||||
.do_static_compilation(true);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Workbench Next
|
||||
* \{ */
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_composite)
|
||||
.sampler(3, ImageType::FLOAT_2D, "normal_tx")
|
||||
.sampler(4, ImageType::FLOAT_2D, "material_tx")
|
||||
.sampler(5, ImageType::DEPTH_2D, "depth_tx")
|
||||
.sampler(6, ImageType::UINT_2D, "stencil_tx")
|
||||
.uniform_buf(WB_WORLD_SLOT, "WorldData", "world_data")
|
||||
.typedef_source("workbench_shader_shared.h")
|
||||
.push_constant(Type::BOOL, "forceShadowing")
|
||||
.fragment_out(0, Type::VEC4, "fragColor")
|
||||
.fragment_source("workbench_next_composite_frag.glsl")
|
||||
.additional_info("draw_fullscreen", "draw_view");
|
||||
|
||||
/* Lighting */
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_resolve_opaque_studio).define("WORKBENCH_LIGHTING_STUDIO");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_resolve_opaque_matcap)
|
||||
.define("WORKBENCH_LIGHTING_MATCAP")
|
||||
.sampler(WB_MATCAP_SLOT, ImageType::FLOAT_2D_ARRAY, "matcap_tx");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_resolve_opaque_flat).define("WORKBENCH_LIGHTING_FLAT");
|
||||
|
||||
/* Effects */
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_resolve_curvature)
|
||||
.define("WORKBENCH_CURVATURE")
|
||||
.sampler(7, ImageType::UINT_2D, "object_id_tx");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_resolve_cavity)
|
||||
.define("WORKBENCH_CAVITY")
|
||||
.sampler(8, ImageType::FLOAT_2D, "jitter_tx") /* TODO(Miguel Pozo): GPU_SAMPLER_REPEAT is set
|
||||
in CavityEffect, it doesn't work here ? */
|
||||
.uniform_buf(5, "vec4", "cavity_samples[512]");
|
||||
|
||||
/* Variations */
|
||||
|
||||
#define WORKBENCH_FINAL_VARIATION(name, ...) \
|
||||
GPU_SHADER_CREATE_INFO(name).additional_info(__VA_ARGS__).do_static_compilation(true);
|
||||
|
||||
#define WORKBENCH_CURVATURE_VARIATIONS(prefix, ...) \
|
||||
WORKBENCH_FINAL_VARIATION(prefix##_curvature, "workbench_next_resolve_curvature", __VA_ARGS__) \
|
||||
WORKBENCH_FINAL_VARIATION(prefix##_no_curvature, __VA_ARGS__)
|
||||
|
||||
#define WORKBENCH_CAVITY_VARIATIONS(prefix, ...) \
|
||||
WORKBENCH_CURVATURE_VARIATIONS(prefix##_cavity, "workbench_next_resolve_cavity", __VA_ARGS__) \
|
||||
WORKBENCH_CURVATURE_VARIATIONS(prefix##_no_cavity, __VA_ARGS__)
|
||||
|
||||
#define WORKBENCH_LIGHTING_VARIATIONS(prefix, ...) \
|
||||
WORKBENCH_CAVITY_VARIATIONS( \
|
||||
prefix##_opaque_studio, "workbench_next_resolve_opaque_studio", __VA_ARGS__) \
|
||||
WORKBENCH_CAVITY_VARIATIONS( \
|
||||
prefix##_opaque_matcap, "workbench_next_resolve_opaque_matcap", __VA_ARGS__) \
|
||||
WORKBENCH_CAVITY_VARIATIONS( \
|
||||
prefix##_opaque_flat, "workbench_next_resolve_opaque_flat", __VA_ARGS__)
|
||||
|
||||
WORKBENCH_LIGHTING_VARIATIONS(workbench_next_resolve, "workbench_next_composite");
|
||||
|
||||
#undef WORKBENCH_FINAL_VARIATION
|
||||
#undef WORKBENCH_CURVATURE_VARIATIONS
|
||||
#undef WORKBENCH_CAVITY_VARIATIONS
|
||||
#undef WORKBENCH_LIGHTING_VARIATIONS
|
||||
|
||||
/** \} */
|
||||
|
@@ -5,7 +5,7 @@
|
||||
GPU_SHADER_CREATE_INFO(workbench_effect_cavity_common)
|
||||
.fragment_out(0, Type::VEC4, "fragColor")
|
||||
.sampler(0, ImageType::FLOAT_2D, "normalBuffer")
|
||||
.uniform_buf(4, "WorldData", "world_data", Frequency::PASS)
|
||||
.uniform_buf(WB_WORLD_SLOT, "WorldData", "world_data")
|
||||
.typedef_source("workbench_shader_shared.h")
|
||||
.fragment_source("workbench_effect_cavity_frag.glsl")
|
||||
.additional_info("draw_fullscreen")
|
||||
|
@@ -6,7 +6,7 @@ GPU_SHADER_CREATE_INFO(workbench_effect_outline)
|
||||
.typedef_source("workbench_shader_shared.h")
|
||||
.fragment_source("workbench_effect_outline_frag.glsl")
|
||||
.sampler(0, ImageType::UINT_2D, "objectIdBuffer")
|
||||
.uniform_buf(4, "WorldData", "world_data", Frequency::PASS)
|
||||
.uniform_buf(WB_WORLD_SLOT, "WorldData", "world_data")
|
||||
.fragment_out(0, Type::VEC4, "fragColor")
|
||||
.additional_info("draw_fullscreen")
|
||||
.do_static_compilation(true);
|
||||
|
@@ -9,3 +9,10 @@ GPU_SHADER_CREATE_INFO(workbench_merge_infront)
|
||||
.additional_info("draw_fullscreen")
|
||||
.depth_write(DepthWrite::ANY)
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_merge_depth)
|
||||
.sampler(0, ImageType::DEPTH_2D, "depth_tx")
|
||||
.fragment_source("workbench_next_merge_depth_frag.glsl")
|
||||
.additional_info("draw_fullscreen")
|
||||
.depth_write(DepthWrite::ANY)
|
||||
.do_static_compilation(true);
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
#include "workbench_defines.hh"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Object Type
|
||||
@@ -29,6 +30,29 @@ GPU_SHADER_CREATE_INFO(workbench_pointcloud)
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Object Type
|
||||
* \{ */
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_mesh)
|
||||
.vertex_in(0, Type::VEC3, "pos")
|
||||
.vertex_in(1, Type::VEC3, "nor")
|
||||
.vertex_in(2, Type::VEC4, "ac")
|
||||
.vertex_in(3, Type::VEC2, "au")
|
||||
.vertex_source("workbench_prepass_vert.glsl")
|
||||
.additional_info("draw_modelmat_new")
|
||||
.additional_info("draw_resource_handle_new");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_curves)
|
||||
/* TODO Adding workbench_next_mesh to avoid shader compilation errors */
|
||||
.additional_info("workbench_next_mesh");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_pointcloud)
|
||||
/* TODO Adding workbench_next_mesh to avoid shader compilation errors */
|
||||
.additional_info("workbench_next_mesh");
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Texture Type
|
||||
* \{ */
|
||||
@@ -39,15 +63,15 @@ GPU_SHADER_CREATE_INFO(workbench_texture_single)
|
||||
.sampler(2, ImageType::FLOAT_2D, "imageTexture", Frequency::BATCH)
|
||||
.push_constant(Type::BOOL, "imagePremult")
|
||||
.push_constant(Type::FLOAT, "imageTransparencyCutoff")
|
||||
.define("V3D_SHADING_TEXTURE_COLOR");
|
||||
.define("WORKBENCH_COLOR_TEXTURE");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_texture_tile)
|
||||
.sampler(2, ImageType::FLOAT_2D_ARRAY, "imageTileArray", Frequency::BATCH)
|
||||
.sampler(3, ImageType::FLOAT_1D_ARRAY, "imageTileData", Frequency::BATCH)
|
||||
.push_constant(Type::BOOL, "imagePremult")
|
||||
.push_constant(Type::FLOAT, "imageTransparencyCutoff")
|
||||
.define("V3D_SHADING_TEXTURE_COLOR")
|
||||
.define("TEXTURE_IMAGE_ARRAY");
|
||||
.define("WORKBENCH_COLOR_TEXTURE")
|
||||
.define("WORKBENCH_TEXTURE_IMAGE_ARRAY");
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -55,12 +79,16 @@ GPU_SHADER_CREATE_INFO(workbench_texture_tile)
|
||||
/** \name Lighting Type (only for transparent)
|
||||
* \{ */
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_lighting_flat).define("V3D_LIGHTING_FLAT");
|
||||
GPU_SHADER_CREATE_INFO(workbench_lighting_studio).define("V3D_LIGHTING_STUDIO");
|
||||
GPU_SHADER_CREATE_INFO(workbench_lighting_flat).define("WORKBENCH_LIGHTING_FLAT");
|
||||
GPU_SHADER_CREATE_INFO(workbench_lighting_studio).define("WORKBENCH_LIGHTING_STUDIO");
|
||||
GPU_SHADER_CREATE_INFO(workbench_lighting_matcap)
|
||||
.define("V3D_LIGHTING_MATCAP")
|
||||
.sampler(4, ImageType::FLOAT_2D, "matcap_diffuse_tx", Frequency::PASS)
|
||||
.sampler(5, ImageType::FLOAT_2D, "matcap_specular_tx", Frequency::PASS);
|
||||
.define("WORKBENCH_LIGHTING_MATCAP")
|
||||
.sampler(4, ImageType::FLOAT_2D, "matcap_diffuse_tx")
|
||||
.sampler(5, ImageType::FLOAT_2D, "matcap_specular_tx");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_lighting_matcap)
|
||||
.define("WORKBENCH_LIGHTING_MATCAP")
|
||||
.sampler(WB_MATCAP_SLOT, ImageType::FLOAT_2D_ARRAY, "matcap_tx");
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -78,12 +106,42 @@ GPU_SHADER_INTERFACE_INFO(workbench_material_iface, "")
|
||||
.flat(Type::FLOAT, "metallic");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_material)
|
||||
.uniform_buf(4, "WorldData", "world_data", Frequency::PASS)
|
||||
.uniform_buf(5, "vec4", "materials_data[4096]", Frequency::PASS)
|
||||
.uniform_buf(WB_WORLD_SLOT, "WorldData", "world_data")
|
||||
.uniform_buf(5, "vec4", "materials_data[4096]")
|
||||
.push_constant(Type::INT, "materialIndex")
|
||||
.push_constant(Type::BOOL, "useMatcap")
|
||||
.vertex_out(workbench_material_iface);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_prepass)
|
||||
.define("WORKBENCH_NEXT")
|
||||
.uniform_buf(WB_WORLD_SLOT, "WorldData", "world_data")
|
||||
.vertex_out(workbench_material_iface)
|
||||
.additional_info("draw_view");
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Material Interface
|
||||
* \{ */
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_color_material)
|
||||
.define("WORKBENCH_COLOR_MATERIAL")
|
||||
.storage_buf(WB_MATERIAL_SLOT, Qualifier::READ, "vec4", "materials_data[]");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_color_texture)
|
||||
.define("WORKBENCH_COLOR_TEXTURE")
|
||||
.define("WORKBENCH_TEXTURE_IMAGE_ARRAY")
|
||||
.define("WORKBENCH_COLOR_MATERIAL")
|
||||
.storage_buf(WB_MATERIAL_SLOT, Qualifier::READ, "vec4", "materials_data[]")
|
||||
.sampler(1, ImageType::FLOAT_2D, "imageTexture", Frequency::BATCH)
|
||||
.sampler(2, ImageType::FLOAT_2D_ARRAY, "imageTileArray", Frequency::BATCH)
|
||||
.sampler(3, ImageType::FLOAT_1D_ARRAY, "imageTileData", Frequency::BATCH)
|
||||
.push_constant(Type::BOOL, "isImageTile")
|
||||
.push_constant(Type::BOOL, "imagePremult")
|
||||
.push_constant(Type::FLOAT, "imageTransparencyCutoff");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_color_vertex).define("WORKBENCH_COLOR_VERTEX");
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -93,17 +151,17 @@ GPU_SHADER_CREATE_INFO(workbench_material)
|
||||
GPU_SHADER_CREATE_INFO(workbench_transparent_accum)
|
||||
/* NOTE: Blending will be skipped on objectId because output is a
|
||||
* non-normalized integer buffer. */
|
||||
.fragment_out(0, Type::VEC4, "transparentAccum")
|
||||
.fragment_out(1, Type::VEC4, "revealageAccum")
|
||||
.fragment_out(2, Type::UINT, "objectId")
|
||||
.fragment_out(0, Type::VEC4, "out_transparent_accum")
|
||||
.fragment_out(1, Type::VEC4, "out_revealage_accum")
|
||||
.fragment_out(2, Type::UINT, "out_object_id")
|
||||
.push_constant(Type::BOOL, "forceShadowing")
|
||||
.typedef_source("workbench_shader_shared.h")
|
||||
.fragment_source("workbench_transparent_accum_frag.glsl");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_opaque)
|
||||
.fragment_out(0, Type::VEC4, "materialData")
|
||||
.fragment_out(1, Type::VEC2, "normalData")
|
||||
.fragment_out(2, Type::UINT, "objectId")
|
||||
.fragment_out(0, Type::VEC4, "out_material")
|
||||
.fragment_out(1, Type::VEC2, "out_normal")
|
||||
.fragment_out(2, Type::UINT, "out_object_id")
|
||||
.typedef_source("workbench_shader_shared.h")
|
||||
.fragment_source("workbench_prepass_frag.glsl");
|
||||
|
||||
@@ -147,4 +205,54 @@ GPU_SHADER_CREATE_INFO(workbench_opaque)
|
||||
|
||||
WORKBENCH_PIPELINE_VARIATIONS(workbench, "workbench_material");
|
||||
|
||||
#undef WORKBENCH_FINAL_VARIATION
|
||||
#undef WORKBENCH_CLIPPING_VARIATIONS
|
||||
#undef WORKBENCH_TEXTURE_VARIATIONS
|
||||
#undef WORKBENCH_DATATYPE_VARIATIONS
|
||||
#undef WORKBENCH_PIPELINE_VARIATIONS
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Variations Declaration
|
||||
* \{ */
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_flat).define("WORKBENCH_SHADING_FLAT");
|
||||
GPU_SHADER_CREATE_INFO(workbench_studio).define("WORKBENCH_SHADING_STUDIO");
|
||||
GPU_SHADER_CREATE_INFO(workbench_matcap).define("WORKBENCH_SHADING_MATCAP");
|
||||
|
||||
#define WORKBENCH_FINAL_VARIATION(name, ...) \
|
||||
GPU_SHADER_CREATE_INFO(name).additional_info(__VA_ARGS__).do_static_compilation(true);
|
||||
|
||||
#define WORKBENCH_CLIPPING_VARIATIONS(prefix, ...) \
|
||||
WORKBENCH_FINAL_VARIATION(prefix##_clip, "drw_clipped", __VA_ARGS__) \
|
||||
WORKBENCH_FINAL_VARIATION(prefix##_no_clip, __VA_ARGS__)
|
||||
|
||||
#define WORKBENCH_COLOR_VARIATIONS(prefix, ...) \
|
||||
WORKBENCH_CLIPPING_VARIATIONS(prefix##_material, "workbench_color_material", __VA_ARGS__) \
|
||||
WORKBENCH_CLIPPING_VARIATIONS(prefix##_texture, "workbench_color_texture", __VA_ARGS__) \
|
||||
WORKBENCH_CLIPPING_VARIATIONS(prefix##_vertex, "workbench_color_vertex", __VA_ARGS__)
|
||||
|
||||
#define WORKBENCH_SHADING_VARIATIONS(prefix, ...) \
|
||||
WORKBENCH_COLOR_VARIATIONS(prefix##_flat, "workbench_lighting_flat", __VA_ARGS__) \
|
||||
WORKBENCH_COLOR_VARIATIONS(prefix##_studio, "workbench_lighting_studio", __VA_ARGS__) \
|
||||
WORKBENCH_COLOR_VARIATIONS(prefix##_matcap, "workbench_next_lighting_matcap", __VA_ARGS__)
|
||||
|
||||
#define WORKBENCH_PIPELINE_VARIATIONS(prefix, ...) \
|
||||
WORKBENCH_SHADING_VARIATIONS(prefix##_transparent, "workbench_transparent_accum", __VA_ARGS__) \
|
||||
WORKBENCH_SHADING_VARIATIONS(prefix##_opaque, "workbench_opaque", __VA_ARGS__)
|
||||
|
||||
#define WORKBENCH_GEOMETRY_VARIATIONS(prefix, ...) \
|
||||
WORKBENCH_PIPELINE_VARIATIONS(prefix##_mesh, "workbench_next_mesh", __VA_ARGS__) \
|
||||
WORKBENCH_PIPELINE_VARIATIONS(prefix##_curves, "workbench_next_curves", __VA_ARGS__) \
|
||||
WORKBENCH_PIPELINE_VARIATIONS(prefix##_ptcloud, "workbench_next_pointcloud", __VA_ARGS__)
|
||||
|
||||
WORKBENCH_GEOMETRY_VARIATIONS(workbench_next_prepass, "workbench_next_prepass");
|
||||
|
||||
#undef WORKBENCH_FINAL_VARIATION
|
||||
#undef WORKBENCH_CLIPPING_VARIATIONS
|
||||
#undef WORKBENCH_TEXTURE_VARIATIONS
|
||||
#undef WORKBENCH_DATATYPE_VARIATIONS
|
||||
#undef WORKBENCH_PIPELINE_VARIATIONS
|
||||
|
||||
/** \} */
|
||||
|
@@ -1,5 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "draw_defines.h"
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -9,7 +11,8 @@
|
||||
GPU_SHADER_INTERFACE_INFO(workbench_shadow_iface, "vData")
|
||||
.smooth(Type::VEC3, "pos")
|
||||
.smooth(Type::VEC4, "frontPosition")
|
||||
.smooth(Type::VEC4, "backPosition");
|
||||
.smooth(Type::VEC4, "backPosition")
|
||||
.flat(Type::VEC3, "light_direction_os"); /*Workbench Next*/
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_shadow_common)
|
||||
.vertex_in(0, Type::VEC3, "pos")
|
||||
@@ -24,6 +27,43 @@ GPU_SHADER_CREATE_INFO(workbench_shadow_common_geom)
|
||||
.vertex_out(workbench_shadow_iface)
|
||||
.vertex_source("workbench_shadow_vert.glsl");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_shadow_common)
|
||||
.vertex_in(0, Type::VEC3, "pos")
|
||||
.vertex_out(workbench_shadow_iface)
|
||||
.define("WORKBENCH_NEXT")
|
||||
.uniform_buf(1, "ShadowPassData", "pass_data")
|
||||
.define("lightDirection", "vData[0].light_direction_os")
|
||||
.typedef_source("workbench_shader_shared.h")
|
||||
.additional_info("draw_view")
|
||||
.additional_info("draw_modelmat_new")
|
||||
.additional_info("draw_resource_handle_new");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_shadow_visibility_compute_common)
|
||||
.local_group_size(DRW_VISIBILITY_GROUP_SIZE)
|
||||
.define("DRW_VIEW_LEN", "64")
|
||||
.storage_buf(0, Qualifier::READ, "ObjectBounds", "bounds_buf[]")
|
||||
.uniform_buf(2, "ExtrudedFrustum", "extruded_frustum")
|
||||
.push_constant(Type::INT, "resource_len")
|
||||
.push_constant(Type::INT, "view_len")
|
||||
.push_constant(Type::INT, "visibility_word_per_draw")
|
||||
.push_constant(Type::BOOL, "force_fail_method")
|
||||
.push_constant(Type::VEC3, "shadow_direction")
|
||||
.typedef_source("workbench_shader_shared.h")
|
||||
.compute_source("workbench_shadow_visibility_comp.glsl")
|
||||
.additional_info("draw_view", "draw_view_culling");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_shadow_visibility_compute_dynamic_pass_type)
|
||||
.additional_info("workbench_next_shadow_visibility_compute_common")
|
||||
.define("DYNAMIC_PASS_SELECTION")
|
||||
.storage_buf(1, Qualifier::READ_WRITE, "uint", "pass_visibility_buf[]")
|
||||
.storage_buf(2, Qualifier::READ_WRITE, "uint", "fail_visibility_buf[]")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_shadow_visibility_compute_static_pass_type)
|
||||
.additional_info("workbench_next_shadow_visibility_compute_common")
|
||||
.storage_buf(1, Qualifier::READ_WRITE, "uint", "visibility_buf[]")
|
||||
.do_static_compilation(true);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -79,42 +119,64 @@ GPU_SHADER_CREATE_INFO(workbench_shadow_debug)
|
||||
.fragment_out(2, Type::UINT, "objectId")
|
||||
.fragment_source("workbench_shadow_debug_frag.glsl");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_shadow_no_debug)
|
||||
.additional_info("workbench_shadow_no_debug");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_next_shadow_debug).additional_info("workbench_shadow_debug");
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Variations Declaration
|
||||
* \{ */
|
||||
|
||||
#define WORKBENCH_SHADOW_VARIATIONS(suffix, ...) \
|
||||
GPU_SHADER_CREATE_INFO(workbench_shadow_pass_manifold_no_caps##suffix) \
|
||||
#define WORKBENCH_SHADOW_VARIATIONS(common, prefix, suffix, ...) \
|
||||
GPU_SHADER_CREATE_INFO(prefix##_pass_manifold_no_caps##suffix) \
|
||||
.define("SHADOW_PASS") \
|
||||
.additional_info("workbench_shadow_common", "workbench_shadow_manifold", __VA_ARGS__) \
|
||||
.additional_info(common, "workbench_shadow_manifold", __VA_ARGS__) \
|
||||
.do_static_compilation(true); \
|
||||
GPU_SHADER_CREATE_INFO(workbench_shadow_pass_no_manifold_no_caps##suffix) \
|
||||
GPU_SHADER_CREATE_INFO(prefix##_pass_no_manifold_no_caps##suffix) \
|
||||
.define("SHADOW_PASS") \
|
||||
.define("DOUBLE_MANIFOLD") \
|
||||
.additional_info("workbench_shadow_common", "workbench_shadow_no_manifold", __VA_ARGS__) \
|
||||
.additional_info(common, "workbench_shadow_no_manifold", __VA_ARGS__) \
|
||||
.do_static_compilation(true); \
|
||||
GPU_SHADER_CREATE_INFO(workbench_shadow_fail_manifold_caps##suffix) \
|
||||
GPU_SHADER_CREATE_INFO(prefix##_fail_manifold_caps##suffix) \
|
||||
.define("SHADOW_FAIL") \
|
||||
.additional_info("workbench_shadow_common", "workbench_shadow_caps", __VA_ARGS__) \
|
||||
.additional_info(common, "workbench_shadow_caps", __VA_ARGS__) \
|
||||
.do_static_compilation(true); \
|
||||
GPU_SHADER_CREATE_INFO(workbench_shadow_fail_manifold_no_caps##suffix) \
|
||||
GPU_SHADER_CREATE_INFO(prefix##_fail_manifold_no_caps##suffix) \
|
||||
.define("SHADOW_FAIL") \
|
||||
.additional_info("workbench_shadow_common", "workbench_shadow_manifold", __VA_ARGS__) \
|
||||
.additional_info(common, "workbench_shadow_manifold", __VA_ARGS__) \
|
||||
.do_static_compilation(true); \
|
||||
GPU_SHADER_CREATE_INFO(workbench_shadow_fail_no_manifold_caps##suffix) \
|
||||
GPU_SHADER_CREATE_INFO(prefix##_fail_no_manifold_caps##suffix) \
|
||||
.define("SHADOW_FAIL") \
|
||||
.define("DOUBLE_MANIFOLD") \
|
||||
.additional_info("workbench_shadow_common", "workbench_shadow_caps", __VA_ARGS__) \
|
||||
.additional_info(common, "workbench_shadow_caps", __VA_ARGS__) \
|
||||
.do_static_compilation(true); \
|
||||
GPU_SHADER_CREATE_INFO(workbench_shadow_fail_no_manifold_no_caps##suffix) \
|
||||
GPU_SHADER_CREATE_INFO(prefix##_fail_no_manifold_no_caps##suffix) \
|
||||
.define("SHADOW_FAIL") \
|
||||
.define("DOUBLE_MANIFOLD") \
|
||||
.additional_info("workbench_shadow_common", "workbench_shadow_no_manifold", __VA_ARGS__) \
|
||||
.additional_info(common, "workbench_shadow_no_manifold", __VA_ARGS__) \
|
||||
.do_static_compilation(true);
|
||||
|
||||
WORKBENCH_SHADOW_VARIATIONS(, "workbench_shadow_no_debug")
|
||||
WORKBENCH_SHADOW_VARIATIONS(_debug, "workbench_shadow_debug")
|
||||
WORKBENCH_SHADOW_VARIATIONS("workbench_shadow_common",
|
||||
workbench_shadow,
|
||||
,
|
||||
"workbench_shadow_no_debug")
|
||||
|
||||
WORKBENCH_SHADOW_VARIATIONS("workbench_shadow_common",
|
||||
workbench_shadow,
|
||||
_debug,
|
||||
"workbench_shadow_debug")
|
||||
|
||||
WORKBENCH_SHADOW_VARIATIONS("workbench_next_shadow_common",
|
||||
workbench_next_shadow,
|
||||
,
|
||||
"workbench_next_shadow_no_debug")
|
||||
|
||||
WORKBENCH_SHADOW_VARIATIONS("workbench_next_shadow_common",
|
||||
workbench_next_shadow,
|
||||
_debug,
|
||||
"workbench_next_shadow_debug")
|
||||
|
||||
/** \} */
|
||||
|
@@ -5,6 +5,12 @@
|
||||
/* From The Alchemy screen-space ambient obscurance algorithm
|
||||
* http://graphics.cs.williams.edu/papers/AlchemyHPG11/VV11AlchemyAO.pdf */
|
||||
|
||||
#ifdef WORKBENCH_CAVITY
|
||||
# define USE_CAVITY
|
||||
# define cavityJitter jitter_tx
|
||||
# define samples_coords cavity_samples
|
||||
#endif
|
||||
|
||||
#ifdef USE_CAVITY
|
||||
|
||||
void cavity_compute(vec2 screenco,
|
||||
|
@@ -16,18 +16,18 @@ void main()
|
||||
float roughness, metallic;
|
||||
workbench_float_pair_decode(mat_data.a, roughness, metallic);
|
||||
|
||||
#ifdef V3D_LIGHTING_MATCAP
|
||||
#ifdef WORKBENCH_LIGHTING_MATCAP
|
||||
/* When using matcaps, mat_data.a is the back-face sign. */
|
||||
N = (mat_data.a > 0.0) ? N : -N;
|
||||
|
||||
fragColor.rgb = get_matcap_lighting(matcap_diffuse_tx, matcap_specular_tx, base_color, N, I);
|
||||
#endif
|
||||
|
||||
#ifdef V3D_LIGHTING_STUDIO
|
||||
#ifdef WORKBENCH_LIGHTING_STUDIO
|
||||
fragColor.rgb = get_world_lighting(base_color, roughness, metallic, N, I);
|
||||
#endif
|
||||
|
||||
#ifdef V3D_LIGHTING_FLAT
|
||||
#ifdef WORKBENCH_LIGHTING_FLAT
|
||||
fragColor.rgb = base_color;
|
||||
#endif
|
||||
|
||||
|
@@ -1,6 +1,10 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(workbench_common_lib.glsl)
|
||||
|
||||
#ifdef WORKBENCH_CURVATURE
|
||||
# define USE_CURVATURE
|
||||
#endif
|
||||
|
||||
#ifdef USE_CURVATURE
|
||||
|
||||
float curvature_soft_clamp(float curvature, float control)
|
||||
|
@@ -27,10 +27,27 @@ bool node_tex_tile_lookup(inout vec3 co, sampler2DArray ima, sampler1DArray map)
|
||||
|
||||
vec3 workbench_image_color(vec2 uvs)
|
||||
{
|
||||
#ifdef V3D_SHADING_TEXTURE_COLOR
|
||||
#ifdef WORKBENCH_COLOR_TEXTURE
|
||||
vec4 color;
|
||||
|
||||
# ifdef TEXTURE_IMAGE_ARRAY
|
||||
# ifdef WORKBENCH_NEXT
|
||||
|
||||
vec3 co = vec3(uvs, 0.0);
|
||||
if (isImageTile) {
|
||||
if (node_tex_tile_lookup(co, imageTileArray, imageTileData)) {
|
||||
color = texture(imageTileArray, co);
|
||||
}
|
||||
else {
|
||||
color = vec4(1.0, 0.0, 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
color = texture(imageTexture, uvs);
|
||||
}
|
||||
|
||||
# else // WORKBENCH_NEXT
|
||||
|
||||
# ifdef WORKBENCH_TEXTURE_IMAGE_ARRAY
|
||||
vec3 co = vec3(uvs, 0.0);
|
||||
if (node_tex_tile_lookup(co, imageTileArray, imageTileData)) {
|
||||
color = texture(imageTileArray, co);
|
||||
@@ -38,10 +55,12 @@ vec3 workbench_image_color(vec2 uvs)
|
||||
else {
|
||||
color = vec4(1.0, 0.0, 1.0, 1.0);
|
||||
}
|
||||
# else
|
||||
# else
|
||||
|
||||
color = texture(imageTexture, uvs);
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# endif // WORKBENCH_NEXT
|
||||
|
||||
/* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */
|
||||
if (imagePremult && !(color.a == 0.0 || color.a == 1.0)) {
|
||||
|
@@ -24,3 +24,14 @@ vec3 get_matcap_lighting(
|
||||
|
||||
return diffuse * base_color + specular * float(world_data.use_specular);
|
||||
}
|
||||
|
||||
vec3 get_matcap_lighting(sampler2DArray matcap, vec3 base_color, vec3 N, vec3 I)
|
||||
{
|
||||
bool flipped = world_data.matcap_orientation != 0;
|
||||
vec2 uv = matcap_uv_compute(I, N, flipped);
|
||||
|
||||
vec3 diffuse = textureLod(matcap, vec3(uv, 0.0), 0.0).rgb;
|
||||
vec3 specular = textureLod(matcap, vec3(uv, 1.0), 0.0).rgb;
|
||||
|
||||
return diffuse * base_color + specular * float(world_data.use_specular);
|
||||
}
|
||||
|
@@ -1,10 +1,28 @@
|
||||
|
||||
void workbench_material_data_get(
|
||||
int handle, out vec3 color, out float alpha, out float roughness, out float metallic)
|
||||
|
||||
void workbench_material_data_get(int handle,
|
||||
vec3 vertex_color,
|
||||
out vec3 color,
|
||||
out float alpha,
|
||||
out float roughness,
|
||||
out float metallic)
|
||||
{
|
||||
#ifndef WORKBENCH_NEXT
|
||||
handle = (materialIndex != -1) ? materialIndex : handle;
|
||||
vec4 data = materials_data[uint(handle) & 0xFFFu];
|
||||
color = data.rgb;
|
||||
if (materialIndex == 0) {
|
||||
color_interp = vertex_color;
|
||||
}
|
||||
#else
|
||||
|
||||
# ifdef WORKBENCH_COLOR_MATERIAL
|
||||
vec4 data = materials_data[handle];
|
||||
# else
|
||||
vec4 data = vec4(0.0);
|
||||
# endif
|
||||
color = (data.r == -1) ? vertex_color : data.rgb;
|
||||
#endif
|
||||
|
||||
uint encoded_data = floatBitsToUint(data.w);
|
||||
alpha = float((encoded_data >> 16u) & 0xFFu) * (1.0 / 255.0);
|
||||
|
@@ -0,0 +1,81 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(workbench_common_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(workbench_matcap_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(workbench_world_light_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(workbench_cavity_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(workbench_curvature_lib.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = uvcoordsvar.st;
|
||||
/* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */
|
||||
vec3 V = get_view_vector_from_screen_uv(uv);
|
||||
vec3 N = workbench_normal_decode(texture(normal_tx, uv));
|
||||
vec4 mat_data = texture(material_tx, uv);
|
||||
float depth = texture(depth_tx, uv).r;
|
||||
|
||||
vec3 base_color = mat_data.rgb;
|
||||
vec4 color = world_data.background_color;
|
||||
|
||||
/* Background pixels. */
|
||||
if (depth != 1.0) {
|
||||
#ifdef WORKBENCH_LIGHTING_MATCAP
|
||||
/* When using matcaps, mat_data.a is the back-face sign. */
|
||||
N = (mat_data.a > 0.0) ? N : -N;
|
||||
color.rgb = get_matcap_lighting(matcap_tx, base_color, N, V);
|
||||
#endif
|
||||
|
||||
#ifdef WORKBENCH_LIGHTING_STUDIO
|
||||
float roughness, metallic;
|
||||
workbench_float_pair_decode(mat_data.a, roughness, metallic);
|
||||
color.rgb = get_world_lighting(base_color, roughness, metallic, N, V);
|
||||
#endif
|
||||
|
||||
#ifdef WORKBENCH_LIGHTING_FLAT
|
||||
color.rgb = base_color;
|
||||
#endif
|
||||
|
||||
#if defined(WORKBENCH_CAVITY) || defined(WORKBENCH_CURVATURE)
|
||||
float cavity = 0.0, edges = 0.0, curvature = 0.0;
|
||||
|
||||
# ifdef WORKBENCH_CAVITY
|
||||
cavity_compute(uv, depth_tx, normal_tx, cavity, edges);
|
||||
# endif
|
||||
|
||||
# ifdef WORKBENCH_CURVATURE
|
||||
curvature_compute(uv, object_id_tx, normal_tx, curvature);
|
||||
# endif
|
||||
|
||||
float final_cavity_factor = clamp(
|
||||
(1.0 - cavity) * (1.0 + edges) * (1.0 + curvature), 0.0, 4.0);
|
||||
|
||||
color.rgb *= final_cavity_factor;
|
||||
#endif
|
||||
|
||||
bool shadow = texture(stencil_tx, uv).r != 0;
|
||||
color.rgb *= get_shadow(N, shadow);
|
||||
|
||||
color.a = 1.0f;
|
||||
}
|
||||
|
||||
#ifdef WORKBENCH_OUTLINE
|
||||
vec3 offset = vec3(world_data.viewport_size_inv, 0.0) * world_data.ui_scale;
|
||||
|
||||
uint center_id = texture(object_id_tx, uv).r;
|
||||
uvec4 adjacent_ids = uvec4(texture(object_id_tx, uv + offset.zy).r,
|
||||
texture(object_id_tx, uv - offset.zy).r,
|
||||
texture(object_id_tx, uv + offset.xz).r,
|
||||
texture(object_id_tx, uv - offset.xz).r);
|
||||
|
||||
float outline_opacity = 1.0 - dot(vec4(equal(uvec4(center_id), adjacent_ids)), vec4(0.25));
|
||||
color = mix(color, world_data.object_outline_color, outline_opacity);
|
||||
#endif
|
||||
|
||||
if (all(equal(color, world_data.background_color))) {
|
||||
discard;
|
||||
}
|
||||
else {
|
||||
fragColor = color;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
|
||||
void main()
|
||||
{
|
||||
float depth = texture(depth_tx, uvcoordsvar.xy).r;
|
||||
if (depth != 1.0) {
|
||||
gl_FragDepth = depth;
|
||||
}
|
||||
else {
|
||||
discard;
|
||||
}
|
||||
}
|
@@ -3,20 +3,43 @@
|
||||
#pragma BLENDER_REQUIRE(workbench_common_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(workbench_image_lib.glsl)
|
||||
|
||||
#ifdef WORKBENCH_NEXT
|
||||
|
||||
void main()
|
||||
{
|
||||
normalData = workbench_normal_encode(gl_FrontFacing, normal_interp);
|
||||
out_object_id = uint(object_id);
|
||||
out_normal = workbench_normal_encode(gl_FrontFacing, normal_interp);
|
||||
|
||||
materialData = vec4(color_interp, workbench_float_pair_encode(_roughness, metallic));
|
||||
out_material = vec4(color_interp, workbench_float_pair_encode(_roughness, metallic));
|
||||
|
||||
objectId = uint(object_id);
|
||||
# ifdef WORKBENCH_COLOR_TEXTURE
|
||||
out_material.rgb = workbench_image_color(uv_interp);
|
||||
# endif
|
||||
|
||||
# ifdef WORKBENCH_LIGHTING_MATCAP
|
||||
/* For matcaps, save front facing in alpha channel. */
|
||||
out_material.a = float(gl_FrontFacing);
|
||||
# endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void main()
|
||||
{
|
||||
out_normal = workbench_normal_encode(gl_FrontFacing, normal_interp);
|
||||
|
||||
out_material = vec4(color_interp, workbench_float_pair_encode(_roughness, metallic));
|
||||
|
||||
out_object_id = uint(object_id);
|
||||
|
||||
if (useMatcap) {
|
||||
/* For matcaps, save front facing in alpha channel. */
|
||||
materialData.a = float(gl_FrontFacing);
|
||||
out_material.a = float(gl_FrontFacing);
|
||||
}
|
||||
|
||||
#ifdef V3D_SHADING_TEXTURE_COLOR
|
||||
materialData.rgb = workbench_image_color(uv_interp);
|
||||
#endif
|
||||
# ifdef WORKBENCH_COLOR_TEXTURE
|
||||
out_material.rgb = workbench_image_color(uv_interp);
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -68,11 +68,12 @@ void main()
|
||||
|
||||
normal_interp = normalize(normal_world_to_view(nor));
|
||||
|
||||
workbench_material_data_get(resource_handle, color_interp, alpha_interp, _roughness, metallic);
|
||||
|
||||
if (materialIndex == 0) {
|
||||
color_interp = hair_get_customdata_vec3(ac);
|
||||
}
|
||||
workbench_material_data_get(resource_handle,
|
||||
hair_get_customdata_vec3(ac),
|
||||
color_interp,
|
||||
alpha_interp,
|
||||
_roughness,
|
||||
metallic);
|
||||
|
||||
/* Hairs have lots of layer and can rapidly become the most prominent surface.
|
||||
* So we lower their alpha artificially. */
|
||||
|
@@ -19,11 +19,8 @@ void main()
|
||||
|
||||
uv_interp = vec2(0.0);
|
||||
|
||||
workbench_material_data_get(resource_handle, color_interp, alpha_interp, _roughness, metallic);
|
||||
|
||||
if (materialIndex == 0) {
|
||||
color_interp = vec3(1.0);
|
||||
}
|
||||
workbench_material_data_get(
|
||||
resource_handle, vec3(1.0), color_interp, alpha_interp, _roughness, metallic);
|
||||
|
||||
object_id = int(uint(resource_handle) & 0xFFFFu) + 1;
|
||||
}
|
||||
|
@@ -16,11 +16,8 @@ void main()
|
||||
|
||||
normal_interp = normalize(normal_object_to_view(nor));
|
||||
|
||||
workbench_material_data_get(resource_handle, color_interp, alpha_interp, _roughness, metallic);
|
||||
|
||||
if (materialIndex == 0) {
|
||||
color_interp = ac.rgb;
|
||||
}
|
||||
workbench_material_data_get(
|
||||
resource_handle, ac.rgb, color_interp, alpha_interp, _roughness, metallic);
|
||||
|
||||
object_id = int(uint(resource_handle) & 0xFFFFu) + 1;
|
||||
}
|
||||
|
@@ -5,6 +5,18 @@ void main()
|
||||
{
|
||||
vData.pos = pos;
|
||||
vData.frontPosition = point_object_to_ndc(pos);
|
||||
vec3 back_pos = pos + lightDirection * lightDistance;
|
||||
vData.backPosition = point_object_to_ndc(back_pos);
|
||||
#ifdef WORKBENCH_NEXT
|
||||
vData.light_direction_os = normal_world_to_object(pass_data.light_direction_ws);
|
||||
vec3 pos_ws = point_object_to_world(pos);
|
||||
float extrude_distance = 1e5f;
|
||||
float LDoFP = dot(pass_data.light_direction_ws, pass_data.far_plane.xyz);
|
||||
if (LDoFP > 0) {
|
||||
float signed_distance = dot(pass_data.far_plane.xyz, pos_ws) - pass_data.far_plane.w;
|
||||
extrude_distance = -signed_distance / LDoFP;
|
||||
}
|
||||
vData.backPosition = point_world_to_ndc(pos_ws +
|
||||
pass_data.light_direction_ws * extrude_distance);
|
||||
#else
|
||||
vData.backPosition = point_object_to_ndc(pos + lightDirection * lightDistance);
|
||||
#endif
|
||||
}
|
||||
|
@@ -0,0 +1,93 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(common_intersect_lib.glsl)
|
||||
|
||||
shared uint shared_result;
|
||||
|
||||
#ifdef DYNAMIC_PASS_SELECTION
|
||||
void set_visibility(bool pass, bool fail)
|
||||
{
|
||||
if (!pass) {
|
||||
atomicAnd(pass_visibility_buf[gl_WorkGroupID.x], ~(1u << gl_LocalInvocationID.x));
|
||||
}
|
||||
if (!fail) {
|
||||
atomicAnd(fail_visibility_buf[gl_WorkGroupID.x], ~(1u << gl_LocalInvocationID.x));
|
||||
}
|
||||
}
|
||||
#else
|
||||
void set_visibility(bool visibility)
|
||||
{
|
||||
if (!visibility) {
|
||||
atomicAnd(visibility_buf[gl_WorkGroupID.x], ~(1u << gl_LocalInvocationID.x));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool is_visible(IsectBox box)
|
||||
{
|
||||
for (int i_plane = 0; i_plane < extruded_frustum.planes_count; i_plane++) {
|
||||
vec4 plane = extruded_frustum.planes[i_plane];
|
||||
bool separating_axis = true;
|
||||
for (int i_corner = 0; i_corner < 8; i_corner++) {
|
||||
float signed_distance = dot(box.corners[i_corner], plane.xyz) - plane.w;
|
||||
if (signed_distance <= 0) {
|
||||
separating_axis = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (separating_axis) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool intersects_near_plane(IsectBox box)
|
||||
{
|
||||
vec4 near_plane = drw_view_culling.planes[4];
|
||||
bool on_positive_side = false;
|
||||
bool on_negative_side = false;
|
||||
|
||||
for (int i_corner = 0; i_corner < 8; i_corner++) {
|
||||
for (int i_displace = 0; i_displace < 2; i_displace++) {
|
||||
vec3 corner = box.corners[i_corner] + (shadow_direction * 1e5f * i_displace);
|
||||
float signed_distance = dot(corner, -near_plane.xyz) - near_plane.w;
|
||||
if (signed_distance <= 0) {
|
||||
on_negative_side = true;
|
||||
}
|
||||
else {
|
||||
on_positive_side = true;
|
||||
}
|
||||
if (on_negative_side && on_positive_side) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
if (gl_GlobalInvocationID.x >= resource_len) {
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectBounds bounds = bounds_buf[gl_GlobalInvocationID.x];
|
||||
IsectBox box = isect_data_setup(bounds.bounding_corners[0].xyz,
|
||||
bounds.bounding_corners[1].xyz,
|
||||
bounds.bounding_corners[2].xyz,
|
||||
bounds.bounding_corners[3].xyz);
|
||||
|
||||
#ifdef DYNAMIC_PASS_SELECTION
|
||||
if (is_visible(box)) {
|
||||
bool use_fail_pass = force_fail_method || intersects_near_plane(box);
|
||||
set_visibility(!use_fail_pass, use_fail_pass);
|
||||
}
|
||||
else {
|
||||
set_visibility(false, false);
|
||||
}
|
||||
#else
|
||||
set_visibility(is_visible(box));
|
||||
#endif
|
||||
}
|
@@ -45,6 +45,8 @@ float calculate_transparent_weight(void)
|
||||
return clamp(w, 1e-2, 3e2);
|
||||
}
|
||||
|
||||
#ifdef WORKBENCH_NEXT
|
||||
|
||||
void main()
|
||||
{
|
||||
/* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */
|
||||
@@ -54,28 +56,68 @@ void main()
|
||||
|
||||
vec3 color = color_interp;
|
||||
|
||||
#ifdef V3D_SHADING_TEXTURE_COLOR
|
||||
# ifdef WORKBENCH_COLOR_TEXTURE
|
||||
color = workbench_image_color(uv_interp);
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#ifdef V3D_LIGHTING_MATCAP
|
||||
vec3 shaded_color = get_matcap_lighting(matcap_diffuse_tx, matcap_specular_tx, color, N, I);
|
||||
#endif
|
||||
# ifdef WORKBENCH_LIGHTING_MATCAP
|
||||
vec3 shaded_color = get_matcap_lighting(matcap_tx, color, N, I);
|
||||
# endif
|
||||
|
||||
#ifdef V3D_LIGHTING_STUDIO
|
||||
# ifdef WORKBENCH_LIGHTING_STUDIO
|
||||
vec3 shaded_color = get_world_lighting(color, _roughness, metallic, N, I);
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#ifdef V3D_LIGHTING_FLAT
|
||||
# ifdef WORKBENCH_LIGHTING_FLAT
|
||||
vec3 shaded_color = color;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
shaded_color *= get_shadow(N, forceShadowing);
|
||||
|
||||
/* Listing 4 */
|
||||
float alpha = alpha_interp * world_data.xray_alpha;
|
||||
float weight = calculate_transparent_weight() * alpha;
|
||||
out_transparent_accum = vec4(shaded_color * weight, alpha);
|
||||
out_revealage_accum = vec4(weight);
|
||||
|
||||
out_object_id = uint(object_id);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void main()
|
||||
{
|
||||
/* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */
|
||||
vec2 uv_viewport = gl_FragCoord.xy * world_data.viewport_size_inv;
|
||||
vec3 I = get_view_vector_from_screen_uv(uv_viewport);
|
||||
vec3 N = normalize(normal_interp);
|
||||
|
||||
vec3 color = color_interp;
|
||||
|
||||
# ifdef WORKBENCH_COLOR_TEXTURE
|
||||
color = workbench_image_color(uv_interp);
|
||||
# endif
|
||||
|
||||
# ifdef WORKBENCH_LIGHTING_MATCAP
|
||||
vec3 shaded_color = get_matcap_lighting(matcap_diffuse_tx, matcap_specular_tx, color, N, I);
|
||||
# endif
|
||||
|
||||
# ifdef WORKBENCH_LIGHTING_STUDIO
|
||||
vec3 shaded_color = get_world_lighting(color, _roughness, metallic, N, I);
|
||||
# endif
|
||||
|
||||
# ifdef WORKBENCH_LIGHTING_FLAT
|
||||
vec3 shaded_color = color;
|
||||
# endif
|
||||
|
||||
shaded_color *= get_shadow(N, forceShadowing);
|
||||
|
||||
/* Listing 4 */
|
||||
float weight = calculate_transparent_weight() * alpha_interp;
|
||||
transparentAccum = vec4(shaded_color * weight, alpha_interp);
|
||||
revealageAccum = vec4(weight);
|
||||
out_transparent_accum = vec4(shaded_color * weight, alpha_interp);
|
||||
out_revealage_accum = vec4(weight);
|
||||
|
||||
objectId = uint(object_id);
|
||||
out_object_id = uint(object_id);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
10
source/blender/draw/engines/workbench/workbench_defines.hh
Normal file
10
source/blender/draw/engines/workbench/workbench_defines.hh
Normal file
@@ -0,0 +1,10 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#define WB_MATCAP_SLOT 0
|
||||
#define WB_TEXTURE_SLOT 1
|
||||
#define WB_TILE_ARRAY_SLOT 2
|
||||
#define WB_TILE_DATA_SLOT 3
|
||||
#define WB_MATERIAL_SLOT 0
|
||||
#define WB_WORLD_SLOT 4
|
||||
|
||||
#define WB_RESOLVE_GROUP_SIZE 8
|
@@ -0,0 +1,311 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "workbench_private.hh"
|
||||
|
||||
#include "BLI_jitter_2d.h"
|
||||
#include "smaa_textures.h"
|
||||
|
||||
namespace blender::workbench {
|
||||
|
||||
class TaaSamples {
|
||||
void init_samples(Array<float2> &samples, const int size)
|
||||
{
|
||||
samples = Array<float2>(size);
|
||||
BLI_jitter_init((float(*)[2])samples.begin(), size);
|
||||
|
||||
/* Find closest element to center */
|
||||
int closest_index = 0;
|
||||
float closest_squared_distance = 1.0f;
|
||||
|
||||
for (int i : samples.index_range()) {
|
||||
float2 sample = samples[i];
|
||||
const float squared_dist = len_squared_v2(sample);
|
||||
if (squared_dist < closest_squared_distance) {
|
||||
closest_squared_distance = squared_dist;
|
||||
closest_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
float2 closest_sample = samples[closest_index];
|
||||
|
||||
for (float2 &sample : samples) {
|
||||
/* Move jitter samples so that closest sample is in center */
|
||||
sample -= closest_sample;
|
||||
/* Avoid samples outside range (wrap around). */
|
||||
sample = {fmodf(sample.x + 0.5f, 1.0f), fmodf(sample.y + 0.5f, 1.0f)};
|
||||
/* Recenter the distribution[-1..1]. */
|
||||
sample = (sample * 2.0f) - 1.0f;
|
||||
}
|
||||
|
||||
/* Swap center sample to the start of the array */
|
||||
if (closest_index != 0) {
|
||||
std::swap(samples[0], samples[closest_index]);
|
||||
}
|
||||
|
||||
/* Sort list based on farthest distance with previous. */
|
||||
for (int i = 0; i < size - 2; i++) {
|
||||
float squared_dist = 0.0;
|
||||
int index = i;
|
||||
for (int j = i + 1; j < size; j++) {
|
||||
const float _squared_dist = len_squared_v2(samples[i] - samples[j]);
|
||||
if (_squared_dist > squared_dist) {
|
||||
squared_dist = _squared_dist;
|
||||
index = j;
|
||||
}
|
||||
}
|
||||
std::swap(samples[i + 1], samples[index]);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
Array<float2> x5;
|
||||
Array<float2> x8;
|
||||
Array<float2> x11;
|
||||
Array<float2> x16;
|
||||
Array<float2> x32;
|
||||
|
||||
TaaSamples()
|
||||
{
|
||||
init_samples(x5, 5);
|
||||
init_samples(x8, 8);
|
||||
init_samples(x11, 11);
|
||||
init_samples(x16, 16);
|
||||
init_samples(x32, 32);
|
||||
}
|
||||
};
|
||||
|
||||
static TaaSamples TAA_SAMPLES = TaaSamples();
|
||||
|
||||
static float filter_blackman_harris(float x, const float width)
|
||||
{
|
||||
if (x > width * 0.5f) {
|
||||
return 0.0f;
|
||||
}
|
||||
x = 2.0f * M_PI * clamp_f((x / width + 0.5f), 0.0f, 1.0f);
|
||||
return 0.35875f - 0.48829f * math::cos(x) + 0.14128f * math::cos(2.0f * x) -
|
||||
0.01168f * math::cos(3.0f * x);
|
||||
}
|
||||
|
||||
/* Compute weights for the 3x3 neighborhood using a 1.5px filter. */
|
||||
static void setup_taa_weights(const float2 offset, float r_weights[9], float &r_weight_sum)
|
||||
{
|
||||
/* NOTE: If filter width is bigger than 2.0f, then we need to sample more neighborhood. */
|
||||
const float filter_width = 2.0f;
|
||||
r_weight_sum = 0.0f;
|
||||
int i = 0;
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int y = -1; y <= 1; y++, i++) {
|
||||
float2 sample_co = float2(x, y) - offset;
|
||||
float r = len_v2(sample_co);
|
||||
/* fclem: Is radial distance ok here? */
|
||||
float weight = filter_blackman_harris(r, filter_width);
|
||||
r_weight_sum += weight;
|
||||
r_weights[i] = weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AntiAliasingPass::AntiAliasingPass()
|
||||
{
|
||||
taa_accumulation_sh_ = GPU_shader_create_from_info_name("workbench_taa");
|
||||
smaa_edge_detect_sh_ = GPU_shader_create_from_info_name("workbench_smaa_stage_0");
|
||||
smaa_aa_weight_sh_ = GPU_shader_create_from_info_name("workbench_smaa_stage_1");
|
||||
smaa_resolve_sh_ = GPU_shader_create_from_info_name("workbench_smaa_stage_2");
|
||||
|
||||
smaa_search_tx_.ensure_2d(
|
||||
GPU_R8, {SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT}, GPU_TEXTURE_USAGE_SHADER_READ);
|
||||
GPU_texture_update(smaa_search_tx_, GPU_DATA_UBYTE, searchTexBytes);
|
||||
GPU_texture_filter_mode(smaa_search_tx_, true);
|
||||
|
||||
smaa_area_tx_.ensure_2d(GPU_RG8, {AREATEX_WIDTH, AREATEX_HEIGHT}, GPU_TEXTURE_USAGE_SHADER_READ);
|
||||
GPU_texture_update(smaa_area_tx_, GPU_DATA_UBYTE, areaTexBytes);
|
||||
GPU_texture_filter_mode(smaa_area_tx_, true);
|
||||
}
|
||||
|
||||
AntiAliasingPass::~AntiAliasingPass()
|
||||
{
|
||||
DRW_SHADER_FREE_SAFE(taa_accumulation_sh_);
|
||||
DRW_SHADER_FREE_SAFE(smaa_edge_detect_sh_);
|
||||
DRW_SHADER_FREE_SAFE(smaa_aa_weight_sh_);
|
||||
DRW_SHADER_FREE_SAFE(smaa_resolve_sh_);
|
||||
}
|
||||
|
||||
void AntiAliasingPass::init(const SceneState &scene_state)
|
||||
{
|
||||
enabled_ = scene_state.draw_aa;
|
||||
sample_ = scene_state.sample;
|
||||
samples_len_ = scene_state.samples_len;
|
||||
}
|
||||
|
||||
void AntiAliasingPass::sync(SceneResources &resources, int2 resolution)
|
||||
{
|
||||
if (!enabled_) {
|
||||
taa_accumulation_tx_.free();
|
||||
sample0_depth_tx_.free();
|
||||
return;
|
||||
}
|
||||
|
||||
taa_accumulation_tx_.ensure_2d(
|
||||
GPU_RGBA16F, resolution, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
sample0_depth_tx_.ensure_2d(GPU_DEPTH24_STENCIL8,
|
||||
resolution,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
|
||||
taa_accumulation_ps_.init();
|
||||
taa_accumulation_ps_.state_set(sample_ == 0 ? DRW_STATE_WRITE_COLOR :
|
||||
DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL);
|
||||
taa_accumulation_ps_.shader_set(taa_accumulation_sh_);
|
||||
taa_accumulation_ps_.bind_texture("colorBuffer", &resources.color_tx);
|
||||
taa_accumulation_ps_.push_constant("samplesWeights", weights_, 9);
|
||||
taa_accumulation_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
|
||||
smaa_edge_detect_ps_.init();
|
||||
smaa_edge_detect_ps_.state_set(DRW_STATE_WRITE_COLOR);
|
||||
smaa_edge_detect_ps_.shader_set(smaa_edge_detect_sh_);
|
||||
smaa_edge_detect_ps_.bind_texture("colorTex", &taa_accumulation_tx_);
|
||||
smaa_edge_detect_ps_.push_constant("viewportMetrics", &smaa_viewport_metrics_, 1);
|
||||
smaa_edge_detect_ps_.clear_color(float4(0.0f));
|
||||
smaa_edge_detect_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
|
||||
smaa_aa_weight_ps_.init();
|
||||
smaa_aa_weight_ps_.state_set(DRW_STATE_WRITE_COLOR);
|
||||
smaa_aa_weight_ps_.shader_set(smaa_aa_weight_sh_);
|
||||
smaa_aa_weight_ps_.bind_texture("edgesTex", &smaa_edge_tx_);
|
||||
smaa_aa_weight_ps_.bind_texture("areaTex", smaa_area_tx_);
|
||||
smaa_aa_weight_ps_.bind_texture("searchTex", smaa_search_tx_);
|
||||
smaa_aa_weight_ps_.push_constant("viewportMetrics", &smaa_viewport_metrics_, 1);
|
||||
smaa_aa_weight_ps_.clear_color(float4(0.0f));
|
||||
smaa_aa_weight_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
|
||||
smaa_resolve_ps_.init();
|
||||
smaa_resolve_ps_.state_set(DRW_STATE_WRITE_COLOR);
|
||||
smaa_resolve_ps_.shader_set(smaa_resolve_sh_);
|
||||
smaa_resolve_ps_.bind_texture("blendTex", &smaa_weight_tx_);
|
||||
smaa_resolve_ps_.bind_texture("colorTex", &taa_accumulation_tx_);
|
||||
smaa_resolve_ps_.push_constant("viewportMetrics", &smaa_viewport_metrics_, 1);
|
||||
smaa_resolve_ps_.push_constant("mixFactor", &smaa_mix_factor_, 1);
|
||||
smaa_resolve_ps_.push_constant("taaAccumulatedWeight", &weight_accum_, 1);
|
||||
smaa_resolve_ps_.clear_color(float4(0.0f));
|
||||
smaa_resolve_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
}
|
||||
|
||||
void AntiAliasingPass::setup_view(View &view, int2 resolution)
|
||||
{
|
||||
if (!enabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
float2 sample_offset;
|
||||
switch (samples_len_) {
|
||||
default:
|
||||
case 5:
|
||||
sample_offset = TAA_SAMPLES.x5[sample_];
|
||||
break;
|
||||
case 8:
|
||||
sample_offset = TAA_SAMPLES.x8[sample_];
|
||||
break;
|
||||
case 11:
|
||||
sample_offset = TAA_SAMPLES.x11[sample_];
|
||||
break;
|
||||
case 16:
|
||||
sample_offset = TAA_SAMPLES.x16[sample_];
|
||||
break;
|
||||
case 32:
|
||||
sample_offset = TAA_SAMPLES.x32[sample_];
|
||||
break;
|
||||
}
|
||||
|
||||
setup_taa_weights(sample_offset, weights_, weights_sum_);
|
||||
|
||||
/* TODO(Miguel Pozo): New API equivalent? */
|
||||
const DRWView *default_view = DRW_view_default_get();
|
||||
float4x4 winmat, viewmat, persmat;
|
||||
/* Construct new matrices from transform delta */
|
||||
DRW_view_winmat_get(default_view, winmat.ptr(), false);
|
||||
DRW_view_viewmat_get(default_view, viewmat.ptr(), false);
|
||||
DRW_view_persmat_get(default_view, persmat.ptr(), false);
|
||||
|
||||
window_translate_m4(
|
||||
winmat.ptr(), persmat.ptr(), sample_offset.x / resolution.x, sample_offset.y / resolution.y);
|
||||
|
||||
view.sync(viewmat, winmat);
|
||||
}
|
||||
|
||||
void AntiAliasingPass::draw(Manager &manager,
|
||||
View &view,
|
||||
SceneResources &resources,
|
||||
int2 resolution,
|
||||
GPUTexture *depth_tx,
|
||||
GPUTexture *color_tx)
|
||||
{
|
||||
if (!enabled_) {
|
||||
/* TODO(Miguel Pozo): Should render to the input color_tx and depth_tx in the first place.
|
||||
* This requires the use of TextureRefs with stencil_view() support,
|
||||
* but whether TextureRef will stay is still TBD. */
|
||||
GPU_texture_copy(color_tx, resources.color_tx);
|
||||
GPU_texture_copy(depth_tx, resources.depth_tx);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* We always do SMAA on top of TAA accumulation, unless the number of samples of TAA is already
|
||||
* high. This ensure a smoother transition.
|
||||
* If TAA accumulation is finished, we only blit the result.
|
||||
*/
|
||||
const bool last_sample = sample_ + 1 == samples_len_;
|
||||
const bool taa_finished = sample_ >= samples_len_;
|
||||
|
||||
if (!taa_finished) {
|
||||
if (sample_ == 0) {
|
||||
weight_accum_ = 0;
|
||||
}
|
||||
/* Accumulate result to the TAA buffer. */
|
||||
taa_accumulation_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(taa_accumulation_tx_));
|
||||
taa_accumulation_fb_.bind();
|
||||
manager.submit(taa_accumulation_ps_, view);
|
||||
weight_accum_ += weights_sum_;
|
||||
}
|
||||
|
||||
if (sample_ == 0) {
|
||||
if (sample0_depth_tx_.is_valid()) {
|
||||
GPU_texture_copy(sample0_depth_tx_, resources.depth_tx);
|
||||
}
|
||||
/* TODO(Miguel Pozo): Should render to the input depth_tx in the first place
|
||||
* This requires the use of TextureRef with stencil_view() support,
|
||||
* but whether TextureRef will stay is still TBD. */
|
||||
|
||||
/* Copy back the saved depth buffer for correct overlays. */
|
||||
GPU_texture_copy(depth_tx, resources.depth_tx);
|
||||
}
|
||||
else {
|
||||
/* Copy back the saved depth buffer for correct overlays. */
|
||||
GPU_texture_copy(depth_tx, sample0_depth_tx_);
|
||||
}
|
||||
|
||||
if (!DRW_state_is_image_render() || last_sample) {
|
||||
smaa_weight_tx_.acquire(
|
||||
resolution, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
smaa_mix_factor_ = 1.0f - clamp_f(sample_ / 4.0f, 0.0f, 1.0f);
|
||||
smaa_viewport_metrics_ = float4(float2(1.0f / float2(resolution)), resolution);
|
||||
|
||||
/* After a certain point SMAA is no longer necessary. */
|
||||
if (smaa_mix_factor_ > 0.0f) {
|
||||
smaa_edge_tx_.acquire(
|
||||
resolution, GPU_RG8, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
smaa_edge_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(smaa_edge_tx_));
|
||||
smaa_edge_fb_.bind();
|
||||
manager.submit(smaa_edge_detect_ps_, view);
|
||||
|
||||
smaa_weight_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(smaa_weight_tx_));
|
||||
smaa_weight_fb_.bind();
|
||||
manager.submit(smaa_aa_weight_ps_, view);
|
||||
smaa_edge_tx_.release();
|
||||
}
|
||||
smaa_resolve_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(color_tx));
|
||||
smaa_resolve_fb_.bind();
|
||||
manager.submit(smaa_resolve_ps_, view);
|
||||
smaa_weight_tx_.release();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::workbench
|
@@ -0,0 +1,89 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*
|
||||
* Cavity Effect:
|
||||
*
|
||||
* We use Screen Space Ambient Occlusion (SSAO) to enhance geometric details of the surfaces.
|
||||
* We also use a Curvature effect computed only using the surface normals.
|
||||
*
|
||||
* This is done as part of the opaque resolve pass. It only affects the opaque surfaces.
|
||||
*/
|
||||
|
||||
#include "BLI_rand.h"
|
||||
#include "workbench_private.hh"
|
||||
|
||||
namespace blender::workbench {
|
||||
|
||||
void CavityEffect::init(const SceneState &scene_state, SceneResources &resources)
|
||||
{
|
||||
cavity_enabled_ = scene_state.draw_cavity;
|
||||
curvature_enabled_ = scene_state.draw_curvature;
|
||||
|
||||
const int ssao_samples = scene_state.scene->display.matcap_ssao_samples;
|
||||
int sample_count = min_ii(scene_state.samples_len * ssao_samples, max_samples_);
|
||||
const int max_iter_count = sample_count / ssao_samples;
|
||||
|
||||
sample_ = scene_state.sample % max_iter_count;
|
||||
|
||||
UniformBuffer<WorldData> &world_buf = resources.world_buf;
|
||||
|
||||
world_buf.cavity_sample_start = ssao_samples * sample_;
|
||||
world_buf.cavity_sample_end = ssao_samples * (sample_ + 1);
|
||||
|
||||
world_buf.cavity_sample_count_inv = 1.0f / (world_buf.cavity_sample_end -
|
||||
world_buf.cavity_sample_start);
|
||||
world_buf.cavity_jitter_scale = 1.0f / 64.0f;
|
||||
|
||||
world_buf.cavity_valley_factor = scene_state.shading.cavity_valley_factor;
|
||||
world_buf.cavity_ridge_factor = scene_state.shading.cavity_ridge_factor;
|
||||
world_buf.cavity_attenuation = scene_state.scene->display.matcap_ssao_attenuation;
|
||||
world_buf.cavity_distance = scene_state.scene->display.matcap_ssao_distance;
|
||||
|
||||
world_buf.curvature_ridge = 0.5f /
|
||||
max_ff(square_f(scene_state.shading.curvature_ridge_factor), 1e-4f);
|
||||
world_buf.curvature_valley = 0.7f / max_ff(square_f(scene_state.shading.curvature_valley_factor),
|
||||
1e-4f);
|
||||
|
||||
if (cavity_enabled_ && sample_count_ != sample_count) {
|
||||
sample_count_ = sample_count;
|
||||
load_samples_buf(ssao_samples);
|
||||
resources.load_jitter_tx(sample_count_);
|
||||
}
|
||||
}
|
||||
|
||||
void CavityEffect::load_samples_buf(int ssao_samples)
|
||||
{
|
||||
const float iteration_samples_inv = 1.0f / ssao_samples;
|
||||
|
||||
/* Create disk samples using Hammersley distribution */
|
||||
for (int i : IndexRange(sample_count_)) {
|
||||
float it_add = (i / ssao_samples) * 0.499f;
|
||||
float r = fmodf((i + 0.5f + it_add) * iteration_samples_inv, 1.0f);
|
||||
double dphi;
|
||||
BLI_hammersley_1d(i, &dphi);
|
||||
|
||||
float phi = float(dphi) * 2.0f * M_PI + it_add;
|
||||
samples_buf[i].x = math::cos(phi);
|
||||
samples_buf[i].y = math::sin(phi);
|
||||
/* This deliberately distribute more samples
|
||||
* at the center of the disk (and thus the shadow). */
|
||||
samples_buf[i].z = r;
|
||||
}
|
||||
|
||||
samples_buf.push_update();
|
||||
}
|
||||
|
||||
void CavityEffect::setup_resolve_pass(PassSimple &pass, SceneResources &resources)
|
||||
{
|
||||
if (cavity_enabled_) {
|
||||
pass.bind_ubo("cavity_samples", samples_buf);
|
||||
pass.bind_texture("jitter_tx", &resources.jitter_tx, eGPUSamplerState::GPU_SAMPLER_REPEAT);
|
||||
}
|
||||
if (curvature_enabled_) {
|
||||
pass.bind_texture("object_id_tx", &resources.object_id_tx);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::workbench
|
271
source/blender/draw/engines/workbench/workbench_effect_dof.cc
Normal file
271
source/blender/draw/engines/workbench/workbench_effect_dof.cc
Normal file
@@ -0,0 +1,271 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*
|
||||
* Depth of Field Effect:
|
||||
*
|
||||
* We use a gather approach by sampling a lowres version of the color buffer.
|
||||
* The process can be summarized like this:
|
||||
* - down-sample the color buffer using a COC (Circle of Confusion) aware down-sample algorithm.
|
||||
* - do a gather pass using the COC computed in the previous pass.
|
||||
* - do a median filter to reduce noise amount.
|
||||
* - composite on top of main color buffer.
|
||||
*
|
||||
* This is done after all passes and affects every surfaces.
|
||||
*/
|
||||
|
||||
#include "workbench_private.hh"
|
||||
|
||||
#include "BKE_camera.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
namespace blender::workbench {
|
||||
/**
|
||||
* Transform [-1..1] square to unit circle.
|
||||
*/
|
||||
static void square_to_circle(float x, float y, float &r, float &T)
|
||||
{
|
||||
if (x > -y) {
|
||||
if (x > y) {
|
||||
r = x;
|
||||
T = M_PI_4 * (y / x);
|
||||
}
|
||||
else {
|
||||
r = y;
|
||||
T = M_PI_4 * (2 - (x / y));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (x < y) {
|
||||
r = -x;
|
||||
T = M_PI_4 * (4 + (y / x));
|
||||
}
|
||||
else {
|
||||
r = -y;
|
||||
if (y != 0) {
|
||||
T = M_PI_4 * (6 - (x / y));
|
||||
}
|
||||
else {
|
||||
T = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DofPass::setup_samples()
|
||||
{
|
||||
float4 *sample = samples_buf_.begin();
|
||||
for (int i = 0; i <= kernel_radius_; i++) {
|
||||
for (int j = -kernel_radius_; j <= kernel_radius_; j++) {
|
||||
for (int k = -kernel_radius_; k <= kernel_radius_; k++) {
|
||||
if (abs(j) > i || abs(k) > i) {
|
||||
continue;
|
||||
}
|
||||
if (abs(j) < i && abs(k) < i) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float2 coord = float2(j, k) / float2(kernel_radius_);
|
||||
float r = 0;
|
||||
float T = 0;
|
||||
square_to_circle(coord.x, coord.y, r, T);
|
||||
sample->z = r;
|
||||
|
||||
/* Bokeh shape parameterization. */
|
||||
if (blades_ > 1.0f) {
|
||||
float denom = T - (2.0 * M_PI / blades_) * floorf((blades_ * T + M_PI) / (2.0 * M_PI));
|
||||
r *= math::cos(M_PI / blades_) / math::cos(denom);
|
||||
}
|
||||
|
||||
T += rotation_;
|
||||
|
||||
sample->x = r * math::cos(T) * ratio_;
|
||||
sample->y = r * math::sin(T);
|
||||
sample->w = 0;
|
||||
sample++;
|
||||
}
|
||||
}
|
||||
}
|
||||
samples_buf_.push_update();
|
||||
}
|
||||
|
||||
void DofPass::init(const SceneState &scene_state)
|
||||
{
|
||||
enabled_ = scene_state.draw_dof;
|
||||
|
||||
if (!enabled_) {
|
||||
source_tx_.free();
|
||||
coc_halfres_tx_.free();
|
||||
return;
|
||||
}
|
||||
|
||||
if (prepare_sh_ == nullptr) {
|
||||
prepare_sh_ = GPU_shader_create_from_info_name("workbench_effect_dof_prepare");
|
||||
downsample_sh_ = GPU_shader_create_from_info_name("workbench_effect_dof_downsample");
|
||||
blur1_sh_ = GPU_shader_create_from_info_name("workbench_effect_dof_blur1");
|
||||
blur2_sh_ = GPU_shader_create_from_info_name("workbench_effect_dof_blur2");
|
||||
resolve_sh_ = GPU_shader_create_from_info_name("workbench_effect_dof_resolve");
|
||||
}
|
||||
|
||||
offset_ = scene_state.sample / float(scene_state.samples_len);
|
||||
|
||||
int2 half_res = scene_state.resolution / 2;
|
||||
half_res = {max_ii(half_res.x, 1), max_ii(half_res.y, 1)};
|
||||
|
||||
source_tx_.ensure_2d(GPU_RGBA16F, half_res, GPU_TEXTURE_USAGE_SHADER_READ, nullptr, 3);
|
||||
source_tx_.ensure_mip_views();
|
||||
source_tx_.filter_mode(true);
|
||||
coc_halfres_tx_.ensure_2d(GPU_RG8, half_res, GPU_TEXTURE_USAGE_SHADER_READ, nullptr, 3);
|
||||
coc_halfres_tx_.ensure_mip_views();
|
||||
coc_halfres_tx_.filter_mode(true);
|
||||
|
||||
Camera *camera = scene_state.camera;
|
||||
|
||||
/* Parameters */
|
||||
float fstop = camera->dof.aperture_fstop;
|
||||
float sensor = BKE_camera_sensor_size(camera->sensor_fit, camera->sensor_x, camera->sensor_y);
|
||||
float focus_dist = BKE_camera_object_dof_distance(scene_state.camera_object);
|
||||
float focal_len = camera->lens;
|
||||
|
||||
/* TODO(fclem): De-duplicate with EEVEE. */
|
||||
const float scale_camera = 0.001f;
|
||||
/* We want radius here for the aperture number. */
|
||||
float aperture = 0.5f * scale_camera * focal_len / fstop;
|
||||
float focal_len_scaled = scale_camera * focal_len;
|
||||
float sensor_scaled = scale_camera * sensor;
|
||||
|
||||
if (RegionView3D *rv3d = DRW_context_state_get()->rv3d) {
|
||||
sensor_scaled *= rv3d->viewcamtexcofac[0];
|
||||
}
|
||||
|
||||
aperture_size_ = aperture * fabsf(focal_len_scaled / (focus_dist - focal_len_scaled));
|
||||
distance_ = -focus_dist;
|
||||
invsensor_size_ = scene_state.resolution.x / sensor_scaled;
|
||||
|
||||
near_ = -camera->clip_start;
|
||||
far_ = -camera->clip_end;
|
||||
|
||||
float blades = camera->dof.aperture_blades;
|
||||
float rotation = camera->dof.aperture_rotation;
|
||||
float ratio = 1.0f / camera->dof.aperture_ratio;
|
||||
|
||||
if (blades_ != blades || rotation_ != rotation || ratio_ != ratio) {
|
||||
blades_ = blades;
|
||||
rotation_ = rotation;
|
||||
ratio_ = ratio;
|
||||
setup_samples();
|
||||
}
|
||||
}
|
||||
|
||||
void DofPass::sync(SceneResources &resources)
|
||||
{
|
||||
if (!enabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
eGPUSamplerState sampler_state = GPU_SAMPLER_FILTER | GPU_SAMPLER_MIPMAP;
|
||||
|
||||
down_ps_.init();
|
||||
down_ps_.state_set(DRW_STATE_WRITE_COLOR);
|
||||
down_ps_.shader_set(prepare_sh_);
|
||||
down_ps_.bind_texture("sceneColorTex", &resources.color_tx);
|
||||
down_ps_.bind_texture("sceneDepthTex", &resources.depth_tx);
|
||||
down_ps_.push_constant("invertedViewportSize", float2(DRW_viewport_invert_size_get()));
|
||||
down_ps_.push_constant("dofParams", float3(aperture_size_, distance_, invsensor_size_));
|
||||
down_ps_.push_constant("nearFar", float2(near_, far_));
|
||||
down_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
|
||||
down2_ps_.init();
|
||||
down2_ps_.state_set(DRW_STATE_WRITE_COLOR);
|
||||
down2_ps_.shader_set(downsample_sh_);
|
||||
down2_ps_.bind_texture("sceneColorTex", &source_tx_, sampler_state);
|
||||
down2_ps_.bind_texture("inputCocTex", &coc_halfres_tx_, sampler_state);
|
||||
down2_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
|
||||
blur_ps_.init();
|
||||
blur_ps_.state_set(DRW_STATE_WRITE_COLOR);
|
||||
blur_ps_.shader_set(blur1_sh_);
|
||||
blur_ps_.bind_ubo("samples", samples_buf_);
|
||||
blur_ps_.bind_texture("noiseTex", resources.jitter_tx);
|
||||
blur_ps_.bind_texture("inputCocTex", &coc_halfres_tx_, sampler_state);
|
||||
blur_ps_.bind_texture("halfResColorTex", &source_tx_, sampler_state);
|
||||
blur_ps_.push_constant("invertedViewportSize", float2(DRW_viewport_invert_size_get()));
|
||||
blur_ps_.push_constant("noiseOffset", offset_);
|
||||
blur_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
|
||||
blur2_ps_.init();
|
||||
blur2_ps_.state_set(DRW_STATE_WRITE_COLOR);
|
||||
blur2_ps_.shader_set(blur2_sh_);
|
||||
blur2_ps_.bind_texture("inputCocTex", &coc_halfres_tx_, sampler_state);
|
||||
blur2_ps_.bind_texture("blurTex", &blur_tx_);
|
||||
blur2_ps_.push_constant("invertedViewportSize", float2(DRW_viewport_invert_size_get()));
|
||||
blur2_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
|
||||
resolve_ps_.init();
|
||||
resolve_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM);
|
||||
resolve_ps_.shader_set(resolve_sh_);
|
||||
resolve_ps_.bind_texture("halfResColorTex", &source_tx_, sampler_state);
|
||||
resolve_ps_.bind_texture("sceneDepthTex", &resources.depth_tx);
|
||||
resolve_ps_.push_constant("invertedViewportSize", float2(DRW_viewport_invert_size_get()));
|
||||
resolve_ps_.push_constant("dofParams", float3(aperture_size_, distance_, invsensor_size_));
|
||||
resolve_ps_.push_constant("nearFar", float2(near_, far_));
|
||||
resolve_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
}
|
||||
|
||||
void DofPass::draw(Manager &manager, View &view, SceneResources &resources, int2 resolution)
|
||||
{
|
||||
if (!enabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
DRW_stats_group_start("Depth Of Field");
|
||||
|
||||
int2 half_res = {max_ii(resolution.x / 2, 1), max_ii(resolution.y / 2, 1)};
|
||||
blur_tx_.acquire(
|
||||
half_res, GPU_RGBA16F, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
|
||||
downsample_fb_.ensure(GPU_ATTACHMENT_NONE,
|
||||
GPU_ATTACHMENT_TEXTURE(source_tx_),
|
||||
GPU_ATTACHMENT_TEXTURE(coc_halfres_tx_));
|
||||
downsample_fb_.bind();
|
||||
manager.submit(down_ps_, view);
|
||||
|
||||
struct CallbackData {
|
||||
Manager &manager;
|
||||
View &view;
|
||||
PassSimple &pass;
|
||||
};
|
||||
CallbackData callback_data = {manager, view, down2_ps_};
|
||||
|
||||
auto downsample_level = [](void *callback_data, int /*level*/) {
|
||||
CallbackData *cd = static_cast<CallbackData *>(callback_data);
|
||||
cd->manager.submit(cd->pass, cd->view);
|
||||
};
|
||||
|
||||
GPU_framebuffer_recursive_downsample(
|
||||
downsample_fb_, 2, downsample_level, static_cast<void *>(&callback_data));
|
||||
|
||||
blur1_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(blur_tx_));
|
||||
blur1_fb_.bind();
|
||||
manager.submit(blur_ps_, view);
|
||||
|
||||
blur2_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(source_tx_));
|
||||
blur2_fb_.bind();
|
||||
manager.submit(blur2_ps_, view);
|
||||
|
||||
resolve_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx));
|
||||
resolve_fb_.bind();
|
||||
manager.submit(resolve_ps_, view);
|
||||
|
||||
blur_tx_.release();
|
||||
|
||||
DRW_stats_group_end();
|
||||
}
|
||||
|
||||
bool DofPass::is_enabled()
|
||||
{
|
||||
return enabled_;
|
||||
}
|
||||
|
||||
} // namespace blender::workbench
|
@@ -0,0 +1,52 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*
|
||||
* Outline Effect:
|
||||
*
|
||||
* Simple effect that just samples an object id buffer to detect objects outlines.
|
||||
*/
|
||||
|
||||
#include "workbench_private.hh"
|
||||
|
||||
namespace blender::workbench {
|
||||
|
||||
void OutlinePass::init(const SceneState &scene_state)
|
||||
{
|
||||
enabled_ = scene_state.draw_outline;
|
||||
if (!enabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sh_ == nullptr) {
|
||||
sh_ = GPU_shader_create_from_info_name("workbench_effect_outline");
|
||||
}
|
||||
}
|
||||
|
||||
void OutlinePass::sync(SceneResources &resources)
|
||||
{
|
||||
if (!enabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
ps_.init();
|
||||
ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL);
|
||||
ps_.shader_set(sh_);
|
||||
ps_.bind_ubo("world_data", resources.world_buf);
|
||||
ps_.bind_texture("objectIdBuffer", &resources.object_id_tx);
|
||||
ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
}
|
||||
|
||||
void OutlinePass::draw(Manager &manager, View &view, SceneResources &resources, int2 resolution)
|
||||
{
|
||||
if (!enabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx));
|
||||
fb_.bind();
|
||||
manager.submit(ps_);
|
||||
}
|
||||
|
||||
} // namespace blender::workbench
|
739
source/blender/draw/engines/workbench/workbench_engine.cc
Normal file
739
source/blender/draw/engines/workbench/workbench_engine.cc
Normal file
@@ -0,0 +1,739 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_pbvh.h"
|
||||
#include "BKE_report.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
#include "DNA_fluid_types.h"
|
||||
#include "ED_paint.h"
|
||||
#include "ED_view3d.h"
|
||||
#include "GPU_capabilities.h"
|
||||
|
||||
#include "workbench_private.hh"
|
||||
|
||||
namespace blender::workbench {
|
||||
|
||||
using namespace draw;
|
||||
|
||||
class Instance {
|
||||
public:
|
||||
View view = {"DefaultView"};
|
||||
|
||||
SceneState scene_state;
|
||||
|
||||
SceneResources resources;
|
||||
|
||||
OpaquePass opaque_ps;
|
||||
TransparentPass transparent_ps;
|
||||
TransparentDepthPass transparent_depth_ps;
|
||||
|
||||
ShadowPass shadow_ps;
|
||||
OutlinePass outline_ps;
|
||||
DofPass dof_ps;
|
||||
AntiAliasingPass anti_aliasing_ps;
|
||||
|
||||
/* An array of nullptr GPUMaterial pointers so we can call DRW_cache_object_surface_material_get.
|
||||
* They never get actually used. */
|
||||
Vector<GPUMaterial *> dummy_gpu_materials = {1, nullptr, {}};
|
||||
GPUMaterial **get_dummy_gpu_materials(int material_count)
|
||||
{
|
||||
if (material_count > dummy_gpu_materials.size()) {
|
||||
dummy_gpu_materials.resize(material_count, nullptr);
|
||||
}
|
||||
return dummy_gpu_materials.begin();
|
||||
};
|
||||
|
||||
void init(Object *camera_ob = nullptr)
|
||||
{
|
||||
scene_state.init(camera_ob);
|
||||
shadow_ps.init(scene_state, resources);
|
||||
resources.init(scene_state);
|
||||
|
||||
outline_ps.init(scene_state);
|
||||
dof_ps.init(scene_state);
|
||||
anti_aliasing_ps.init(scene_state);
|
||||
}
|
||||
|
||||
void begin_sync()
|
||||
{
|
||||
const float2 viewport_size = DRW_viewport_size_get();
|
||||
const int2 resolution = {int(viewport_size.x), int(viewport_size.y)};
|
||||
resources.depth_tx.ensure_2d(GPU_DEPTH24_STENCIL8,
|
||||
resolution,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
|
||||
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW);
|
||||
|
||||
opaque_ps.sync(scene_state, resources);
|
||||
transparent_ps.sync(scene_state, resources);
|
||||
transparent_depth_ps.sync(scene_state, resources);
|
||||
|
||||
shadow_ps.sync();
|
||||
outline_ps.sync(resources);
|
||||
dof_ps.sync(resources);
|
||||
anti_aliasing_ps.sync(resources, scene_state.resolution);
|
||||
}
|
||||
|
||||
void end_sync()
|
||||
{
|
||||
resources.material_buf.push_update();
|
||||
}
|
||||
|
||||
void object_sync(Manager &manager, ObjectRef &ob_ref)
|
||||
{
|
||||
if (scene_state.render_finished) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object *ob = ob_ref.object;
|
||||
if (!DRW_object_is_renderable(ob)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ObjectState object_state = ObjectState(scene_state, ob);
|
||||
|
||||
/* Needed for mesh cache validation, to prevent two copies of
|
||||
* of vertex color arrays from being sent to the GPU (e.g.
|
||||
* when switching from eevee to workbench).
|
||||
*/
|
||||
if (ob_ref.object->sculpt && ob_ref.object->sculpt->pbvh) {
|
||||
BKE_pbvh_is_drawing_set(ob_ref.object->sculpt->pbvh, object_state.sculpt_pbvh);
|
||||
}
|
||||
|
||||
if (ob->type == OB_MESH && ob->modifiers.first != nullptr) {
|
||||
|
||||
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
|
||||
if (md->type != eModifierType_ParticleSystem) {
|
||||
continue;
|
||||
}
|
||||
ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
|
||||
if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
|
||||
continue;
|
||||
}
|
||||
ParticleSettings *part = psys->part;
|
||||
const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
|
||||
|
||||
if (draw_as == PART_DRAW_PATH) {
|
||||
/* TODO(Miguel Pozo):
|
||||
workbench_cache_hair_populate(
|
||||
wpd, ob, psys, md, object_state.color_type, object_state.texture_paint_mode,
|
||||
part->omat);
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ob->base_flag & BASE_FROM_DUPLI)) {
|
||||
ModifierData *md = BKE_modifiers_findby_type(ob, eModifierType_Fluid);
|
||||
if (md && BKE_modifier_is_enabled(scene_state.scene, md, eModifierMode_Realtime)) {
|
||||
FluidModifierData *fmd = (FluidModifierData *)md;
|
||||
if (fmd->domain) {
|
||||
/* TODO(Miguel Pozo):
|
||||
workbench_volume_cache_populate(vedata, wpd->scene, ob, md, V3D_SHADING_SINGLE_COLOR);
|
||||
*/
|
||||
if (fmd->domain->type == FLUID_DOMAIN_TYPE_GAS) {
|
||||
return; /* Do not draw solid in this case. */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ob->dt < OB_SOLID) && !DRW_state_is_scene_render()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ELEM(ob->type, OB_MESH, OB_POINTCLOUD)) {
|
||||
mesh_sync(manager, ob_ref, object_state);
|
||||
}
|
||||
else if (ob->type == OB_CURVES) {
|
||||
/* TODO(Miguel Pozo):
|
||||
DRWShadingGroup *grp = workbench_material_hair_setup(
|
||||
wpd, ob, CURVES_MATERIAL_NR, object_state.color_type);
|
||||
DRW_shgroup_curves_create_sub(ob, grp, NULL);
|
||||
*/
|
||||
}
|
||||
else if (ob->type == OB_VOLUME) {
|
||||
if (scene_state.shading.type != OB_WIRE) {
|
||||
/* TODO(Miguel Pozo):
|
||||
workbench_volume_cache_populate(vedata, wpd->scene, ob, NULL, object_state.color_type);
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mesh_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state)
|
||||
{
|
||||
ResourceHandle handle = manager.resource_handle(ob_ref);
|
||||
bool has_transparent_material = false;
|
||||
|
||||
if (object_state.sculpt_pbvh) {
|
||||
/* TODO(Miguel Pozo):
|
||||
workbench_cache_sculpt_populate(wpd, ob, object_state.color_type);
|
||||
*/
|
||||
}
|
||||
else {
|
||||
if (object_state.use_per_material_batches) {
|
||||
const int material_count = DRW_cache_object_material_count_get(ob_ref.object);
|
||||
|
||||
struct GPUBatch **batches;
|
||||
if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
|
||||
batches = DRW_cache_mesh_surface_texpaint_get(ob_ref.object);
|
||||
}
|
||||
else {
|
||||
batches = DRW_cache_object_surface_material_get(
|
||||
ob_ref.object, get_dummy_gpu_materials(material_count), material_count);
|
||||
}
|
||||
|
||||
if (batches) {
|
||||
for (auto i : IndexRange(material_count)) {
|
||||
if (batches[i] == nullptr) {
|
||||
continue;
|
||||
}
|
||||
/* TODO(fclem): This create a cull-able instance for each sub-object. This is done
|
||||
* for simplicity to reduce complexity. But this increase the overhead per object.
|
||||
* Instead, we should use an indirection buffer to the material buffer. */
|
||||
ResourceHandle _handle = i == 0 ? handle : manager.resource_handle(ob_ref);
|
||||
|
||||
Material &mat = resources.material_buf.get_or_resize(_handle.resource_index());
|
||||
|
||||
if (::Material *_mat = BKE_object_material_get_eval(ob_ref.object, i + 1)) {
|
||||
mat = Material(*_mat);
|
||||
}
|
||||
else {
|
||||
mat = Material(*BKE_material_default_empty());
|
||||
}
|
||||
|
||||
has_transparent_material = has_transparent_material || mat.is_transparent();
|
||||
|
||||
::Image *image = nullptr;
|
||||
ImageUser *iuser = nullptr;
|
||||
eGPUSamplerState sampler_state = eGPUSamplerState::GPU_SAMPLER_DEFAULT;
|
||||
if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
|
||||
get_material_image(ob_ref.object, i + 1, image, iuser, sampler_state);
|
||||
}
|
||||
|
||||
draw_mesh(ob_ref, mat, batches[i], _handle, image, sampler_state, iuser);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
struct GPUBatch *batch;
|
||||
if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
|
||||
batch = DRW_cache_mesh_surface_texpaint_single_get(ob_ref.object);
|
||||
}
|
||||
else if (object_state.color_type == V3D_SHADING_VERTEX_COLOR) {
|
||||
if (ob_ref.object->mode & OB_MODE_VERTEX_PAINT) {
|
||||
batch = DRW_cache_mesh_surface_vertpaint_get(ob_ref.object);
|
||||
}
|
||||
else {
|
||||
batch = DRW_cache_mesh_surface_sculptcolors_get(ob_ref.object);
|
||||
}
|
||||
}
|
||||
else {
|
||||
batch = DRW_cache_object_surface_get(ob_ref.object);
|
||||
}
|
||||
|
||||
if (batch) {
|
||||
Material &mat = resources.material_buf.get_or_resize(handle.resource_index());
|
||||
|
||||
if (object_state.color_type == V3D_SHADING_OBJECT_COLOR) {
|
||||
mat = Material(*ob_ref.object);
|
||||
}
|
||||
else if (object_state.color_type == V3D_SHADING_RANDOM_COLOR) {
|
||||
mat = Material(*ob_ref.object, true);
|
||||
}
|
||||
else if (object_state.color_type == V3D_SHADING_SINGLE_COLOR) {
|
||||
mat = scene_state.material_override;
|
||||
}
|
||||
else if (object_state.color_type == V3D_SHADING_VERTEX_COLOR) {
|
||||
mat = scene_state.material_attribute_color;
|
||||
}
|
||||
else {
|
||||
mat = Material(*BKE_material_default_empty());
|
||||
}
|
||||
|
||||
has_transparent_material = has_transparent_material || mat.is_transparent();
|
||||
|
||||
draw_mesh(ob_ref,
|
||||
mat,
|
||||
batch,
|
||||
handle,
|
||||
object_state.image_paint_override,
|
||||
object_state.override_sampler_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (object_state.draw_shadow) {
|
||||
shadow_ps.object_sync(manager, scene_state, ob_ref, handle, has_transparent_material);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_mesh(ObjectRef &ob_ref,
|
||||
Material &material,
|
||||
GPUBatch *batch,
|
||||
ResourceHandle handle,
|
||||
::Image *image = nullptr,
|
||||
eGPUSamplerState sampler_state = GPU_SAMPLER_DEFAULT,
|
||||
ImageUser *iuser = nullptr)
|
||||
{
|
||||
const bool in_front = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0;
|
||||
|
||||
auto draw = [&](MeshPass &pass) {
|
||||
pass.draw(ob_ref, batch, handle, image, sampler_state, iuser);
|
||||
};
|
||||
|
||||
if (scene_state.xray_mode || material.is_transparent()) {
|
||||
if (in_front) {
|
||||
draw(transparent_ps.accumulation_in_front_ps_);
|
||||
if (scene_state.draw_transparent_depth) {
|
||||
draw(transparent_depth_ps.in_front_ps_);
|
||||
}
|
||||
}
|
||||
else {
|
||||
draw(transparent_ps.accumulation_ps_);
|
||||
if (scene_state.draw_transparent_depth) {
|
||||
draw(transparent_depth_ps.main_ps_);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (in_front) {
|
||||
draw(opaque_ps.gbuffer_in_front_ps_);
|
||||
}
|
||||
else {
|
||||
draw(opaque_ps.gbuffer_ps_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw(Manager &manager, GPUTexture *depth_tx, GPUTexture *color_tx)
|
||||
{
|
||||
view.sync(DRW_view_default_get());
|
||||
|
||||
int2 resolution = scene_state.resolution;
|
||||
|
||||
if (scene_state.render_finished) {
|
||||
/* Just copy back the already rendered result */
|
||||
anti_aliasing_ps.draw(manager, view, resources, resolution, depth_tx, color_tx);
|
||||
return;
|
||||
}
|
||||
|
||||
anti_aliasing_ps.setup_view(view, resolution);
|
||||
|
||||
resources.color_tx.acquire(
|
||||
resolution, GPU_RGBA16F, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
resources.color_tx.clear(resources.world_buf.background_color);
|
||||
if (scene_state.draw_object_id) {
|
||||
resources.object_id_tx.acquire(
|
||||
resolution, GPU_R16UI, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
resources.object_id_tx.clear(uint4(0));
|
||||
}
|
||||
|
||||
Framebuffer fb = Framebuffer("Workbench.Clear");
|
||||
fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx));
|
||||
fb.bind();
|
||||
GPU_framebuffer_clear_depth_stencil(fb, 1.0f, 0x00);
|
||||
|
||||
if (!transparent_ps.accumulation_in_front_ps_.is_empty()) {
|
||||
resources.depth_in_front_tx.acquire(resolution,
|
||||
GPU_DEPTH24_STENCIL8,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ |
|
||||
GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
if (opaque_ps.gbuffer_in_front_ps_.is_empty()) {
|
||||
/* Clear only if it wont be overwitten by opaque_ps */
|
||||
Framebuffer fb = Framebuffer("Workbench.Clear");
|
||||
fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_in_front_tx));
|
||||
fb.bind();
|
||||
GPU_framebuffer_clear_depth_stencil(fb, 1.0f, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
opaque_ps.draw(manager,
|
||||
view,
|
||||
resources,
|
||||
resolution,
|
||||
&shadow_ps,
|
||||
transparent_ps.accumulation_ps_.is_empty());
|
||||
transparent_ps.draw(manager, view, resources, resolution);
|
||||
transparent_depth_ps.draw(manager, view, resources, resolution);
|
||||
|
||||
// volume_ps.draw_prepass(manager, view, resources.depth_tx);
|
||||
|
||||
outline_ps.draw(manager, view, resources, resolution);
|
||||
dof_ps.draw(manager, view, resources, resolution);
|
||||
anti_aliasing_ps.draw(manager, view, resources, resolution, depth_tx, color_tx);
|
||||
|
||||
resources.color_tx.release();
|
||||
resources.object_id_tx.release();
|
||||
resources.depth_in_front_tx.release();
|
||||
}
|
||||
|
||||
void draw_viewport(Manager &manager, GPUTexture *depth_tx, GPUTexture *color_tx)
|
||||
{
|
||||
this->draw(manager, depth_tx, color_tx);
|
||||
|
||||
if (scene_state.sample + 1 < scene_state.samples_len) {
|
||||
DRW_viewport_request_redraw();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace blender::workbench
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Interface with legacy C DRW manager
|
||||
* \{ */
|
||||
|
||||
using namespace blender;
|
||||
|
||||
struct WORKBENCH_Data {
|
||||
DrawEngineType *engine_type;
|
||||
DRWViewportEmptyList *fbl;
|
||||
DRWViewportEmptyList *txl;
|
||||
DRWViewportEmptyList *psl;
|
||||
DRWViewportEmptyList *stl;
|
||||
workbench::Instance *instance;
|
||||
draw::View *view;
|
||||
|
||||
char info[GPU_INFO_SIZE];
|
||||
};
|
||||
|
||||
static void workbench_engine_init(void *vedata)
|
||||
{
|
||||
/* TODO(fclem): Remove once it is minimum required. */
|
||||
if (!GPU_shader_storage_buffer_objects_support()) {
|
||||
return;
|
||||
}
|
||||
|
||||
WORKBENCH_Data *ved = reinterpret_cast<WORKBENCH_Data *>(vedata);
|
||||
if (ved->instance == nullptr) {
|
||||
ved->instance = new workbench::Instance();
|
||||
ved->view = new draw::View("Default View");
|
||||
}
|
||||
|
||||
ved->instance->init();
|
||||
}
|
||||
|
||||
static void workbench_cache_init(void *vedata)
|
||||
{
|
||||
if (!GPU_shader_storage_buffer_objects_support()) {
|
||||
return;
|
||||
}
|
||||
reinterpret_cast<WORKBENCH_Data *>(vedata)->instance->begin_sync();
|
||||
}
|
||||
|
||||
static void workbench_cache_populate(void *vedata, Object *object)
|
||||
{
|
||||
if (!GPU_shader_storage_buffer_objects_support()) {
|
||||
return;
|
||||
}
|
||||
draw::Manager *manager = DRW_manager_get();
|
||||
|
||||
draw::ObjectRef ref;
|
||||
ref.object = object;
|
||||
ref.dupli_object = DRW_object_get_dupli(object);
|
||||
ref.dupli_parent = DRW_object_get_dupli_parent(object);
|
||||
|
||||
reinterpret_cast<WORKBENCH_Data *>(vedata)->instance->object_sync(*manager, ref);
|
||||
}
|
||||
|
||||
static void workbench_cache_finish(void *vedata)
|
||||
{
|
||||
if (!GPU_shader_storage_buffer_objects_support()) {
|
||||
return;
|
||||
}
|
||||
reinterpret_cast<WORKBENCH_Data *>(vedata)->instance->end_sync();
|
||||
}
|
||||
|
||||
static void workbench_draw_scene(void *vedata)
|
||||
{
|
||||
WORKBENCH_Data *ved = reinterpret_cast<WORKBENCH_Data *>(vedata);
|
||||
if (!GPU_shader_storage_buffer_objects_support()) {
|
||||
STRNCPY(ved->info, "Error: No shader storage buffer support");
|
||||
return;
|
||||
}
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
draw::Manager *manager = DRW_manager_get();
|
||||
ved->instance->draw_viewport(*manager, dtxl->depth, dtxl->color);
|
||||
}
|
||||
|
||||
static void workbench_instance_free(void *instance)
|
||||
{
|
||||
if (!GPU_shader_storage_buffer_objects_support()) {
|
||||
return;
|
||||
}
|
||||
delete reinterpret_cast<workbench::Instance *>(instance);
|
||||
}
|
||||
|
||||
static void workbench_view_update(void *vedata)
|
||||
{
|
||||
WORKBENCH_Data *ved = reinterpret_cast<WORKBENCH_Data *>(vedata);
|
||||
if (ved->instance) {
|
||||
ved->instance->scene_state.reset_taa_next_sample = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void workbench_id_update(void *vedata, struct ID *id)
|
||||
{
|
||||
UNUSED_VARS(vedata, id);
|
||||
}
|
||||
|
||||
/* RENDER */
|
||||
|
||||
static bool workbench_render_framebuffers_init(void)
|
||||
{
|
||||
/* For image render, allocate own buffers because we don't have a viewport. */
|
||||
const float2 viewport_size = DRW_viewport_size_get();
|
||||
const int2 size = {int(viewport_size.x), int(viewport_size.y)};
|
||||
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
/* When doing a multi view rendering the first view will allocate the buffers
|
||||
* the other views will reuse these buffers */
|
||||
if (dtxl->color == nullptr) {
|
||||
BLI_assert(dtxl->depth == nullptr);
|
||||
dtxl->color = GPU_texture_create_2d("txl.color", size.x, size.y, 1, GPU_RGBA16F, nullptr);
|
||||
dtxl->depth = GPU_texture_create_2d(
|
||||
"txl.depth", size.x, size.y, 1, GPU_DEPTH24_STENCIL8, nullptr);
|
||||
}
|
||||
|
||||
if (!(dtxl->depth && dtxl->color)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
|
||||
|
||||
GPU_framebuffer_ensure_config(
|
||||
&dfbl->default_fb,
|
||||
{GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
|
||||
|
||||
GPU_framebuffer_ensure_config(&dfbl->depth_only_fb,
|
||||
{GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_NONE});
|
||||
|
||||
GPU_framebuffer_ensure_config(&dfbl->color_only_fb,
|
||||
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dtxl->color)});
|
||||
|
||||
return GPU_framebuffer_check_valid(dfbl->default_fb, nullptr) &&
|
||||
GPU_framebuffer_check_valid(dfbl->color_only_fb, nullptr) &&
|
||||
GPU_framebuffer_check_valid(dfbl->depth_only_fb, nullptr);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* This is just to ease GPU debugging when the frame delimiter is set to Finish */
|
||||
# define GPU_FINISH_DELIMITER() GPU_finish()
|
||||
#else
|
||||
# define GPU_FINISH_DELIMITER()
|
||||
#endif
|
||||
|
||||
static void write_render_color_output(struct RenderLayer *layer,
|
||||
const char *viewname,
|
||||
GPUFrameBuffer *fb,
|
||||
const struct rcti *rect)
|
||||
{
|
||||
RenderPass *rp = RE_pass_find_by_name(layer, RE_PASSNAME_COMBINED, viewname);
|
||||
if (rp) {
|
||||
GPU_framebuffer_bind(fb);
|
||||
GPU_framebuffer_read_color(fb,
|
||||
rect->xmin,
|
||||
rect->ymin,
|
||||
BLI_rcti_size_x(rect),
|
||||
BLI_rcti_size_y(rect),
|
||||
4,
|
||||
0,
|
||||
GPU_DATA_FLOAT,
|
||||
rp->rect);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_render_z_output(struct RenderLayer *layer,
|
||||
const char *viewname,
|
||||
GPUFrameBuffer *fb,
|
||||
const struct rcti *rect,
|
||||
float4x4 winmat)
|
||||
{
|
||||
RenderPass *rp = RE_pass_find_by_name(layer, RE_PASSNAME_Z, viewname);
|
||||
if (rp) {
|
||||
GPU_framebuffer_bind(fb);
|
||||
GPU_framebuffer_read_depth(fb,
|
||||
rect->xmin,
|
||||
rect->ymin,
|
||||
BLI_rcti_size_x(rect),
|
||||
BLI_rcti_size_y(rect),
|
||||
GPU_DATA_FLOAT,
|
||||
rp->rect);
|
||||
|
||||
int pix_num = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
|
||||
|
||||
/* Convert ogl depth [0..1] to view Z [near..far] */
|
||||
if (DRW_view_is_persp_get(nullptr)) {
|
||||
for (float &z : MutableSpan(rp->rect, pix_num)) {
|
||||
if (z == 1.0f) {
|
||||
z = 1e10f; /* Background */
|
||||
}
|
||||
else {
|
||||
z = z * 2.0f - 1.0f;
|
||||
z = winmat[3][2] / (z + winmat[2][2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Keep in mind, near and far distance are negatives. */
|
||||
float near = DRW_view_near_distance_get(nullptr);
|
||||
float far = DRW_view_far_distance_get(nullptr);
|
||||
float range = fabsf(far - near);
|
||||
|
||||
for (float &z : MutableSpan(rp->rect, pix_num)) {
|
||||
if (z == 1.0f) {
|
||||
z = 1e10f; /* Background */
|
||||
}
|
||||
else {
|
||||
z = z * range - near;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void workbench_render_to_image(void *vedata,
|
||||
struct RenderEngine *engine,
|
||||
struct RenderLayer *layer,
|
||||
const struct rcti *rect)
|
||||
{
|
||||
/* TODO(fclem): Remove once it is minimum required. */
|
||||
if (!GPU_shader_storage_buffer_objects_support()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!workbench_render_framebuffers_init()) {
|
||||
RE_engine_report(engine, RPT_ERROR, "Failed to allocate GPU buffers");
|
||||
return;
|
||||
}
|
||||
|
||||
GPU_FINISH_DELIMITER();
|
||||
|
||||
/* Setup */
|
||||
|
||||
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
Depsgraph *depsgraph = draw_ctx->depsgraph;
|
||||
|
||||
WORKBENCH_Data *ved = reinterpret_cast<WORKBENCH_Data *>(vedata);
|
||||
if (ved->instance == nullptr) {
|
||||
ved->instance = new workbench::Instance();
|
||||
}
|
||||
|
||||
/* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */
|
||||
Object *camera_ob = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
|
||||
|
||||
/* Set the perspective, view and window matrix. */
|
||||
float4x4 winmat, viewmat, viewinv;
|
||||
RE_GetCameraWindow(engine->re, camera_ob, winmat.ptr());
|
||||
RE_GetCameraModelMatrix(engine->re, camera_ob, viewinv.ptr());
|
||||
viewmat = viewinv.inverted();
|
||||
|
||||
DRWView *view = DRW_view_create(viewmat.ptr(), winmat.ptr(), nullptr, nullptr, nullptr);
|
||||
DRW_view_default_set(view);
|
||||
DRW_view_set_active(view);
|
||||
|
||||
/* Render */
|
||||
do {
|
||||
if (RE_engine_test_break(engine)) {
|
||||
break;
|
||||
}
|
||||
|
||||
ved->instance->init(camera_ob);
|
||||
|
||||
DRW_manager_get()->begin_sync();
|
||||
|
||||
workbench_cache_init(vedata);
|
||||
auto workbench_render_cache = [](void *vedata,
|
||||
struct Object *ob,
|
||||
struct RenderEngine * /*engine*/,
|
||||
struct Depsgraph * /*depsgraph*/) {
|
||||
workbench_cache_populate(vedata, ob);
|
||||
};
|
||||
DRW_render_object_iter(vedata, engine, depsgraph, workbench_render_cache);
|
||||
workbench_cache_finish(vedata);
|
||||
|
||||
DRW_manager_get()->end_sync();
|
||||
|
||||
/* Also we weed to have a correct FBO bound for #DRW_curves_update */
|
||||
// GPU_framebuffer_bind(dfbl->default_fb);
|
||||
// DRW_curves_update(); /* TODO(Miguel Pozo): Check this once curves are implemented */
|
||||
|
||||
workbench_draw_scene(vedata);
|
||||
|
||||
/* Perform render step between samples to allow
|
||||
* flushing of freed GPUBackend resources. */
|
||||
GPU_render_step();
|
||||
GPU_FINISH_DELIMITER();
|
||||
} while (ved->instance->scene_state.sample + 1 < ved->instance->scene_state.samples_len);
|
||||
|
||||
const char *viewname = RE_GetActiveRenderView(engine->re);
|
||||
write_render_color_output(layer, viewname, dfbl->default_fb, rect);
|
||||
write_render_z_output(layer, viewname, dfbl->default_fb, rect, winmat);
|
||||
}
|
||||
|
||||
static void workbench_render_update_passes(RenderEngine *engine,
|
||||
Scene *scene,
|
||||
ViewLayer *view_layer)
|
||||
{
|
||||
if (view_layer->passflag & SCE_PASS_COMBINED) {
|
||||
RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
|
||||
}
|
||||
if (view_layer->passflag & SCE_PASS_Z) {
|
||||
RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_Z, 1, "Z", SOCK_FLOAT);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
static const DrawEngineDataSize workbench_data_size = DRW_VIEWPORT_DATA_SIZE(WORKBENCH_Data);
|
||||
|
||||
DrawEngineType draw_engine_workbench_next = {
|
||||
nullptr,
|
||||
nullptr,
|
||||
N_("Workbench"),
|
||||
&workbench_data_size,
|
||||
&workbench_engine_init,
|
||||
nullptr,
|
||||
&workbench_instance_free,
|
||||
&workbench_cache_init,
|
||||
&workbench_cache_populate,
|
||||
&workbench_cache_finish,
|
||||
&workbench_draw_scene,
|
||||
&workbench_view_update,
|
||||
&workbench_id_update,
|
||||
&workbench_render_to_image,
|
||||
nullptr,
|
||||
};
|
||||
|
||||
RenderEngineType DRW_engine_viewport_workbench_next_type = {
|
||||
nullptr,
|
||||
nullptr,
|
||||
"BLENDER_WORKBENCH_NEXT",
|
||||
N_("Workbench Next"),
|
||||
RE_INTERNAL | RE_USE_STEREO_VIEWPORT | RE_USE_GPU_CONTEXT,
|
||||
nullptr,
|
||||
&DRW_render_to_image,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&workbench_render_update_passes,
|
||||
&draw_engine_workbench_next,
|
||||
{nullptr, nullptr, nullptr},
|
||||
};
|
||||
}
|
||||
|
||||
/** \} */
|
@@ -8,3 +8,4 @@
|
||||
#pragma once
|
||||
|
||||
extern RenderEngineType DRW_engine_viewport_workbench_type;
|
||||
extern RenderEngineType DRW_engine_viewport_workbench_next_type;
|
||||
|
96
source/blender/draw/engines/workbench/workbench_enums.hh
Normal file
96
source/blender/draw/engines/workbench/workbench_enums.hh
Normal file
@@ -0,0 +1,96 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_assert.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_view3d_enums.h"
|
||||
|
||||
namespace blender::workbench {
|
||||
|
||||
enum class eGeometryType {
|
||||
MESH = 0,
|
||||
CURVES,
|
||||
POINTCLOUD,
|
||||
};
|
||||
static constexpr int geometry_type_len = static_cast<int>(eGeometryType::POINTCLOUD) + 1;
|
||||
|
||||
static inline const char *get_name(eGeometryType type)
|
||||
{
|
||||
switch (type) {
|
||||
case eGeometryType::MESH:
|
||||
return "Mesh";
|
||||
case eGeometryType::CURVES:
|
||||
return "Curves";
|
||||
case eGeometryType::POINTCLOUD:
|
||||
return "PointCloud";
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
static inline eGeometryType geometry_type_from_object(Object *ob)
|
||||
{
|
||||
switch (ob->type) {
|
||||
case OB_CURVES:
|
||||
return eGeometryType::CURVES;
|
||||
case OB_POINTCLOUD:
|
||||
return eGeometryType::POINTCLOUD;
|
||||
default:
|
||||
return eGeometryType::MESH;
|
||||
}
|
||||
}
|
||||
|
||||
enum class ePipelineType {
|
||||
OPAQUE = 0,
|
||||
TRANSPARENT,
|
||||
SHADOW,
|
||||
};
|
||||
static constexpr int pipeline_type_len = static_cast<int>(ePipelineType::SHADOW) + 1;
|
||||
|
||||
enum class eLightingType {
|
||||
FLAT = 0,
|
||||
STUDIO,
|
||||
MATCAP,
|
||||
};
|
||||
static constexpr int lighting_type_len = static_cast<int>(eLightingType::MATCAP) + 1;
|
||||
|
||||
static inline eLightingType lighting_type_from_v3d_lighting(char lighting)
|
||||
{
|
||||
switch (lighting) {
|
||||
case V3D_LIGHTING_FLAT:
|
||||
return eLightingType::FLAT;
|
||||
case V3D_LIGHTING_MATCAP:
|
||||
return eLightingType::MATCAP;
|
||||
case V3D_LIGHTING_STUDIO:
|
||||
return eLightingType::STUDIO;
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
return static_cast<eLightingType>(-1);
|
||||
}
|
||||
}
|
||||
|
||||
enum class eShaderType {
|
||||
MATERIAL = 0,
|
||||
TEXTURE,
|
||||
};
|
||||
static constexpr int shader_type_len = static_cast<int>(eShaderType::TEXTURE) + 1;
|
||||
|
||||
static inline eShaderType shader_type_from_v3d_shading(char shading)
|
||||
{
|
||||
return shading == V3D_SHADING_TEXTURE_COLOR ? eShaderType::TEXTURE : eShaderType::MATERIAL;
|
||||
}
|
||||
|
||||
static inline const char *get_name(eShaderType type)
|
||||
{
|
||||
switch (type) {
|
||||
case eShaderType::MATERIAL:
|
||||
return "Material";
|
||||
case eShaderType::TEXTURE:
|
||||
return "Texture";
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::workbench
|
@@ -0,0 +1,95 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "workbench_private.hh"
|
||||
|
||||
#include "BLI_hash.h"
|
||||
/* get_image */
|
||||
#include "BKE_node.h"
|
||||
#include "DNA_node_types.h"
|
||||
#include "ED_uvedit.h"
|
||||
/* get_image */
|
||||
|
||||
namespace blender::workbench {
|
||||
|
||||
Material::Material() = default;
|
||||
|
||||
Material::Material(float3 color)
|
||||
{
|
||||
base_color = color;
|
||||
packed_data = Material::pack_data(0.0f, 0.4f, 1.0f);
|
||||
}
|
||||
|
||||
Material::Material(::Object &ob, bool random)
|
||||
{
|
||||
if (random) {
|
||||
uint hash = BLI_ghashutil_strhash_p_murmur(ob.id.name);
|
||||
if (ob.id.lib) {
|
||||
hash = (hash * 13) ^ BLI_ghashutil_strhash_p_murmur(ob.id.lib->filepath);
|
||||
}
|
||||
float3 hsv = float3(BLI_hash_int_01(hash), 0.5f, 0.8f);
|
||||
hsv_to_rgb_v(hsv, base_color);
|
||||
}
|
||||
else {
|
||||
base_color = ob.color;
|
||||
}
|
||||
packed_data = Material::pack_data(0.0f, 0.4f, ob.color[3]);
|
||||
}
|
||||
|
||||
Material::Material(::Material &mat)
|
||||
{
|
||||
base_color = &mat.r;
|
||||
packed_data = Material::pack_data(mat.metallic, mat.roughness, mat.a);
|
||||
}
|
||||
|
||||
bool Material::is_transparent()
|
||||
{
|
||||
uint32_t full_alpha_ref = 0x00ff0000;
|
||||
return (packed_data & full_alpha_ref) != full_alpha_ref;
|
||||
}
|
||||
|
||||
uint32_t Material::pack_data(float metallic, float roughness, float alpha)
|
||||
{
|
||||
/* Remap to Disney roughness. */
|
||||
roughness = sqrtf(roughness);
|
||||
uint32_t packed_roughness = unit_float_to_uchar_clamp(roughness);
|
||||
uint32_t packed_metallic = unit_float_to_uchar_clamp(metallic);
|
||||
uint32_t packed_alpha = unit_float_to_uchar_clamp(alpha);
|
||||
return (packed_alpha << 16u) | (packed_roughness << 8u) | packed_metallic;
|
||||
}
|
||||
|
||||
void get_material_image(Object *ob,
|
||||
int material_index,
|
||||
::Image *&image,
|
||||
ImageUser *&iuser,
|
||||
eGPUSamplerState &sampler_state)
|
||||
{
|
||||
const ::bNode *node = nullptr;
|
||||
|
||||
ED_object_get_active_image(ob, material_index, &image, &iuser, &node, nullptr);
|
||||
if (node && image) {
|
||||
switch (node->type) {
|
||||
case SH_NODE_TEX_IMAGE: {
|
||||
const NodeTexImage *storage = static_cast<NodeTexImage *>(node->storage);
|
||||
const bool use_filter = (storage->interpolation != SHD_INTERP_CLOSEST);
|
||||
const bool use_mirror = (storage->extension == SHD_IMAGE_EXTENSION_MIRROR);
|
||||
const bool use_repeat = use_mirror || (storage->extension == SHD_IMAGE_EXTENSION_REPEAT);
|
||||
const bool use_clip = (storage->extension == SHD_IMAGE_EXTENSION_CLIP);
|
||||
SET_FLAG_FROM_TEST(sampler_state, use_filter, GPU_SAMPLER_FILTER);
|
||||
SET_FLAG_FROM_TEST(sampler_state, use_repeat, GPU_SAMPLER_REPEAT);
|
||||
SET_FLAG_FROM_TEST(sampler_state, use_clip, GPU_SAMPLER_CLAMP_BORDER);
|
||||
SET_FLAG_FROM_TEST(sampler_state, use_mirror, GPU_SAMPLER_MIRROR_REPEAT);
|
||||
break;
|
||||
}
|
||||
case SH_NODE_TEX_ENVIRONMENT: {
|
||||
const NodeTexEnvironment *storage = static_cast<NodeTexEnvironment *>(node->storage);
|
||||
const bool use_filter = (storage->interpolation != SHD_INTERP_CLOSEST);
|
||||
SET_FLAG_FROM_TEST(sampler_state, use_filter, GPU_SAMPLER_FILTER);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BLI_assert_msg(0, "Node type not supported by workbench");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::workbench
|
405
source/blender/draw/engines/workbench/workbench_mesh_passes.cc
Normal file
405
source/blender/draw/engines/workbench/workbench_mesh_passes.cc
Normal file
@@ -0,0 +1,405 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "workbench_private.hh"
|
||||
|
||||
namespace blender::workbench {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name MeshPass
|
||||
* \{ */
|
||||
|
||||
MeshPass::MeshPass(const char *name) : PassMain(name){};
|
||||
|
||||
/* Move to draw::Pass */
|
||||
bool MeshPass::is_empty() const
|
||||
{
|
||||
return is_empty_;
|
||||
}
|
||||
|
||||
void MeshPass::init_pass(SceneResources &resources, DRWState state, int clip_planes)
|
||||
{
|
||||
is_empty_ = true;
|
||||
PassMain::init();
|
||||
state_set(state, clip_planes);
|
||||
bind_texture(WB_MATCAP_SLOT, resources.matcap_tx);
|
||||
bind_ssbo(WB_MATERIAL_SLOT, &resources.material_buf);
|
||||
bind_ubo(WB_WORLD_SLOT, resources.world_buf);
|
||||
if (clip_planes > 0) {
|
||||
bind_ubo(DRW_CLIPPING_UBO_SLOT, resources.clip_planes_buf);
|
||||
}
|
||||
}
|
||||
|
||||
void MeshPass::init_subpasses(ePipelineType pipeline,
|
||||
eLightingType lighting,
|
||||
bool clip,
|
||||
ShaderCache &shaders)
|
||||
{
|
||||
texture_subpass_map_.clear();
|
||||
|
||||
static std::string pass_names[geometry_type_len][shader_type_len] = {};
|
||||
|
||||
for (auto geom : IndexRange(geometry_type_len)) {
|
||||
for (auto shader : IndexRange(shader_type_len)) {
|
||||
eGeometryType geom_type = static_cast<eGeometryType>(geom);
|
||||
eShaderType shader_type = static_cast<eShaderType>(shader);
|
||||
if (pass_names[geom][shader].empty()) {
|
||||
pass_names[geom][shader] = std::string(get_name(geom_type)) +
|
||||
std::string(get_name(shader_type));
|
||||
}
|
||||
GPUShader *sh = shaders.prepass_shader_get(pipeline, geom_type, shader_type, lighting, clip);
|
||||
PassMain::Sub *pass = &sub(pass_names[geom][shader].c_str());
|
||||
pass->shader_set(sh);
|
||||
passes_[geom][shader] = pass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MeshPass::draw(ObjectRef &ref,
|
||||
GPUBatch *batch,
|
||||
ResourceHandle handle,
|
||||
::Image *image /* = nullptr */,
|
||||
eGPUSamplerState sampler_state /* = GPU_SAMPLER_DEFAULT */,
|
||||
ImageUser *iuser /* = nullptr */)
|
||||
{
|
||||
is_empty_ = false;
|
||||
|
||||
eGeometryType geometry_type = geometry_type_from_object(ref.object);
|
||||
if (image) {
|
||||
GPUTexture *texture = nullptr;
|
||||
GPUTexture *tilemap = nullptr;
|
||||
if (image->source == IMA_SRC_TILED) {
|
||||
texture = BKE_image_get_gpu_tiles(image, iuser, nullptr);
|
||||
tilemap = BKE_image_get_gpu_tilemap(image, iuser, nullptr);
|
||||
}
|
||||
else {
|
||||
texture = BKE_image_get_gpu_texture(image, iuser, nullptr);
|
||||
}
|
||||
if (texture) {
|
||||
auto add_cb = [&] {
|
||||
PassMain::Sub *sub_pass =
|
||||
passes_[static_cast<int>(geometry_type)][static_cast<int>(eShaderType::TEXTURE)];
|
||||
sub_pass = &sub_pass->sub(image->id.name);
|
||||
if (tilemap) {
|
||||
sub_pass->bind_texture(WB_TILE_ARRAY_SLOT, texture, sampler_state);
|
||||
sub_pass->bind_texture(WB_TILE_DATA_SLOT, tilemap);
|
||||
}
|
||||
else {
|
||||
sub_pass->bind_texture(WB_TEXTURE_SLOT, texture, sampler_state);
|
||||
}
|
||||
sub_pass->push_constant("isImageTile", tilemap != nullptr);
|
||||
sub_pass->push_constant("imagePremult", image && image->alpha_mode == IMA_ALPHA_PREMUL);
|
||||
/* TODO(Miguel Pozo): This setting should be exposed on the user side,
|
||||
* either as a global parameter (and set it here)
|
||||
* or by reading the Material Clipping Threshold (and set it per material) */
|
||||
sub_pass->push_constant("imageTransparencyCutoff", 0.1f);
|
||||
return sub_pass;
|
||||
};
|
||||
|
||||
texture_subpass_map_.lookup_or_add_cb(TextureSubPassKey(texture, geometry_type), add_cb)
|
||||
->draw(batch, handle);
|
||||
}
|
||||
}
|
||||
passes_[static_cast<int>(geometry_type)][static_cast<int>(eShaderType::MATERIAL)]->draw(batch,
|
||||
handle);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name OpaquePass
|
||||
* \{ */
|
||||
|
||||
void OpaquePass::sync(const SceneState &scene_state, SceneResources &resources)
|
||||
{
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
|
||||
scene_state.cull_state;
|
||||
|
||||
bool clip = scene_state.clip_planes.size() > 0;
|
||||
|
||||
DRWState in_front_state = state | DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS;
|
||||
gbuffer_in_front_ps_.init_pass(resources, in_front_state, scene_state.clip_planes.size());
|
||||
gbuffer_in_front_ps_.state_stencil(0xFF, 0xFF, 0x00);
|
||||
gbuffer_in_front_ps_.init_subpasses(
|
||||
ePipelineType::OPAQUE, scene_state.lighting_type, clip, resources.shader_cache);
|
||||
|
||||
state |= DRW_STATE_STENCIL_NEQUAL;
|
||||
gbuffer_ps_.init_pass(resources, state, scene_state.clip_planes.size());
|
||||
gbuffer_ps_.state_stencil(0x00, 0xFF, 0xFF);
|
||||
gbuffer_ps_.init_subpasses(
|
||||
ePipelineType::OPAQUE, scene_state.lighting_type, clip, resources.shader_cache);
|
||||
|
||||
deferred_ps_.init();
|
||||
deferred_ps_.state_set(DRW_STATE_WRITE_COLOR);
|
||||
deferred_ps_.shader_set(resources.shader_cache.resolve_shader_get(ePipelineType::OPAQUE,
|
||||
scene_state.lighting_type,
|
||||
scene_state.draw_cavity,
|
||||
scene_state.draw_curvature));
|
||||
deferred_ps_.push_constant("forceShadowing", false);
|
||||
deferred_ps_.bind_ubo(WB_WORLD_SLOT, resources.world_buf);
|
||||
deferred_ps_.bind_texture(WB_MATCAP_SLOT, resources.matcap_tx);
|
||||
deferred_ps_.bind_texture("normal_tx", &gbuffer_normal_tx);
|
||||
deferred_ps_.bind_texture("material_tx", &gbuffer_material_tx);
|
||||
deferred_ps_.bind_texture("depth_tx", &resources.depth_tx);
|
||||
deferred_ps_.bind_texture("stencil_tx", &deferred_ps_stencil_tx);
|
||||
resources.cavity.setup_resolve_pass(deferred_ps_, resources);
|
||||
deferred_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
}
|
||||
|
||||
void OpaquePass::draw(Manager &manager,
|
||||
View &view,
|
||||
SceneResources &resources,
|
||||
int2 resolution,
|
||||
ShadowPass *shadow_pass,
|
||||
bool accumulation_ps_is_empty)
|
||||
{
|
||||
if (is_empty()) {
|
||||
return;
|
||||
}
|
||||
gbuffer_material_tx.acquire(
|
||||
resolution, GPU_RGBA16F, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
gbuffer_normal_tx.acquire(
|
||||
resolution, GPU_RG16F, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
|
||||
GPUAttachment object_id_attachment = GPU_ATTACHMENT_NONE;
|
||||
if (resources.object_id_tx.is_valid()) {
|
||||
object_id_attachment = GPU_ATTACHMENT_TEXTURE(resources.object_id_tx);
|
||||
}
|
||||
|
||||
if (!gbuffer_in_front_ps_.is_empty()) {
|
||||
opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(gbuffer_material_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(gbuffer_normal_tx),
|
||||
object_id_attachment);
|
||||
opaque_fb.bind();
|
||||
|
||||
manager.submit(gbuffer_in_front_ps_, view);
|
||||
if (resources.depth_in_front_tx.is_valid()) {
|
||||
/* Only needed when transparent infront is needed */
|
||||
GPU_texture_copy(resources.depth_in_front_tx, resources.depth_tx);
|
||||
}
|
||||
}
|
||||
|
||||
if (!gbuffer_ps_.is_empty()) {
|
||||
opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(gbuffer_material_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(gbuffer_normal_tx),
|
||||
object_id_attachment);
|
||||
opaque_fb.bind();
|
||||
|
||||
manager.submit(gbuffer_ps_, view);
|
||||
}
|
||||
|
||||
bool needs_stencil_copy = shadow_pass && !gbuffer_in_front_ps_.is_empty() &&
|
||||
!accumulation_ps_is_empty;
|
||||
|
||||
if (needs_stencil_copy) {
|
||||
shadow_depth_stencil_tx.ensure_2d(GPU_DEPTH24_STENCIL8,
|
||||
resolution,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ |
|
||||
GPU_TEXTURE_USAGE_ATTACHMENT |
|
||||
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW);
|
||||
GPU_texture_copy(shadow_depth_stencil_tx, resources.depth_tx);
|
||||
|
||||
deferred_ps_stencil_tx = shadow_depth_stencil_tx.stencil_view();
|
||||
}
|
||||
else {
|
||||
shadow_depth_stencil_tx.free();
|
||||
|
||||
deferred_ps_stencil_tx = resources.depth_tx.stencil_view();
|
||||
}
|
||||
|
||||
if (shadow_pass && !gbuffer_in_front_ps_.is_empty()) {
|
||||
opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(deferred_ps_stencil_tx));
|
||||
opaque_fb.bind();
|
||||
GPU_framebuffer_clear_stencil(opaque_fb, 0);
|
||||
}
|
||||
|
||||
if (shadow_pass) {
|
||||
shadow_pass->draw(manager,
|
||||
view,
|
||||
resources,
|
||||
resolution,
|
||||
*deferred_ps_stencil_tx,
|
||||
!gbuffer_in_front_ps_.is_empty());
|
||||
}
|
||||
|
||||
opaque_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx));
|
||||
opaque_fb.bind();
|
||||
manager.submit(deferred_ps_, view);
|
||||
|
||||
if (shadow_pass && !needs_stencil_copy) {
|
||||
opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx));
|
||||
opaque_fb.bind();
|
||||
GPU_framebuffer_clear_stencil(opaque_fb, 0);
|
||||
}
|
||||
|
||||
gbuffer_normal_tx.release();
|
||||
gbuffer_material_tx.release();
|
||||
}
|
||||
|
||||
bool OpaquePass::is_empty() const
|
||||
{
|
||||
return gbuffer_ps_.is_empty() && gbuffer_in_front_ps_.is_empty();
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name TransparentPass
|
||||
* \{ */
|
||||
|
||||
void TransparentPass::sync(const SceneState &scene_state, SceneResources &resources)
|
||||
{
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_OIT |
|
||||
scene_state.cull_state;
|
||||
|
||||
bool clip = scene_state.clip_planes.size() > 0;
|
||||
|
||||
accumulation_ps_.init_pass(
|
||||
resources, state | DRW_STATE_STENCIL_NEQUAL, scene_state.clip_planes.size());
|
||||
accumulation_ps_.state_stencil(0x00, 0xFF, 0xFF);
|
||||
accumulation_ps_.clear_color(float4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
accumulation_ps_.init_subpasses(
|
||||
ePipelineType::TRANSPARENT, scene_state.lighting_type, clip, resources.shader_cache);
|
||||
|
||||
accumulation_in_front_ps_.init_pass(resources, state, scene_state.clip_planes.size());
|
||||
accumulation_in_front_ps_.clear_color(float4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
accumulation_in_front_ps_.init_subpasses(
|
||||
ePipelineType::TRANSPARENT, scene_state.lighting_type, clip, resources.shader_cache);
|
||||
|
||||
if (resolve_sh_ == nullptr) {
|
||||
resolve_sh_ = GPU_shader_create_from_info_name("workbench_transparent_resolve");
|
||||
}
|
||||
resolve_ps_.init();
|
||||
resolve_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA);
|
||||
resolve_ps_.shader_set(resolve_sh_);
|
||||
resolve_ps_.bind_texture("transparentAccum", &accumulation_tx);
|
||||
resolve_ps_.bind_texture("transparentRevealage", &reveal_tx);
|
||||
resolve_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
}
|
||||
|
||||
void TransparentPass::draw(Manager &manager,
|
||||
View &view,
|
||||
SceneResources &resources,
|
||||
int2 resolution)
|
||||
{
|
||||
if (is_empty()) {
|
||||
return;
|
||||
}
|
||||
accumulation_tx.acquire(
|
||||
resolution, GPU_RGBA16F, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
reveal_tx.acquire(
|
||||
resolution, GPU_R16F, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
|
||||
resolve_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx));
|
||||
|
||||
if (!accumulation_ps_.is_empty()) {
|
||||
transparent_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(accumulation_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(reveal_tx));
|
||||
transparent_fb.bind();
|
||||
manager.submit(accumulation_ps_, view);
|
||||
resolve_fb.bind();
|
||||
manager.submit(resolve_ps_, view);
|
||||
}
|
||||
if (!accumulation_in_front_ps_.is_empty()) {
|
||||
transparent_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_in_front_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(accumulation_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(reveal_tx));
|
||||
transparent_fb.bind();
|
||||
manager.submit(accumulation_in_front_ps_, view);
|
||||
resolve_fb.bind();
|
||||
manager.submit(resolve_ps_, view);
|
||||
}
|
||||
|
||||
accumulation_tx.release();
|
||||
reveal_tx.release();
|
||||
}
|
||||
|
||||
bool TransparentPass::is_empty() const
|
||||
{
|
||||
return accumulation_ps_.is_empty() && accumulation_in_front_ps_.is_empty();
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name TransparentDepthPass
|
||||
* \{ */
|
||||
|
||||
void TransparentDepthPass::sync(const SceneState &scene_state, SceneResources &resources)
|
||||
{
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
|
||||
scene_state.cull_state;
|
||||
|
||||
bool clip = scene_state.clip_planes.size() > 0;
|
||||
|
||||
DRWState in_front_state = state | DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS;
|
||||
in_front_ps_.init_pass(resources, in_front_state, scene_state.clip_planes.size());
|
||||
in_front_ps_.state_stencil(0xFF, 0xFF, 0x00);
|
||||
in_front_ps_.init_subpasses(
|
||||
ePipelineType::OPAQUE, eLightingType::FLAT, clip, resources.shader_cache);
|
||||
|
||||
if (merge_sh_ == nullptr) {
|
||||
merge_sh_ = GPU_shader_create_from_info_name("workbench_next_merge_depth");
|
||||
}
|
||||
merge_ps_.init();
|
||||
merge_ps_.shader_set(merge_sh_);
|
||||
merge_ps_.state_set(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_WRITE_STENCIL |
|
||||
DRW_STATE_STENCIL_ALWAYS);
|
||||
merge_ps_.state_stencil(0xFF, 0xFF, 0x00);
|
||||
merge_ps_.bind_texture("depth_tx", &resources.depth_in_front_tx);
|
||||
merge_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
|
||||
state |= DRW_STATE_STENCIL_NEQUAL;
|
||||
main_ps_.init_pass(resources, state, scene_state.clip_planes.size());
|
||||
main_ps_.state_stencil(0x00, 0xFF, 0xFF);
|
||||
main_ps_.init_subpasses(
|
||||
ePipelineType::OPAQUE, eLightingType::FLAT, clip, resources.shader_cache);
|
||||
}
|
||||
|
||||
void TransparentDepthPass::draw(Manager &manager,
|
||||
View &view,
|
||||
SceneResources &resources,
|
||||
int2 resolution)
|
||||
{
|
||||
if (is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
GPUAttachment object_id_attachment = GPU_ATTACHMENT_NONE;
|
||||
if (resources.object_id_tx.is_valid()) {
|
||||
object_id_attachment = GPU_ATTACHMENT_TEXTURE(resources.object_id_tx);
|
||||
}
|
||||
|
||||
if (!in_front_ps_.is_empty()) {
|
||||
in_front_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_in_front_tx),
|
||||
GPU_ATTACHMENT_NONE,
|
||||
GPU_ATTACHMENT_NONE,
|
||||
object_id_attachment);
|
||||
in_front_fb.bind();
|
||||
manager.submit(in_front_ps_, view);
|
||||
|
||||
merge_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx));
|
||||
merge_fb.bind();
|
||||
manager.submit(merge_ps_, view);
|
||||
}
|
||||
|
||||
if (!main_ps_.is_empty()) {
|
||||
main_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx),
|
||||
GPU_ATTACHMENT_NONE,
|
||||
GPU_ATTACHMENT_NONE,
|
||||
object_id_attachment);
|
||||
main_fb.bind();
|
||||
manager.submit(main_ps_, view);
|
||||
}
|
||||
}
|
||||
|
||||
bool TransparentDepthPass::is_empty() const
|
||||
{
|
||||
return main_ps_.is_empty() && in_front_ps_.is_empty();
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::workbench
|
@@ -200,8 +200,12 @@ typedef struct WORKBENCH_UBO_World {
|
||||
|
||||
int matcap_orientation;
|
||||
int use_specular; /* Bools are 32bit ints in GLSL. */
|
||||
int _pad1;
|
||||
float xray_alpha; /* Workbench Next */
|
||||
int _pad2;
|
||||
|
||||
/* Workbench Next data
|
||||
* (Not used here, but needs to be kept in sync with workbench_shader_shared WorldData) */
|
||||
float background_color[4];
|
||||
} WORKBENCH_UBO_World;
|
||||
|
||||
BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_World, 16)
|
||||
|
439
source/blender/draw/engines/workbench/workbench_private.hh
Normal file
439
source/blender/draw/engines/workbench/workbench_private.hh
Normal file
@@ -0,0 +1,439 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DRW_render.h"
|
||||
#include "draw_manager.hh"
|
||||
#include "draw_pass.hh"
|
||||
|
||||
#include "workbench_defines.hh"
|
||||
#include "workbench_enums.hh"
|
||||
#include "workbench_shader_shared.h"
|
||||
|
||||
extern "C" DrawEngineType draw_engine_workbench_next;
|
||||
|
||||
namespace blender::workbench {
|
||||
|
||||
using namespace draw;
|
||||
|
||||
class ShaderCache {
|
||||
public:
|
||||
~ShaderCache();
|
||||
|
||||
GPUShader *prepass_shader_get(ePipelineType pipeline_type,
|
||||
eGeometryType geometry_type,
|
||||
eShaderType shader_type,
|
||||
eLightingType lighting_type,
|
||||
bool clip);
|
||||
|
||||
GPUShader *resolve_shader_get(ePipelineType pipeline_type,
|
||||
eLightingType lighting_type,
|
||||
bool cavity = false,
|
||||
bool curvature = false);
|
||||
|
||||
private:
|
||||
/* TODO(fclem): We might want to change to a Map since most shader will never be compiled. */
|
||||
GPUShader *prepass_shader_cache_[pipeline_type_len][geometry_type_len][shader_type_len]
|
||||
[lighting_type_len][2 /*clip*/] = {{{{{nullptr}}}}};
|
||||
GPUShader *resolve_shader_cache_[pipeline_type_len][lighting_type_len][2 /*cavity*/]
|
||||
[2 /*curvature*/] = {{{{nullptr}}}};
|
||||
};
|
||||
|
||||
struct Material {
|
||||
float3 base_color = float3(0);
|
||||
/* Packed data into a int. Decoded in the shader. */
|
||||
uint packed_data = 0;
|
||||
|
||||
Material();
|
||||
Material(float3 color);
|
||||
Material(::Object &ob, bool random = false);
|
||||
Material(::Material &mat);
|
||||
|
||||
static uint32_t pack_data(float metallic, float roughness, float alpha);
|
||||
|
||||
bool is_transparent();
|
||||
};
|
||||
|
||||
void get_material_image(Object *ob,
|
||||
int material_index,
|
||||
::Image *&image,
|
||||
ImageUser *&iuser,
|
||||
eGPUSamplerState &sampler_state);
|
||||
|
||||
struct SceneState {
|
||||
Scene *scene = nullptr;
|
||||
|
||||
Object *camera_object = nullptr;
|
||||
Camera *camera = nullptr;
|
||||
float4x4 view_projection_matrix = float4x4::identity();
|
||||
int2 resolution = int2(0);
|
||||
|
||||
eContextObjectMode object_mode = CTX_MODE_OBJECT;
|
||||
|
||||
View3DShading shading = {};
|
||||
eLightingType lighting_type = eLightingType::STUDIO;
|
||||
bool xray_mode = false;
|
||||
|
||||
DRWState cull_state = DRW_STATE_NO_DRAW;
|
||||
Vector<float4> clip_planes = {};
|
||||
|
||||
float4 background_color = float4(0);
|
||||
|
||||
bool draw_cavity = false;
|
||||
bool draw_curvature = false;
|
||||
bool draw_shadows = false;
|
||||
bool draw_outline = false;
|
||||
bool draw_dof = false;
|
||||
bool draw_aa = false;
|
||||
|
||||
bool draw_object_id = false;
|
||||
bool draw_transparent_depth = false;
|
||||
|
||||
int sample = 0;
|
||||
int samples_len = 0;
|
||||
bool reset_taa_next_sample = false;
|
||||
bool render_finished = false;
|
||||
|
||||
/* Used when material_type == eMaterialType::SINGLE */
|
||||
Material material_override = Material(float3(1.0f));
|
||||
/* When r == -1.0 the shader uses the vertex color */
|
||||
Material material_attribute_color = Material(float3(-1.0f));
|
||||
|
||||
void init(Object *camera_ob = nullptr);
|
||||
};
|
||||
|
||||
struct ObjectState {
|
||||
eV3DShadingColorType color_type = V3D_SHADING_SINGLE_COLOR;
|
||||
bool sculpt_pbvh = false;
|
||||
bool texture_paint_mode = false;
|
||||
::Image *image_paint_override = nullptr;
|
||||
eGPUSamplerState override_sampler_state = GPU_SAMPLER_DEFAULT;
|
||||
bool draw_shadow = false;
|
||||
bool use_per_material_batches = false;
|
||||
|
||||
ObjectState(const SceneState &scene_state, Object *ob);
|
||||
};
|
||||
|
||||
class CavityEffect {
|
||||
private:
|
||||
/* This value must be kept in sync with the one declared at
|
||||
* workbench_composite_info.hh (cavity_samples) */
|
||||
static const int max_samples_ = 512;
|
||||
|
||||
UniformArrayBuffer<float4, max_samples_> samples_buf = {};
|
||||
|
||||
int sample_ = 0;
|
||||
int sample_count_ = 0;
|
||||
bool curvature_enabled_ = false;
|
||||
bool cavity_enabled_ = false;
|
||||
|
||||
public:
|
||||
void init(const SceneState &scene_state, struct SceneResources &resources);
|
||||
void setup_resolve_pass(PassSimple &pass, struct SceneResources &resources);
|
||||
|
||||
private:
|
||||
void load_samples_buf(int ssao_samples);
|
||||
};
|
||||
|
||||
struct SceneResources {
|
||||
static const int jitter_tx_size = 64;
|
||||
|
||||
ShaderCache shader_cache = {};
|
||||
|
||||
StringRefNull current_matcap = {};
|
||||
Texture matcap_tx = "matcap_tx";
|
||||
|
||||
TextureFromPool color_tx = "wb_color_tx";
|
||||
TextureFromPool object_id_tx = "wb_object_id_tx";
|
||||
Texture depth_tx = "wb_depth_tx";
|
||||
TextureFromPool depth_in_front_tx = "wb_depth_in_front_tx";
|
||||
|
||||
StorageVectorBuffer<Material> material_buf = {"material_buf"};
|
||||
UniformBuffer<WorldData> world_buf = {};
|
||||
UniformArrayBuffer<float4, 6> clip_planes_buf;
|
||||
|
||||
Texture jitter_tx = "wb_jitter_tx";
|
||||
|
||||
CavityEffect cavity = {};
|
||||
|
||||
void init(const SceneState &scene_state);
|
||||
void load_jitter_tx(int total_samples);
|
||||
};
|
||||
|
||||
class MeshPass : public PassMain {
|
||||
private:
|
||||
using TextureSubPassKey = std::pair<GPUTexture *, eGeometryType>;
|
||||
|
||||
Map<TextureSubPassKey, PassMain::Sub *> texture_subpass_map_ = {};
|
||||
|
||||
PassMain::Sub *passes_[geometry_type_len][shader_type_len] = {{nullptr}};
|
||||
|
||||
bool is_empty_ = false;
|
||||
|
||||
public:
|
||||
MeshPass(const char *name);
|
||||
|
||||
/* TODO: Move to draw::Pass */
|
||||
bool is_empty() const;
|
||||
|
||||
void init_pass(SceneResources &resources, DRWState state, int clip_planes);
|
||||
void init_subpasses(ePipelineType pipeline,
|
||||
eLightingType lighting,
|
||||
bool clip,
|
||||
ShaderCache &shaders);
|
||||
|
||||
void draw(ObjectRef &ref,
|
||||
GPUBatch *batch,
|
||||
ResourceHandle handle,
|
||||
::Image *image = nullptr,
|
||||
eGPUSamplerState sampler_state = eGPUSamplerState::GPU_SAMPLER_DEFAULT,
|
||||
ImageUser *iuser = nullptr);
|
||||
};
|
||||
|
||||
class OpaquePass {
|
||||
public:
|
||||
TextureFromPool gbuffer_normal_tx = {"gbuffer_normal_tx"};
|
||||
TextureFromPool gbuffer_material_tx = {"gbuffer_material_tx"};
|
||||
Framebuffer opaque_fb = {};
|
||||
|
||||
Texture shadow_depth_stencil_tx = {"shadow_depth_stencil_tx"};
|
||||
GPUTexture *deferred_ps_stencil_tx = nullptr;
|
||||
|
||||
MeshPass gbuffer_ps_ = {"Opaque.Gbuffer"};
|
||||
MeshPass gbuffer_in_front_ps_ = {"Opaque.GbufferInFront"};
|
||||
PassSimple deferred_ps_ = {"Opaque.Deferred"};
|
||||
|
||||
void sync(const SceneState &scene_state, SceneResources &resources);
|
||||
void draw(Manager &manager,
|
||||
View &view,
|
||||
SceneResources &resources,
|
||||
int2 resolution,
|
||||
class ShadowPass *shadow_pass,
|
||||
bool accumulation_ps_is_empty);
|
||||
bool is_empty() const;
|
||||
};
|
||||
|
||||
class TransparentPass {
|
||||
private:
|
||||
GPUShader *resolve_sh_ = nullptr;
|
||||
|
||||
public:
|
||||
TextureFromPool accumulation_tx = {"accumulation_accumulation_tx"};
|
||||
TextureFromPool reveal_tx = {"accumulation_reveal_tx"};
|
||||
Framebuffer transparent_fb = {};
|
||||
|
||||
MeshPass accumulation_ps_ = {"Transparent.Accumulation"};
|
||||
MeshPass accumulation_in_front_ps_ = {"Transparent.AccumulationInFront"};
|
||||
PassSimple resolve_ps_ = {"Transparent.Resolve"};
|
||||
Framebuffer resolve_fb = {};
|
||||
|
||||
void sync(const SceneState &scene_state, SceneResources &resources);
|
||||
void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution);
|
||||
bool is_empty() const;
|
||||
};
|
||||
|
||||
class TransparentDepthPass {
|
||||
private:
|
||||
GPUShader *merge_sh_ = nullptr;
|
||||
|
||||
public:
|
||||
MeshPass main_ps_ = {"TransparentDepth.Main"};
|
||||
Framebuffer main_fb = {"TransparentDepth.Main"};
|
||||
MeshPass in_front_ps_ = {"TransparentDepth.InFront"};
|
||||
Framebuffer in_front_fb = {"TransparentDepth.InFront"};
|
||||
PassSimple merge_ps_ = {"TransparentDepth.Merge"};
|
||||
Framebuffer merge_fb = {"TransparentDepth.Merge"};
|
||||
|
||||
void sync(const SceneState &scene_state, SceneResources &resources);
|
||||
void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution);
|
||||
bool is_empty() const;
|
||||
};
|
||||
|
||||
class ShadowPass {
|
||||
private:
|
||||
enum PassType { PASS = 0, FAIL, FORCED_FAIL, MAX };
|
||||
|
||||
class ShadowView : public View {
|
||||
bool force_fail_method_ = false;
|
||||
float3 light_direction_ = float3(0);
|
||||
UniformBuffer<ExtrudedFrustum> extruded_frustum_ = {};
|
||||
ShadowPass::PassType current_pass_type_ = PASS;
|
||||
|
||||
VisibilityBuf pass_visibility_buf_ = {};
|
||||
VisibilityBuf fail_visibility_buf_ = {};
|
||||
|
||||
public:
|
||||
void setup(View &view, float3 light_direction, bool force_fail_method);
|
||||
bool debug_object_culling(Object *ob);
|
||||
void set_mode(PassType type);
|
||||
|
||||
ShadowView();
|
||||
|
||||
protected:
|
||||
virtual void compute_visibility(ObjectMatricesBuf &matrices,
|
||||
ObjectBoundsBuf &bounds,
|
||||
uint resource_len,
|
||||
bool debug_freeze);
|
||||
virtual VisibilityBuf &get_visibility_buffer();
|
||||
} view_ = {};
|
||||
|
||||
bool enabled_;
|
||||
|
||||
UniformBuffer<ShadowPassData> pass_data_ = {};
|
||||
|
||||
/* Draws are added to both passes and the visibily compute shader selects one of them */
|
||||
PassMain pass_ps_ = {"Shadow.Pass"};
|
||||
PassMain fail_ps_ = {"Shadow.Fail"};
|
||||
|
||||
/* In some cases, we know beforehand that we need to use the fail technique */
|
||||
PassMain forced_fail_ps_ = {"Shadow.ForcedFail"};
|
||||
|
||||
/* [PassType][Is Manifold][Is Cap] */
|
||||
PassMain::Sub *passes_[PassType::MAX][2][2] = {{{nullptr}}};
|
||||
PassMain::Sub *&get_pass_ptr(PassType type, bool manifold, bool cap = false);
|
||||
|
||||
/* [Is Pass Technique][Is Manifold][Is Cap] */
|
||||
GPUShader *shaders_[2][2][2] = {{{nullptr}}};
|
||||
GPUShader *get_shader(bool depth_pass, bool manifold, bool cap = false);
|
||||
|
||||
TextureFromPool depth_tx_ = {};
|
||||
Framebuffer fb_ = {};
|
||||
|
||||
public:
|
||||
void init(const SceneState &scene_state, SceneResources &resources);
|
||||
void update();
|
||||
void sync();
|
||||
void object_sync(Manager &manager,
|
||||
SceneState &scene_state,
|
||||
ObjectRef &ob_ref,
|
||||
ResourceHandle handle,
|
||||
const bool has_transp_mat);
|
||||
void draw(Manager &manager,
|
||||
View &view,
|
||||
SceneResources &resources,
|
||||
int2 resolution,
|
||||
GPUTexture &depth_stencil_tx,
|
||||
/* Needed when there are opaque "In Front" objects in the scene */
|
||||
bool force_fail_method);
|
||||
};
|
||||
|
||||
class OutlinePass {
|
||||
private:
|
||||
bool enabled_ = false;
|
||||
|
||||
PassSimple ps_ = PassSimple("Workbench.Outline");
|
||||
GPUShader *sh_ = nullptr;
|
||||
Framebuffer fb_ = Framebuffer("Workbench.Outline");
|
||||
|
||||
public:
|
||||
void init(const SceneState &scene_state);
|
||||
void sync(SceneResources &resources);
|
||||
void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution);
|
||||
};
|
||||
|
||||
class DofPass {
|
||||
private:
|
||||
static const int kernel_radius_ = 3;
|
||||
static const int samples_len_ = (kernel_radius_ * 2 + 1) * (kernel_radius_ * 2 + 1);
|
||||
|
||||
bool enabled_ = false;
|
||||
|
||||
float offset_ = 0;
|
||||
|
||||
UniformArrayBuffer<float4, samples_len_> samples_buf_ = {};
|
||||
|
||||
Texture source_tx_ = {};
|
||||
Texture coc_halfres_tx_ = {};
|
||||
TextureFromPool blur_tx_ = {};
|
||||
|
||||
Framebuffer downsample_fb_ = {};
|
||||
Framebuffer blur1_fb_ = {};
|
||||
Framebuffer blur2_fb_ = {};
|
||||
Framebuffer resolve_fb_ = {};
|
||||
|
||||
GPUShader *prepare_sh_ = nullptr;
|
||||
GPUShader *downsample_sh_ = nullptr;
|
||||
GPUShader *blur1_sh_ = nullptr;
|
||||
GPUShader *blur2_sh_ = nullptr;
|
||||
GPUShader *resolve_sh_ = nullptr;
|
||||
|
||||
PassSimple down_ps_ = {"Workbench.DoF.DownSample"};
|
||||
PassSimple down2_ps_ = {"Workbench.DoF.DownSample2"};
|
||||
PassSimple blur_ps_ = {"Workbench.DoF.Blur"};
|
||||
PassSimple blur2_ps_ = {"Workbench.DoF.Blur2"};
|
||||
PassSimple resolve_ps_ = {"Workbench.DoF.Resolve"};
|
||||
|
||||
float aperture_size_ = 0;
|
||||
float distance_ = 0;
|
||||
float invsensor_size_ = 0;
|
||||
float near_ = 0;
|
||||
float far_ = 0;
|
||||
float blades_ = 0;
|
||||
float rotation_ = 0;
|
||||
float ratio_ = 0;
|
||||
|
||||
public:
|
||||
void init(const SceneState &scene_state);
|
||||
void sync(SceneResources &resources);
|
||||
void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution);
|
||||
bool is_enabled();
|
||||
|
||||
private:
|
||||
void setup_samples();
|
||||
};
|
||||
|
||||
class AntiAliasingPass {
|
||||
private:
|
||||
bool enabled_ = false;
|
||||
/* Current TAA sample index in [0..samples_len_] range. */
|
||||
int sample_ = 0;
|
||||
/* Total number of samples to after which TAA stops accumulating samples. */
|
||||
int samples_len_ = 0;
|
||||
/* Weight accumulated. */
|
||||
float weight_accum_ = 0;
|
||||
/* Samples weight for this iteration. */
|
||||
float weights_[9] = {0};
|
||||
/* Sum of weights. */
|
||||
float weights_sum_ = 0;
|
||||
|
||||
Texture sample0_depth_tx_ = {"sample0_depth_tx"};
|
||||
|
||||
Texture taa_accumulation_tx_ = {"taa_accumulation_tx"};
|
||||
Texture smaa_search_tx_ = {"smaa_search_tx"};
|
||||
Texture smaa_area_tx_ = {"smaa_area_tx"};
|
||||
TextureFromPool smaa_edge_tx_ = {"smaa_edge_tx"};
|
||||
TextureFromPool smaa_weight_tx_ = {"smaa_weight_tx"};
|
||||
|
||||
Framebuffer taa_accumulation_fb_ = {"taa_accumulation_fb"};
|
||||
Framebuffer smaa_edge_fb_ = {"smaa_edge_fb"};
|
||||
Framebuffer smaa_weight_fb_ = {"smaa_weight_fb"};
|
||||
Framebuffer smaa_resolve_fb_ = {"smaa_resolve_fb"};
|
||||
|
||||
float4 smaa_viewport_metrics_ = float4(0);
|
||||
float smaa_mix_factor_ = 0;
|
||||
|
||||
GPUShader *taa_accumulation_sh_ = nullptr;
|
||||
GPUShader *smaa_edge_detect_sh_ = nullptr;
|
||||
GPUShader *smaa_aa_weight_sh_ = nullptr;
|
||||
GPUShader *smaa_resolve_sh_ = nullptr;
|
||||
|
||||
PassSimple taa_accumulation_ps_ = {"TAA.Accumulation"};
|
||||
PassSimple smaa_edge_detect_ps_ = {"SMAA.EdgeDetect"};
|
||||
PassSimple smaa_aa_weight_ps_ = {"SMAA.BlendWeights"};
|
||||
PassSimple smaa_resolve_ps_ = {"SMAA.Resolve"};
|
||||
|
||||
public:
|
||||
AntiAliasingPass();
|
||||
~AntiAliasingPass();
|
||||
|
||||
void init(const SceneState &scene_state);
|
||||
void sync(SceneResources &resources, int2 resolution);
|
||||
void setup_view(View &view, int2 resolution);
|
||||
void draw(Manager &manager,
|
||||
View &view,
|
||||
SceneResources &resources,
|
||||
int2 resolution,
|
||||
GPUTexture *depth_tx,
|
||||
GPUTexture *color_tx);
|
||||
};
|
||||
|
||||
} // namespace blender::workbench
|
171
source/blender/draw/engines/workbench/workbench_resources.cc
Normal file
171
source/blender/draw/engines/workbench/workbench_resources.cc
Normal file
@@ -0,0 +1,171 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "../eevee/eevee_lut.h" /* TODO: find somewhere to share blue noise Table. */
|
||||
#include "BKE_studiolight.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "workbench_private.hh"
|
||||
|
||||
namespace blender::workbench {
|
||||
|
||||
bool get_matcap_tx(Texture &matcap_tx, const StudioLight &studio_light)
|
||||
{
|
||||
ImBuf *matcap_diffuse = studio_light.matcap_diffuse.ibuf;
|
||||
ImBuf *matcap_specular = studio_light.matcap_specular.ibuf;
|
||||
if (matcap_diffuse && matcap_diffuse->rect_float) {
|
||||
int layers = 1;
|
||||
float *buffer = matcap_diffuse->rect_float;
|
||||
Vector<float> combined_buffer = {};
|
||||
|
||||
if (matcap_specular && matcap_specular->rect_float) {
|
||||
int size = matcap_diffuse->x * matcap_diffuse->y * 4;
|
||||
combined_buffer.extend(matcap_diffuse->rect_float, size);
|
||||
combined_buffer.extend(matcap_specular->rect_float, size);
|
||||
buffer = combined_buffer.begin();
|
||||
layers++;
|
||||
}
|
||||
|
||||
matcap_tx = Texture(studio_light.name,
|
||||
GPU_RGBA16F,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ,
|
||||
int2(matcap_diffuse->x, matcap_diffuse->y),
|
||||
layers,
|
||||
buffer);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float4x4 get_world_shading_rotation_matrix(float studiolight_rot_z)
|
||||
{
|
||||
/* TODO(Miguel Pozo) C++ API ? */
|
||||
float V[4][4], R[4][4];
|
||||
DRW_view_viewmat_get(nullptr, V, false);
|
||||
axis_angle_to_mat4_single(R, 'Z', -studiolight_rot_z);
|
||||
mul_m4_m4m4(R, V, R);
|
||||
swap_v3_v3(R[2], R[1]);
|
||||
negate_v3(R[2]);
|
||||
return float4x4(R);
|
||||
}
|
||||
|
||||
LightData get_light_data_from_studio_solidlight(const SolidLight *sl,
|
||||
float4x4 world_shading_rotation)
|
||||
{
|
||||
LightData light = {};
|
||||
if (sl && sl->flag) {
|
||||
float3 direction = world_shading_rotation.ref_3x3() * float3(sl->vec);
|
||||
light.direction = float4(direction, 0.0f);
|
||||
/* We should pre-divide the power by PI but that makes the lights really dim. */
|
||||
light.specular_color = float4(float3(sl->spec), 0.0f);
|
||||
light.diffuse_color_wrap = float4(float3(sl->col), sl->smooth);
|
||||
}
|
||||
else {
|
||||
light.direction = float4(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
light.specular_color = float4(0.0f);
|
||||
light.diffuse_color_wrap = float4(0.0f);
|
||||
}
|
||||
return light;
|
||||
}
|
||||
|
||||
void SceneResources::load_jitter_tx(int total_samples)
|
||||
{
|
||||
const int texel_count = jitter_tx_size * jitter_tx_size;
|
||||
static float4 jitter[texel_count];
|
||||
|
||||
const float total_samples_inv = 1.0f / total_samples;
|
||||
|
||||
/* Create blue noise jitter texture */
|
||||
for (int i = 0; i < texel_count; i++) {
|
||||
float phi = blue_noise[i][0] * 2.0f * M_PI;
|
||||
/* This rotate the sample per pixels */
|
||||
jitter[i].x = math::cos(phi);
|
||||
jitter[i].y = math::sin(phi);
|
||||
/* This offset the sample along its direction axis (reduce banding) */
|
||||
float bn = blue_noise[i][1] - 0.5f;
|
||||
bn = clamp_f(bn, -0.499f, 0.499f); /* fix fireflies */
|
||||
jitter[i].z = bn * total_samples_inv;
|
||||
jitter[i].w = blue_noise[i][1];
|
||||
}
|
||||
|
||||
jitter_tx.free();
|
||||
jitter_tx.ensure_2d(GPU_RGBA16F, int2(jitter_tx_size), GPU_TEXTURE_USAGE_SHADER_READ, jitter[0]);
|
||||
}
|
||||
|
||||
void SceneResources::init(const SceneState &scene_state)
|
||||
{
|
||||
const View3DShading &shading = scene_state.shading;
|
||||
|
||||
world_buf.viewport_size = DRW_viewport_size_get();
|
||||
world_buf.viewport_size_inv = DRW_viewport_invert_size_get();
|
||||
world_buf.xray_alpha = shading.xray_alpha;
|
||||
world_buf.background_color = scene_state.background_color;
|
||||
world_buf.object_outline_color = float4(float3(shading.object_outline_color), 1.0f);
|
||||
world_buf.ui_scale = DRW_state_is_image_render() ? 1.0f : G_draw.block.size_pixel;
|
||||
world_buf.matcap_orientation = (shading.flag & V3D_SHADING_MATCAP_FLIP_X) != 0;
|
||||
|
||||
StudioLight *studio_light = nullptr;
|
||||
if (U.edit_studio_light) {
|
||||
studio_light = BKE_studiolight_studio_edit_get();
|
||||
}
|
||||
else {
|
||||
if (shading.light == V3D_LIGHTING_MATCAP) {
|
||||
studio_light = BKE_studiolight_find(shading.matcap, STUDIOLIGHT_TYPE_MATCAP);
|
||||
if (studio_light && studio_light->name != current_matcap) {
|
||||
if (get_matcap_tx(matcap_tx, *studio_light)) {
|
||||
current_matcap = studio_light->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If matcaps are missing, use this as fallback. */
|
||||
if (studio_light == nullptr) {
|
||||
studio_light = BKE_studiolight_find(shading.studio_light, STUDIOLIGHT_TYPE_STUDIO);
|
||||
}
|
||||
}
|
||||
if (!matcap_tx.is_valid()) {
|
||||
matcap_tx.ensure_2d_array(GPU_RGBA16F, int2(1), 1, GPU_TEXTURE_USAGE_SHADER_READ);
|
||||
}
|
||||
|
||||
float4x4 world_shading_rotation = float4x4::identity();
|
||||
if (shading.flag & V3D_SHADING_WORLD_ORIENTATION) {
|
||||
world_shading_rotation = get_world_shading_rotation_matrix(shading.studiolight_rot_z);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
SolidLight *sl = (studio_light) ? &studio_light->light[i] : nullptr;
|
||||
world_buf.lights[i] = get_light_data_from_studio_solidlight(sl, world_shading_rotation);
|
||||
}
|
||||
|
||||
if (studio_light != nullptr) {
|
||||
world_buf.ambient_color = float4(float3(studio_light->light_ambient), 0.0f);
|
||||
world_buf.use_specular = shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT &&
|
||||
studio_light->flag & STUDIOLIGHT_SPECULAR_HIGHLIGHT_PASS;
|
||||
}
|
||||
else {
|
||||
world_buf.ambient_color = float4(1.0f, 1.0f, 1.0f, 0.0f);
|
||||
world_buf.use_specular = false;
|
||||
}
|
||||
|
||||
/* TODO(Miguel Pozo) volumes_do */
|
||||
|
||||
cavity.init(scene_state, *this);
|
||||
|
||||
if (scene_state.draw_dof && !jitter_tx.is_valid()) {
|
||||
/* We don't care about total_samples in this case */
|
||||
load_jitter_tx(1);
|
||||
}
|
||||
|
||||
world_buf.push_update();
|
||||
|
||||
for (int i : IndexRange(6)) {
|
||||
if (i < scene_state.clip_planes.size()) {
|
||||
clip_planes_buf[i] = scene_state.clip_planes[i];
|
||||
}
|
||||
else {
|
||||
clip_planes_buf[i] = float4(0);
|
||||
}
|
||||
}
|
||||
|
||||
clip_planes_buf.push_update();
|
||||
}
|
||||
|
||||
} // namespace blender::workbench
|
132
source/blender/draw/engines/workbench/workbench_shader_cache.cc
Normal file
132
source/blender/draw/engines/workbench/workbench_shader_cache.cc
Normal file
@@ -0,0 +1,132 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "workbench_private.hh"
|
||||
|
||||
namespace blender::workbench {
|
||||
|
||||
ShaderCache::~ShaderCache()
|
||||
{
|
||||
for (auto i : IndexRange(lighting_type_len)) {
|
||||
for (auto j : IndexRange(shader_type_len)) {
|
||||
for (auto k : IndexRange(geometry_type_len)) {
|
||||
for (auto l : IndexRange(pipeline_type_len)) {
|
||||
for (auto m : IndexRange(2)) {
|
||||
DRW_SHADER_FREE_SAFE(prepass_shader_cache_[i][j][k][l][m]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto i : IndexRange(lighting_type_len)) {
|
||||
for (auto j : IndexRange(pipeline_type_len)) {
|
||||
for (auto k : IndexRange(2)) {
|
||||
for (auto l : IndexRange(2)) {
|
||||
DRW_SHADER_FREE_SAFE(resolve_shader_cache_[i][j][k][l]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GPUShader *ShaderCache::prepass_shader_get(ePipelineType pipeline_type,
|
||||
eGeometryType geometry_type,
|
||||
eShaderType shader_type,
|
||||
eLightingType lighting_type,
|
||||
bool clip)
|
||||
{
|
||||
GPUShader *&shader_ptr = prepass_shader_cache_[static_cast<int>(pipeline_type)][static_cast<int>(
|
||||
geometry_type)][static_cast<int>(shader_type)][static_cast<int>(lighting_type)]
|
||||
[clip ? 1 : 0];
|
||||
|
||||
if (shader_ptr != nullptr) {
|
||||
return shader_ptr;
|
||||
}
|
||||
std::string info_name = "workbench_next_prepass_";
|
||||
switch (geometry_type) {
|
||||
case eGeometryType::MESH:
|
||||
info_name += "mesh_";
|
||||
break;
|
||||
case eGeometryType::CURVES:
|
||||
info_name += "curves_";
|
||||
break;
|
||||
case eGeometryType::POINTCLOUD:
|
||||
info_name += "ptcloud_";
|
||||
break;
|
||||
}
|
||||
switch (pipeline_type) {
|
||||
case ePipelineType::OPAQUE:
|
||||
info_name += "opaque_";
|
||||
break;
|
||||
case ePipelineType::TRANSPARENT:
|
||||
info_name += "transparent_";
|
||||
break;
|
||||
case ePipelineType::SHADOW:
|
||||
info_name += "shadow_";
|
||||
break;
|
||||
}
|
||||
switch (lighting_type) {
|
||||
case eLightingType::FLAT:
|
||||
info_name += "flat_";
|
||||
break;
|
||||
case eLightingType::STUDIO:
|
||||
info_name += "studio_";
|
||||
break;
|
||||
case eLightingType::MATCAP:
|
||||
info_name += "matcap_";
|
||||
break;
|
||||
}
|
||||
switch (shader_type) {
|
||||
case eShaderType::MATERIAL:
|
||||
info_name += "material";
|
||||
break;
|
||||
case eShaderType::TEXTURE:
|
||||
info_name += "texture";
|
||||
break;
|
||||
}
|
||||
info_name += clip ? "_clip" : "_no_clip";
|
||||
shader_ptr = GPU_shader_create_from_info_name(info_name.c_str());
|
||||
return shader_ptr;
|
||||
}
|
||||
|
||||
GPUShader *ShaderCache::resolve_shader_get(ePipelineType pipeline_type,
|
||||
eLightingType lighting_type,
|
||||
bool cavity,
|
||||
bool curvature)
|
||||
{
|
||||
GPUShader *&shader_ptr = resolve_shader_cache_[static_cast<int>(pipeline_type)][static_cast<int>(
|
||||
lighting_type)][cavity][curvature];
|
||||
|
||||
if (shader_ptr != nullptr) {
|
||||
return shader_ptr;
|
||||
}
|
||||
std::string info_name = "workbench_next_resolve_";
|
||||
switch (pipeline_type) {
|
||||
case ePipelineType::OPAQUE:
|
||||
info_name += "opaque_";
|
||||
break;
|
||||
case ePipelineType::TRANSPARENT:
|
||||
info_name += "transparent_";
|
||||
break;
|
||||
case ePipelineType::SHADOW:
|
||||
BLI_assert_unreachable();
|
||||
break;
|
||||
}
|
||||
switch (lighting_type) {
|
||||
case eLightingType::FLAT:
|
||||
info_name += "flat";
|
||||
break;
|
||||
case eLightingType::STUDIO:
|
||||
info_name += "studio";
|
||||
break;
|
||||
case eLightingType::MATCAP:
|
||||
info_name += "matcap";
|
||||
break;
|
||||
}
|
||||
info_name += cavity ? "_cavity" : "_no_cavity";
|
||||
info_name += curvature ? "_curvature" : "_no_curvature";
|
||||
|
||||
shader_ptr = GPU_shader_create_from_info_name(info_name.c_str());
|
||||
return shader_ptr;
|
||||
}
|
||||
|
||||
} // namespace blender::workbench
|
@@ -13,7 +13,8 @@ struct LightData {
|
||||
};
|
||||
|
||||
struct WorldData {
|
||||
float4 viewport_size;
|
||||
float2 viewport_size;
|
||||
float2 viewport_size_inv;
|
||||
float4 object_outline_color;
|
||||
float4 shadow_direction_vs;
|
||||
float shadow_focus;
|
||||
@@ -41,8 +42,23 @@ struct WorldData {
|
||||
|
||||
int matcap_orientation;
|
||||
bool use_specular;
|
||||
float xray_alpha;
|
||||
int _pad1;
|
||||
int _pad2;
|
||||
|
||||
float4 background_color;
|
||||
};
|
||||
|
||||
#define viewport_size_inv viewport_size.zw
|
||||
struct ExtrudedFrustum {
|
||||
/** \note vec3 array padded to vec4. */
|
||||
float4 corners[16];
|
||||
float4 planes[12];
|
||||
int corners_count;
|
||||
int planes_count;
|
||||
int _padding[2];
|
||||
};
|
||||
|
||||
struct ShadowPassData {
|
||||
float4 far_plane;
|
||||
float3 light_direction_ws;
|
||||
int _padding;
|
||||
};
|
||||
|
465
source/blender/draw/engines/workbench/workbench_shadow.cc
Normal file
465
source/blender/draw/engines/workbench/workbench_shadow.cc
Normal file
@@ -0,0 +1,465 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*
|
||||
* Shadow:
|
||||
*
|
||||
* Use stencil shadow buffer to cast a sharp shadow over opaque surfaces.
|
||||
*
|
||||
* After the main pre-pass we render shadow volumes using custom depth & stencil states to
|
||||
* set the stencil of shadowed area to anything but 0.
|
||||
*
|
||||
* Then the shading pass will shade the areas with stencil not equal 0 differently.
|
||||
*/
|
||||
|
||||
#include "BKE_object.h"
|
||||
#include "BLI_math.h"
|
||||
#include "DRW_render.h"
|
||||
#include "GPU_compute.h"
|
||||
|
||||
#include "workbench_private.hh"
|
||||
|
||||
#define DEBUG_SHADOW_VOLUME 0
|
||||
|
||||
namespace blender::workbench {
|
||||
|
||||
ShadowPass::ShadowView::ShadowView() : View("ShadowPass.View"){};
|
||||
|
||||
void ShadowPass::ShadowView::setup(View &view, float3 light_direction, bool force_fail_method)
|
||||
{
|
||||
force_fail_method_ = force_fail_method;
|
||||
light_direction_ = light_direction;
|
||||
sync(view.viewmat(), view.winmat());
|
||||
|
||||
/* Prepare frustum extruded in the negative light direction,
|
||||
* so we can test regular bounding boxes against it for culling. */
|
||||
|
||||
/* Frustum Corners indices
|
||||
* Z Y
|
||||
* | /
|
||||
* |/
|
||||
* .-----X
|
||||
* 3----------7
|
||||
* /| /|
|
||||
* / | / |
|
||||
* 0----------4 |
|
||||
* | | | |
|
||||
* | 2-------|--6
|
||||
* | / | /
|
||||
* |/ |/
|
||||
* 1----------5
|
||||
*/
|
||||
|
||||
/* Frustum Planes indices */
|
||||
const int x_neg = 0; /* Left */
|
||||
const int x_pos = 5; /* Right */
|
||||
const int y_neg = 1; /* Bottom */
|
||||
const int y_pos = 3; /* Top */
|
||||
const int z_pos = 4; /* Near */
|
||||
const int z_neg = 2; /* Far */
|
||||
|
||||
int3 corner_faces[8] = {{x_neg, y_neg, z_pos},
|
||||
{x_neg, y_neg, z_neg},
|
||||
{x_neg, y_pos, z_neg},
|
||||
{x_neg, y_pos, z_pos},
|
||||
{x_pos, y_neg, z_pos},
|
||||
{x_pos, y_neg, z_neg},
|
||||
{x_pos, y_pos, z_neg},
|
||||
{x_pos, y_pos, z_pos}};
|
||||
|
||||
int2 edge_faces[12] = {{x_neg, y_neg},
|
||||
{x_neg, z_neg},
|
||||
{x_neg, y_pos},
|
||||
{x_neg, z_pos},
|
||||
{y_neg, x_pos},
|
||||
{z_neg, x_pos},
|
||||
{y_pos, x_pos},
|
||||
{z_pos, x_pos},
|
||||
{y_neg, z_pos},
|
||||
{z_neg, y_neg},
|
||||
{y_pos, z_neg},
|
||||
{z_pos, y_pos}};
|
||||
|
||||
int2 edge_corners[12] = {{0, 1},
|
||||
{1, 2},
|
||||
{2, 3},
|
||||
{3, 0},
|
||||
{4, 5},
|
||||
{5, 6},
|
||||
{6, 7},
|
||||
{7, 4},
|
||||
{0, 4},
|
||||
{1, 5},
|
||||
{2, 6},
|
||||
{3, 7}};
|
||||
|
||||
BoundBox frustum_corners;
|
||||
DRW_culling_frustum_corners_get(nullptr, &frustum_corners);
|
||||
float4 frustum_planes[6];
|
||||
DRW_culling_frustum_planes_get(nullptr, (float(*)[4])frustum_planes);
|
||||
|
||||
Vector<float4> faces_result = {};
|
||||
Vector<float3> corners_result = {};
|
||||
|
||||
/* "Unlit" frustum faces are left "as-is" */
|
||||
|
||||
bool face_lit[6];
|
||||
for (int i : IndexRange(6)) {
|
||||
/* Make the frustum normals face outwards */
|
||||
frustum_planes[i] *= float4(-1, -1, -1, 1);
|
||||
|
||||
face_lit[i] = math::dot(float3(frustum_planes[i]), light_direction_) < 0;
|
||||
if (!face_lit[i]) {
|
||||
faces_result.append(frustum_planes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Edges between lit and unlit faces are extruded "infinitely" towards the light source */
|
||||
|
||||
for (int i : IndexRange(12)) {
|
||||
int2 f = edge_faces[i];
|
||||
bool a_lit = face_lit[f[0]];
|
||||
bool b_lit = face_lit[f[1]];
|
||||
if (a_lit != b_lit) {
|
||||
/* Extrude Face */
|
||||
float3 corner_a = frustum_corners.vec[edge_corners[i][0]];
|
||||
float3 corner_b = frustum_corners.vec[edge_corners[i][1]];
|
||||
float3 edge_direction = math::normalize(corner_b - corner_a);
|
||||
float3 normal = math::normalize(math::cross(light_direction_, edge_direction));
|
||||
|
||||
float4 extruded_face = float4(UNPACK3(normal), math::dot(normal, corner_a));
|
||||
|
||||
/* Ensure the plane faces outwards */
|
||||
bool flipped = false;
|
||||
for (float3 corner : frustum_corners.vec) {
|
||||
if (math::dot(float3(extruded_face), corner) > (extruded_face.w + 0.1)) {
|
||||
BLI_assert(!flipped);
|
||||
flipped = true;
|
||||
extruded_face *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
faces_result.append(extruded_face);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i_corner : IndexRange(8)) {
|
||||
int lit_faces = 0;
|
||||
for (int i_face : IndexRange(3)) {
|
||||
lit_faces += face_lit[corner_faces[i_corner][i_face]] ? 1 : 0;
|
||||
}
|
||||
if (lit_faces < 3) {
|
||||
/* Add original corner */
|
||||
corners_result.append(frustum_corners.vec[i_corner]);
|
||||
|
||||
if (lit_faces > 0) {
|
||||
/* Add extruded corner */
|
||||
corners_result.append(float3(frustum_corners.vec[i_corner]) - (light_direction_ * 1e4f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i : corners_result.index_range()) {
|
||||
extruded_frustum_.corners[i] = float4(corners_result[i], 1);
|
||||
}
|
||||
extruded_frustum_.corners_count = corners_result.size();
|
||||
|
||||
for (int i : faces_result.index_range()) {
|
||||
extruded_frustum_.planes[i] = faces_result[i];
|
||||
}
|
||||
extruded_frustum_.planes_count = faces_result.size();
|
||||
|
||||
extruded_frustum_.push_update();
|
||||
}
|
||||
|
||||
bool ShadowPass::ShadowView::debug_object_culling(Object *ob)
|
||||
{
|
||||
printf("Test %s\n", ob->id.name);
|
||||
const BoundBox *_bbox = BKE_object_boundbox_get(ob);
|
||||
for (int p : IndexRange(extruded_frustum_.planes_count)) {
|
||||
float4 plane = extruded_frustum_.planes[p];
|
||||
bool separating_axis = true;
|
||||
for (float3 corner : _bbox->vec) {
|
||||
corner = float4x4(ob->object_to_world) * corner;
|
||||
float signed_distance = math::dot(corner, float3(plane)) - plane.w;
|
||||
if (signed_distance <= 0) {
|
||||
separating_axis = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (separating_axis) {
|
||||
printf("Sepatating Axis >>> x: %f, y: %f, z: %f, w: %f \n", UNPACK4(plane));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ShadowPass::ShadowView::set_mode(ShadowPass::PassType type)
|
||||
{
|
||||
current_pass_type_ = type;
|
||||
}
|
||||
|
||||
void ShadowPass::ShadowView::compute_visibility(ObjectMatricesBuf &matrices,
|
||||
ObjectBoundsBuf &bounds,
|
||||
uint resource_len,
|
||||
bool debug_freeze)
|
||||
{
|
||||
GPU_debug_group_begin("ShadowView.compute_visibility");
|
||||
|
||||
uint word_per_draw = this->visibility_word_per_draw();
|
||||
/* Switch between tightly packed and set of whole word per instance. */
|
||||
uint words_len = (view_len_ == 1) ? divide_ceil_u(resource_len, 32) :
|
||||
resource_len * word_per_draw;
|
||||
words_len = ceil_to_multiple_u(max_ii(1, words_len), 4);
|
||||
uint32_t data = 0xFFFFFFFFu;
|
||||
|
||||
if (current_pass_type_ == ShadowPass::PASS) {
|
||||
/* TODO(fclem): Resize to nearest pow2 to reduce fragmentation. */
|
||||
pass_visibility_buf_.resize(words_len);
|
||||
GPU_storagebuf_clear(pass_visibility_buf_, GPU_R32UI, GPU_DATA_UINT, &data);
|
||||
fail_visibility_buf_.resize(words_len);
|
||||
GPU_storagebuf_clear(fail_visibility_buf_, GPU_R32UI, GPU_DATA_UINT, &data);
|
||||
}
|
||||
else if (current_pass_type_ == ShadowPass::FAIL) {
|
||||
/* Already computed in the ShadowPass::PASS */
|
||||
GPU_debug_group_end();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
visibility_buf_.resize(words_len);
|
||||
GPU_storagebuf_clear(visibility_buf_, GPU_R32UI, GPU_DATA_UINT, &data);
|
||||
}
|
||||
|
||||
/* TODO(Miguel Pozo): Disabled in the optimization branch */
|
||||
do_visibility_ = false;
|
||||
if (do_visibility_) {
|
||||
/* TODO(Miguel Pozo): Use regular culling for the caps pass */
|
||||
|
||||
static GPUShader *dynamic_pass_type_shader = GPU_shader_create_from_info_name(
|
||||
"workbench_next_shadow_visibility_compute_dynamic_pass_type");
|
||||
static GPUShader *static_pass_type_shader = GPU_shader_create_from_info_name(
|
||||
"workbench_next_shadow_visibility_compute_static_pass_type");
|
||||
|
||||
GPUShader *shader = current_pass_type_ == ShadowPass::FORCED_FAIL ? static_pass_type_shader :
|
||||
dynamic_pass_type_shader;
|
||||
GPU_shader_bind(shader);
|
||||
GPU_shader_uniform_1i(shader, "resource_len", resource_len);
|
||||
GPU_shader_uniform_1i(shader, "view_len", view_len_);
|
||||
GPU_shader_uniform_1i(shader, "visibility_word_per_draw", word_per_draw);
|
||||
GPU_shader_uniform_1b(shader, "force_fail_method", force_fail_method_);
|
||||
GPU_shader_uniform_3fv(shader, "shadow_direction", light_direction_);
|
||||
GPU_uniformbuf_bind(extruded_frustum_,
|
||||
GPU_shader_get_uniform_block(shader, "extruded_frustum"));
|
||||
GPU_storagebuf_bind(matrices, GPU_shader_get_ssbo(shader, "matrix_buf"));
|
||||
GPU_storagebuf_bind(bounds, GPU_shader_get_ssbo(shader, "bounds_buf"));
|
||||
if (current_pass_type_ == ShadowPass::FORCED_FAIL) {
|
||||
GPU_storagebuf_bind(visibility_buf_, GPU_shader_get_ssbo(shader, "visibility_buf"));
|
||||
}
|
||||
else {
|
||||
GPU_storagebuf_bind(pass_visibility_buf_,
|
||||
GPU_shader_get_ssbo(shader, "pass_visibility_buf"));
|
||||
GPU_storagebuf_bind(fail_visibility_buf_,
|
||||
GPU_shader_get_ssbo(shader, "fail_visibility_buf"));
|
||||
}
|
||||
GPU_uniformbuf_bind(data_, DRW_VIEW_UBO_SLOT);
|
||||
GPU_compute_dispatch(shader, divide_ceil_u(resource_len, DRW_VISIBILITY_GROUP_SIZE), 1, 1);
|
||||
GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE);
|
||||
}
|
||||
|
||||
GPU_debug_group_end();
|
||||
}
|
||||
|
||||
VisibilityBuf &ShadowPass::ShadowView::get_visibility_buffer()
|
||||
{
|
||||
switch (current_pass_type_) {
|
||||
case ShadowPass::PASS:
|
||||
return pass_visibility_buf_;
|
||||
case ShadowPass::FAIL:
|
||||
return fail_visibility_buf_;
|
||||
case ShadowPass::FORCED_FAIL:
|
||||
return visibility_buf_;
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
return visibility_buf_;
|
||||
}
|
||||
|
||||
PassMain::Sub *&ShadowPass::get_pass_ptr(PassType type, bool manifold, bool cap /*= false*/)
|
||||
{
|
||||
return passes_[type][manifold][cap];
|
||||
}
|
||||
|
||||
GPUShader *ShadowPass::get_shader(bool depth_pass, bool manifold, bool cap /*= false*/)
|
||||
{
|
||||
GPUShader *&shader = shaders_[depth_pass][manifold][cap];
|
||||
|
||||
if (shader == nullptr) {
|
||||
std::string create_info_name = "workbench_next_shadow";
|
||||
create_info_name += (depth_pass) ? "_pass" : "_fail";
|
||||
create_info_name += (manifold) ? "_manifold" : "_no_manifold";
|
||||
create_info_name += (cap) ? "_caps" : "_no_caps";
|
||||
#if DEBUG_SHADOW_VOLUME
|
||||
create_info_name += "_debug";
|
||||
#endif
|
||||
shader = GPU_shader_create_from_info_name(create_info_name.c_str());
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
void ShadowPass::init(const SceneState &scene_state, SceneResources &resources)
|
||||
{
|
||||
enabled_ = scene_state.draw_shadows;
|
||||
if (!enabled_) {
|
||||
resources.world_buf.shadow_mul = 0.0f;
|
||||
resources.world_buf.shadow_add = 1.0f;
|
||||
return;
|
||||
}
|
||||
const Scene &scene = *scene_state.scene;
|
||||
|
||||
float3 direction_ws = scene.display.light_direction;
|
||||
/* Turn the light in a way where it's more user friendly to control. */
|
||||
SWAP(float, direction_ws.y, direction_ws.z);
|
||||
direction_ws *= float3(-1, 1, -1);
|
||||
|
||||
float planes[6][4];
|
||||
DRW_culling_frustum_planes_get(nullptr, planes);
|
||||
|
||||
pass_data_.light_direction_ws = direction_ws;
|
||||
pass_data_.far_plane = planes[2] * float4(-1, -1, -1, 1);
|
||||
pass_data_.push_update();
|
||||
|
||||
/* Shadow direction. */
|
||||
float4x4 view_matrix;
|
||||
DRW_view_viewmat_get(NULL, view_matrix.ptr(), false);
|
||||
resources.world_buf.shadow_direction_vs = float4(view_matrix.ref_3x3() * direction_ws);
|
||||
|
||||
/* Clamp to avoid overshadowing and shading errors. */
|
||||
float focus = clamp_f(scene.display.shadow_focus, 0.0001f, 0.99999f);
|
||||
resources.world_buf.shadow_shift = scene.display.shadow_shift;
|
||||
resources.world_buf.shadow_focus = 1.0f - focus * (1.0f - resources.world_buf.shadow_shift);
|
||||
resources.world_buf.shadow_mul = scene_state.shading.shadow_intensity;
|
||||
resources.world_buf.shadow_add = 1.0f - resources.world_buf.shadow_mul;
|
||||
}
|
||||
|
||||
void ShadowPass::sync()
|
||||
{
|
||||
if (!enabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if DEBUG_SHADOW_VOLUME
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL;
|
||||
DRWState depth_pass_state = state | DRW_STATE_DEPTH_LESS;
|
||||
DRWState depth_fail_state = state | DRW_STATE_DEPTH_GREATER_EQUAL;
|
||||
#else
|
||||
DRWState state = DRW_STATE_DEPTH_LESS | DRW_STATE_STENCIL_ALWAYS;
|
||||
DRWState depth_pass_state = state | DRW_STATE_WRITE_STENCIL_SHADOW_PASS;
|
||||
DRWState depth_fail_state = state | DRW_STATE_WRITE_STENCIL_SHADOW_FAIL;
|
||||
#endif
|
||||
|
||||
pass_ps_.init();
|
||||
pass_ps_.state_set(depth_pass_state);
|
||||
pass_ps_.state_stencil(0xFF, 0xFF, 0xFF);
|
||||
|
||||
fail_ps_.init();
|
||||
fail_ps_.state_set(depth_fail_state);
|
||||
fail_ps_.state_stencil(0xFF, 0xFF, 0xFF);
|
||||
|
||||
forced_fail_ps_.init();
|
||||
forced_fail_ps_.state_set(depth_fail_state);
|
||||
forced_fail_ps_.state_stencil(0xFF, 0xFF, 0xFF);
|
||||
|
||||
/* Stencil Shadow passes. */
|
||||
for (bool manifold : {false, true}) {
|
||||
PassMain::Sub *&ps = get_pass_ptr(PASS, manifold);
|
||||
ps = &pass_ps_.sub(manifold ? "manifold" : "non_manifold");
|
||||
ps->shader_set(get_shader(true, manifold));
|
||||
ps->bind_ubo("pass_data", pass_data_);
|
||||
|
||||
for (PassType fail_type : {FAIL, FORCED_FAIL}) {
|
||||
PassMain &ps_main = fail_type == FAIL ? fail_ps_ : forced_fail_ps_;
|
||||
|
||||
PassMain::Sub *&ps = get_pass_ptr(fail_type, manifold, false);
|
||||
ps = &ps_main.sub(manifold ? "NoCaps.manifold" : "NoCaps.non_manifold");
|
||||
ps->shader_set(get_shader(false, manifold, false));
|
||||
ps->bind_ubo("pass_data", pass_data_);
|
||||
|
||||
PassMain::Sub *&caps_ps = get_pass_ptr(fail_type, manifold, true);
|
||||
caps_ps = &ps_main.sub(manifold ? "Caps.manifold" : "Caps.non_manifold");
|
||||
caps_ps->shader_set(get_shader(false, manifold, true));
|
||||
caps_ps->bind_ubo("pass_data", pass_data_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ShadowPass::object_sync(Manager &manager,
|
||||
SceneState &scene_state,
|
||||
ObjectRef &ob_ref,
|
||||
ResourceHandle handle,
|
||||
const bool has_transp_mat)
|
||||
{
|
||||
if (!enabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object *ob = ob_ref.object;
|
||||
bool is_manifold;
|
||||
GPUBatch *geom_shadow = DRW_cache_object_edge_detection_get(ob, &is_manifold);
|
||||
if (geom_shadow == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
#define DEBUG_CULLING 0
|
||||
#if DEBUG_CULLING
|
||||
View view = View("View", DRW_view_default_get());
|
||||
ShadowView shadow_view = ShadowView("ShadowView", view, pass_data_.light_direction_ws);
|
||||
printf(
|
||||
"%s culling : %s\n", ob->id.name, shadow_view.debug_object_culling(ob) ? "true" : "false");
|
||||
#endif
|
||||
|
||||
/* Shadow pass technique needs object to be have all its surface opaque. */
|
||||
/* We cannot use the PASS technique on non-manifold object (see T76168). */
|
||||
bool force_fail_pass = has_transp_mat || (!is_manifold && (scene_state.cull_state != 0));
|
||||
|
||||
PassType fail_type = force_fail_pass ? FORCED_FAIL : FAIL;
|
||||
|
||||
/* Unless we force the FAIL Method we add draw commands to both methods,
|
||||
* then the visibility compute shader selects the one needed */
|
||||
|
||||
if (!force_fail_pass) {
|
||||
PassMain::Sub &ps = *get_pass_ptr(PASS, is_manifold);
|
||||
ps.draw(geom_shadow, handle);
|
||||
}
|
||||
|
||||
get_pass_ptr(fail_type, is_manifold, true)->draw(DRW_cache_object_surface_get(ob), handle);
|
||||
get_pass_ptr(fail_type, is_manifold, false)->draw(geom_shadow, handle);
|
||||
}
|
||||
|
||||
void ShadowPass::draw(Manager &manager,
|
||||
View &view,
|
||||
SceneResources &resources,
|
||||
int2 resolution,
|
||||
GPUTexture &depth_stencil_tx,
|
||||
bool force_fail_method)
|
||||
{
|
||||
if (!enabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
fb_.ensure(GPU_ATTACHMENT_TEXTURE(&depth_stencil_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(resources.color_tx));
|
||||
fb_.bind();
|
||||
|
||||
view_.setup(view, pass_data_.light_direction_ws, force_fail_method);
|
||||
|
||||
view_.set_mode(PASS);
|
||||
manager.submit(pass_ps_, view_);
|
||||
view_.set_mode(FAIL);
|
||||
manager.submit(fail_ps_, view_);
|
||||
view_.set_mode(FORCED_FAIL);
|
||||
manager.submit(forced_fail_ps_, view_);
|
||||
}
|
||||
|
||||
} // namespace blender::workbench
|
301
source/blender/draw/engines/workbench/workbench_state.cc
Normal file
301
source/blender/draw/engines/workbench/workbench_state.cc
Normal file
@@ -0,0 +1,301 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "workbench_private.hh"
|
||||
|
||||
#include "BKE_camera.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_pbvh.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
#include "DNA_fluid_types.h"
|
||||
#include "ED_paint.h"
|
||||
#include "ED_view3d.h"
|
||||
#include "GPU_capabilities.h"
|
||||
|
||||
namespace blender::workbench {
|
||||
|
||||
void SceneState::init(Object *camera_ob /*= nullptr*/)
|
||||
{
|
||||
bool reset_taa = reset_taa_next_sample;
|
||||
reset_taa_next_sample = false;
|
||||
|
||||
const DRWContextState *context = DRW_context_state_get();
|
||||
View3D *v3d = context->v3d;
|
||||
RegionView3D *rv3d = context->rv3d;
|
||||
|
||||
scene = DEG_get_evaluated_scene(context->depsgraph);
|
||||
|
||||
GPUTexture *viewport_tx = DRW_viewport_texture_list_get()->color;
|
||||
resolution = int2(GPU_texture_width(viewport_tx), GPU_texture_height(viewport_tx));
|
||||
|
||||
camera_object = camera_ob;
|
||||
if (camera_object == nullptr && v3d && rv3d) {
|
||||
camera_object = (rv3d->persp == RV3D_CAMOB) ? v3d->camera : nullptr;
|
||||
}
|
||||
camera = camera_object && camera_object->type == OB_CAMERA ?
|
||||
static_cast<Camera *>(camera_object->data) :
|
||||
nullptr;
|
||||
|
||||
object_mode = CTX_data_mode_enum_ex(context->object_edit, context->obact, context->object_mode);
|
||||
|
||||
/* TODO(Miguel Pozo):
|
||||
* Check why Workbench Next exposes OB_MATERIAL, and Workbench exposes OB_RENDER */
|
||||
bool is_render_mode = !v3d || ELEM(v3d->shading.type, OB_RENDER, OB_MATERIAL);
|
||||
|
||||
const View3DShading previous_shading = shading;
|
||||
shading = is_render_mode ? scene->display.shading : v3d->shading;
|
||||
|
||||
cull_state = shading.flag & V3D_SHADING_BACKFACE_CULLING ? DRW_STATE_CULL_BACK :
|
||||
DRW_STATE_NO_DRAW;
|
||||
|
||||
/* FIXME: This reproduce old behavior when workbench was separated in 2 engines.
|
||||
* But this is a workaround for a missing update tagging. */
|
||||
DRWState new_clip_state = RV3D_CLIPPING_ENABLED(v3d, rv3d) ? DRW_STATE_CLIP_PLANES :
|
||||
DRW_STATE_NO_DRAW;
|
||||
DRWState old_clip_state = clip_planes.size() > 0 ? DRW_STATE_CLIP_PLANES : DRW_STATE_NO_DRAW;
|
||||
if (new_clip_state != old_clip_state) {
|
||||
reset_taa = true;
|
||||
}
|
||||
clip_planes.clear();
|
||||
if (new_clip_state & DRW_STATE_CLIP_PLANES) {
|
||||
int plane_len = (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) ? 4 : 6;
|
||||
for (auto i : IndexRange(plane_len)) {
|
||||
clip_planes.append(rv3d->clip[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_render_mode) {
|
||||
if (shading.type < OB_SOLID) {
|
||||
shading.light = V3D_LIGHTING_FLAT;
|
||||
shading.color_type = V3D_SHADING_OBJECT_COLOR;
|
||||
shading.xray_alpha = 0.0f;
|
||||
}
|
||||
else if (SHADING_XRAY_ENABLED(shading)) {
|
||||
shading.xray_alpha = SHADING_XRAY_ALPHA(shading);
|
||||
}
|
||||
else {
|
||||
shading.xray_alpha = 1.0f;
|
||||
}
|
||||
}
|
||||
xray_mode = !is_render_mode && shading.xray_alpha != 1.0f;
|
||||
|
||||
if (SHADING_XRAY_FLAG_ENABLED(shading)) {
|
||||
/* Disable shading options that aren't supported in transparency mode. */
|
||||
shading.flag &= ~(V3D_SHADING_SHADOW | V3D_SHADING_CAVITY | V3D_SHADING_DEPTH_OF_FIELD);
|
||||
}
|
||||
if (SHADING_XRAY_ENABLED(shading) != SHADING_XRAY_ENABLED(previous_shading) ||
|
||||
shading.flag != previous_shading.flag) {
|
||||
reset_taa = true;
|
||||
}
|
||||
|
||||
lighting_type = lighting_type_from_v3d_lighting(shading.light);
|
||||
material_override = Material(shading.single_color);
|
||||
|
||||
background_color = float4(0.0f);
|
||||
if (is_render_mode && scene->r.alphamode != R_ALPHAPREMUL) {
|
||||
if (World *w = scene->world) {
|
||||
background_color = float4(w->horr, w->horg, w->horb, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (rv3d && rv3d->rflag & RV3D_GPULIGHT_UPDATE) {
|
||||
reset_taa = true;
|
||||
/* FIXME: This reproduce old behavior when workbench was separated in 2 engines.
|
||||
* But this is a workaround for a missing update tagging. */
|
||||
rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE;
|
||||
}
|
||||
|
||||
float4x4 matrix;
|
||||
/*TODO(Miguel Pozo): New API ?*/
|
||||
DRW_view_persmat_get(nullptr, matrix.ptr(), false);
|
||||
if (matrix != view_projection_matrix) {
|
||||
view_projection_matrix = matrix;
|
||||
reset_taa = true;
|
||||
}
|
||||
|
||||
bool is_playback = DRW_state_is_playback();
|
||||
bool is_navigating = DRW_state_is_navigating();
|
||||
|
||||
/* Reset complete drawing when navigating or during viewport playback or when
|
||||
* leaving one of those states. In case of multires modifier the navigation
|
||||
* mesh differs from the viewport mesh, so we need to be sure to restart. */
|
||||
if (is_playback || is_navigating) {
|
||||
reset_taa = true;
|
||||
reset_taa_next_sample = true;
|
||||
}
|
||||
|
||||
int _samples_len = U.viewport_aa;
|
||||
if (v3d && ELEM(v3d->shading.type, OB_RENDER, OB_MATERIAL)) {
|
||||
_samples_len = scene->display.viewport_aa;
|
||||
}
|
||||
else if (DRW_state_is_image_render()) {
|
||||
_samples_len = scene->display.render_aa;
|
||||
}
|
||||
if (is_navigating || is_playback) {
|
||||
/* Only draw using SMAA or no AA when navigating. */
|
||||
_samples_len = min_ii(_samples_len, 1);
|
||||
}
|
||||
/* 0 samples means no AA */
|
||||
draw_aa = _samples_len > 0;
|
||||
_samples_len = max_ii(_samples_len, 1);
|
||||
|
||||
/* Reset the TAA when we have already draw a sample, but the sample count differs from previous
|
||||
* time. This removes render artifacts when the viewport anti-aliasing in the user preferences
|
||||
* is set to a lower value. */
|
||||
if (samples_len != _samples_len) {
|
||||
samples_len = _samples_len;
|
||||
reset_taa = true;
|
||||
}
|
||||
|
||||
if (reset_taa || samples_len <= 1) {
|
||||
sample = 0;
|
||||
}
|
||||
else {
|
||||
sample++;
|
||||
}
|
||||
render_finished = sample >= samples_len && samples_len > 1;
|
||||
|
||||
/* TODO(Miguel Pozo) volumes_do */
|
||||
|
||||
draw_cavity = shading.flag & V3D_SHADING_CAVITY &&
|
||||
ELEM(shading.cavity_type, V3D_SHADING_CAVITY_SSAO, V3D_SHADING_CAVITY_BOTH);
|
||||
draw_curvature = shading.flag & V3D_SHADING_CAVITY && ELEM(shading.cavity_type,
|
||||
V3D_SHADING_CAVITY_CURVATURE,
|
||||
V3D_SHADING_CAVITY_BOTH);
|
||||
draw_shadows = shading.flag & V3D_SHADING_SHADOW;
|
||||
draw_outline = shading.flag & V3D_SHADING_OBJECT_OUTLINE;
|
||||
draw_dof = camera && camera->dof.flag & CAM_DOF_ENABLED &&
|
||||
shading.flag & V3D_SHADING_DEPTH_OF_FIELD;
|
||||
|
||||
draw_transparent_depth = draw_outline || draw_dof;
|
||||
draw_object_id = draw_outline || draw_curvature;
|
||||
};
|
||||
|
||||
static const CustomData *get_loop_custom_data(const Mesh *mesh)
|
||||
{
|
||||
if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
|
||||
BLI_assert(mesh->edit_mesh != nullptr);
|
||||
BLI_assert(mesh->edit_mesh->bm != nullptr);
|
||||
return &mesh->edit_mesh->bm->ldata;
|
||||
}
|
||||
return &mesh->ldata;
|
||||
}
|
||||
|
||||
static const CustomData *get_vert_custom_data(const Mesh *mesh)
|
||||
{
|
||||
if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
|
||||
BLI_assert(mesh->edit_mesh != nullptr);
|
||||
BLI_assert(mesh->edit_mesh->bm != nullptr);
|
||||
return &mesh->edit_mesh->bm->vdata;
|
||||
}
|
||||
return &mesh->vdata;
|
||||
}
|
||||
|
||||
ObjectState::ObjectState(const SceneState &scene_state, Object *ob)
|
||||
{
|
||||
sculpt_pbvh = false;
|
||||
texture_paint_mode = false;
|
||||
image_paint_override = nullptr;
|
||||
override_sampler_state = GPU_SAMPLER_DEFAULT;
|
||||
draw_shadow = false;
|
||||
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const Mesh *me = (ob->type == OB_MESH) ? static_cast<Mesh *>(ob->data) : nullptr;
|
||||
const bool is_active = (ob == draw_ctx->obact);
|
||||
/* TODO(Miguel Pozo) Is the double check needed?
|
||||
* If it is, wouldn't be needed for sculpt_pbvh too?
|
||||
*/
|
||||
const bool is_render = DRW_state_is_image_render() && (draw_ctx->v3d == nullptr);
|
||||
|
||||
color_type = (eV3DShadingColorType)scene_state.shading.color_type;
|
||||
if (!(is_active && DRW_object_use_hide_faces(ob))) {
|
||||
draw_shadow = (ob->dtx & OB_DRAW_NO_SHADOW_CAST) == 0 && scene_state.draw_shadows;
|
||||
}
|
||||
if (me == nullptr) {
|
||||
if (color_type == V3D_SHADING_TEXTURE_COLOR) {
|
||||
color_type = V3D_SHADING_MATERIAL_COLOR;
|
||||
}
|
||||
else if (color_type == V3D_SHADING_VERTEX_COLOR) {
|
||||
color_type = V3D_SHADING_OBJECT_COLOR;
|
||||
}
|
||||
use_per_material_batches = color_type == V3D_SHADING_MATERIAL_COLOR;
|
||||
/* Early return */
|
||||
return;
|
||||
}
|
||||
|
||||
sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->rv3d) &&
|
||||
!DRW_state_is_image_render();
|
||||
|
||||
if (sculpt_pbvh) {
|
||||
/* Shadows are unsupported in sculpt mode. We could revert to the slow
|
||||
* method in this case but I'm not sure if it's a good idea given that
|
||||
* sculpted meshes are heavy to begin with. */
|
||||
draw_shadow = false;
|
||||
|
||||
if (color_type == V3D_SHADING_TEXTURE_COLOR && BKE_pbvh_type(ob->sculpt->pbvh) != PBVH_FACES) {
|
||||
/* Force use of material color for sculpt. */
|
||||
color_type = V3D_SHADING_MATERIAL_COLOR;
|
||||
}
|
||||
|
||||
/* Bad call C is required to access the tool system that is context aware. Cast to non-const
|
||||
* due to current API. */
|
||||
bContext *C = (bContext *)DRW_context_state_get()->evil_C;
|
||||
if (C != NULL) {
|
||||
color_type = ED_paint_shading_color_override(
|
||||
C, &scene_state.scene->toolsettings->paint_mode, ob, color_type);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const CustomData *cd_vdata = get_vert_custom_data(me);
|
||||
const CustomData *cd_ldata = get_loop_custom_data(me);
|
||||
|
||||
bool has_color = (CustomData_has_layer(cd_vdata, CD_PROP_COLOR) ||
|
||||
CustomData_has_layer(cd_vdata, CD_PROP_BYTE_COLOR) ||
|
||||
CustomData_has_layer(cd_ldata, CD_PROP_COLOR) ||
|
||||
CustomData_has_layer(cd_ldata, CD_PROP_BYTE_COLOR));
|
||||
|
||||
bool has_uv = CustomData_has_layer(cd_ldata, CD_PROP_FLOAT2);
|
||||
|
||||
if (color_type == V3D_SHADING_TEXTURE_COLOR) {
|
||||
if (ob->dt < OB_TEXTURE || !has_uv) {
|
||||
color_type = V3D_SHADING_MATERIAL_COLOR;
|
||||
}
|
||||
}
|
||||
else if (color_type == V3D_SHADING_VERTEX_COLOR && !has_color) {
|
||||
color_type = V3D_SHADING_OBJECT_COLOR;
|
||||
}
|
||||
|
||||
if (!is_render) {
|
||||
/* Force texture or vertex mode if object is in paint mode. */
|
||||
const bool is_vertpaint_mode = is_active &&
|
||||
(scene_state.object_mode == CTX_MODE_PAINT_VERTEX);
|
||||
const bool is_texpaint_mode = is_active &&
|
||||
(scene_state.object_mode == CTX_MODE_PAINT_TEXTURE);
|
||||
if (is_vertpaint_mode && has_color) {
|
||||
color_type = V3D_SHADING_VERTEX_COLOR;
|
||||
}
|
||||
else if (is_texpaint_mode && has_uv) {
|
||||
color_type = V3D_SHADING_TEXTURE_COLOR;
|
||||
texture_paint_mode = true;
|
||||
|
||||
const ImagePaintSettings *imapaint = &scene_state.scene->toolsettings->imapaint;
|
||||
if (imapaint->mode == IMAGEPAINT_MODE_IMAGE) {
|
||||
image_paint_override = imapaint->canvas;
|
||||
override_sampler_state = GPU_SAMPLER_REPEAT;
|
||||
SET_FLAG_FROM_TEST(override_sampler_state,
|
||||
imapaint->interp == IMAGEPAINT_INTERP_LINEAR,
|
||||
GPU_SAMPLER_FILTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use_per_material_batches = image_paint_override == nullptr && ELEM(color_type,
|
||||
V3D_SHADING_TEXTURE_COLOR,
|
||||
V3D_SHADING_MATERIAL_COLOR);
|
||||
}
|
||||
|
||||
} // namespace blender::workbench
|
@@ -1052,6 +1052,16 @@ class Framebuffer : NonCopyable {
|
||||
&fb_, {depth, color1, color2, color3, color4, color5, color6, color7, color8});
|
||||
}
|
||||
|
||||
void bind()
|
||||
{
|
||||
GPU_framebuffer_bind(fb_);
|
||||
}
|
||||
|
||||
void clear_depth(float depth)
|
||||
{
|
||||
GPU_framebuffer_clear_depth(fb_, depth);
|
||||
}
|
||||
|
||||
Framebuffer &operator=(Framebuffer &&a)
|
||||
{
|
||||
if (*this != a) {
|
||||
|
@@ -1007,8 +1007,10 @@ void DRW_cache_free_old_batches(Main *bmain)
|
||||
|
||||
static void drw_engines_init(void)
|
||||
{
|
||||
DRW_stats_group_start("drw_engines.engines_init");
|
||||
DRW_ENABLED_ENGINE_ITER (DST.view_data_active, engine, data) {
|
||||
PROFILE_START(stime);
|
||||
DRW_stats_group_start(engine->idname);
|
||||
|
||||
const DrawEngineDataSize *data_size = engine->vedata_size;
|
||||
memset(data->psl->passes, 0, sizeof(*data->psl->passes) * data_size->psl_len);
|
||||
@@ -1017,15 +1019,19 @@ static void drw_engines_init(void)
|
||||
engine->engine_init(data);
|
||||
}
|
||||
|
||||
DRW_stats_group_end();
|
||||
PROFILE_END_UPDATE(data->init_time, stime);
|
||||
}
|
||||
DRW_stats_group_end();
|
||||
}
|
||||
|
||||
static void drw_engines_cache_init(void)
|
||||
{
|
||||
DRW_stats_group_start("drw_engines.cache_init");
|
||||
DRW_manager_begin_sync();
|
||||
|
||||
DRW_ENABLED_ENGINE_ITER (DST.view_data_active, engine, data) {
|
||||
DRW_stats_group_start(engine->idname);
|
||||
if (data->text_draw_cache) {
|
||||
DRW_text_cache_destroy(data->text_draw_cache);
|
||||
data->text_draw_cache = NULL;
|
||||
@@ -1037,7 +1043,9 @@ static void drw_engines_cache_init(void)
|
||||
if (engine->cache_init) {
|
||||
engine->cache_init(data);
|
||||
}
|
||||
DRW_stats_group_end();
|
||||
}
|
||||
DRW_stats_group_end();
|
||||
}
|
||||
|
||||
static void drw_engines_world_update(Scene *scene)
|
||||
@@ -1045,12 +1053,16 @@ static void drw_engines_world_update(Scene *scene)
|
||||
if (scene->world == NULL) {
|
||||
return;
|
||||
}
|
||||
DRW_stats_group_start("drw_engines.world_update");
|
||||
|
||||
DRW_ENABLED_ENGINE_ITER (DST.view_data_active, engine, data) {
|
||||
if (engine->id_update) {
|
||||
DRW_stats_group_start(engine->idname);
|
||||
engine->id_update(data, &scene->world->id);
|
||||
DRW_stats_group_end();
|
||||
}
|
||||
}
|
||||
DRW_stats_group_end();
|
||||
}
|
||||
|
||||
static void drw_engines_cache_populate(Object *ob)
|
||||
@@ -1091,17 +1103,22 @@ static void drw_engines_cache_populate(Object *ob)
|
||||
|
||||
static void drw_engines_cache_finish(void)
|
||||
{
|
||||
DRW_stats_group_start("drw_engines.cache_finish");
|
||||
DRW_ENABLED_ENGINE_ITER (DST.view_data_active, engine, data) {
|
||||
if (engine->cache_finish) {
|
||||
DRW_stats_group_start(engine->idname);
|
||||
engine->cache_finish(data);
|
||||
DRW_stats_group_end();
|
||||
}
|
||||
}
|
||||
|
||||
DRW_manager_end_sync();
|
||||
DRW_stats_group_end();
|
||||
}
|
||||
|
||||
static void drw_engines_draw_scene(void)
|
||||
{
|
||||
DRW_stats_group_start("drw_engines.draw_scene");
|
||||
DRW_ENABLED_ENGINE_ITER (DST.view_data_active, engine, data) {
|
||||
PROFILE_START(stime);
|
||||
if (engine->draw_scene) {
|
||||
@@ -1117,6 +1134,7 @@ static void drw_engines_draw_scene(void)
|
||||
}
|
||||
/* Reset state after drawing */
|
||||
DRW_state_reset();
|
||||
DRW_stats_group_end();
|
||||
}
|
||||
|
||||
static void drw_engines_draw_text(void)
|
||||
@@ -1183,6 +1201,11 @@ static void drw_engines_enable_from_engine(const RenderEngineType *engine_type,
|
||||
switch (drawtype) {
|
||||
case OB_WIRE:
|
||||
case OB_SOLID:
|
||||
if (U.experimental.enable_workbench_next &&
|
||||
strcmp(engine_type->idname, "BLENDER_WORKBENCH_NEXT") == 0) {
|
||||
use_drw_engine(DRW_engine_viewport_workbench_next_type.draw_engine);
|
||||
break;
|
||||
}
|
||||
use_drw_engine(DRW_engine_viewport_workbench_type.draw_engine);
|
||||
break;
|
||||
case OB_MATERIAL:
|
||||
@@ -1669,6 +1692,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
|
||||
drw_context_state_init();
|
||||
|
||||
drw_manager_init(&DST, viewport, NULL);
|
||||
|
||||
DRW_viewport_colormanagement_set(viewport);
|
||||
|
||||
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
|
||||
@@ -1707,6 +1731,8 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
|
||||
|
||||
/* Only iterate over objects for internal engines or when overlays are enabled */
|
||||
if (do_populate_loop) {
|
||||
DRW_stats_group_start("drw_render.populate_loop");
|
||||
|
||||
DST.dupli_origin = NULL;
|
||||
DST.dupli_origin_data = NULL;
|
||||
DEGObjectIterSettings deg_iter_settings = {0};
|
||||
@@ -1728,6 +1754,8 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
|
||||
drw_engines_cache_populate(ob);
|
||||
}
|
||||
DEG_OBJECT_ITER_END;
|
||||
|
||||
DRW_stats_group_end();
|
||||
}
|
||||
|
||||
drw_duplidata_free();
|
||||
@@ -2990,6 +3018,9 @@ void DRW_engines_register_experimental(void)
|
||||
if (U.experimental.enable_eevee_next) {
|
||||
RE_engines_register(&DRW_engine_viewport_eevee_next_type);
|
||||
}
|
||||
if (U.experimental.enable_workbench_next) {
|
||||
RE_engines_register(&DRW_engine_viewport_workbench_next_type);
|
||||
}
|
||||
}
|
||||
|
||||
void DRW_engines_register(void)
|
||||
|
@@ -166,7 +166,7 @@ void Manager::submit(PassMain &pass, View &view)
|
||||
bool freeze_culling = (U.experimental.use_viewport_debug && DST.draw_ctx.v3d &&
|
||||
(DST.draw_ctx.v3d->debug_flag & V3D_DEBUG_FREEZE_CULLING) != 0);
|
||||
|
||||
view.compute_visibility(bounds_buf, resource_len_, freeze_culling);
|
||||
view.compute_visibility(matrix_buf, bounds_buf, resource_len_, freeze_culling);
|
||||
|
||||
command::RecordingState state;
|
||||
state.inverted_view = view.is_inverted();
|
||||
@@ -174,7 +174,7 @@ void Manager::submit(PassMain &pass, View &view)
|
||||
pass.draw_commands_buf_.bind(state,
|
||||
pass.headers_,
|
||||
pass.commands_,
|
||||
view.visibility_buf_,
|
||||
view.get_visibility_buffer(),
|
||||
view.visibility_word_per_draw(),
|
||||
view.view_len_);
|
||||
|
||||
@@ -217,7 +217,7 @@ Manager::SubmitDebugOutput Manager::submit_debug(PassSimple &pass, View &view)
|
||||
output.resource_id = {pass.draw_commands_buf_.resource_id_buf_.data(),
|
||||
pass.draw_commands_buf_.resource_id_count_};
|
||||
/* There is no visibility data for PassSimple. */
|
||||
output.visibility = {(uint *)view.visibility_buf_.data(), 0};
|
||||
output.visibility = {(uint *)view.get_visibility_buffer().data(), 0};
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -228,12 +228,13 @@ Manager::SubmitDebugOutput Manager::submit_debug(PassMain &pass, View &view)
|
||||
GPU_finish();
|
||||
|
||||
pass.draw_commands_buf_.resource_id_buf_.read();
|
||||
view.visibility_buf_.read();
|
||||
view.get_visibility_buffer().read();
|
||||
|
||||
Manager::SubmitDebugOutput output;
|
||||
output.resource_id = {pass.draw_commands_buf_.resource_id_buf_.data(),
|
||||
pass.draw_commands_buf_.resource_id_count_};
|
||||
output.visibility = {(uint *)view.visibility_buf_.data(), divide_ceil_u(resource_len_, 32)};
|
||||
output.visibility = {(uint *)view.get_visibility_buffer().data(),
|
||||
divide_ceil_u(resource_len_, 32)};
|
||||
return output;
|
||||
}
|
||||
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_wrapper.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_pbvh.h"
|
||||
@@ -695,7 +696,7 @@ static void drw_call_obinfos_init(DRWObjectInfos *ob_infos, Object *ob)
|
||||
drw_call_calc_orco(ob, ob_infos->orcotexfac);
|
||||
/* Random float value. */
|
||||
uint random = (DST.dupli_source) ?
|
||||
DST.dupli_source->random_id :
|
||||
DST.dupli_source->random_id :
|
||||
/* TODO(fclem): this is rather costly to do at runtime. Maybe we can
|
||||
* put it in ob->runtime and make depsgraph ensure it is up to date. */
|
||||
BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0);
|
||||
@@ -719,26 +720,41 @@ static void drw_call_obinfos_init(DRWObjectInfos *ob_infos, Object *ob)
|
||||
|
||||
static void drw_call_culling_init(DRWCullingState *cull, Object *ob)
|
||||
{
|
||||
const BoundBox *bbox;
|
||||
if (ob != nullptr && (bbox = BKE_object_boundbox_get(ob))) {
|
||||
float corner[3];
|
||||
/* Get BoundSphere center and radius from the BoundBox. */
|
||||
mid_v3_v3v3(cull->bsphere.center, bbox->vec[0], bbox->vec[6]);
|
||||
mul_v3_m4v3(corner, ob->object_to_world, bbox->vec[0]);
|
||||
mul_m4_v3(ob->object_to_world, cull->bsphere.center);
|
||||
cull->bsphere.radius = len_v3v3(cull->bsphere.center, corner);
|
||||
/* Bypass test */
|
||||
cull->bsphere.radius = -1.0f;
|
||||
/* Reset user data */
|
||||
cull->user_data = nullptr;
|
||||
|
||||
if (ob != nullptr) {
|
||||
if (ob->type == OB_MESH) {
|
||||
/* Optimization: Retrieve the mesh cached min max directly.
|
||||
* Avoids allocating a BoundBox on every sample for each DupliObject instance.
|
||||
* TODO(Miguel Pozo): Remove once T92963 or T96968 are done */
|
||||
float3 min, max;
|
||||
INIT_MINMAX(min, max);
|
||||
BKE_mesh_wrapper_minmax(static_cast<Mesh *>(ob->data), min, max);
|
||||
|
||||
/* Get BoundSphere center and radius from min/max. */
|
||||
float3 min_world = float4x4(ob->object_to_world) * min;
|
||||
float3 max_world = float4x4(ob->object_to_world) * max;
|
||||
|
||||
mid_v3_v3v3(cull->bsphere.center, min_world, max_world);
|
||||
cull->bsphere.radius = len_v3v3(cull->bsphere.center, max_world);
|
||||
}
|
||||
else if (const BoundBox *bbox = BKE_object_boundbox_get(ob)) {
|
||||
float corner[3];
|
||||
/* Get BoundSphere center and radius from the BoundBox. */
|
||||
mid_v3_v3v3(cull->bsphere.center, bbox->vec[0], bbox->vec[6]);
|
||||
mul_v3_m4v3(corner, ob->object_to_world, bbox->vec[0]);
|
||||
mul_m4_v3(ob->object_to_world, cull->bsphere.center);
|
||||
cull->bsphere.radius = len_v3v3(cull->bsphere.center, corner);
|
||||
}
|
||||
|
||||
/* Bypass test for very large objects (see T67319). */
|
||||
if (UNLIKELY(cull->bsphere.radius > 1e12)) {
|
||||
cull->bsphere.radius = -1.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Bypass test. */
|
||||
cull->bsphere.radius = -1.0f;
|
||||
}
|
||||
/* Reset user data */
|
||||
cull->user_data = nullptr;
|
||||
}
|
||||
|
||||
static DRWResourceHandle drw_resource_handle_new(float (*obmat)[4], Object *ob)
|
||||
|
@@ -252,6 +252,7 @@ class PassBase {
|
||||
/**
|
||||
* Record a compute dispatch call.
|
||||
*/
|
||||
void dispatch(int2 group_len);
|
||||
void dispatch(int3 group_len);
|
||||
void dispatch(int3 *group_len);
|
||||
void dispatch(StorageBuffer<DispatchCommand> &indirect_buffer);
|
||||
@@ -705,6 +706,12 @@ inline void PassBase<T>::draw_procedural_indirect(
|
||||
/** \name Compute Dispatch Implementation
|
||||
* \{ */
|
||||
|
||||
template<class T> inline void PassBase<T>::dispatch(int2 group_len)
|
||||
{
|
||||
BLI_assert(shader_);
|
||||
create_command(Type::Dispatch).dispatch = {int3(group_len.x, group_len.y, 1)};
|
||||
}
|
||||
|
||||
template<class T> inline void PassBase<T>::dispatch(int3 group_len)
|
||||
{
|
||||
BLI_assert(shader_);
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_duplilist.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_wrapper.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_volume.h"
|
||||
#include "BLI_hash.h"
|
||||
@@ -82,15 +83,6 @@ inline void ObjectInfos::sync(const blender::draw::ObjectRef ref, bool is_active
|
||||
SET_FLAG_FROM_TEST(
|
||||
flag, ref.object->transflag & OB_NEG_SCALE, eObjectInfoFlag::OBJECT_NEGATIVE_SCALE);
|
||||
|
||||
if (ref.dupli_object == nullptr) {
|
||||
/* TODO(fclem): this is rather costly to do at draw time. Maybe we can
|
||||
* put it in ob->runtime and make depsgraph ensure it is up to date. */
|
||||
random = BLI_hash_int_2d(BLI_hash_string(ref.object->id.name + 2), 0) *
|
||||
(1.0f / (float)0xFFFFFFFF);
|
||||
}
|
||||
else {
|
||||
random = ref.dupli_object->random_id * (1.0f / (float)0xFFFFFFFF);
|
||||
}
|
||||
/* Default values. Set if needed. */
|
||||
random = 0.0f;
|
||||
|
||||
@@ -155,51 +147,54 @@ inline std::ostream &operator<<(std::ostream &stream, const ObjectInfos &infos)
|
||||
|
||||
inline void ObjectBounds::sync()
|
||||
{
|
||||
bounding_sphere.w = -1.0f; /* Disable test. */
|
||||
test_enabled = false;
|
||||
}
|
||||
|
||||
inline void ObjectBounds::sync(Object &ob)
|
||||
{
|
||||
const BoundBox *bbox = BKE_object_boundbox_get(&ob);
|
||||
if (bbox == nullptr) {
|
||||
bounding_sphere.w = -1.0f; /* Disable test. */
|
||||
return;
|
||||
float3 min, max;
|
||||
INIT_MINMAX(min, max);
|
||||
|
||||
if (ob.type == OB_MESH) {
|
||||
/* Optimization: Retrieve the mesh cached min max directly.
|
||||
* Avoids allocating a BoundBox on every sample for each DupliObject instance.
|
||||
* TODO(Miguel Pozo): Remove once T92963 or T96968 are done */
|
||||
BKE_mesh_wrapper_minmax(static_cast<Mesh *>(ob.data), min, max);
|
||||
}
|
||||
*reinterpret_cast<float3 *>(&bounding_corners[0]) = bbox->vec[0];
|
||||
*reinterpret_cast<float3 *>(&bounding_corners[1]) = bbox->vec[4];
|
||||
*reinterpret_cast<float3 *>(&bounding_corners[2]) = bbox->vec[3];
|
||||
*reinterpret_cast<float3 *>(&bounding_corners[3]) = bbox->vec[1];
|
||||
bounding_sphere.w = 0.0f; /* Enable test. */
|
||||
else {
|
||||
const BoundBox *bbox = BKE_object_boundbox_get(&ob);
|
||||
if (bbox == nullptr) {
|
||||
test_enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
for (const float3 &corner : bbox->vec) {
|
||||
minmax_v3v3_v3(min, max, corner);
|
||||
}
|
||||
}
|
||||
|
||||
size = (max - min) / 2.0f;
|
||||
center = min + size;
|
||||
test_enabled = true;
|
||||
}
|
||||
|
||||
inline void ObjectBounds::sync(const float3 ¢er, const float3 &size)
|
||||
{
|
||||
*reinterpret_cast<float3 *>(&bounding_corners[0]) = center - size;
|
||||
*reinterpret_cast<float3 *>(&bounding_corners[1]) = center + float3(+size.x, -size.y, -size.z);
|
||||
*reinterpret_cast<float3 *>(&bounding_corners[2]) = center + float3(-size.x, +size.y, -size.z);
|
||||
*reinterpret_cast<float3 *>(&bounding_corners[3]) = center + float3(-size.x, -size.y, +size.z);
|
||||
bounding_sphere.w = 0.0; /* Enable test. */
|
||||
this->center = center;
|
||||
this->size = size;
|
||||
test_enabled = true;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &stream, const ObjectBounds &bounds)
|
||||
{
|
||||
stream << "ObjectBounds(";
|
||||
if (bounds.bounding_sphere.w == -1.0f) {
|
||||
if (!bounds.test_enabled) {
|
||||
stream << "skipped)" << std::endl;
|
||||
return stream;
|
||||
}
|
||||
stream << std::endl;
|
||||
stream << ".bounding_corners[0]"
|
||||
<< *reinterpret_cast<const float3 *>(&bounds.bounding_corners[0]) << std::endl;
|
||||
stream << ".bounding_corners[1]"
|
||||
<< *reinterpret_cast<const float3 *>(&bounds.bounding_corners[1]) << std::endl;
|
||||
stream << ".bounding_corners[2]"
|
||||
<< *reinterpret_cast<const float3 *>(&bounds.bounding_corners[2]) << std::endl;
|
||||
stream << ".bounding_corners[3]"
|
||||
<< *reinterpret_cast<const float3 *>(&bounds.bounding_corners[3]) << std::endl;
|
||||
stream << ".sphere=(pos=" << float3(bounds.bounding_sphere)
|
||||
<< ", rad=" << bounds.bounding_sphere.w << std::endl;
|
||||
stream << ")" << std::endl;
|
||||
stream << ".center" << bounds.center << std::endl;
|
||||
stream << ".size" << bounds.size << std::endl;
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
@@ -175,15 +175,11 @@ struct ObjectInfos {
|
||||
BLI_STATIC_ASSERT_ALIGN(ObjectInfos, 16)
|
||||
|
||||
struct ObjectBounds {
|
||||
/**
|
||||
* Uploaded as vertex (0, 4, 3, 1) of the bbox in local space, matching XYZ axis order.
|
||||
* Then processed by GPU and stored as (0, 4-0, 3-0, 1-0) in world space for faster culling.
|
||||
*/
|
||||
float4 bounding_corners[4];
|
||||
/** Bounding sphere derived from the bounding corner. Computed on GPU. */
|
||||
float4 bounding_sphere;
|
||||
/** Radius of the inscribed sphere derived from the bounding corner. Computed on GPU. */
|
||||
#define _inner_sphere_radius bounding_corners[3].w
|
||||
float3 center;
|
||||
bool test_enabled;
|
||||
/* TODO(Miguel Pozo): This is actually half size */
|
||||
float3 size;
|
||||
uint _pad;
|
||||
|
||||
#if !defined(GPU_SHADER) && defined(__cplusplus)
|
||||
void sync();
|
||||
|
@@ -31,6 +31,14 @@ void View::sync(const float4x4 &view_mat, const float4x4 &win_mat, int view_id)
|
||||
dirty_ = true;
|
||||
}
|
||||
|
||||
void View::sync(const DRWView *view)
|
||||
{
|
||||
float4x4 view_mat, win_mat;
|
||||
DRW_view_viewmat_get(view, view_mat.ptr(), false);
|
||||
DRW_view_winmat_get(view, win_mat.ptr(), false);
|
||||
this->sync(view_mat, win_mat);
|
||||
}
|
||||
|
||||
void View::frustum_boundbox_calc(int view_id)
|
||||
{
|
||||
/* Extract the 8 corners from a Projection Matrix. */
|
||||
@@ -219,7 +227,10 @@ void View::bind()
|
||||
GPU_uniformbuf_bind(culling_, DRW_VIEW_CULLING_UBO_SLOT);
|
||||
}
|
||||
|
||||
void View::compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool debug_freeze)
|
||||
void View::compute_visibility(ObjectMatricesBuf &matrices,
|
||||
ObjectBoundsBuf &bounds,
|
||||
uint resource_len,
|
||||
bool debug_freeze)
|
||||
{
|
||||
if (debug_freeze && frozen_ == false) {
|
||||
data_freeze_[0] = static_cast<ViewMatrices>(data_[0]);
|
||||
@@ -256,6 +267,7 @@ void View::compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool d
|
||||
GPU_shader_uniform_1i(shader, "resource_len", resource_len);
|
||||
GPU_shader_uniform_1i(shader, "view_len", view_len_);
|
||||
GPU_shader_uniform_1i(shader, "visibility_word_per_draw", word_per_draw);
|
||||
GPU_storagebuf_bind(matrices, GPU_shader_get_ssbo(shader, "matrix_buf"));
|
||||
GPU_storagebuf_bind(bounds, GPU_shader_get_ssbo(shader, "bounds_buf"));
|
||||
GPU_storagebuf_bind(visibility_buf_, GPU_shader_get_ssbo(shader, "visibility_buf"));
|
||||
GPU_uniformbuf_bind(frozen_ ? data_freeze_ : data_, DRW_VIEW_UBO_SLOT);
|
||||
@@ -273,4 +285,9 @@ void View::compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool d
|
||||
GPU_debug_group_end();
|
||||
}
|
||||
|
||||
VisibilityBuf &View::get_visibility_buffer()
|
||||
{
|
||||
return visibility_buf_;
|
||||
}
|
||||
|
||||
} // namespace blender::draw
|
||||
|
@@ -26,13 +26,14 @@ namespace blender::draw {
|
||||
class Manager;
|
||||
|
||||
/* TODO: de-duplicate. */
|
||||
using ObjectMatricesBuf = StorageArrayBuffer<ObjectMatrices, 128>;
|
||||
using ObjectBoundsBuf = StorageArrayBuffer<ObjectBounds, 128>;
|
||||
using VisibilityBuf = StorageArrayBuffer<uint, 4, true>;
|
||||
|
||||
class View {
|
||||
friend Manager;
|
||||
|
||||
private:
|
||||
protected:
|
||||
/** TODO(fclem): Maybe try to reduce the minimum cost if the number of view is lower. */
|
||||
|
||||
UniformArrayBuffer<ViewMatrices, DRW_VIEW_MAX> data_;
|
||||
@@ -64,14 +65,14 @@ class View {
|
||||
View(const char *name, const DRWView *view)
|
||||
: visibility_buf_(name), debug_name_(name), view_len_(1)
|
||||
{
|
||||
float4x4 view_mat, win_mat;
|
||||
DRW_view_viewmat_get(view, view_mat.ptr(), false);
|
||||
DRW_view_winmat_get(view, win_mat.ptr(), false);
|
||||
this->sync(view_mat, win_mat);
|
||||
this->sync(view);
|
||||
}
|
||||
|
||||
void sync(const float4x4 &view_mat, const float4x4 &win_mat, int view_id = 0);
|
||||
|
||||
/* For compatibility with old system. Will be removed at some point. */
|
||||
void sync(const DRWView *view);
|
||||
|
||||
bool is_persp(int view_id = 0) const
|
||||
{
|
||||
BLI_assert(view_id < view_len_);
|
||||
@@ -132,10 +133,14 @@ class View {
|
||||
return (view_len_ == 1) ? 0 : divide_ceil_u(view_len_, 32);
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
/** Called from draw manager. */
|
||||
void bind();
|
||||
void compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool debug_freeze);
|
||||
virtual void compute_visibility(ObjectMatricesBuf &matrices,
|
||||
ObjectBoundsBuf &bounds,
|
||||
uint resource_len,
|
||||
bool debug_freeze);
|
||||
virtual VisibilityBuf &get_visibility_buffer();
|
||||
|
||||
void update_viewport_size();
|
||||
|
||||
|
@@ -123,312 +123,138 @@ IsectFrustum isect_data_setup(Frustum shape)
|
||||
|
||||
/** \} */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name View Intersection functions.
|
||||
* \{ */
|
||||
|
||||
bool intersect_view(Pyramid pyramid)
|
||||
{
|
||||
bool intersects = true;
|
||||
|
||||
/* Do Pyramid vertices vs Frustum planes. */
|
||||
for (int p = 0; p < 6; ++p) {
|
||||
bool is_any_vertex_on_positive_side = false;
|
||||
for (int v = 0; v < 5; ++v) {
|
||||
float test = dot(drw_view_culling.planes[p], vec4(pyramid.corners[v], 1.0));
|
||||
if (test > 0.0) {
|
||||
is_any_vertex_on_positive_side = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool all_vertex_on_negative_side = !is_any_vertex_on_positive_side;
|
||||
if (all_vertex_on_negative_side) {
|
||||
intersects = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!intersects) {
|
||||
return intersects;
|
||||
}
|
||||
|
||||
/* Now do Frustum vertices vs Pyramid planes. */
|
||||
IsectPyramid i_pyramid = isect_data_setup(pyramid);
|
||||
for (int p = 0; p < 5; ++p) {
|
||||
bool is_any_vertex_on_positive_side = false;
|
||||
for (int v = 0; v < 8; ++v) {
|
||||
float test = dot(i_pyramid.planes[p], vec4(drw_view_culling.corners[v].xyz, 1.0));
|
||||
if (test > 0.0) {
|
||||
is_any_vertex_on_positive_side = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool all_vertex_on_negative_side = !is_any_vertex_on_positive_side;
|
||||
if (all_vertex_on_negative_side) {
|
||||
intersects = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return intersects;
|
||||
}
|
||||
|
||||
bool intersect_view(Box box)
|
||||
{
|
||||
bool intersects = true;
|
||||
|
||||
/* Do Box vertices vs Frustum planes. */
|
||||
for (int p = 0; p < 6; ++p) {
|
||||
bool is_any_vertex_on_positive_side = false;
|
||||
for (int v = 0; v < 8; ++v) {
|
||||
float test = dot(drw_view_culling.planes[p], vec4(box.corners[v], 1.0));
|
||||
if (test > 0.0) {
|
||||
is_any_vertex_on_positive_side = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool all_vertex_on_negative_side = !is_any_vertex_on_positive_side;
|
||||
if (all_vertex_on_negative_side) {
|
||||
intersects = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!intersects) {
|
||||
return intersects;
|
||||
}
|
||||
|
||||
/* Now do Frustum vertices vs Box planes. */
|
||||
IsectBox i_box = isect_data_setup(box);
|
||||
for (int p = 0; p < 6; ++p) {
|
||||
bool is_any_vertex_on_positive_side = false;
|
||||
for (int v = 0; v < 8; ++v) {
|
||||
float test = dot(i_box.planes[p], vec4(drw_view_culling.corners[v].xyz, 1.0));
|
||||
if (test > 0.0) {
|
||||
is_any_vertex_on_positive_side = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool all_vertex_on_negative_side = !is_any_vertex_on_positive_side;
|
||||
if (all_vertex_on_negative_side) {
|
||||
intersects = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return intersects;
|
||||
}
|
||||
|
||||
bool intersect_view(IsectBox i_box)
|
||||
{
|
||||
bool intersects = true;
|
||||
|
||||
/* Do Box vertices vs Frustum planes. */
|
||||
for (int p = 0; p < 6; ++p) {
|
||||
bool is_any_vertex_on_positive_side = false;
|
||||
for (int v = 0; v < 8; ++v) {
|
||||
float test = dot(drw_view_culling.planes[p], vec4(i_box.corners[v], 1.0));
|
||||
if (test > 0.0) {
|
||||
is_any_vertex_on_positive_side = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool all_vertex_on_negative_side = !is_any_vertex_on_positive_side;
|
||||
if (all_vertex_on_negative_side) {
|
||||
intersects = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!intersects) {
|
||||
return intersects;
|
||||
}
|
||||
|
||||
for (int p = 0; p < 6; ++p) {
|
||||
bool is_any_vertex_on_positive_side = false;
|
||||
for (int v = 0; v < 8; ++v) {
|
||||
float test = dot(i_box.planes[p], vec4(drw_view_culling.corners[v].xyz, 1.0));
|
||||
if (test > 0.0) {
|
||||
is_any_vertex_on_positive_side = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool all_vertex_on_negative_side = !is_any_vertex_on_positive_side;
|
||||
if (all_vertex_on_negative_side) {
|
||||
intersects = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return intersects;
|
||||
}
|
||||
|
||||
bool intersect_view(Sphere sphere)
|
||||
{
|
||||
bool intersects = true;
|
||||
|
||||
for (int p = 0; p < 6 && intersects; ++p) {
|
||||
float dist_to_plane = dot(drw_view_culling.planes[p], vec4(sphere.center, 1.0));
|
||||
if (dist_to_plane < -sphere.radius) {
|
||||
intersects = false;
|
||||
}
|
||||
}
|
||||
/* TODO reject false positive. */
|
||||
return intersects;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name Shape vs. Shape Intersection functions.
|
||||
* \{ */
|
||||
|
||||
bool intersect(IsectPyramid i_pyramid, Box box)
|
||||
bool intersect(IsectPyramid i_pyramid, IsectBox i_box)
|
||||
{
|
||||
bool intersects = true;
|
||||
|
||||
/* Do Box vertices vs Pyramid planes. */
|
||||
for (int p = 0; p < 5; ++p) {
|
||||
bool is_any_vertex_on_positive_side = false;
|
||||
bool separating_axis = true;
|
||||
for (int v = 0; v < 8; ++v) {
|
||||
float test = dot(i_pyramid.planes[p], vec4(box.corners[v], 1.0));
|
||||
if (test > 0.0) {
|
||||
is_any_vertex_on_positive_side = true;
|
||||
float signed_distance = point_plane_projection_dist(i_box.corners[v], i_pyramid.planes[p]);
|
||||
if (signed_distance <= 0.0) {
|
||||
separating_axis = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool all_vertex_on_negative_side = !is_any_vertex_on_positive_side;
|
||||
if (all_vertex_on_negative_side) {
|
||||
intersects = false;
|
||||
break;
|
||||
if (separating_axis) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!intersects) {
|
||||
return intersects;
|
||||
}
|
||||
|
||||
/* Now do Pyramid vertices vs Box planes. */
|
||||
IsectBox i_box = isect_data_setup(box);
|
||||
for (int p = 0; p < 6; ++p) {
|
||||
bool is_any_vertex_on_positive_side = false;
|
||||
bool separating_axis = true;
|
||||
for (int v = 0; v < 5; ++v) {
|
||||
float test = dot(i_box.planes[p], vec4(i_pyramid.corners[v], 1.0));
|
||||
if (test > 0.0) {
|
||||
is_any_vertex_on_positive_side = true;
|
||||
float signed_distance = point_plane_projection_dist(i_pyramid.corners[v], i_box.planes[p]);
|
||||
if (signed_distance <= 0.0) {
|
||||
separating_axis = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool all_vertex_on_negative_side = !is_any_vertex_on_positive_side;
|
||||
if (all_vertex_on_negative_side) {
|
||||
intersects = false;
|
||||
break;
|
||||
if (separating_axis) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return intersects;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool intersect(IsectPyramid i_pyramid, Box box)
|
||||
{
|
||||
return intersect(i_pyramid, isect_data_setup(box));
|
||||
}
|
||||
|
||||
bool intersect(IsectFrustum i_frustum, Pyramid pyramid)
|
||||
{
|
||||
bool intersects = true;
|
||||
|
||||
/* Do Pyramid vertices vs Frustum planes. */
|
||||
for (int p = 0; p < 6; ++p) {
|
||||
bool is_any_vertex_on_positive_side = false;
|
||||
bool separating_axis = true;
|
||||
for (int v = 0; v < 5; ++v) {
|
||||
float test = dot(i_frustum.planes[p], vec4(pyramid.corners[v], 1.0));
|
||||
if (test > 0.0) {
|
||||
is_any_vertex_on_positive_side = true;
|
||||
float signed_distance = point_plane_projection_dist(pyramid.corners[v], i_frustum.planes[p]);
|
||||
if (signed_distance <= 0.0) {
|
||||
separating_axis = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool all_vertex_on_negative_side = !is_any_vertex_on_positive_side;
|
||||
if (all_vertex_on_negative_side) {
|
||||
intersects = false;
|
||||
break;
|
||||
if (separating_axis) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!intersects) {
|
||||
return intersects;
|
||||
}
|
||||
|
||||
/* Now do Frustum vertices vs Pyramid planes. */
|
||||
IsectPyramid i_pyramid = isect_data_setup(pyramid);
|
||||
for (int p = 0; p < 5; ++p) {
|
||||
bool is_any_vertex_on_positive_side = false;
|
||||
bool separating_axis = true;
|
||||
for (int v = 0; v < 8; ++v) {
|
||||
float test = dot(i_pyramid.planes[p], vec4(i_frustum.corners[v].xyz, 1.0));
|
||||
if (test > 0.0) {
|
||||
is_any_vertex_on_positive_side = true;
|
||||
float signed_distance = point_plane_projection_dist(i_frustum.corners[v].xyz,
|
||||
i_pyramid.planes[p]);
|
||||
if (signed_distance <= 0.0) {
|
||||
separating_axis = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool all_vertex_on_negative_side = !is_any_vertex_on_positive_side;
|
||||
if (all_vertex_on_negative_side) {
|
||||
intersects = false;
|
||||
break;
|
||||
if (separating_axis) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return intersects;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool intersect(IsectFrustum i_frustum, IsectBox i_box)
|
||||
{
|
||||
/* Do Box vertices vs Frustum planes. */
|
||||
for (int p = 0; p < 6; ++p) {
|
||||
bool separating_axis = true;
|
||||
for (int v = 0; v < 8; ++v) {
|
||||
float signed_distance = point_plane_projection_dist(i_box.corners[v], i_frustum.planes[p]);
|
||||
if (signed_distance <= 0.0) {
|
||||
separating_axis = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (separating_axis) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now do Frustum vertices vs Box planes. */
|
||||
for (int p = 0; p < 6; ++p) {
|
||||
bool separating_axis = true;
|
||||
for (int v = 0; v < 8; ++v) {
|
||||
float signed_distance = point_plane_projection_dist(i_frustum.corners[v].xyz,
|
||||
i_box.planes[p]);
|
||||
if (signed_distance <= 0.0) {
|
||||
separating_axis = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (separating_axis) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool intersect(IsectFrustum i_frustum, Box box)
|
||||
{
|
||||
bool intersects = true;
|
||||
|
||||
/* Do Box vertices vs Frustum planes. */
|
||||
for (int p = 0; p < 6; ++p) {
|
||||
bool is_any_vertex_on_positive_side = false;
|
||||
for (int v = 0; v < 8; ++v) {
|
||||
float test = dot(i_frustum.planes[p], vec4(box.corners[v], 1.0));
|
||||
if (test > 0.0) {
|
||||
is_any_vertex_on_positive_side = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool all_vertex_on_negative_side = !is_any_vertex_on_positive_side;
|
||||
if (all_vertex_on_negative_side) {
|
||||
intersects = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!intersects) {
|
||||
return intersects;
|
||||
}
|
||||
|
||||
/* Now do Frustum vertices vs Box planes. */
|
||||
IsectBox i_box = isect_data_setup(box);
|
||||
for (int p = 0; p < 6; ++p) {
|
||||
bool is_any_vertex_on_positive_side = false;
|
||||
for (int v = 0; v < 8; ++v) {
|
||||
float test = dot(i_box.planes[p], vec4(i_frustum.corners[v].xyz, 1.0));
|
||||
if (test > 0.0) {
|
||||
is_any_vertex_on_positive_side = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool all_vertex_on_negative_side = !is_any_vertex_on_positive_side;
|
||||
if (all_vertex_on_negative_side) {
|
||||
intersects = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return intersects;
|
||||
return intersect(i_frustum, isect_data_setup(box));
|
||||
}
|
||||
|
||||
bool intersect(IsectFrustum i_frustum, Sphere sphere)
|
||||
{
|
||||
bool intersects = true;
|
||||
for (int p = 0; p < 6; ++p) {
|
||||
float dist_to_plane = dot(i_frustum.planes[p], vec4(sphere.center, 1.0));
|
||||
if (dist_to_plane < -sphere.radius) {
|
||||
intersects = false;
|
||||
break;
|
||||
float signed_distance = point_plane_projection_dist(sphere.center, i_frustum.planes[p]);
|
||||
if (signed_distance > sphere.radius) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return intersects;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool intersect(Cone cone, Sphere sphere)
|
||||
@@ -454,7 +280,7 @@ bool intersect(Cone cone, Sphere sphere)
|
||||
* only in the monotonic region [0 .. M_PI / 2]. This saves costly acos() calls. */
|
||||
bool intersects = (cone_sphere_center_cos >= cone_sphere_angle_sum_cos);
|
||||
|
||||
return intersects;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool intersect(Circle circle_a, Circle circle_b)
|
||||
@@ -464,3 +290,41 @@ bool intersect(Circle circle_a, Circle circle_b)
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name View Intersection functions.
|
||||
* \{ */
|
||||
|
||||
IsectFrustum IsectFrustum_from_view()
|
||||
{
|
||||
IsectFrustum result;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
result.corners[i] = drw_view_culling.corners[i].xyz;
|
||||
}
|
||||
for (int i = 0; i < 6; i++) {
|
||||
result.planes[i] = drw_view_culling.planes[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool intersect_view(Pyramid pyramid)
|
||||
{
|
||||
return intersect(IsectFrustum_from_view(), pyramid);
|
||||
}
|
||||
|
||||
bool intersect_view(Box box)
|
||||
{
|
||||
return intersect(IsectFrustum_from_view(), box);
|
||||
}
|
||||
|
||||
bool intersect_view(IsectBox i_box)
|
||||
{
|
||||
return intersect(IsectFrustum_from_view(), i_box);
|
||||
}
|
||||
|
||||
bool intersect_view(Sphere sphere)
|
||||
{
|
||||
return intersect(IsectFrustum_from_view(), sphere);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@@ -5,6 +5,9 @@
|
||||
/** \name Math intersection & projection functions.
|
||||
* \{ */
|
||||
|
||||
/* WARNING: For legacy reasons,
|
||||
* planes in Blender are represented with the projection component (w) flipped. */
|
||||
|
||||
vec4 plane_from_quad(vec3 v0, vec3 v1, vec3 v2, vec3 v3)
|
||||
{
|
||||
vec3 nor = normalize(cross(v2 - v1, v0 - v1) + cross(v0 - v3, v2 - v3));
|
||||
@@ -17,6 +20,11 @@ vec4 plane_from_tri(vec3 v0, vec3 v1, vec3 v2)
|
||||
return vec4(nor, -dot(nor, v2));
|
||||
}
|
||||
|
||||
float point_plane_projection_dist(vec3 point, vec4 plane)
|
||||
{
|
||||
return -dot(vec4(point, 1), plane);
|
||||
}
|
||||
|
||||
float point_plane_projection_dist(vec3 line_origin, vec3 plane_origin, vec3 plane_normal)
|
||||
{
|
||||
return dot(plane_normal, plane_origin - line_origin);
|
||||
|
@@ -14,6 +14,8 @@ void main()
|
||||
|
||||
mat4 model_mat = matrix_buf[resource_id].model;
|
||||
ObjectInfos infos = infos_buf[resource_id];
|
||||
|
||||
#if 0
|
||||
ObjectBounds bounds = bounds_buf[resource_id];
|
||||
|
||||
if (bounds.bounding_sphere.w != -1.0) {
|
||||
@@ -51,6 +53,7 @@ void main()
|
||||
bounds_buf[resource_id].bounding_sphere.w = -1.0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 loc = infos.orco_add; /* Box center. */
|
||||
vec3 size = infos.orco_mul; /* Box half-extent. */
|
||||
|
@@ -160,8 +160,9 @@ GPU_SHADER_CREATE_INFO(draw_visibility_compute)
|
||||
.do_static_compilation(true)
|
||||
.local_group_size(DRW_VISIBILITY_GROUP_SIZE)
|
||||
.define("DRW_VIEW_LEN", "64")
|
||||
.storage_buf(0, Qualifier::READ, "ObjectBounds", "bounds_buf[]")
|
||||
.storage_buf(1, Qualifier::READ_WRITE, "uint", "visibility_buf[]")
|
||||
.storage_buf(0, Qualifier::READ, "ObjectMatrices", "matrix_buf[]")
|
||||
.storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]")
|
||||
.storage_buf(2, Qualifier::READ_WRITE, "uint", "visibility_buf[]")
|
||||
.push_constant(Type::INT, "resource_len")
|
||||
.push_constant(Type::INT, "view_len")
|
||||
.push_constant(Type::INT, "visibility_word_per_draw")
|
||||
@@ -202,6 +203,9 @@ GPU_SHADER_CREATE_INFO(draw_resource_id_fallback)
|
||||
.define("UNIFORM_RESOURCE_ID_NEW")
|
||||
.vertex_in(15, Type::INT, "drw_ResourceID");
|
||||
|
||||
/** TODO mask view id bits. */
|
||||
GPU_SHADER_CREATE_INFO(draw_resource_handle_new).define("resource_handle", "drw_ResourceID");
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@@ -26,25 +26,31 @@ void main()
|
||||
return;
|
||||
}
|
||||
|
||||
mat4 model_mat = matrix_buf[gl_GlobalInvocationID.x].model;
|
||||
ObjectBounds bounds = bounds_buf[gl_GlobalInvocationID.x];
|
||||
|
||||
if (bounds.bounding_sphere.w != -1.0) {
|
||||
IsectBox box = isect_data_setup(bounds.bounding_corners[0].xyz,
|
||||
bounds.bounding_corners[1].xyz,
|
||||
bounds.bounding_corners[2].xyz,
|
||||
bounds.bounding_corners[3].xyz);
|
||||
Sphere bounding_sphere = Sphere(bounds.bounding_sphere.xyz, bounds.bounding_sphere.w);
|
||||
Sphere inscribed_sphere = Sphere(bounds.bounding_sphere.xyz, bounds._inner_sphere_radius);
|
||||
if (bounds.test_enabled) {
|
||||
vec3 origin = transform_point(model_mat, bounds.center - bounds.size);
|
||||
vec3 side_x = transform_point(model_mat, bounds.center + bounds.size * vec3(1, -1, -1)) -
|
||||
origin;
|
||||
vec3 side_y = transform_point(model_mat, bounds.center + bounds.size * vec3(-1, 1, -1)) -
|
||||
origin;
|
||||
vec3 side_z = transform_point(model_mat, bounds.center + bounds.size * vec3(-1, -1, 1)) -
|
||||
origin;
|
||||
|
||||
vec3 center = origin + ((side_x + side_y + side_z) / 2.0f);
|
||||
float radius = distance(origin, center);
|
||||
float inscribed_radius = min(min(bounds.size.x, bounds.size.y), bounds.size.z);
|
||||
|
||||
IsectBox box = isect_data_setup(origin, side_x, side_y, side_z);
|
||||
Sphere bounding_sphere = Sphere(center, radius);
|
||||
Sphere inscribed_sphere = Sphere(center, inscribed_radius);
|
||||
|
||||
for (drw_view_id = 0; drw_view_id < view_len; drw_view_id++) {
|
||||
if (intersect_view(inscribed_sphere) == true) {
|
||||
/* Visible. */
|
||||
if (intersect_view(inscribed_sphere)) {
|
||||
/* Visible */
|
||||
}
|
||||
else if (intersect_view(bounding_sphere) == false) {
|
||||
/* Not visible. */
|
||||
mask_visibility_bit(drw_view_id);
|
||||
}
|
||||
else if (intersect_view(box) == false) {
|
||||
else if (intersect_view(bounding_sphere) == false || intersect_view(box) == false) {
|
||||
/* Not visible. */
|
||||
mask_visibility_bit(drw_view_id);
|
||||
}
|
||||
|
@@ -7,6 +7,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define AREATEX_WIDTH 160
|
||||
#define AREATEX_HEIGHT 560
|
||||
#define AREATEX_PITCH (AREATEX_WIDTH * 2)
|
||||
@@ -28,3 +32,8 @@ extern const unsigned char areaTexBytes[];
|
||||
* - DX10: DXGI_FORMAT_R8_UNORM
|
||||
*/
|
||||
extern const unsigned char searchTexBytes[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -1296,13 +1296,21 @@ void ED_scene_draw_fps(const struct Scene *scene, int xoffset, int *yoffset);
|
||||
void ED_view3d_stop_render_preview(struct wmWindowManager *wm, struct ARegion *region);
|
||||
void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *area);
|
||||
|
||||
#define XRAY_ALPHA(v3d) \
|
||||
(((v3d)->shading.type == OB_WIRE) ? (v3d)->shading.xray_alpha_wire : (v3d)->shading.xray_alpha)
|
||||
#define XRAY_FLAG(v3d) \
|
||||
(((v3d)->shading.type == OB_WIRE) ? V3D_SHADING_XRAY_WIREFRAME : V3D_SHADING_XRAY)
|
||||
#define XRAY_FLAG_ENABLED(v3d) (((v3d)->shading.flag & XRAY_FLAG(v3d)) != 0)
|
||||
#define XRAY_ENABLED(v3d) (XRAY_FLAG_ENABLED(v3d) && (XRAY_ALPHA(v3d) < 1.0f))
|
||||
#define XRAY_ACTIVE(v3d) (XRAY_ENABLED(v3d) && ((v3d)->shading.type < OB_MATERIAL))
|
||||
#define SHADING_XRAY_ALPHA(shading) \
|
||||
(((shading).type == OB_WIRE) ? (shading).xray_alpha_wire : (shading).xray_alpha)
|
||||
#define SHADING_XRAY_FLAG(shading) \
|
||||
(((shading).type == OB_WIRE) ? V3D_SHADING_XRAY_WIREFRAME : V3D_SHADING_XRAY)
|
||||
#define SHADING_XRAY_FLAG_ENABLED(shading) (((shading).flag & SHADING_XRAY_FLAG(shading)) != 0)
|
||||
#define SHADING_XRAY_ENABLED(shading) \
|
||||
(SHADING_XRAY_FLAG_ENABLED(shading) && (SHADING_XRAY_ALPHA(shading) < 1.0f))
|
||||
#define SHADING_XRAY_ACTIVE(shading) \
|
||||
(SHADING_XRAY_ENABLED(shading) && ((shading).type < OB_MATERIAL))
|
||||
|
||||
#define XRAY_ALPHA(v3d) SHADING_XRAY_ALPHA((v3d)->shading)
|
||||
#define XRAY_FLAG(v3d) SHADING_XRAY_FLAG((v3d)->shading)
|
||||
#define XRAY_FLAG_ENABLED(v3d) SHADING_XRAY_FLAG_ENABLED((v3d)->shading)
|
||||
#define XRAY_ENABLED(v3d) SHADING_XRAY_ENABLED((v3d)->shading)
|
||||
#define XRAY_ACTIVE(v3d) SHADING_XRAY_ACTIVE((v3d)->shading)
|
||||
|
||||
/* view3d_draw_legacy.c */
|
||||
|
||||
|
@@ -29,6 +29,7 @@ set(INC
|
||||
# For *_info.hh includes.
|
||||
../compositor/realtime_compositor
|
||||
../draw/engines/eevee_next
|
||||
../draw/engines/workbench
|
||||
../draw/intern
|
||||
|
||||
# For node muting stuff.
|
||||
|
@@ -41,7 +41,7 @@ typedef enum eGPUTextureType {
|
||||
GPU_TEXTURE_CUBE_ARRAY = (GPU_TEXTURE_CUBE | GPU_TEXTURE_ARRAY),
|
||||
} eGPUTextureType;
|
||||
|
||||
ENUM_OPERATORS(eGPUTextureType, GPU_TEXTURE_CUBE_ARRAY)
|
||||
ENUM_OPERATORS(eGPUTextureType, GPU_TEXTURE_BUFFER)
|
||||
|
||||
/* Format types for samplers within the shader.
|
||||
* This covers the sampler format type permutations within GLSL/MSL. */
|
||||
|
@@ -141,6 +141,8 @@ void GLContext::activate()
|
||||
bound_ubo_slots = 0;
|
||||
|
||||
immActivate();
|
||||
|
||||
process_frame_timings();
|
||||
}
|
||||
|
||||
void GLContext::deactivate()
|
||||
|
@@ -95,6 +95,21 @@ class GLContext : public Context {
|
||||
/** #GLBackend owns this data. */
|
||||
GLSharedOrphanLists &shared_orphan_list_;
|
||||
|
||||
struct TimeQuery {
|
||||
std::string name;
|
||||
GLuint handles[2];
|
||||
int stack_depth;
|
||||
bool finished;
|
||||
int64_t cpu_start;
|
||||
float cpu_time;
|
||||
};
|
||||
struct FrameQueries {
|
||||
Vector<TimeQuery> queries;
|
||||
};
|
||||
Vector<FrameQueries> frame_timings;
|
||||
|
||||
void process_frame_timings();
|
||||
|
||||
public:
|
||||
GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list);
|
||||
~GLContext();
|
||||
|
@@ -80,7 +80,7 @@ static void APIENTRY debug_callback(GLenum /*source*/,
|
||||
const bool use_color = CLG_color_support_get(&LOG);
|
||||
|
||||
if (ELEM(severity, GL_DEBUG_SEVERITY_LOW, GL_DEBUG_SEVERITY_NOTIFICATION)) {
|
||||
if ((LOG.type->flag & CLG_FLAG_USE) && (LOG.type->level >= CLG_SEVERITY_INFO)) {
|
||||
if ((LOG.type->flag & CLG_FLAG_USE) && (LOG.type->level <= CLG_SEVERITY_INFO)) {
|
||||
const char *format = use_color ? "\033[2m%s\033[0m" : "%s";
|
||||
CLG_logf(LOG.type, CLG_SEVERITY_INFO, "Notification", "", format, message);
|
||||
}
|
||||
@@ -131,6 +131,10 @@ static void APIENTRY debug_callback(GLenum /*source*/,
|
||||
|
||||
void init_gl_callbacks()
|
||||
{
|
||||
if (G.log.level >= CLG_SEVERITY_LEN) {
|
||||
return;
|
||||
}
|
||||
|
||||
CLOG_ENSURE(&LOG);
|
||||
|
||||
char msg[256] = "";
|
||||
@@ -362,6 +366,9 @@ namespace blender::gpu {
|
||||
* Useful for debugging through render-doc. This makes all the API calls grouped into "passes".
|
||||
* \{ */
|
||||
|
||||
#define PROFILE_DEBUG_GROUPS 0
|
||||
#define MAX_DEBUG_GROUPS_STACK_DEPTH 4
|
||||
|
||||
void GLContext::debug_group_begin(const char *name, int index)
|
||||
{
|
||||
if ((G.debug & G_DEBUG_GPU) &&
|
||||
@@ -369,6 +376,23 @@ void GLContext::debug_group_begin(const char *name, int index)
|
||||
/* Add 10 to avoid collision with other indices from other possible callback layers. */
|
||||
index += 10;
|
||||
glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, index, -1, name);
|
||||
|
||||
#if PROFILE_DEBUG_GROUPS
|
||||
if (frame_timings.is_empty()) {
|
||||
frame_timings.append({});
|
||||
}
|
||||
|
||||
TimeQuery query = {};
|
||||
query.finished = false;
|
||||
query.name = name;
|
||||
query.stack_depth = debug_stack.size();
|
||||
glGetInteger64v(GL_TIMESTAMP, &query.cpu_start);
|
||||
|
||||
/* Use GL_TIMESTAMP instead of GL_ELAPSED_TIME to support nested debug groups */
|
||||
glGenQueries(2, query.handles);
|
||||
glQueryCounter(query.handles[0], GL_TIMESTAMP);
|
||||
frame_timings.last().queries.append(query);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,9 +401,96 @@ void GLContext::debug_group_end()
|
||||
if ((G.debug & G_DEBUG_GPU) &&
|
||||
(epoxy_gl_version() >= 43 || epoxy_has_gl_extension("GL_KHR_debug"))) {
|
||||
glPopDebugGroup();
|
||||
|
||||
#if PROFILE_DEBUG_GROUPS
|
||||
Vector<TimeQuery> &queries = frame_timings.last().queries;
|
||||
for (int i = queries.size() - 1; i >= 0; i--) {
|
||||
TimeQuery &query = queries[i];
|
||||
if (!query.finished) {
|
||||
glQueryCounter(query.handles[1], GL_TIMESTAMP);
|
||||
query.finished = true;
|
||||
int64_t cpu_end;
|
||||
glGetInteger64v(GL_TIMESTAMP, &cpu_end);
|
||||
query.cpu_time = (cpu_end - query.cpu_start) / 1000000.0;
|
||||
break;
|
||||
}
|
||||
BLI_assert(i != 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void GLContext::process_frame_timings()
|
||||
{
|
||||
#if PROFILE_DEBUG_GROUPS
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
for (int frame_i = 0; frame_i < frame_timings.size(); frame_i++) {
|
||||
Vector<TimeQuery> &queries = frame_timings[frame_i].queries;
|
||||
if (queries.is_empty() || !queries.last().finished /* Group begin/end mismatch */) {
|
||||
frame_timings.remove(frame_i--);
|
||||
continue;
|
||||
}
|
||||
|
||||
GLint ready = 0;
|
||||
glGetQueryObjectiv(queries.last().handles[1], GL_QUERY_RESULT_AVAILABLE, &ready);
|
||||
if (!ready) {
|
||||
break;
|
||||
}
|
||||
|
||||
std::stringstream result;
|
||||
result << "\n";
|
||||
// clang-format off
|
||||
result << " Group | GPU | CPU | Latency\n";
|
||||
result << "--------------------------------|------|------|--------\n";
|
||||
result << " Total | ";
|
||||
// clang-format on
|
||||
GLuint64 begin_timestamp = 0;
|
||||
GLuint64 end_timestamp = 0;
|
||||
glGetQueryObjectui64v(queries.first().handles[0], GL_QUERY_RESULT, &begin_timestamp);
|
||||
glGetQueryObjectui64v(queries.last().handles[1], GL_QUERY_RESULT, &end_timestamp);
|
||||
|
||||
float gpu_total_time = (end_timestamp - begin_timestamp) / 1000000.0;
|
||||
result << std::to_string(gpu_total_time).substr(0, 4) << " | ";
|
||||
|
||||
float cpu_total_time = (queries.last().cpu_start - queries.first().cpu_start) / 1000000.0 +
|
||||
queries.last().cpu_time;
|
||||
result << std::to_string(cpu_total_time).substr(0, 4) << " | \n";
|
||||
|
||||
for (TimeQuery &query : queries) {
|
||||
if (query.stack_depth >= MAX_DEBUG_GROUPS_STACK_DEPTH) {
|
||||
glDeleteQueries(2, query.handles);
|
||||
continue;
|
||||
}
|
||||
GLuint64 begin_timestamp = 0;
|
||||
GLuint64 end_timestamp = 0;
|
||||
glGetQueryObjectui64v(query.handles[0], GL_QUERY_RESULT, &begin_timestamp);
|
||||
glGetQueryObjectui64v(query.handles[1], GL_QUERY_RESULT, &end_timestamp);
|
||||
glDeleteQueries(2, query.handles);
|
||||
|
||||
result << std::string(query.stack_depth, '.');
|
||||
result << " " << query.name
|
||||
<< std::string(max_ii(0, 30 - query.stack_depth - query.name.length()), ' ')
|
||||
<< " | ";
|
||||
|
||||
float gpu_time = (end_timestamp - begin_timestamp) / 1000000.0;
|
||||
|
||||
result << std::to_string(gpu_time).substr(0, 4) << " | ";
|
||||
result << std::to_string(query.cpu_time).substr(0, 4) << " | ";
|
||||
result << std::to_string((begin_timestamp - query.cpu_start) / 1000000.0).substr(0, 4)
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
std::string print = result.str();
|
||||
printf("%s", print.c_str());
|
||||
|
||||
frame_timings.remove(frame_i--);
|
||||
}
|
||||
|
||||
frame_timings.append({});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
@@ -385,7 +385,9 @@ void GLTexture::clear(eGPUDataFormat data_format, const void *data)
|
||||
{
|
||||
BLI_assert(validate_data_format(format_, data_format));
|
||||
|
||||
if (GLContext::clear_texture_support) {
|
||||
/* ClearTexImage can be up to 10 times slower */
|
||||
const bool USE_CLEAR_TEX_IMAGE = false;
|
||||
if (USE_CLEAR_TEX_IMAGE && GLContext::clear_texture_support) {
|
||||
int mip = 0;
|
||||
GLenum gl_format = to_gl_data_format(format_);
|
||||
GLenum gl_type = to_gl(data_format);
|
||||
|
@@ -652,6 +652,8 @@ typedef struct UserDef_Experimental {
|
||||
char use_override_templates;
|
||||
char enable_eevee_next;
|
||||
char use_sculpt_texture_paint;
|
||||
char enable_workbench_next;
|
||||
char _pad[7];
|
||||
/** `makesdna` does not allow empty structs. */
|
||||
} UserDef_Experimental;
|
||||
|
||||
@@ -955,7 +957,7 @@ extern UserDef U;
|
||||
/* ***************** USERDEF ****************** */
|
||||
|
||||
/* Toggles for unfinished 2.8 UserPref design. */
|
||||
//#define WITH_USERDEF_WORKSPACES
|
||||
// #define WITH_USERDEF_WORKSPACES
|
||||
|
||||
/** #UserDef_SpaceData.section_active (UI active_section) */
|
||||
typedef enum eUserPref_Section {
|
||||
|
@@ -6426,6 +6426,13 @@ static void rna_def_userdef_experimental(BlenderRNA *brna)
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "enable_eevee_next", 1);
|
||||
RNA_def_property_ui_text(prop, "EEVEE Next", "Enable the new EEVEE codebase, requires restart");
|
||||
|
||||
prop = RNA_def_property(srna, "enable_workbench_next", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "enable_workbench_next", 1);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Workbench Next",
|
||||
"Enable the new Workbench codebase, requires "
|
||||
"restart");
|
||||
|
||||
prop = RNA_def_property(srna, "use_viewport_debug", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "use_viewport_debug", 1);
|
||||
RNA_def_property_ui_text(prop,
|
||||
|
Reference in New Issue
Block a user