[Bf-blender-cvs] [0e1f34a] cycles_camera_nodes: Cycles; Camera ray nodes initial commit

Sergey Sharybin noreply at git.blender.org
Fri Sep 26 14:35:00 CEST 2014


Commit: 0e1f34a0c8b7f2a6ecddbca65f44bbd444c1386a
Author: Sergey Sharybin
Date:   Wed Sep 3 11:30:18 2014 +0600
Branches: cycles_camera_nodes
https://developer.blender.org/rB0e1f34a0c8b7f2a6ecddbca65f44bbd444c1386a

Cycles; Camera ray nodes initial commit

This commit lays down an initial playground for the camera ray nodes.

The idea of this nodes is to be able to have a control over the rays
which are being casted from the camera in order to gain several use
case scenarios:

- Panorama cameras with custom mapping (kinda generalized way doing
  what Daniel Basso tried to address in T35428).

- Distortion rendering, to produce renders which matches the footage
  precisely, improving motrack work flow in general.

- Some possible artistic scenarios.

It's the very beginning and loads of stuff to be done, but it's
already possible to render a distorted images on CPU using the same
exact distortion model as used by the motion tracker.

Committing the stuff in order to be able to gather early feedback
about how exactly this nodes are expected to work from the artists
point of view, and hopefully someone will pick the work up and help
finishing it all up.

Some technical details:

- Camera nodes are using pynodes, so no changes to the blender itself
  is to be done. This leads some limitations and corners on the usage,
  but that's probably something to be addressed for pynodes in general.

  That said, current annoyance is:

  * Modifying node declaration in the cycles addon doesn't update the
    files, leading to wrong render results. Not sure how it's expected
    to be handled actually.

  * Some operators like Ctrl-X are not re-linking noodles correctly.

  * Muting is impossible.

  * Some major update issues, mainly in cycles viewport. This also
    involves dependency graph stupidness into here.

- Nodes are implemented using SVM, which is really easy to use and
  extend. Would also make it possible to have custom socket types, for
  example in SVM we can have socket type named "Ray" which would pass
  all the origin, direction length via a single noodle.

  In OSL it's not so trivial by the looks of it, so for now we stick
  to a stupid regular socket types.

- Supporting OSL could be a rather tricky business via pynodes and
  could involve quite some work in here. Also it'll stress OSL with
  something it wasn't really designed to do, but it might just work.

- Since inverting the distortion is an optimization problem which is
  rather tricky to implement on GPU, only CPU supports camera ray
  nodes at this moment.

- The above thing might be solved if we bake distortion into a grid
  and use as a lookup table from the kernel. Would also help performance
  by avoiding solving optimization problem for each single camera ray
  at each sample.

- Some stuff might be totally broken at this moment, use with care
  and don't forget to back your files up before doing experiments.

Real quick example: ftp://ftp.blender.org/sergey/camera_nodes.blend.png

===================================================================

M	intern/cycles/CMakeLists.txt
M	intern/cycles/SConscript
M	intern/cycles/blender/CMakeLists.txt
M	intern/cycles/blender/addon/__init__.py
A	intern/cycles/blender/addon/camera_nodes.py
M	intern/cycles/blender/addon/properties.py
M	intern/cycles/blender/addon/ui.py
M	intern/cycles/blender/blender_camera.cpp
A	intern/cycles/blender/blender_camera_nodes.cpp
M	intern/cycles/blender/blender_sync.h
M	intern/cycles/kernel/kernel_camera.h
M	intern/cycles/kernel/kernel_math.h
M	intern/cycles/kernel/kernel_types.h
A	intern/cycles/kernel/svm/camera_nodes/svm_camera_distortion.h
A	intern/cycles/kernel/svm/camera_nodes/svm_camera_path_attribute.h
A	intern/cycles/kernel/svm/camera_nodes/svm_camera_ray_output.h
A	intern/cycles/kernel/svm/camera_nodes/svm_camera_sample_perspective.h
M	intern/cycles/kernel/svm/svm.h
M	intern/cycles/kernel/svm/svm_types.h
M	intern/cycles/render/CMakeLists.txt
M	intern/cycles/render/camera.cpp
M	intern/cycles/render/camera.h
A	intern/cycles/render/camera_nodes.cpp
A	intern/cycles/render/camera_nodes.h
M	intern/cycles/render/graph.cpp
M	intern/cycles/render/graph.h
M	intern/cycles/render/svm.cpp
M	intern/cycles/render/svm.h
A	intern/cycles/util/util_distort.h

===================================================================

diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index bfd29dc..ae38fbb 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -146,6 +146,13 @@ if(WITH_CYCLES_LOGGING)
 	endif()
 endif()
 
