[Bf-codereview] OSL Script Node (issue 6506102)

lukas.toenne at gmail.com lukas.toenne at gmail.com
Wed Sep 12 09:28:37 CEST 2012


Reviewers: bf-codereview_blender.org, brechtvl,

Description:
= OSL Script Node =

A new node type that passes an OSL script file to cycles to use as a
customizable shader. This allows scripting of OSL shaders and runtime
compilation as well as creation of a node interface (inputs/outputs)
based on the OSL shader parameters. Scripts can be linked to the node by
a simple Text data block. An operator then executes the OSL compiler and
subsequently performs an OSL query to get detailed shader information
for the node interface.


== Cycles Addon API ==

The actual OSL code is wrapped by the cycles addon Python module. This
means that the OSL compile and query functionality can be accessed by
other features and addons in the future, i.e. the script node is just
one possible way of using OSL.
The Python code is accessible from the _cycles extension, under the .osl
object(just a PyObject "pseudo module" to keep it separate from base
engine API). The _cycles.osl addon is in turn accessed through a local
osl.py module that should be used by operators instead of the base
_cycles extension. This module also encodes the standard paths used for
Cycles shaders at this time, which may need to be adjusted for proper
path usage.

* osl.compile: Takes a path to a .osl file and a list of optional
include paths for finding .h header files. Creates a temporary
OSL::OSLCompiler object and calls its compile function with these
arguments.

* osl.query: First argument is the shader name, i.e. the base name of a
compiled .oso file (original file: "/some/path/my_shader.osl" ->
compiled shader: "/shader/path/my_shader.oso" -> shader name for query:
"my_shader"). Second argument is a search path in which to look for the
.oso file. Query data is returned from osl.query as a python object,
which closely follows the OSL::OSLQuery struct.

For the purpose of generating the Python API the boost::python library
has been used, since manually writing the Python extension would become
very bloated (the native Blender bpy system is not available in Cycles).
For using boost::python with the new Python 3.2 version a few additional
compile settings have to be made. The library versions used in Blender
need an update for OSL integration anyway (see this page for details:
http://wiki.blender.org/index.php/User:DingTo/OpenShadingLanguage).


== Script Node Interface ==

The OSL Script node automatically updates its interface (input/output
sockets) from the parameters of the shader it uses. This allows rapid
prototyping because the script writer does not have to care about
additional UI code for the node.

However, with the current Python API functions for nodes it is not
possible to directly add and remove sockets to/from nodes. This will
eventually become standard procedure with the "custom nodes" branch, but
in the meantime the OSL Script node defines its own limited API for this
purpose.

With the "custom nodes" branch it will also be possible to actually
register the script node type itself from within Cycles, just like it is
possible to define operators, menus and the like using the registration
API.


== Node Operators ==

To actually make use of OSL functionality in the node editor a few
operators are defined by Cycles.

* render.cycles_osl_script_node_compile: Takes the linked Text data
block file name and passes it on to the osl module for compiling. There
is also some unfinished code for directly compiling the internal Text to
a shader using a temporary file (OSL only takes actual files on disk so
far, not strings or IO streams). This would avoid the confusion that can
arise when editing unsaved text inside Blender, but it doesn't work
reliably yet, so the operator will cancel if the Text is only in memory.

   If compiling is successful, the resulting shader name is stored in the
node. This way it can be subsequently used for querying shader info.

* render.cycles_osl_script_node_update: Updates the node interface from
shader parameters. Uses the stored shader_name string to query info from
the osl module, then verifies sockets by name.


== Cycles Rendering ==

Finally the OSL Script node must be used in a Cycles ShaderGraph. This
is straightforward: Take the node's stored shader_name and set the
parameters from sockets.

Please review this at http://codereview.appspot.com/6506102/

Affected files:
   CMakeLists.txt
   intern/cycles/blender/CMakeLists.txt
   intern/cycles/blender/addon/__init__.py
   intern/cycles/blender/addon/engine.py
   intern/cycles/blender/addon/enums.py
   intern/cycles/blender/addon/nodes.py
   intern/cycles/blender/addon/osl.py
   intern/cycles/blender/addon/properties.py
   intern/cycles/blender/blender_python.cpp
   intern/cycles/blender/blender_session.cpp
   intern/cycles/blender/blender_session.h
   intern/cycles/blender/blender_shader.cpp
   intern/cycles/kernel/osl/nodes/CMakeLists.txt
   intern/cycles/render/nodes.cpp
   intern/cycles/render/nodes.h
   intern/cycles/render/osl.cpp
   intern/cycles/render/osl.h
   intern/cycles/render/shader.cpp
   intern/cycles/render/shader.h
   source/blender/blenkernel/BKE_node.h
   source/blender/blenkernel/intern/node.c
   source/blender/editors/space_node/drawnode.c
   source/blender/makesdna/DNA_node_types.h
   source/blender/makesrna/intern/rna_nodetree.c
   source/blender/makesrna/intern/rna_nodetree_types.h
   source/blender/nodes/CMakeLists.txt
   source/blender/nodes/NOD_shader.h
   source/blender/nodes/shader/nodes/node_shader_osl_script.c




More information about the Bf-codereview mailing list