feat: boost render speed

This commit is contained in:
2024-08-16 13:56:14 +08:00
parent 9e885865f7
commit 051df670a5
8 changed files with 160 additions and 47 deletions

View File

@@ -9,7 +9,8 @@ from uuid import uuid4
from ..nodes import custom_nodes
from ..bioxel.layer import Layer
from .utils import get_layer_prop_value, move_node_between_nodes
from .utils import (get_layer_prop_value,
move_node_between_nodes, add_direct_driver)
def obj_to_layer(layer_obj: bpy.types.Object):
@@ -135,9 +136,14 @@ def layer_to_obj(layer: Layer,
cache_filepaths = [cache_filepath]
layer_data = bpy.data.volumes.new(layer_display_name)
layer_data.render.space = 'WORLD'
layer_data.render.step_size = container_obj.scale[0] * layer.bioxel_size[0]
layer_data.sequence_mode = 'REPEAT'
layer_data.filepath = str(cache_filepaths[0])
# add_direct_driver(layer_data, "render.step_size",
# container_obj, "scale[0]")
if layer.frame_count > 1:
layer_data.is_sequence = True
layer_data.frame_duration = layer.frame_count
@@ -145,7 +151,6 @@ def layer_to_obj(layer: Layer,
layer_data.is_sequence = False
layer_obj = bpy.data.objects.new(layer_display_name, layer_data)
layer_obj['bioxel_layer'] = True
print(f"Creating Node for {layer.name}...")

View File

@@ -94,3 +94,35 @@ def get_all_layer_objs():
layer_objs.append(obj)
return layer_objs
def add_driver(target, target_prop, var_sources, expression):
driver = target.driver_add(target_prop)
is_vector = isinstance(driver, list)
drivers = driver if is_vector else [driver]
for i, driver in enumerate(drivers):
for j, var_source in enumerate(var_sources):
source = var_source['source']
prop = var_source['prop']
var = driver.driver.variables.new()
var.name = f"var{j}"
var.targets[0].id_type = source.id_type
var.targets[0].id = source
var.targets[0].data_path = f'["{prop}"][{i}]'\
if is_vector else f'["{prop}"]'
driver.driver.expression = expression
def add_direct_driver(target, target_prop, source, source_prop):
drivers = [
{
"source": source,
"prop": source_prop
}
]
expression = "var0"
add_driver(target, target_prop, drivers, expression)

View File

@@ -13,10 +13,10 @@ from .operators.layer import (FetchLayerMenu, FetchLayer,
from .operators.container import (SaveAllLayerCaches, SaveContainer, LoadContainer,
AddPieCutter, AddPlaneCutter,
AddCylinderCutter, AddCubeCutter, AddSphereCutter,
PickBboxWire, PickMesh, PickVolume)
PickBboxWire, PickMesh, PickVolume, ScaleContainer)
from .operators.io import (ImportAsLabel, ImportAsScalar, ImportAsColor)
from .operators.misc import (CleanAllCaches,
ReLinkNodes, RenderSettingPreset, SaveStagedData)
ReLinkNodes, RenderSettingPreset, SaveStagedData, SliceViewer)
class PickFromContainerMenu(bpy.types.Menu):
@@ -156,19 +156,19 @@ class BioxelNodesNodeMenu(bpy.types.Menu):
active_obj_name = ""
layout = self.layout
layout.separator()
layout.menu(AddLayerMenu.bl_idname,
icon=AddLayerMenu.bl_icon)
layout.operator(RemoveMissingLayers.bl_idname,
icon=RemoveMissingLayers.bl_icon)
layout.separator()
layout.operator(SaveContainer.bl_idname)
layout.separator()
layout.operator(ScaleContainer.bl_idname)
layout.menu(AddCutterMenu.bl_idname)
layout.menu(PickFromContainerMenu.bl_idname)
layout.operator(SaveAllLayerCaches.bl_idname,
icon=SaveAllLayerCaches.bl_icon)
layout.operator(RemoveMissingLayers.bl_idname,
icon=RemoveMissingLayers.bl_icon)
layout.separator()
layout.menu(FetchLayerMenu.bl_idname)
@@ -247,6 +247,8 @@ def NODE_PT(self, context):
sidebar.menu(AddLayerMenu.bl_idname,
icon=AddLayerMenu.bl_icon, text="")
sidebar.operator(SaveAllLayerCaches.bl_idname,
icon=SaveAllLayerCaches.bl_icon, text="")
sidebar.operator(RemoveMissingLayers.bl_idname,
icon=RemoveMissingLayers.bl_icon, text="")
@@ -285,13 +287,21 @@ def NODE_PT(self, context):
layout.separator()
def VIEW3D_TOPBAR(self, context):
layout = self.layout
layout.operator(SliceViewer.bl_idname,
icon=SliceViewer.bl_icon, text="")
def add():
bpy.types.VIEW3D_HT_header.append(VIEW3D_TOPBAR)
bpy.types.NODE_PT_node_tree_properties.prepend(NODE_PT)
bpy.types.TOPBAR_MT_editor_menus.append(TOPBAR)
bpy.types.NODE_MT_editor_menus.append(NODE)
def remove():
bpy.types.VIEW3D_HT_header.remove(VIEW3D_TOPBAR)
bpy.types.NODE_PT_node_tree_properties.remove(NODE_PT)
bpy.types.TOPBAR_MT_editor_menus.remove(TOPBAR)
bpy.types.NODE_MT_editor_menus.remove(NODE)

View File

@@ -60,9 +60,9 @@ MENU_ITEMS = [
'node_description': ''
},
{
'label': 'Set Color by Layer',
'label': 'Set Color by Color',
'icon': 'IPO_QUINT',
'node_type': 'BioxelNodes_SetColorByLayer',
'node_type': 'BioxelNodes_SetColorByColor',
'node_description': ''
},
{

View File

@@ -6,7 +6,8 @@ from ..nodes import custom_nodes
from ..customnodes.nodes import AddCustomNode
from ..bioxel.io import load_container, save_container
from ..bioxelutils.container import container_to_obj, obj_to_container
from ..bioxelutils.utils import (get_container_layer_objs, get_container_obj, get_nodes_by_type,
from ..bioxelutils.utils import (get_container_layer_objs, get_container_obj,
get_layer_prop_value, get_nodes_by_type,
move_node_between_nodes,
move_node_to_node,
get_all_layer_objs)
@@ -66,7 +67,8 @@ class LoadContainer(bpy.types.Operator):
select_object(container_obj)
if is_first_import:
change_render_setting(context)
bpy.ops.bioxelnodes.render_setting_preset('EXEC_DEFAULT',
preset="preview_c")
self.report({"INFO"}, f"Successfully load {load_path}")
return {'FINISHED'}
@@ -158,14 +160,24 @@ class AddCutter():
bpy.ops.mesh.primitive_ico_sphere_add(
radius=1, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
elif self.cutter_type == "pie":
bpy.ops.mesh.primitive_plane_add(
size=2, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
pie = bpy.context.active_object
pie.name = "Pie"
orig_data = pie.data
# Create mesh
pie_mesh = bpy.data.meshes.new('Pie')
# Create object
pie = bpy.data.objects.new('Pie', pie_mesh)
pie.data = pie_mesh
bpy.data.meshes.remove(orig_data)
# # Create object
# pie = bpy.data.objects.new('Pie', pie_mesh)
# # Link object to scene
# bpy.context.scene.collection.objects.link(pie)
# Link object to scene
bpy.context.scene.collection.objects.link(pie)
# Get a BMesh representation
bm = bmesh.new() # create an empty BMesh
bm.from_mesh(pie_mesh) # fill it in from a Mesh
@@ -189,7 +201,7 @@ class AddCutter():
# Finish up, write the bmesh back to the mesh
bm.to_mesh(pie_mesh)
bpy.context.view_layer.objects.active = pie
# bpy.context.view_layer.objects.active = pie
cutter_obj = bpy.context.active_object
cutter_obj.location = container_obj.location
@@ -325,6 +337,46 @@ class AddPieCutter(bpy.types.Operator, AddCutter):
cutter_type = "pie"
class ScaleContainer(bpy.types.Operator):
bl_idname = "bioxelnodes.scale_container"
bl_label = "Scale Container"
bl_description = "Scale Container."
bl_icon = "FILE_TICK"
scene_scale: bpy.props.FloatProperty(name="Scene Scale",
soft_min=0.0001, soft_max=10.0,
min=1e-6, max=1e6,
default=0.01) # type: ignore
def execute(self, context):
container_obj = get_container_obj(context.object)
if container_obj is None:
self.report({"WARNING"}, "Cannot find any bioxel container.")
return {'FINISHED'}
container_obj.scale[0] = self.scene_scale
container_obj.scale[1] = self.scene_scale
container_obj.scale[2] = self.scene_scale
for layer_obj in get_container_layer_objs(container_obj):
bioxel_size = get_layer_prop_value(layer_obj, "bioxel_size")
layer_obj.data.render.step_size = self.scene_scale * bioxel_size
return {'FINISHED'}
def invoke(self, context, event):
container_obj = get_container_obj(context.object)
if container_obj is None:
return self.execute(context)
else:
self.scene_scale = container_obj.scale[0]
context.window_manager.invoke_props_dialog(self,
width=500)
return {'RUNNING_MODAL'}
class SaveAllLayerCaches(bpy.types.Operator):
bl_idname = "bioxelnodes.save_all_layer_caches"
bl_label = "Save All Layer Caches"

View File

@@ -782,9 +782,8 @@ class ImportVolumetricDataDialog(bpy.types.Operator):
# Change render setting for better result
if is_first_import:
bpy.ops.bioxelnodes.render_setting_preset('EXEC_DEFAULT',
preset="slice_viewer")
bpy.ops.bioxelnodes.render_setting_preset('EXEC_DEFAULT',
preset="cycles_preview")
preset="preview_c")
# bpy.ops.bioxelnodes.slice_viewer('EXEC_DEFAULT')
self.report({"INFO"}, "Successfully Imported")
return {'FINISHED'}

View File

@@ -151,20 +151,19 @@ class RenderSettingPreset(bpy.types.Operator):
bl_description = "Render Setting Preset"
PRESETS = {
"slice_viewer": "Slice Viewer",
"eevee_preview": "EEVEE Preview",
"eevee_production": "EEVEE Production",
"cycles_preview": "Cycles Preview",
"cycles_production": "Cycles Production"
"preview_e": "Preview (EEVEE)",
"preview_c": "Preview (Cycles)",
"production_e": "Production (EEVEE)",
"production_c": "Production (Cycles)"
}
preset: bpy.props.EnumProperty(name="Preset",
default="eevee_preview",
default="preview_c",
items=[(k, v, "")
for k, v in PRESETS.items()]) # type: ignore
def execute(self, context):
if self.preset == "eevee_preview":
if self.preset == "preview_e":
bpy.context.scene.render.engine = 'BLENDER_EEVEE_NEXT'
bpy.context.scene.eevee.use_taa_reprojection = False
bpy.context.scene.eevee.taa_samples = 16
@@ -174,7 +173,7 @@ class RenderSettingPreset(bpy.types.Operator):
bpy.context.scene.eevee.volumetric_ray_depth = 16
bpy.context.scene.eevee.use_volumetric_shadows = True
elif self.preset == "eevee_production":
elif self.preset == "production_e":
bpy.context.scene.render.engine = 'BLENDER_EEVEE_NEXT'
bpy.context.scene.eevee.use_taa_reprojection = False
bpy.context.scene.eevee.taa_samples = 16
@@ -184,24 +183,31 @@ class RenderSettingPreset(bpy.types.Operator):
bpy.context.scene.eevee.volumetric_ray_depth = 16
bpy.context.scene.eevee.use_volumetric_shadows = True
elif self.preset == "cycles_preview":
elif self.preset == "preview_c":
bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.cycles.shading_system = True
bpy.context.scene.cycles.volume_bounces = 12
bpy.context.scene.cycles.transparent_max_bounces = 16
bpy.context.scene.cycles.volume_preview_step_rate = 10
bpy.context.scene.cycles.volume_step_rate = 10
bpy.context.scene.cycles.volume_preview_step_rate = 1
bpy.context.scene.cycles.volume_step_rate = 1
elif self.preset == "cycles_production":
elif self.preset == "production_c":
bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.cycles.shading_system = True
bpy.context.scene.cycles.volume_bounces = 16
bpy.context.scene.cycles.transparent_max_bounces = 32
bpy.context.scene.cycles.volume_preview_step_rate = 1
bpy.context.scene.cycles.volume_step_rate = 1
bpy.context.scene.cycles.volume_preview_step_rate = 0.1
bpy.context.scene.cycles.volume_step_rate = 0.1
elif self.preset == "slice_viewer":
# bpy.context.scene.render.engine = 'BLENDER_EEVEE_NEXT'
return {'FINISHED'}
class SliceViewer(bpy.types.Operator):
bl_idname = "bioxelnodes.slice_viewer"
bl_label = "Slice Viewer"
bl_description = "Slice Viewer"
bl_icon = "FILE_VOLUME"
def execute(self, context):
bpy.context.scene.eevee.use_taa_reprojection = False
bpy.context.scene.eevee.taa_samples = 4
bpy.context.scene.eevee.volumetric_tile_size = '2'
@@ -210,4 +216,13 @@ class RenderSettingPreset(bpy.types.Operator):
bpy.context.scene.eevee.volumetric_ray_depth = 1
bpy.context.scene.eevee.use_volumetric_shadows = False
for area in bpy.context.screen.areas:
if area.type == 'VIEW_3D':
area.spaces[0].shading.type = 'MATERIAL'
area.spaces[0].shading.studio_light = 'studio.exr'
area.spaces[0].shading.studiolight_intensity = 2.5
area.spaces[0].shading.use_scene_lights = False
area.spaces[0].shading.use_scene_world = False
return {'FINISHED'}