Compare commits
4 Commits
temp-geome
...
cycles_cam
Author | SHA1 | Date | |
---|---|---|---|
![]() |
27b3ea622f | ||
![]() |
372dff8d1d | ||
![]() |
91d64cbf0f | ||
0e1f34a0c8 |
@@ -195,6 +195,13 @@ if(WITH_CYCLES_DEBUG)
|
||||
add_definitions(-DWITH_CYCLES_DEBUG)
|
||||
endif()
|
||||
|
||||
if(WITH_LIBMV)
|
||||
add_definitions(-DWITH_CYCLES_DISTORTION)
|
||||
include_directories(
|
||||
../../extern/libmv
|
||||
)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
SYSTEM
|
||||
${BOOST_INCLUDE_DIR}
|
||||
|
@@ -67,6 +67,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')
|
||||
|
||||
if env['WITH_BF_CYCLES_DEBUG']:
|
||||
defs.append('WITH_CYCLES_DEBUG')
|
||||
|
||||
|
@@ -22,6 +22,7 @@ set(INC_SYS
|
||||
|
||||
set(SRC
|
||||
blender_camera.cpp
|
||||
blender_camera_nodes.cpp
|
||||
blender_mesh.cpp
|
||||
blender_object.cpp
|
||||
blender_particles.cpp
|
||||
@@ -42,6 +43,7 @@ set(SRC
|
||||
|
||||
set(ADDON_FILES
|
||||
addon/__init__.py
|
||||
addon/camera_nodes.py
|
||||
addon/engine.py
|
||||
addon/osl.py
|
||||
addon/presets.py
|
||||
|
@@ -30,10 +30,7 @@ bl_info = {
|
||||
|
||||
import bpy
|
||||
|
||||
from . import (
|
||||
engine,
|
||||
version_update,
|
||||
)
|
||||
from . import engine
|
||||
|
||||
|
||||
class CyclesRender(bpy.types.RenderEngine):
|
||||
@@ -89,28 +86,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__)
|
||||
|
165
intern/cycles/blender/addon/camera_nodes.py
Normal file
165
intern/cycles/blender/addon/camera_nodes.py
Normal file
@@ -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)
|
@@ -21,7 +21,8 @@ from bpy.props import (BoolProperty,
|
||||
EnumProperty,
|
||||
FloatProperty,
|
||||
IntProperty,
|
||||
PointerProperty)
|
||||
PointerProperty,
|
||||
StringProperty)
|
||||
|
||||
# enums
|
||||
|
||||
@@ -625,6 +626,9 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
|
||||
subtype='ANGLE',
|
||||
default=math.pi,
|
||||
)
|
||||
cls.nodes = StringProperty(
|
||||
name="nodes",
|
||||
description="Camera ray nodes")
|
||||
|
||||
@classmethod
|
||||
def unregister(cls):
|
||||
|
@@ -547,6 +547,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_context = "material"
|
||||
|
@@ -335,6 +335,8 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
|
||||
{
|
||||
/* copy camera to compare later */
|
||||
Camera prevcam = *cam;
|
||||
prevcam.graph = NULL;
|
||||
|
||||
float aspectratio, sensor_size;
|
||||
|
||||
/* viewplane */
|
||||
@@ -370,6 +372,9 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
|
||||
cam->sensorheight = sensor_size;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cam->sensorwidth = sensor_size;
|
||||
}
|
||||
|
||||
/* clipping distances */
|
||||
cam->nearclip = bcam->nearclip;
|
||||
@@ -377,6 +382,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
|
||||
|
||||
/* type */
|
||||
cam->type = bcam->type;
|
||||
cam->focal_length = bcam->lens;
|
||||
|
||||
/* panorama */
|
||||
cam->panorama_type = bcam->panorama_type;
|
||||
@@ -455,6 +461,7 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override
|
||||
/* sync */
|
||||
Camera *cam = scene->camera;
|
||||
blender_camera_sync(cam, &bcam, width, height);
|
||||
sync_camera_nodes(b_ob);
|
||||
}
|
||||
|
||||
void BlenderSync::sync_camera_motion(BL::RenderSettings b_render,
|
||||
@@ -687,6 +694,7 @@ void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int
|
||||
blender_camera_border(&bcam, b_engine, b_scene.render(), b_scene, b_v3d, b_rv3d, width, height);
|
||||
|
||||
blender_camera_sync(scene->camera, &bcam, width, height);
|
||||
sync_view_nodes(b_rv3d);
|
||||
}
|
||||
|
||||
BufferParams BlenderSync::get_buffer_params(BL::RenderSettings b_render, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height)
|
||||
|
267
intern/cycles/blender/blender_camera_nodes.cpp
Normal file
267
intern/cycles/blender/blender_camera_nodes.cpp
Normal file
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "camera.h"
|
||||
#include "graph.h"
|
||||
#include "nodes.h"
|
||||
#include "camera_nodes.h"
|
||||
#include "scene.h"
|
||||
|
||||
#include "blender_sync.h"
|
||||
#include "blender_util.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
typedef map<void*, ShaderInput*> PtrInputMap;
|
||||
typedef map<void*, ShaderOutput*> PtrOutputMap;
|
||||
|
||||
static void set_default_value(ShaderInput *input, BL::Node b_node, BL::NodeSocket b_sock, BL::BlendData b_data, BL::ID b_id)
|
||||
{
|
||||
/* copy values for non linked inputs */
|
||||
switch(input->type) {
|
||||
case SHADER_SOCKET_FLOAT: {
|
||||
input->set(get_float(b_sock.ptr, "default_value"));
|
||||
break;
|
||||
}
|
||||
case SHADER_SOCKET_INT: {
|
||||
input->set((float)get_int(b_sock.ptr, "default_value"));
|
||||
break;
|
||||
}
|
||||
case SHADER_SOCKET_COLOR: {
|
||||
input->set(float4_to_float3(get_float4(b_sock.ptr, "default_value")));
|
||||
break;
|
||||
}
|
||||
case SHADER_SOCKET_NORMAL:
|
||||
case SHADER_SOCKET_POINT:
|
||||
case SHADER_SOCKET_VECTOR: {
|
||||
input->set(get_float3(b_sock.ptr, "default_value"));
|
||||
break;
|
||||
}
|
||||
case SHADER_SOCKET_STRING: {
|
||||
input->set((ustring)blender_absolute_path(b_data, b_id, get_string(b_sock.ptr, "default_value")));
|
||||
break;
|
||||
}
|
||||
|
||||
case SHADER_SOCKET_CLOSURE:
|
||||
case SHADER_SOCKET_UNDEFINED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool node_use_modified_socket_name(ShaderNode *node)
|
||||
{
|
||||
if (node->special_type == SHADER_SPECIAL_TYPE_SCRIPT)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static ShaderInput *node_find_input_by_name(ShaderNode *node, BL::Node b_node, BL::NodeSocket b_socket)
|
||||
{
|
||||
string name = b_socket.name();
|
||||
|
||||
if (node_use_modified_socket_name(node)) {
|
||||
BL::Node::inputs_iterator b_input;
|
||||
bool found = false;
|
||||
int counter = 0, total = 0;
|
||||
|
||||
for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
|
||||
if (b_input->name() == name) {
|
||||
if (!found)
|
||||
counter++;
|
||||
total++;
|
||||
}
|
||||
|
||||
if(b_input->ptr.data == b_socket.ptr.data)
|
||||
found = true;
|
||||
}
|
||||
|
||||
/* rename if needed */
|
||||
if (name == "Shader")
|
||||
name = "Closure";
|
||||
|
||||
if (total > 1)
|
||||
name = string_printf("%s%d", name.c_str(), counter);
|
||||
}
|
||||
|
||||
return node->input(name.c_str());
|
||||
}
|
||||
|
||||
static ShaderOutput *node_find_output_by_name(ShaderNode *node, BL::Node b_node, BL::NodeSocket b_socket)
|
||||
{
|
||||
string name = b_socket.name();
|
||||
|
||||
if (node_use_modified_socket_name(node)) {
|
||||
BL::Node::outputs_iterator b_output;
|
||||
bool found = false;
|
||||
int counter = 0, total = 0;
|
||||
|
||||
for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
|
||||
if (b_output->name() == name) {
|
||||
if (!found)
|
||||
counter++;
|
||||
total++;
|
||||
}
|
||||
|
||||
if(b_output->ptr.data == b_socket.ptr.data)
|
||||
found = true;
|
||||
}
|
||||
|
||||
/* rename if needed */
|
||||
if (name == "Shader")
|
||||
name = "Closure";
|
||||
|
||||
if (total > 1)
|
||||
name = string_printf("%s%d", name.c_str(), counter);
|
||||
}
|
||||
|
||||
return node->output(name.c_str());
|
||||
}
|
||||
|
||||
static void add_nodes(BL::BlendData b_data, BL::NodeTree b_ntree, CameraNodesGraph *graph)
|
||||
{
|
||||
PtrInputMap input_map;
|
||||
PtrOutputMap output_map;
|
||||
|
||||
/* Synchronize nodes themselves. */
|
||||
BL::NodeTree::nodes_iterator b_node;
|
||||
for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
|
||||
ShaderNode *node = NULL;
|
||||
string type = b_node->bl_idname();
|
||||
/* TODO(sergey): Support node groups. */
|
||||
if(type == "PathAttributeNodeType") {
|
||||
node = new PathAttributeNode();
|
||||
}
|
||||
else if(type == "CameraSamplePerspectiveNodeType") {
|
||||
node = new SamplePerspectiveNode();
|
||||
}
|
||||
else if(type == "PolynomialDistortionNodeType") {
|
||||
PolynomialDistortionNode *distortion_node;
|
||||
node = distortion_node = new PolynomialDistortionNode();
|
||||
|
||||
distortion_node->k1 = get_float(b_node->ptr, "k1");
|
||||
distortion_node->k2 = get_float(b_node->ptr, "k2");
|
||||
distortion_node->k3 = get_float(b_node->ptr, "k3");
|
||||
distortion_node->invert = get_enum(b_node->ptr, "mode") == 1;
|
||||
}
|
||||
else if(type == "CameraRayOutputNodeType") {
|
||||
node = graph->output();
|
||||
}
|
||||
else {
|
||||
printf("Uknown camera node type: %s\n", type.c_str());
|
||||
/* Unknown node type, could happen when opening newer file in older
|
||||
* blender or the node has been deprecated/removed.
|
||||
*/
|
||||
}
|
||||
|
||||
if(node != NULL) {
|
||||
if(node != graph->output())
|
||||
graph->add(node);
|
||||
|
||||
/* Map node sockets for linking */
|
||||
BL::Node::inputs_iterator b_input;
|
||||
for(b_node->inputs.begin(b_input);
|
||||
b_input != b_node->inputs.end();
|
||||
++b_input)
|
||||
{
|
||||
ShaderInput *input = node_find_input_by_name(node,
|
||||
*b_node,
|
||||
*b_input);
|
||||
if(!input) {
|
||||
/* XXX should not happen, report error? */
|
||||
continue;
|
||||
}
|
||||
input_map[b_input->ptr.data] = input;
|
||||
|
||||
set_default_value(input, *b_node, *b_input, b_data, b_ntree);
|
||||
}
|
||||
|
||||
BL::Node::outputs_iterator b_output;
|
||||
for(b_node->outputs.begin(b_output);
|
||||
b_output != b_node->outputs.end();
|
||||
++b_output)
|
||||
{
|
||||
ShaderOutput *output = node_find_output_by_name(node,
|
||||
*b_node,
|
||||
*b_output);
|
||||
if(!output) {
|
||||
/* XXX should not happen, report error? */
|
||||
continue;
|
||||
}
|
||||
output_map[b_output->ptr.data] = output;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Connect nodes with noodles. */
|
||||
BL::NodeTree::links_iterator b_link;
|
||||
for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
|
||||
BL::NodeSocket b_from_sock = b_link->from_socket();
|
||||
BL::NodeSocket b_to_sock = b_link->to_socket();
|
||||
|
||||
ShaderOutput *output = 0;
|
||||
ShaderInput *input = 0;
|
||||
|
||||
PtrOutputMap::iterator output_it = output_map.find(b_from_sock.ptr.data);
|
||||
if(output_it != output_map.end())
|
||||
output = output_it->second;
|
||||
PtrInputMap::iterator input_it = input_map.find(b_to_sock.ptr.data);
|
||||
if(input_it != input_map.end())
|
||||
input = input_it->second;
|
||||
|
||||
/* Either node may be NULL when the node was not exported, typically
|
||||
* because the node type is not supported */
|
||||
if(output && input)
|
||||
graph->connect(output, input);
|
||||
}
|
||||
}
|
||||
|
||||
void BlenderSync::sync_camera_nodes(BL::Object b_ob)
|
||||
{
|
||||
if(!b_ob) {
|
||||
return;
|
||||
}
|
||||
|
||||
BL::ID b_ob_data = b_ob.data();
|
||||
assert(b_ob_data.is_a(&RNA_Camera));
|
||||
|
||||
BL::Camera b_camera(b_ob_data);
|
||||
PointerRNA ccamera = RNA_pointer_get(&b_ob_data.ptr, "cycles");
|
||||
string nodes_tree_name = get_string(ccamera, "nodes");
|
||||
|
||||
if(nodes_tree_name != "") {
|
||||
BL::NodeTree b_ntree = b_data.node_groups[nodes_tree_name];
|
||||
if (b_ntree) {
|
||||
progress.set_status("Synchronizing camera nodes", b_ntree.name());
|
||||
CameraNodesGraph *graph = new CameraNodesGraph();
|
||||
add_nodes(b_data, b_ntree, graph);
|
||||
scene->camera->set_graph(graph);
|
||||
progress.set_status("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BlenderSync::sync_view_nodes(BL::RegionView3D b_rv3d)
|
||||
{
|
||||
if(b_rv3d.view_perspective() ==
|
||||
BL::RegionView3D::view_perspective_CAMERA)
|
||||
{
|
||||
sync_camera_nodes(b_scene.camera());
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -62,7 +62,9 @@ public:
|
||||
void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer);
|
||||
void sync_integrator();
|
||||
void sync_camera(BL::RenderSettings b_render, BL::Object b_override, int width, int height);
|
||||
void sync_camera_nodes(BL::Object b_ob);
|
||||
void sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height);
|
||||
void sync_view_nodes(BL::RegionView3D b_rv3d);
|
||||
int get_layer_samples() { return render_layer.samples; }
|
||||
int get_layer_bound_samples() { return render_layer.bound_samples; }
|
||||
|
||||
|
@@ -16,6 +16,8 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device_noinline void svm_eval_camera_nodes(KernelGlobals *kg, CameraData *cd, ShaderType type);
|
||||
|
||||
/* Perspective Camera */
|
||||
|
||||
ccl_device float2 camera_sample_aperture(KernelGlobals *kg, float u, float v)
|
||||
@@ -296,6 +298,20 @@ ccl_device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, f
|
||||
ray->time = time;
|
||||
#endif
|
||||
|
||||
#ifdef __CAMERA_RAY_NODES__
|
||||
/* TODO(sergey): Add proper check for nodes tree here. */
|
||||
if(kernel_data.cam.shader != 0) {
|
||||
CameraData cd;
|
||||
cd.raster = make_float2(raster_x, raster_y);
|
||||
cd.lens = make_float2(lens_u, lens_v);
|
||||
cd.shader = kernel_data.cam.shader;
|
||||
cd.ray = *ray;
|
||||
svm_eval_camera_nodes(kg, &cd, SHADER_TYPE_CAMERA_RAY);
|
||||
*ray = cd.ray;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* sample */
|
||||
if(kernel_data.cam.type == CAMERA_PERSPECTIVE)
|
||||
camera_sample_perspective(kg, raster_x, raster_y, lens_u, lens_v, ray);
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include "util_math.h"
|
||||
#include "util_math_fast.h"
|
||||
#include "util_transform.h"
|
||||
#include "util_distort.h"
|
||||
|
||||
#endif /* __KERNEL_MATH_H__ */
|
||||
|
||||
|
@@ -74,6 +74,7 @@ CCL_NAMESPACE_BEGIN
|
||||
#define __VOLUME_SCATTER__
|
||||
#define __SHADOW_RECORD_ALL__
|
||||
#define __VOLUME_RECORD_ALL__
|
||||
#define __CAMERA_RAY_NODES__
|
||||
#endif
|
||||
|
||||
#ifdef __KERNEL_CUDA__
|
||||
@@ -795,6 +796,10 @@ typedef struct KernelCamera {
|
||||
float inv_aperture_ratio;
|
||||
|
||||
int is_inside_volume;
|
||||
int shader;
|
||||
|
||||
float focal_length;
|
||||
float pad[2];
|
||||
|
||||
/* more matrices */
|
||||
Transform screentoworld;
|
||||
@@ -999,6 +1004,13 @@ typedef struct KernelData {
|
||||
KernelTables tables;
|
||||
} KernelData;
|
||||
|
||||
typedef struct CameraData {
|
||||
float2 raster;
|
||||
float2 lens;
|
||||
Ray ray;
|
||||
int shader;
|
||||
} CameraData;
|
||||
|
||||
#ifdef __KERNEL_DEBUG__
|
||||
typedef ccl_addr_space struct DebugData {
|
||||
// Total number of BVH node traversal steps and primitives intersections
|
||||
|
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2011-2013 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
|
||||
*/
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Polynomial distortion */
|
||||
|
||||
ccl_device void svm_node_camera_polynomial_distortion(KernelGlobals *kg,
|
||||
CameraData *cd,
|
||||
uint4 node,
|
||||
float *stack,
|
||||
int *offset)
|
||||
{
|
||||
/* Read extra data. */
|
||||
uint4 node1 = read_node(kg, offset);
|
||||
const float k1 = __int_as_float(node.y);
|
||||
const float k2 = __int_as_float(node.z);
|
||||
const float k3 = __int_as_float(node.w);
|
||||
const int invert = __float_as_int(node1.y);
|
||||
const int raster_in_offset = node1.z;
|
||||
const int raster_out_offset =node1.w;
|
||||
const float focal_length = kernel_data.cam.focal_length *
|
||||
kernel_data.cam.width / kernel_data.cam.sensorwidth;
|
||||
|
||||
float2 raster_in, raster_out;
|
||||
raster_in = stack_load_float2(stack, raster_in_offset);
|
||||
|
||||
float2 principal_point = make_float2(kernel_data.cam.width * 0.5f,
|
||||
kernel_data.cam.height * 0.5f);
|
||||
|
||||
if(invert) {
|
||||
util_invert_polynomial_distortion(raster_in,
|
||||
focal_length,
|
||||
principal_point,
|
||||
k1, k2, k3,
|
||||
&raster_out);
|
||||
}
|
||||
else {
|
||||
util_apply_polynomial_distortion(raster_in,
|
||||
focal_length,
|
||||
principal_point,
|
||||
k1, k2, k3,
|
||||
&raster_out);
|
||||
}
|
||||
|
||||
stack_store_float2(stack, raster_out_offset, raster_out);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Path attribute node */
|
||||
|
||||
ccl_device void svm_camera_node_path_attribute(KernelGlobals *kg,
|
||||
CameraData *cd,
|
||||
float *stack,
|
||||
uint type,
|
||||
uint out_offset)
|
||||
{
|
||||
switch(type) {
|
||||
case NODE_CAMERA_PATH_ATTRIBUTE_RASTER:
|
||||
stack_store_float2(stack, out_offset, cd->raster);
|
||||
break;
|
||||
case NODE_CAMERA_PATH_ATTRIBUTE_LENS:
|
||||
stack_store_float2(stack, out_offset, cd->lens);
|
||||
break;
|
||||
case NODE_CAMERA_PATH_ATTRIBUTE_TIME:
|
||||
stack_store_float(stack, out_offset, cd->ray.time);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Ray output node */
|
||||
|
||||
ccl_device void svm_camera_node_ray_output(KernelGlobals *kg,
|
||||
CameraData *cd,
|
||||
float *stack,
|
||||
uint4 node)
|
||||
{
|
||||
uint ray_origin_offset, ray_direction_offset, ray_length_offset;
|
||||
uint time_offset;
|
||||
|
||||
decode_node_uchar4(node.y,
|
||||
&ray_origin_offset,
|
||||
&ray_direction_offset,
|
||||
&ray_length_offset,
|
||||
&time_offset);
|
||||
|
||||
cd->ray.P = stack_load_float3(stack, ray_origin_offset);
|
||||
cd->ray.D = stack_load_float3(stack, ray_direction_offset);
|
||||
cd->ray.t = stack_load_float(stack, ray_length_offset);
|
||||
cd->ray.time = stack_load_float(stack, time_offset);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Sample perspective node */
|
||||
|
||||
ccl_device void svm_camera_node_sample_perspective(KernelGlobals *kg,
|
||||
CameraData *cd,
|
||||
float *stack,
|
||||
uint4 node)
|
||||
{
|
||||
uint raster_offset, lens_offset, time_offset;
|
||||
decode_node_uchar4(node.y, &raster_offset, &lens_offset, &time_offset, NULL);
|
||||
|
||||
/* TODO(sergey): Make sure unconnected sockets are fine here. */
|
||||
float2 raster = stack_load_float2(stack, raster_offset);
|
||||
float2 lens = stack_load_float2(stack, lens_offset);
|
||||
Ray ray;
|
||||
if(stack_valid(time_offset)) {
|
||||
ray.time = stack_load_float(stack, time_offset);
|
||||
}
|
||||
else {
|
||||
ray.time = TIME_INVALID;
|
||||
}
|
||||
camera_sample_perspective(kg, raster.x, raster.y, lens.x, lens.y, &ray);
|
||||
|
||||
uint ray_origin_offset, ray_direction_offset, ray_length_offset;
|
||||
decode_node_uchar4(node.z,
|
||||
&ray_origin_offset,
|
||||
&ray_direction_offset,
|
||||
&ray_length_offset,
|
||||
NULL);
|
||||
|
||||
if(stack_valid(ray_origin_offset)) {
|
||||
stack_store_float3(stack, ray_origin_offset, ray.P);
|
||||
}
|
||||
if(stack_valid(ray_direction_offset)) {
|
||||
stack_store_float3(stack, ray_direction_offset, ray.D);
|
||||
}
|
||||
if(stack_valid(ray_length_offset)) {
|
||||
stack_store_float(stack, ray_length_offset, ray.t);
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -61,6 +61,21 @@ ccl_device_inline void stack_store_float3(float *stack, uint a, float3 f)
|
||||
stack[a+2] = f.z;
|
||||
}
|
||||
|
||||
ccl_device_inline float2 stack_load_float2(float *stack, uint a)
|
||||
{
|
||||
kernel_assert(a+1 < SVM_STACK_SIZE);
|
||||
|
||||
return make_float2(stack[a+0], stack[a+1]);
|
||||
}
|
||||
|
||||
ccl_device_inline void stack_store_float2(float *stack, uint a, float2 f)
|
||||
{
|
||||
kernel_assert(a+1 < SVM_STACK_SIZE);
|
||||
|
||||
stack[a+0] = f.x;
|
||||
stack[a+1] = f.y;
|
||||
}
|
||||
|
||||
ccl_device_inline float stack_load_float(float *stack, uint a)
|
||||
{
|
||||
kernel_assert(a < SVM_STACK_SIZE);
|
||||
@@ -467,5 +482,60 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __SVM_H__ */
|
||||
#ifdef __CAMERA_RAY_NODES__
|
||||
# include "camera_nodes/svm_camera_distortion.h"
|
||||
# include "camera_nodes/svm_camera_path_attribute.h"
|
||||
# include "camera_nodes/svm_camera_ray_output.h"
|
||||
# include "camera_nodes/svm_camera_sample_perspective.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device_noinline void svm_eval_camera_nodes(KernelGlobals *kg,
|
||||
CameraData *cd,
|
||||
ShaderType type)
|
||||
{
|
||||
float stack[SVM_STACK_SIZE];
|
||||
int offset = cd->shader & SHADER_MASK;
|
||||
|
||||
kernel_assert(type == SHADER_TYPE_CAMERA_RAY);
|
||||
|
||||
while(1) {
|
||||
uint4 node = read_node(kg, &offset);
|
||||
|
||||
switch(node.x) {
|
||||
case NODE_SHADER_JUMP: {
|
||||
if(type == SHADER_TYPE_CAMERA_RAY) offset = node.y;
|
||||
else return;
|
||||
break;
|
||||
}
|
||||
case NODE_CAMERA_PATH_ATTRIBUTE:
|
||||
svm_camera_node_path_attribute(kg, cd, stack, node.y, node.z);
|
||||
break;
|
||||
case NODE_CAMERA_SAMPLE_PERSPECTIVE:
|
||||
svm_camera_node_sample_perspective(kg, cd, stack, node);
|
||||
break;
|
||||
case NODE_CAMERA_RAY_OUTPUT:
|
||||
svm_camera_node_ray_output(kg, cd, stack, node);
|
||||
break;
|
||||
case NODE_CAMERA_POLYNOMIAL_DISTORTION:
|
||||
svm_node_camera_polynomial_distortion(kg, cd, node,
|
||||
stack, &offset);
|
||||
break;
|
||||
case NODE_VALUE_F:
|
||||
svm_node_value_f(kg, NULL, stack, node.y, node.z);
|
||||
break;
|
||||
case NODE_VALUE_V:
|
||||
svm_node_value_v(kg, NULL, stack, node.y, &offset);
|
||||
break;
|
||||
case NODE_END:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __SVM_H__ */
|
||||
|
@@ -127,6 +127,11 @@ typedef enum NodeType {
|
||||
NODE_HAIR_INFO,
|
||||
NODE_UVMAP,
|
||||
NODE_TEX_VOXEL,
|
||||
|
||||
NODE_CAMERA_PATH_ATTRIBUTE,
|
||||
NODE_CAMERA_SAMPLE_PERSPECTIVE,
|
||||
NODE_CAMERA_RAY_OUTPUT,
|
||||
NODE_CAMERA_POLYNOMIAL_DISTORTION,
|
||||
} NodeType;
|
||||
|
||||
typedef enum NodeAttributeType {
|
||||
@@ -358,7 +363,8 @@ typedef enum NodeTexVoxelSpace {
|
||||
typedef enum ShaderType {
|
||||
SHADER_TYPE_SURFACE,
|
||||
SHADER_TYPE_VOLUME,
|
||||
SHADER_TYPE_DISPLACEMENT
|
||||
SHADER_TYPE_DISPLACEMENT,
|
||||
SHADER_TYPE_CAMERA_RAY,
|
||||
} ShaderType;
|
||||
|
||||
/* Closure */
|
||||
@@ -419,6 +425,12 @@ typedef enum ClosureType {
|
||||
NBUILTIN_CLOSURES
|
||||
} ClosureType;
|
||||
|
||||
typedef enum NodePathAttribute {
|
||||
NODE_CAMERA_PATH_ATTRIBUTE_RASTER,
|
||||
NODE_CAMERA_PATH_ATTRIBUTE_LENS,
|
||||
NODE_CAMERA_PATH_ATTRIBUTE_TIME,
|
||||
} NodePathAttribute;
|
||||
|
||||
/* watch this, being lazy with memory usage */
|
||||
#define CLOSURE_IS_BSDF(type) (type <= CLOSURE_BSDF_TRANSPARENT_ID)
|
||||
#define CLOSURE_IS_BSDF_DIFFUSE(type) (type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_DIFFUSE_TOON_ID)
|
||||
|
@@ -20,6 +20,7 @@ set(SRC
|
||||
bake.cpp
|
||||
buffers.cpp
|
||||
camera.cpp
|
||||
camera_nodes.cpp
|
||||
film.cpp
|
||||
graph.cpp
|
||||
image.cpp
|
||||
@@ -48,6 +49,7 @@ set(SRC_HEADERS
|
||||
background.h
|
||||
buffers.h
|
||||
camera.h
|
||||
camera_nodes.h
|
||||
film.h
|
||||
graph.h
|
||||
image.h
|
||||
|
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
|
||||
#include "camera.h"
|
||||
#include "graph.h"
|
||||
#include "mesh.h"
|
||||
#include "nodes.h"
|
||||
#include "object.h"
|
||||
#include "scene.h"
|
||||
|
||||
@@ -84,10 +86,13 @@ Camera::Camera()
|
||||
need_device_update = true;
|
||||
need_flags_update = true;
|
||||
previous_need_motion = -1;
|
||||
|
||||
graph = NULL;
|
||||
}
|
||||
|
||||
Camera::~Camera()
|
||||
{
|
||||
delete graph;
|
||||
}
|
||||
|
||||
void Camera::compute_auto_viewplane()
|
||||
@@ -316,6 +321,17 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
|
||||
kcam->is_inside_volume = 0;
|
||||
|
||||
previous_need_motion = need_motion;
|
||||
|
||||
/* focal length */
|
||||
kcam->focal_length = focal_length;
|
||||
|
||||
/* TODO(sergey): Make sure shaders are fully synced at this point. */
|
||||
if(graph != NULL) {
|
||||
kcam->shader = scene->shader_manager->get_shader_id(scene->shaders.size());
|
||||
}
|
||||
else {
|
||||
kcam->shader = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::device_update_volume(Device * /*device*/,
|
||||
@@ -355,6 +371,7 @@ bool Camera::modified(const Camera& cam)
|
||||
(focaldistance == cam.focaldistance) &&
|
||||
(type == cam.type) &&
|
||||
(fov == cam.fov) &&
|
||||
(focal_length == cam.focal_length) &&
|
||||
(nearclip == cam.nearclip) &&
|
||||
(farclip == cam.farclip) &&
|
||||
(sensorwidth == cam.sensorwidth) &&
|
||||
@@ -444,4 +461,14 @@ BoundBox Camera::viewplane_bounds_get()
|
||||
return bounds;
|
||||
}
|
||||
|
||||
void Camera::set_graph(CameraNodesGraph *graph_)
|
||||
{
|
||||
if(graph_) {
|
||||
graph_->remove_unneeded_nodes();
|
||||
}
|
||||
|
||||
delete graph;
|
||||
graph = graph_;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -28,6 +28,7 @@ CCL_NAMESPACE_BEGIN
|
||||
class Device;
|
||||
class DeviceScene;
|
||||
class Scene;
|
||||
class CameraNodesGraph;
|
||||
|
||||
/* Camera
|
||||
*
|
||||
@@ -48,6 +49,7 @@ public:
|
||||
/* type */
|
||||
CameraType type;
|
||||
float fov;
|
||||
float focal_length;
|
||||
|
||||
/* panorama */
|
||||
PanoramaType panorama_type;
|
||||
@@ -110,12 +112,17 @@ public:
|
||||
bool need_flags_update;
|
||||
int previous_need_motion;
|
||||
|
||||
/* Camera ray nodes. */
|
||||
CameraNodesGraph *graph;
|
||||
|
||||
/* functions */
|
||||
Camera();
|
||||
~Camera();
|
||||
|
||||
void compute_auto_viewplane();
|
||||
|
||||
void set_graph(CameraNodesGraph *graph);
|
||||
|
||||
void update();
|
||||
|
||||
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
|
||||
|
187
intern/cycles/render/camera_nodes.cpp
Normal file
187
intern/cycles/render/camera_nodes.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "nodes.h"
|
||||
#include "camera_nodes.h"
|
||||
#include "svm.h"
|
||||
#include "osl.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Path attribute */
|
||||
|
||||
PathAttributeNode::PathAttributeNode()
|
||||
: ShaderNode("path_attribute")
|
||||
{
|
||||
add_output("Raster", SHADER_SOCKET_VECTOR);
|
||||
add_output("Lens", SHADER_SOCKET_VECTOR);
|
||||
add_output("Time", SHADER_SOCKET_FLOAT);
|
||||
}
|
||||
|
||||
void PathAttributeNode::compile(SVMCompiler& compiler)
|
||||
{
|
||||
ShaderOutput *out;
|
||||
|
||||
out = output("Raster");
|
||||
if(!out->links.empty()) {
|
||||
compiler.stack_assign(out);
|
||||
compiler.add_node(NODE_CAMERA_PATH_ATTRIBUTE,
|
||||
NODE_CAMERA_PATH_ATTRIBUTE_RASTER,
|
||||
out->stack_offset);
|
||||
}
|
||||
|
||||
out = output("Lens");
|
||||
if(!out->links.empty()) {
|
||||
compiler.stack_assign(out);
|
||||
compiler.add_node(NODE_CAMERA_PATH_ATTRIBUTE,
|
||||
NODE_CAMERA_PATH_ATTRIBUTE_LENS,
|
||||
out->stack_offset);
|
||||
}
|
||||
|
||||
out = output("Time");
|
||||
if(!out->links.empty()) {
|
||||
compiler.stack_assign(out);
|
||||
compiler.add_node(NODE_CAMERA_PATH_ATTRIBUTE,
|
||||
NODE_CAMERA_PATH_ATTRIBUTE_TIME,
|
||||
out->stack_offset);
|
||||
}
|
||||
}
|
||||
|
||||
void PathAttributeNode::compile(OSLCompiler& compiler)
|
||||
{
|
||||
}
|
||||
|
||||
/* Sample perspective */
|
||||
|
||||
SamplePerspectiveNode::SamplePerspectiveNode()
|
||||
: ShaderNode("sample_perspective")
|
||||
{
|
||||
add_input("Raster", SHADER_SOCKET_VECTOR);
|
||||
add_input("Lens", SHADER_SOCKET_VECTOR);
|
||||
add_input("Time", SHADER_SOCKET_FLOAT);
|
||||
add_output("Ray Origin", SHADER_SOCKET_VECTOR);
|
||||
add_output("Ray Direction", SHADER_SOCKET_VECTOR);
|
||||
add_output("Ray Length", SHADER_SOCKET_FLOAT);
|
||||
}
|
||||
|
||||
void SamplePerspectiveNode::compile(SVMCompiler& compiler)
|
||||
{
|
||||
ShaderInput *raster_in = input("Raster");
|
||||
ShaderInput *lens_in = input("Lens");
|
||||
ShaderInput *time_in = input("Time");
|
||||
ShaderOutput *ray_origin_out = output("Ray Origin");
|
||||
ShaderOutput *ray_direction_out = output("Ray Direction");
|
||||
ShaderOutput *ray_length_out = output("Ray Length");
|
||||
|
||||
if(raster_in->link) {
|
||||
compiler.stack_assign(raster_in);
|
||||
}
|
||||
if(lens_in->link) {
|
||||
compiler.stack_assign(lens_in);
|
||||
}
|
||||
if(time_in->link) {
|
||||
compiler.stack_assign(time_in);
|
||||
}
|
||||
if(!ray_origin_out->links.empty()) {
|
||||
compiler.stack_assign(ray_origin_out);
|
||||
}
|
||||
if(!ray_direction_out->links.empty()) {
|
||||
compiler.stack_assign(ray_direction_out);
|
||||
}
|
||||
if(!ray_length_out->links.empty()) {
|
||||
compiler.stack_assign(ray_length_out);
|
||||
}
|
||||
|
||||
compiler.add_node(NODE_CAMERA_SAMPLE_PERSPECTIVE,
|
||||
compiler.encode_uchar4(raster_in->stack_offset,
|
||||
lens_in->stack_offset,
|
||||
time_in->stack_offset, 0),
|
||||
compiler.encode_uchar4(ray_origin_out->stack_offset,
|
||||
ray_direction_out->stack_offset,
|
||||
ray_length_out->stack_offset,
|
||||
0));
|
||||
}
|
||||
|
||||
void SamplePerspectiveNode::compile(OSLCompiler& compiler)
|
||||
{
|
||||
}
|
||||
|
||||
/* Polynomial distortion node. */
|
||||
|
||||
PolynomialDistortionNode::PolynomialDistortionNode()
|
||||
: ShaderNode("polynomial_distortion"),
|
||||
k1(0.0f), k2(0.0f), k3(0.0f),
|
||||
invert(false)
|
||||
{
|
||||
add_input("Raster", SHADER_SOCKET_VECTOR);
|
||||
add_output("Raster", SHADER_SOCKET_VECTOR);
|
||||
}
|
||||
|
||||
void PolynomialDistortionNode::compile(SVMCompiler& compiler)
|
||||
{
|
||||
ShaderInput *raster_in = input("Raster");
|
||||
ShaderOutput *raster_out = output("Raster");
|
||||
|
||||
compiler.stack_assign(raster_in);
|
||||
compiler.stack_assign(raster_out);
|
||||
|
||||
float3 encoded_distortion = make_float3(k1, k2, k3);
|
||||
compiler.add_node(NODE_CAMERA_POLYNOMIAL_DISTORTION, encoded_distortion);
|
||||
compiler.add_node(NODE_CAMERA_POLYNOMIAL_DISTORTION,
|
||||
(int)invert,
|
||||
raster_in->stack_offset,
|
||||
raster_out->stack_offset);
|
||||
}
|
||||
|
||||
void PolynomialDistortionNode::compile(OSLCompiler& compiler)
|
||||
{
|
||||
}
|
||||
|
||||
/* Camera Ray Output */
|
||||
|
||||
RayOutputNode::RayOutputNode()
|
||||
: ShaderNode("ray_output")
|
||||
{
|
||||
add_input("Ray Origin", SHADER_SOCKET_VECTOR);
|
||||
add_input("Ray Direction", SHADER_SOCKET_VECTOR);
|
||||
add_input("Ray Length", SHADER_SOCKET_FLOAT);
|
||||
add_input("Time", SHADER_SOCKET_FLOAT);
|
||||
}
|
||||
|
||||
void RayOutputNode::compile(SVMCompiler& compiler)
|
||||
{
|
||||
ShaderInput *ray_origin_in = input("Ray Origin");
|
||||
ShaderInput *ray_direction_in = input("Ray Direction");
|
||||
ShaderInput *ray_length_in = input("Ray Length");
|
||||
ShaderInput *time_in = input("Time");
|
||||
|
||||
compiler.stack_assign(ray_origin_in);
|
||||
compiler.stack_assign(ray_direction_in);
|
||||
compiler.stack_assign(ray_length_in);
|
||||
compiler.stack_assign(time_in);
|
||||
|
||||
compiler.add_node(NODE_CAMERA_RAY_OUTPUT,
|
||||
compiler.encode_uchar4(ray_origin_in->stack_offset,
|
||||
ray_direction_in->stack_offset,
|
||||
ray_length_in->stack_offset,
|
||||
time_in->stack_offset));
|
||||
}
|
||||
|
||||
void RayOutputNode::compile(OSLCompiler& compiler)
|
||||
{
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
49
intern/cycles/render/camera_nodes.h
Normal file
49
intern/cycles/render/camera_nodes.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __CAMERA_NODES_H__
|
||||
#define __CAMERA_NODES_H__
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* TODO(sergey): Add a petter suitable name. */
|
||||
class PathAttributeNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(PathAttributeNode)
|
||||
};
|
||||
|
||||
class SamplePerspectiveNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(SamplePerspectiveNode)
|
||||
};
|
||||
|
||||
class PolynomialDistortionNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(PolynomialDistortionNode)
|
||||
|
||||
/* Third order polynomial distortion coefficients. */
|
||||
float k1, k2, k3;
|
||||
bool invert;
|
||||
};
|
||||
|
||||
class RayOutputNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(RayOutputNode)
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __CAMERA_NODES_H__ */
|
@@ -17,6 +17,7 @@
|
||||
#include "attribute.h"
|
||||
#include "graph.h"
|
||||
#include "nodes.h"
|
||||
#include "camera_nodes.h"
|
||||
#include "shader.h"
|
||||
|
||||
#include "util_algorithm.h"
|
||||
@@ -968,5 +969,27 @@ void ShaderGraph::dump_graph(const char *filename)
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
/* CameraNodesGraph */
|
||||
|
||||
CameraNodesGraph::CameraNodesGraph()
|
||||
{
|
||||
finalized = false;
|
||||
num_node_ids = 0;
|
||||
|
||||
/* TODO(sergey): Ideally we just don't want parent constructor
|
||||
* to be called from this class.
|
||||
*/
|
||||
foreach(ShaderNode *node, nodes)
|
||||
delete node;
|
||||
nodes.clear();
|
||||
|
||||
add(new RayOutputNode());
|
||||
}
|
||||
|
||||
RayOutputNode *CameraNodesGraph::output()
|
||||
{
|
||||
return (RayOutputNode*)nodes.front();
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
|
@@ -37,6 +37,7 @@ class ShaderGraph;
|
||||
class SVMCompiler;
|
||||
class OSLCompiler;
|
||||
class OutputNode;
|
||||
class RayOutputNode;
|
||||
|
||||
/* Socket Type
|
||||
*
|
||||
@@ -292,6 +293,13 @@ protected:
|
||||
void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume);
|
||||
};
|
||||
|
||||
/* Graph of camera ray nodes. */
|
||||
class CameraNodesGraph : public ShaderGraph {
|
||||
public:
|
||||
CameraNodesGraph();
|
||||
RayOutputNode *output();
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __GRAPH_H__ */
|
||||
|
@@ -14,11 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "camera.h"
|
||||
#include "device.h"
|
||||
#include "graph.h"
|
||||
#include "light.h"
|
||||
#include "mesh.h"
|
||||
#include "nodes.h"
|
||||
#include "camera_nodes.h"
|
||||
#include "scene.h"
|
||||
#include "shader.h"
|
||||
#include "svm.h"
|
||||
@@ -65,7 +67,12 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
|
||||
svm_nodes.push_back(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
|
||||
svm_nodes.push_back(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
if(scene->camera->graph != NULL) {
|
||||
svm_nodes.push_back(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
|
||||
svm_nodes.push_back(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
|
||||
}
|
||||
|
||||
for(i = 0; i < scene->shaders.size(); i++) {
|
||||
Shader *shader = scene->shaders[i];
|
||||
|
||||
@@ -81,6 +88,12 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
|
||||
compiler.compile(shader, svm_nodes, i);
|
||||
}
|
||||
|
||||
if(scene->camera->graph != NULL) {
|
||||
SVMCompiler compiler(scene->shader_manager, scene->image_manager);
|
||||
compiler.background = false;
|
||||
compiler.compile(scene->camera, svm_nodes, scene->shaders.size());
|
||||
}
|
||||
|
||||
dscene->svm_nodes.copy((uint4*)&svm_nodes[0], svm_nodes.size());
|
||||
device->tex_alloc("__svm_nodes", dscene->svm_nodes);
|
||||
|
||||
@@ -691,6 +704,36 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
|
||||
add_node(NODE_END, 0, 0, 0);
|
||||
}
|
||||
|
||||
void SVMCompiler::compile_type(Camera *camera,
|
||||
CameraNodesGraph *graph)
|
||||
{
|
||||
current_type = SHADER_TYPE_CAMERA_RAY;
|
||||
current_graph = graph;
|
||||
|
||||
/* Clear all compiler state. */
|
||||
memset(&active_stack, 0, sizeof(active_stack));
|
||||
svm_nodes.clear();
|
||||
|
||||
foreach(ShaderNode *node_iter, graph->nodes) {
|
||||
foreach(ShaderInput *input, node_iter->inputs)
|
||||
input->stack_offset = SVM_STACK_INVALID;
|
||||
foreach(ShaderOutput *output, node_iter->outputs)
|
||||
output->stack_offset = SVM_STACK_INVALID;
|
||||
}
|
||||
|
||||
RayOutputNode *node = graph->output();
|
||||
set<ShaderNode*> done, closure_done;
|
||||
generate_multi_closure(node, node, done, closure_done);
|
||||
|
||||
/* If compile failed, generate empty shader. */
|
||||
if(compile_failed) {
|
||||
svm_nodes.clear();
|
||||
compile_failed = false;
|
||||
}
|
||||
|
||||
add_node(NODE_END, 0, 0, 0);
|
||||
}
|
||||
|
||||
void SVMCompiler::compile(Shader *shader, vector<int4>& global_svm_nodes, int index)
|
||||
{
|
||||
/* copy graph for shader with bump mapping */
|
||||
@@ -742,5 +785,22 @@ void SVMCompiler::compile(Shader *shader, vector<int4>& global_svm_nodes, int in
|
||||
global_svm_nodes.insert(global_svm_nodes.end(), svm_nodes.begin(), svm_nodes.end());
|
||||
}
|
||||
|
||||
void SVMCompiler::compile(Camera *camera,
|
||||
vector<int4>& global_svm_nodes,
|
||||
int index)
|
||||
{
|
||||
/* Finalize the graph. */
|
||||
/* TODO(sergey): Finalization is currently working for shader nodes only. */
|
||||
/* camera->graph->finalize(false, false); */
|
||||
|
||||
/* Generate camera nodes to SVM nodes. */
|
||||
compile_type(camera, camera->graph);
|
||||
global_svm_nodes[index*2 + 0].y = global_svm_nodes.size();
|
||||
global_svm_nodes[index*2 + 1].y = global_svm_nodes.size();
|
||||
global_svm_nodes.insert(global_svm_nodes.end(),
|
||||
svm_nodes.begin(),
|
||||
svm_nodes.end());
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
|
@@ -26,6 +26,8 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class Camera;
|
||||
class CameraNodesGraph;
|
||||
class Device;
|
||||
class DeviceScene;
|
||||
class ImageManager;
|
||||
@@ -54,6 +56,7 @@ class SVMCompiler {
|
||||
public:
|
||||
SVMCompiler(ShaderManager *shader_manager, ImageManager *image_manager);
|
||||
void compile(Shader *shader, vector<int4>& svm_nodes, int index);
|
||||
void compile(Camera *camera, vector<int4>& svm_nodes, int index);
|
||||
|
||||
void stack_assign(ShaderOutput *output);
|
||||
void stack_assign(ShaderInput *input);
|
||||
@@ -141,6 +144,7 @@ protected:
|
||||
|
||||
/* compile */
|
||||
void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);
|
||||
void compile_type(Camera *camera, CameraNodesGraph *graph);
|
||||
|
||||
vector<int4> svm_nodes;
|
||||
ShaderType current_type;
|
||||
|
77
intern/cycles/util/util_distort.h
Normal file
77
intern/cycles/util/util_distort.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_DISTORT_H__
|
||||
#define __UTIL_DISTORT_H__
|
||||
|
||||
#ifdef WITH_CYCLES_DISTORTION
|
||||
# include "libmv/simple_pipeline/distortion_models.h"
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device void util_apply_polynomial_distortion(const float2 image,
|
||||
const float focal_length,
|
||||
const float2 principal_point,
|
||||
const float k1,
|
||||
const float k2,
|
||||
const float k3,
|
||||
float2 *result)
|
||||
{
|
||||
#if defined(WITH_CYCLES_DISTORTION) && !defined(__KERNEL_GPU__)
|
||||
double normalized_x = (image.x - principal_point.x) / focal_length;
|
||||
double normalized_y = (image.y - principal_point.y) / focal_length;
|
||||
double image_x, image_y;
|
||||
libmv::InvertPolynomialDistortionModel(focal_length, focal_length,
|
||||
normalized_x, normalized_y,
|
||||
k1, k2, k3,
|
||||
0.0, 0.0,
|
||||
image.x, image.y,
|
||||
&image_x, &image_y);
|
||||
result->x = image_x;
|
||||
result->y = image_y;
|
||||
#else
|
||||
*result = image;
|
||||
#endif
|
||||
}
|
||||
|
||||
ccl_device void util_invert_polynomial_distortion(const float2 image,
|
||||
const float focal_length,
|
||||
const float2 principal_point,
|
||||
const float k1,
|
||||
const float k2,
|
||||
const float k3,
|
||||
float2 *result)
|
||||
{
|
||||
#if defined(WITH_CYCLES_DISTORTION) && !defined(__KERNEL_GPU__)
|
||||
double normalized_x, normalized_y;
|
||||
libmv::InvertPolynomialDistortionModel(focal_length, focal_length,
|
||||
principal_point.x, principal_point.y,
|
||||
k1, k2, k3,
|
||||
0.0, 0.0,
|
||||
image.x, image.y,
|
||||
&normalized_x,
|
||||
&normalized_y);
|
||||
result->x = normalized_x * (double)focal_length + (double)principal_point.x;
|
||||
result->y = normalized_y * (double)focal_length + (double)principal_point.y;
|
||||
#else
|
||||
*result = image;
|
||||
#endif
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __UTIL_DISTORT_H__ */
|
Reference in New Issue
Block a user