+if(WITH_LIBMV)
+	add_definitions(-DWITH_CYCLES_DISTORTION)
+	include_directories(
+		../../extern/libmv
+	)
+endif()
+
 include_directories(
 	SYSTEM
 	${BOOST_INCLUDE_DIR}
diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript
index a6c947b..58685f5 100644
--- a/intern/cycles/SConscript
+++ b/intern/cycles/SConscript
@@ -59,6 +59,10 @@ if env['WITH_BF_CYCLES_OSL']:
     defs.append('OSL_STATIC_LIBRARY')
     incs.append(cycles['BF_OSL_INC'])
 
+if env['WITH_BF_LIBMV']:
+    defs.append('WITH_CYCLES_DISTORTION')
+    incs.append('#extern/libmv')
+
 incs.extend('. bvh render device kernel kernel/osl kernel/svm util subd'.split())
 incs.extend('#intern/guardedalloc #source/blender/makesrna #source/blender/makesdna #source/blender/blenlib'.split())
 incs.extend('#source/blender/blenloader ../../source/blender/makesrna/intern'.split())
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index 13ac0be..0b1c161 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -21,6 +21,7 @@ set(INC_SYS
 
 set(SRC
 	blender_camera.cpp
+	blender_camera_nodes.cpp
 	blender_mesh.cpp
 	blender_object.cpp
 	blender_particles.cpp
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index 8c60ea3..415f6e8 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -31,7 +31,6 @@ bl_info = {
 import bpy
 
 from . import engine
-from . import version_update
 
 
 class CyclesRender(bpy.types.RenderEngine):
@@ -90,28 +89,34 @@ class CyclesRender(bpy.types.RenderEngine):
 
 
 def register():
+    from . import camera_nodes
     from . import ui
     from . import properties
     from . import presets
+    from . import version_update
 
     engine.init()
 
     properties.register()
     ui.register()
     presets.register()
+    camera_nodes.register()
     bpy.utils.register_module(__name__)
 
     bpy.app.handlers.version_update.append(version_update.do_versions)
 
 
 def unregister():
+    from . import camera_nodes
     from . import ui
     from . import properties
     from . import presets
+    from . import version_update
 
     bpy.app.handlers.version_update.remove(version_update.do_versions)
 
     ui.unregister()
     properties.unregister()
     presets.unregister()
+    camera_nodes.unregister()
     bpy.utils.unregister_module(__name__)
diff --git a/intern/cycles/blender/addon/camera_nodes.py b/intern/cycles/blender/addon/camera_nodes.py
new file mode 100644
index 0000000..76050fe
--- /dev/null
+++ b/intern/cycles/blender/addon/camera_nodes.py
@@ -0,0 +1,165 @@
+#
+# Copyright 2011-2014 Blender Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License
+#
+
+# <pep8 compliant>
+
+import bpy
+import nodeitems_utils
+from bpy.types import NodeTree, Node, NodeSocket
+from bpy.props import EnumProperty, FloatProperty
+from nodeitems_utils import NodeCategory, NodeItem
+
+
+class CameraRaysTree(NodeTree):
+    '''Camera rays node tree'''
+    bl_idname = 'CameraRaysTreeType'
+    bl_label = 'Camera Rays'
+    bl_icon = 'CAMERA_DATA'
+
+
+class CameraRaysTreeNode:
+    @classmethod
+    def poll(cls, ntree):
+        return ntree.bl_idname == 'CameraRaysTreeType'
+
+
+class PathAttributeNode(Node, CameraRaysTreeNode):
+    '''Path attribute input node'''
+    bl_idname = 'PathAttributeNodeType'
+    bl_label = 'Attribute'
+
+    def init(self, context):
+        self.outputs.new('NodeSocketVector', "Raster")
+        self.outputs.new('NodeSocketVector', "Lens")
+        self.outputs.new('NodeSocketFloat', "Time")
+
+    def draw_buttons(self, context, layout):
+        pass
+
+
+class CameraSamplePerspectiveNode(Node, CameraRaysTreeNode):
+    '''Sample perspective camera ray'''
+    bl_idname = 'CameraSamplePerspectiveNodeType'
+    bl_label = 'Sample Perspective'
+
+    def init(self, context):
+        self.inputs.new('NodeSocketVector', "Raster")
+        self.inputs.new('NodeSocketVector', "Lens")
+        self.inputs.new('NodeSocketFloat', "Time")
+        self.outputs.new('NodeSocketVector', "Ray Origin")
+        self.outputs.new('NodeSocketVector', "Ray Direction")
+        self.outputs.new('NodeSocketFloat', "Ray Length")
+
+    def draw_buttons(self, context, layout):
+        pass
+
+
+class CameraRayOutputNode(Node, CameraRaysTreeNode):
+    '''Camera ray output node'''
+    bl_idname = 'CameraRayOutputNodeType'
+    bl_label = 'Ray Output'
+
+    def init(self, context):
+        self.inputs.new('NodeSocketVector', "Ray Origin")
+        self.inputs.new('NodeSocketVector', "Ray Direction")
+        self.inputs.new('NodeSocketFloat', "Ray Length")
+        self.inputs.new('NodeSocketFloat', "Time")
+
+    def draw_buttons(self, context, layout):
+        pass
+
+
+class PolynomialDistortionNode(Node, CameraRaysTreeNode):
+    '''Ray distortion node type'''
+    bl_idname = 'PolynomialDistortionNodeType'
+    bl_label = 'Polynomial Distortion'
+
+    mode = EnumProperty(name="Mode",
+        description="Mode of the distortion",
+        items=(('APPLY', 'Apply',
+                "Apply the radial distortion on the input"),
+               ('INVERT', "Invert",
+                "Invert the radial distortion from the input")),
+        default='INVERT')
+
+    k1 = FloatProperty(name="K1",
+                       description="First coefficient of third "
+                                   "order polynomial radial distortion",
+                       default=0.0)
+
+    k2 = FloatProperty(name="K2",
+                       description="Second coefficient of third "
+                                   "order polynomial radial distortion",
+                       default=0.0)
+
+    k3 = FloatProperty(name="K3",
+                       description="Third coefficient of third "
+                                   "order polynomial radial distortion",
+                       default=0.0)
+
+    def init(self, context):
+        self.inputs.new('NodeSocketVector', "Raster")
+        self.outputs.new('NodeSocketVector', "Raster")
+
+    def draw_buttons(self, context, layout):
+        col = layout.column()
+        col.prop(self, "mode", text="")
+
+        col = layout.column(align=True)
+        col.prop(self, "k1")
+        col.prop(self, "k2")
+        col.prop(self, "k3")
+
+
+class CameraRaysNodeCategory(NodeCategory):
+    @classmethod
+    def poll(cls, context):
+        return context.space_data.tree_type == 'CameraRaysTreeType'
+
+node_categories = [
+    CameraRaysNodeCategory("INPUT", "Input", items=[
+        NodeItem("PathAttributeNodeType"),
+        ]),
+    CameraRaysNodeCategory("OUTPUT", "Output", items=[
+        NodeItem("CameraRayOutputNodeType"),
+        ]),
+    CameraRaysNodeCategory("SAMPLE", "Sample", items=[
+        NodeItem("CameraSamplePerspectiveNodeType"),
+        ]),
+    CameraRaysNodeCategory("DISTORTION", "Distortion", items=[
+        NodeItem("PolynomialDistortionNodeType"),
+        ]),
+    ]
+
+
+def register():
+    bpy.utils.register_class(CameraRaysTree)
+    bpy.utils.register_class(PathAttributeNode)
+    bpy.utils.register_class(CameraSamplePerspectiveNode)
+    bpy.utils.register_class(CameraRayOutputNode)
+    bpy.utils.register_class(PolynomialDistortionNode)
+
+    nodeitems_utils.register_node_categories("CAMERA_NODES", node_categories)
+
+
+def unregister():
+    nodeitems_utils.unregister_node_categories("CAMERA_NODES")
+
+    bpy.utils.unregister_class(CameraRaysTree)
+    bpy.utils.unregister_class(PathAttributeNode)
+    bpy.utils.unregister_class(CameraSamplePerspectiveNode)
+    bpy.utils.unregister_class(CameraRayOutputNode)
+    bpy.utils.unregister_class(PolynomialDistortionNode)
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 597ac1a..12c1cd8 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -21,7 +21,8 @@ from bpy.props import (BoolProperty,
                        EnumProperty,
                        FloatProperty,
                        IntProperty,
-                       PointerProperty)
+                       PointerProperty,
+                       StringProperty)
 
 # enums
 
@@ -577,6 +578,9 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
                 min=0.01, soft_max=15.0, max=100.0,
                 default=10.5,
                 )
+        cls.nodes = StringProperty(
+                name="nodes",
+                description="Camera ray nodes")
 
     @classmethod
     def unregister(cls):
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 9632b12..b544c47 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -472,6 +472,24 @@ class CyclesCamera_PT_dof(CyclesButtonsPanel, Panel):
         sub.prop(ccam, "aperture_ratio", text="Ratio")
 
 
+class CyclesCamera_PT_ray_nodes(CyclesButtonsPanel, Panel):
+    bl_label = "Ray Nodes"
+    bl_context = "data"
+
+    @classmethod
+    def poll(cls, context):
+        return context.camera and CyclesButtonsPanel.poll(context)
+
+    def draw(self, context):
+        layout = self.layout
+
+        cam = context.camera
+        ccam = cam.cycles
+
+        col = layout.column()
+        col.prop_search(ccam, "nodes", bpy.data, "node_groups", text="")
+
+
 class Cycles_PT_context_material(CyclesButtonsPanel, Panel):
     bl_label = ""
     bl_c

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list