Cycles: tweaks to properties and nodes
* Passes renamed to samples * Camera lens radius renamed to aperature size/blades/rotation * Glass and fresnel nodes input is now index of refraction * Glossy and velvet fresnel socket removed * Mix/add closure node renamed to mix/add shader node * Blend weight node added for shader mixing weights There is some version patching code for reading existing files, but it's not perfect, so shaders may work a bit different.
This commit is contained in:
@@ -66,26 +66,26 @@ static void session_print(const string& str)
|
||||
|
||||
static void session_print_status()
|
||||
{
|
||||
int pass;
|
||||
double total_time, pass_time;
|
||||
int sample;
|
||||
double total_time, sample_time;
|
||||
string status, substatus;
|
||||
|
||||
/* get status */
|
||||
options.session->progress.get_pass(pass, total_time, pass_time);
|
||||
options.session->progress.get_sample(sample, total_time, sample_time);
|
||||
options.session->progress.get_status(status, substatus);
|
||||
|
||||
if(substatus != "")
|
||||
status += ": " + substatus;
|
||||
|
||||
/* print status */
|
||||
status = string_printf("Pass %d %s", pass, status.c_str());
|
||||
status = string_printf("Sample %d %s", sample, status.c_str());
|
||||
session_print(status);
|
||||
}
|
||||
|
||||
static void session_init()
|
||||
{
|
||||
options.session = new Session(options.session_params);
|
||||
options.session->reset(options.width, options.height, options.session_params.passes);
|
||||
options.session->reset(options.width, options.height, options.session_params.samples);
|
||||
options.session->scene = options.scene;
|
||||
|
||||
if(options.session_params.background && !options.quiet)
|
||||
@@ -133,18 +133,18 @@ static void display_info(Progress& progress)
|
||||
latency = (elapsed - last);
|
||||
last = elapsed;
|
||||
|
||||
int pass;
|
||||
double total_time, pass_time;
|
||||
int sample;
|
||||
double total_time, sample_time;
|
||||
string status, substatus;
|
||||
|
||||
progress.get_pass(pass, total_time, pass_time);
|
||||
progress.get_sample(sample, total_time, sample_time);
|
||||
progress.get_status(status, substatus);
|
||||
|
||||
if(substatus != "")
|
||||
status += ": " + substatus;
|
||||
|
||||
str = string_printf("latency: %.4f pass: %d total: %.4f average: %.4f %s",
|
||||
latency, pass, total_time, pass_time, status.c_str());
|
||||
str = string_printf("latency: %.4f sample: %d total: %.4f average: %.4f %s",
|
||||
latency, sample, total_time, sample_time, status.c_str());
|
||||
|
||||
view_display_info(str.c_str());
|
||||
}
|
||||
@@ -162,13 +162,13 @@ static void resize(int width, int height)
|
||||
options.height= height;
|
||||
|
||||
if(options.session)
|
||||
options.session->reset(options.width, options.height, options.session_params.passes);
|
||||
options.session->reset(options.width, options.height, options.session_params.samples);
|
||||
}
|
||||
|
||||
void keyboard(unsigned char key)
|
||||
{
|
||||
if(key == 'r')
|
||||
options.session->reset(options.width, options.height, options.session_params.passes);
|
||||
options.session->reset(options.width, options.height, options.session_params.samples);
|
||||
else if(key == 27) // escape
|
||||
options.session->progress.set_cancel("Cancelled");
|
||||
}
|
||||
@@ -220,7 +220,7 @@ static void options_parse(int argc, const char **argv)
|
||||
"--shadingsys %s", &ssname, "Shading system to use: svm, osl",
|
||||
"--background", &options.session_params.background, "Render in background, without user interface",
|
||||
"--quiet", &options.quiet, "In background mode, don't print progress messages",
|
||||
"--passes %d", &options.session_params.passes, "Number of passes to render",
|
||||
"--samples %d", &options.session_params.samples, "Number of samples to render",
|
||||
"--output %s", &options.session_params.output_path, "File path to write output image",
|
||||
"--threads %d", &options.session_params.threads, "CPU Rendering Threads",
|
||||
"--help", &help, "Print help message",
|
||||
@@ -266,8 +266,8 @@ static void options_parse(int argc, const char **argv)
|
||||
fprintf(stderr, "OSL shading system only works with CPU device\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else if(options.session_params.passes < 0) {
|
||||
fprintf(stderr, "Invalid number of passes: %d\n", options.session_params.passes);
|
||||
else if(options.session_params.samples < 0) {
|
||||
fprintf(stderr, "Invalid number of samples: %d\n", options.session_params.samples);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else if(options.filepath == "") {
|
||||
|
||||
@@ -272,7 +272,7 @@ static void xml_read_camera(const XMLReadState& state, pugi::xml_node node)
|
||||
|
||||
xml_read_float(&cam->nearclip, node, "nearclip");
|
||||
xml_read_float(&cam->farclip, node, "farclip");
|
||||
xml_read_float(&cam->lensradius, node, "lensradius"); // 0.5*focallength/fstop
|
||||
xml_read_float(&cam->aperturesize, node, "aperturesize"); // 0.5*focallength/fstop
|
||||
xml_read_float(&cam->focaldistance, node, "focaldistance");
|
||||
xml_read_float(&cam->shutteropen, node, "shutteropen");
|
||||
xml_read_float(&cam->shutterclose, node, "shutterclose");
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
import bpy
|
||||
from bpy.props import *
|
||||
|
||||
import math
|
||||
|
||||
from cycles import enums
|
||||
|
||||
class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
@@ -35,9 +37,9 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
cls.shading_system = EnumProperty(name="Shading System", description="Shading system to use for rendering",
|
||||
items=enums.shading_systems, default="GPU_COMPATIBLE")
|
||||
|
||||
cls.passes = IntProperty(name="Passes", description="Number of passes to render",
|
||||
cls.samples = IntProperty(name="Samples", description="Number of samples to render for each pixel",
|
||||
default=10, min=1, max=2147483647)
|
||||
cls.preview_passes = IntProperty(name="Preview Passes", description="Number of passes to render in the viewport, unlimited if 0",
|
||||
cls.preview_samples = IntProperty(name="Preview Samples", description="Number of samples to render in the viewport, unlimited if 0",
|
||||
default=0, min=0, max=2147483647)
|
||||
cls.preview_pause = BoolProperty(name="Pause Preview", description="Pause all viewport preview renders",
|
||||
default=False)
|
||||
@@ -99,8 +101,12 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
|
||||
def register(cls):
|
||||
bpy.types.Camera.cycles = PointerProperty(type=cls, name="Cycles Camera Settings", description="Cycles camera settings")
|
||||
|
||||
cls.lens_radius = FloatProperty(name="Lens radius", description="Lens radius for depth of field",
|
||||
cls.aperture_size = FloatProperty(name="Aperture Size", description="Radius of the aperture for depth of field",
|
||||
default=0.0, min=0.0, max=10.0)
|
||||
cls.aperture_blades = IntProperty(name="Aperture Blades", description="Number of blades in aperture for polygonal bokeh (need 3 or more)",
|
||||
default=0, min=0, max=100)
|
||||
cls.aperture_rotation = FloatProperty(name="Aperture Rotation", description="Rotation of blades in aperture",
|
||||
default=0, soft_min=-math.pi, soft_max=math.pi, subtype='ANGLE')
|
||||
|
||||
@classmethod
|
||||
def unregister(cls):
|
||||
|
||||
@@ -59,9 +59,9 @@ class CyclesRender_PT_integrator(CyclesButtonsPanel, Panel):
|
||||
|
||||
col = split.column()
|
||||
sub = col.column(align=True)
|
||||
sub.label(text="Passes:")
|
||||
sub.prop(cscene, "passes", text="Render")
|
||||
sub.prop(cscene, "preview_passes", text="Preview")
|
||||
sub.label(text="Samples:")
|
||||
sub.prop(cscene, "samples", text="Render")
|
||||
sub.prop(cscene, "preview_samples", text="Preview")
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.label("Tranparency:")
|
||||
@@ -194,21 +194,38 @@ class Cycles_PT_post_processing(CyclesButtonsPanel, Panel):
|
||||
col = split.column()
|
||||
col.prop(rd, "dither_intensity", text="Dither", slider=True)
|
||||
|
||||
class Cycles_PT_camera(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Cycles"
|
||||
class CyclesCamera_PT_dof(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Depth of Field"
|
||||
bl_context = "data"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.camera
|
||||
return context.camera and CyclesButtonsPanel.poll(context)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
camera = context.camera
|
||||
ccamera = camera.cycles
|
||||
cam = context.camera
|
||||
ccam = cam.cycles
|
||||
|
||||
layout.prop(ccamera, "lens_radius")
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.label("Focus:")
|
||||
col.prop(cam, "dof_object", text="")
|
||||
|
||||
sub = col.row()
|
||||
sub.active = cam.dof_object is None
|
||||
sub.prop(cam, "dof_distance", text="Distance")
|
||||
|
||||
col = split.column()
|
||||
|
||||
col.label("Aperture:")
|
||||
col.prop(ccam, "aperture_size", text="Size")
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.prop(ccam, "aperture_blades", text="Blades")
|
||||
sub.prop(ccam, "aperture_rotation", text="Rotation")
|
||||
|
||||
class Cycles_PT_context_material(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Surface"
|
||||
@@ -550,7 +567,7 @@ class CyclesTexture_PT_color(CyclesButtonsPanel, Panel):
|
||||
layout = self.layout
|
||||
layout.label("Color modification options go here.");
|
||||
layout.label("Ramp, brightness, contrast, saturation.")
|
||||
|
||||
|
||||
def draw_device(self, context):
|
||||
scene = context.scene
|
||||
layout = self.layout
|
||||
|
||||
@@ -35,7 +35,10 @@ struct BlenderCamera {
|
||||
float ortho_scale;
|
||||
|
||||
float lens;
|
||||
float lensradius;
|
||||
|
||||
float aperturesize;
|
||||
uint apertureblades;
|
||||
float aperturerotation;
|
||||
float focaldistance;
|
||||
|
||||
float2 shift;
|
||||
@@ -90,7 +93,9 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob)
|
||||
bcam->ortho_scale = b_camera.ortho_scale();
|
||||
|
||||
bcam->lens = b_camera.lens();
|
||||
bcam->lensradius = RNA_float_get(&ccamera, "lens_radius");
|
||||
bcam->aperturesize = RNA_float_get(&ccamera, "aperture_size");
|
||||
bcam->apertureblades = RNA_int_get(&ccamera, "aperture_blades");
|
||||
bcam->aperturerotation = RNA_float_get(&ccamera, "aperture_rotation");
|
||||
bcam->focaldistance = blender_camera_focal_distance(b_ob, b_camera);
|
||||
|
||||
bcam->shift.x = b_camera.shift_x();
|
||||
@@ -162,7 +167,9 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
|
||||
/* perspective */
|
||||
cam->fov = 2.0f*atan(16.0f/bcam->lens/aspectratio);
|
||||
cam->focaldistance = bcam->focaldistance;
|
||||
cam->lensradius = bcam->lensradius;
|
||||
cam->aperturesize = bcam->aperturesize;
|
||||
cam->blades = bcam->apertureblades;
|
||||
cam->bladesrotation = bcam->aperturerotation;
|
||||
|
||||
/* transform, note the blender camera points along the negative z-axis */
|
||||
cam->matrix = bcam->matrix * transform_scale(1.0f, 1.0f, -1.0f);
|
||||
|
||||
@@ -96,7 +96,7 @@ void BlenderSession::create_session()
|
||||
session->set_pause(BlenderSync::get_session_pause(b_scene, background));
|
||||
|
||||
/* start rendering */
|
||||
session->reset(width, height, session_params.passes);
|
||||
session->reset(width, height, session_params.samples);
|
||||
session->start();
|
||||
}
|
||||
|
||||
@@ -122,11 +122,11 @@ void BlenderSession::write_render_result()
|
||||
/* get result */
|
||||
RenderBuffers *buffers = session->buffers;
|
||||
float exposure = scene->film->exposure;
|
||||
double total_time, pass_time;
|
||||
int pass;
|
||||
session->progress.get_pass(pass, total_time, pass_time);
|
||||
double total_time, sample_time;
|
||||
int sample;
|
||||
session->progress.get_sample(sample, total_time, sample_time);
|
||||
|
||||
float4 *pixels = buffers->copy_from_device(exposure, pass);
|
||||
float4 *pixels = buffers->copy_from_device(exposure, sample);
|
||||
|
||||
if(!pixels)
|
||||
return;
|
||||
@@ -158,8 +158,8 @@ void BlenderSession::synchronize()
|
||||
return;
|
||||
}
|
||||
|
||||
/* increase passes, but never decrease */
|
||||
session->set_passes(session_params.passes);
|
||||
/* increase samples, but never decrease */
|
||||
session->set_samples(session_params.samples);
|
||||
session->set_pause(BlenderSync::get_session_pause(b_scene, background));
|
||||
|
||||
/* copy recalc flags, outside of mutex so we can decide to do the real
|
||||
@@ -185,7 +185,7 @@ void BlenderSession::synchronize()
|
||||
|
||||
/* reset if needed */
|
||||
if(scene->need_reset())
|
||||
session->reset(width, height, session_params.passes);
|
||||
session->reset(width, height, session_params.samples);
|
||||
}
|
||||
|
||||
bool BlenderSession::draw(int w, int h)
|
||||
@@ -221,7 +221,7 @@ bool BlenderSession::draw(int w, int h)
|
||||
/* reset if requested */
|
||||
if(reset) {
|
||||
SessionParams session_params = BlenderSync::get_session_params(b_scene, background);
|
||||
session->reset(width, height, session_params.passes);
|
||||
session->reset(width, height, session_params.samples);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,11 +239,11 @@ void BlenderSession::get_status(string& status, string& substatus)
|
||||
|
||||
void BlenderSession::get_progress(float& progress, double& total_time)
|
||||
{
|
||||
double pass_time;
|
||||
int pass;
|
||||
double sample_time;
|
||||
int sample;
|
||||
|
||||
session->progress.get_pass(pass, total_time, pass_time);
|
||||
progress = ((float)pass/(float)session->params.passes);
|
||||
session->progress.get_sample(sample, total_time, sample_time);
|
||||
progress = ((float)sample/(float)session->params.samples);
|
||||
}
|
||||
|
||||
void BlenderSession::update_status_progress()
|
||||
|
||||
@@ -190,11 +190,15 @@ static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::Node *
|
||||
node = new FresnelNode();
|
||||
break;
|
||||
}
|
||||
case BL::ShaderNode::type_ADD_CLOSURE: {
|
||||
case BL::ShaderNode::type_BLEND_WEIGHT: {
|
||||
node = new BlendWeightNode();
|
||||
break;
|
||||
}
|
||||
case BL::ShaderNode::type_ADD_SHADER: {
|
||||
node = new AddClosureNode();
|
||||
break;
|
||||
}
|
||||
case BL::ShaderNode::type_MIX_CLOSURE: {
|
||||
case BL::ShaderNode::type_MIX_SHADER: {
|
||||
node = new MixClosureNode();
|
||||
break;
|
||||
}
|
||||
@@ -402,6 +406,20 @@ static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::Node *
|
||||
return node;
|
||||
}
|
||||
|
||||
static const char *node_socket_map_name(const char *name)
|
||||
{
|
||||
if(strstr(name, "Shader")) {
|
||||
if(strcmp(name, "Shader") == 0)
|
||||
return "Closure";
|
||||
if(strcmp(name, "Shader1") == 0)
|
||||
return "Closure1";
|
||||
if(strcmp(name, "Shader2") == 0)
|
||||
return "Closure2";
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, BL::Node *b_group_node, PtrSockMap& sockets_map)
|
||||
{
|
||||
/* add nodes */
|
||||
@@ -427,7 +445,7 @@ static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTr
|
||||
node_map[b_node->ptr.data] = node;
|
||||
|
||||
for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
|
||||
ShaderInput *input = node->input(b_input->name().c_str());
|
||||
ShaderInput *input = node->input(node_socket_map_name(b_input->name().c_str()));
|
||||
BL::NodeSocket sock(get_node_input(b_group_node, *b_node, b_input->name()));
|
||||
|
||||
assert(input);
|
||||
@@ -522,7 +540,7 @@ static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTr
|
||||
/* in case of groups there may not actually be a node inside the group
|
||||
that the group socket connects to, so from_node or to_node may be NULL */
|
||||
if(from_node && to_node)
|
||||
graph->connect(from_node->output(from_name.c_str()), to_node->input(to_name.c_str()));
|
||||
graph->connect(from_node->output(node_socket_map_name(from_name.c_str())), to_node->input(node_socket_map_name(to_name.c_str())));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -185,13 +185,17 @@ void BlenderSync::sync_render_layer(BL::SpaceView3D b_v3d)
|
||||
else {
|
||||
BL::RenderSettings r = b_scene.render();
|
||||
BL::RenderSettings::layers_iterator b_rlay;
|
||||
bool first = true;
|
||||
|
||||
for(r.layers.begin(b_rlay); b_rlay != r.layers.end(); ++b_rlay) {
|
||||
render_layer.scene_layer = get_layer(b_scene.layers());
|
||||
render_layer.layer = get_layer(b_rlay->layers());
|
||||
render_layer.material_override = b_rlay->material_override();
|
||||
/* single layer for now */
|
||||
if(first) {
|
||||
render_layer.scene_layer = get_layer(b_scene.layers());
|
||||
render_layer.layer = get_layer(b_rlay->layers());
|
||||
render_layer.material_override = b_rlay->material_override();
|
||||
|
||||
break; /* single layer for now */
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,14 +259,14 @@ SessionParams BlenderSync::get_session_params(BL::Scene b_scene, bool background
|
||||
/* Background */
|
||||
params.background = background;
|
||||
|
||||
/* passes */
|
||||
/* samples */
|
||||
if(background) {
|
||||
params.passes = get_int(cscene, "passes");
|
||||
params.samples = get_int(cscene, "samples");
|
||||
}
|
||||
else {
|
||||
params.passes = get_int(cscene, "preview_passes");
|
||||
if(params.passes == 0)
|
||||
params.passes = INT_MAX;
|
||||
params.samples = get_int(cscene, "preview_samples");
|
||||
if(params.samples == 0)
|
||||
params.samples = INT_MAX;
|
||||
}
|
||||
|
||||
/* other parameters */
|
||||
|
||||
@@ -36,7 +36,7 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
DeviceTask::DeviceTask(Type type_)
|
||||
: type(type_), x(0), y(0), w(0), h(0), rng_state(0), rgba(0), buffer(0),
|
||||
pass(0), resolution(0),
|
||||
sample(0), resolution(0),
|
||||
displace_input(0), displace_offset(0), displace_x(0), displace_w(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
device_ptr rng_state;
|
||||
device_ptr rgba;
|
||||
device_ptr buffer;
|
||||
int pass;
|
||||
int sample;
|
||||
int resolution;
|
||||
|
||||
device_ptr displace_input;
|
||||
|
||||
@@ -152,7 +152,7 @@ public:
|
||||
|
||||
for(int y = task.y; y < task.y + task.h; y++) {
|
||||
for(int x = task.x; x < task.x + task.w; x++)
|
||||
kernel_cpu_path_trace(kg, (float4*)task.buffer, (unsigned int*)task.rng_state, task.pass, x, y);
|
||||
kernel_cpu_path_trace(kg, (float4*)task.buffer, (unsigned int*)task.rng_state, task.sample, x, y);
|
||||
|
||||
if(tasks.worker_cancel())
|
||||
break;
|
||||
@@ -168,7 +168,7 @@ public:
|
||||
{
|
||||
for(int y = task.y; y < task.y + task.h; y++) {
|
||||
for(int x = task.x; x < task.x + task.w; x++)
|
||||
kernel_cpu_tonemap(kg, (uchar4*)task.rgba, (float4*)task.buffer, task.pass, task.resolution, x, y);
|
||||
kernel_cpu_tonemap(kg, (uchar4*)task.rgba, (float4*)task.buffer, task.sample, task.resolution, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -455,11 +455,11 @@ public:
|
||||
cuda_assert(cuParamSetv(cuPathTrace, offset, &d_rng_state, sizeof(d_rng_state)))
|
||||
offset += sizeof(d_rng_state);
|
||||
|
||||
int pass = task.pass;
|
||||
offset = cuda_align_up(offset, __alignof(pass));
|
||||
int sample = task.sample;
|
||||
offset = cuda_align_up(offset, __alignof(sample));
|
||||
|
||||
cuda_assert(cuParamSeti(cuPathTrace, offset, task.pass))
|
||||
offset += sizeof(task.pass);
|
||||
cuda_assert(cuParamSeti(cuPathTrace, offset, task.sample))
|
||||
offset += sizeof(task.sample);
|
||||
|
||||
cuda_assert(cuParamSeti(cuPathTrace, offset, task.x))
|
||||
offset += sizeof(task.x);
|
||||
@@ -513,11 +513,11 @@ public:
|
||||
cuda_assert(cuParamSetv(cuFilmConvert, offset, &d_buffer, sizeof(d_buffer)))
|
||||
offset += sizeof(d_buffer);
|
||||
|
||||
int pass = task.pass;
|
||||
offset = cuda_align_up(offset, __alignof(pass));
|
||||
int sample = task.sample;
|
||||
offset = cuda_align_up(offset, __alignof(sample));
|
||||
|
||||
cuda_assert(cuParamSeti(cuFilmConvert, offset, task.pass))
|
||||
offset += sizeof(task.pass);
|
||||
cuda_assert(cuParamSeti(cuFilmConvert, offset, task.sample))
|
||||
offset += sizeof(task.sample);
|
||||
|
||||
cuda_assert(cuParamSeti(cuFilmConvert, offset, task.resolution))
|
||||
offset += sizeof(task.resolution);
|
||||
|
||||
@@ -178,22 +178,22 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
void path_trace(int x, int y, int w, int h, device_ptr buffer, device_ptr rng_state, int pass)
|
||||
void path_trace(int x, int y, int w, int h, device_ptr buffer, device_ptr rng_state, int sample)
|
||||
{
|
||||
#if 0
|
||||
RPCSend snd(socket, "path_trace");
|
||||
|
||||
snd.archive & x & y & w & h & buffer & rng_state & pass;
|
||||
snd.archive & x & y & w & h & buffer & rng_state & sample;
|
||||
snd.write();
|
||||
#endif
|
||||
}
|
||||
|
||||
void tonemap(int x, int y, int w, int h, device_ptr rgba, device_ptr buffer, int pass, int resolution)
|
||||
void tonemap(int x, int y, int w, int h, device_ptr rgba, device_ptr buffer, int sample, int resolution)
|
||||
{
|
||||
#if 0
|
||||
RPCSend snd(socket, "tonemap");
|
||||
|
||||
snd.archive & x & y & w & h & rgba & buffer & pass & resolution;
|
||||
snd.archive & x & y & w & h & rgba & buffer & sample & resolution;
|
||||
snd.write();
|
||||
#endif
|
||||
}
|
||||
@@ -201,9 +201,9 @@ public:
|
||||
void task_add(DeviceTask& task)
|
||||
{
|
||||
if(task.type == DeviceTask::TONEMAP)
|
||||
tonemap(task.x, task.y, task.w, task.h, task.rgba, task.buffer, task.pass, task.resolution);
|
||||
tonemap(task.x, task.y, task.w, task.h, task.rgba, task.buffer, task.sample, task.resolution);
|
||||
else if(task.type == DeviceTask::PATH_TRACE)
|
||||
path_trace(task.x, task.y, task.w, task.h, task.buffer, task.rng_state, task.pass);
|
||||
path_trace(task.x, task.y, task.w, task.h, task.buffer, task.rng_state, task.sample);
|
||||
}
|
||||
|
||||
void task_wait()
|
||||
@@ -355,20 +355,20 @@ void Device::server_run()
|
||||
#if 0
|
||||
device_ptr buffer, rng_state;
|
||||
int x, y, w, h;
|
||||
int pass;
|
||||
int sample;
|
||||
|
||||
*rcv.archive & x & y & w & h & buffer & rng_state & pass;
|
||||
path_trace(x, y, w, h, buffer, rng_state, pass);
|
||||
*rcv.archive & x & y & w & h & buffer & rng_state & sample;
|
||||
path_trace(x, y, w, h, buffer, rng_state, sample);
|
||||
#endif
|
||||
}
|
||||
else if(rcv.name == "tonemap") {
|
||||
#if 0
|
||||
device_ptr rgba, buffer;
|
||||
int x, y, w, h;
|
||||
int pass, resolution;
|
||||
int sample, resolution;
|
||||
|
||||
*rcv.archive & x & y & w & h & rgba & buffer & pass & resolution;
|
||||
tonemap(x, y, w, h, rgba, buffer, pass, resolution);
|
||||
*rcv.archive & x & y & w & h & rgba & buffer & sample & resolution;
|
||||
tonemap(x, y, w, h, rgba, buffer, sample, resolution);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,9 +502,9 @@ public:
|
||||
cl_int d_y = task.y;
|
||||
cl_int d_w = task.w;
|
||||
cl_int d_h = task.h;
|
||||
cl_int d_pass = task.pass;
|
||||
cl_int d_sample = task.sample;
|
||||
|
||||
/* pass arguments */
|
||||
/* sample arguments */
|
||||
int narg = 0;
|
||||
ciErr = 0;
|
||||
|
||||
@@ -516,7 +516,7 @@ public:
|
||||
ciErr |= set_kernel_arg_mem(ckPathTraceKernel, &narg, #name);
|
||||
#include "kernel_textures.h"
|
||||
|
||||
ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_pass), (void*)&d_pass);
|
||||
ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_sample), (void*)&d_sample);
|
||||
ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_x), (void*)&d_x);
|
||||
ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_y), (void*)&d_y);
|
||||
ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_w), (void*)&d_w);
|
||||
@@ -575,10 +575,10 @@ public:
|
||||
cl_int d_y = task.y;
|
||||
cl_int d_w = task.w;
|
||||
cl_int d_h = task.h;
|
||||
cl_int d_pass = task.pass;
|
||||
cl_int d_sample = task.sample;
|
||||
cl_int d_resolution = task.resolution;
|
||||
|
||||
/* pass arguments */
|
||||
/* sample arguments */
|
||||
int narg = 0;
|
||||
ciErr = 0;
|
||||
|
||||
@@ -590,7 +590,7 @@ public:
|
||||
ciErr |= set_kernel_arg_mem(ckFilmConvertKernel, &narg, #name);
|
||||
#include "kernel_textures.h"
|
||||
|
||||
ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_pass), (void*)&d_pass);
|
||||
ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_sample), (void*)&d_sample);
|
||||
ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_resolution), (void*)&d_resolution);
|
||||
ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_x), (void*)&d_x);
|
||||
ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_y), (void*)&d_y);
|
||||
|
||||
@@ -37,7 +37,7 @@ __kernel void kernel_ocl_path_trace(
|
||||
int name##_width,
|
||||
#include "kernel_textures.h"
|
||||
|
||||
int pass,
|
||||
int sample,
|
||||
int sx, int sy, int sw, int sh)
|
||||
{
|
||||
KernelGlobals kglobals, *kg = &kglobals;
|
||||
@@ -53,7 +53,7 @@ __kernel void kernel_ocl_path_trace(
|
||||
int y = sy + get_global_id(1);
|
||||
|
||||
if(x < sx + sw && y < sy + sh)
|
||||
kernel_path_trace(kg, buffer, rng_state, pass, x, y);
|
||||
kernel_path_trace(kg, buffer, rng_state, sample, x, y);
|
||||
}
|
||||
|
||||
__kernel void kernel_ocl_tonemap(
|
||||
@@ -66,7 +66,7 @@ __kernel void kernel_ocl_tonemap(
|
||||
int name##_width,
|
||||
#include "kernel_textures.h"
|
||||
|
||||
int pass, int resolution,
|
||||
int sample, int resolution,
|
||||
int sx, int sy, int sw, int sh)
|
||||
{
|
||||
KernelGlobals kglobals, *kg = &kglobals;
|
||||
@@ -82,7 +82,7 @@ __kernel void kernel_ocl_tonemap(
|
||||
int y = sy + get_global_id(1);
|
||||
|
||||
if(x < sx + sw && y < sy + sh)
|
||||
kernel_film_tonemap(kg, rgba, buffer, pass, resolution, x, y);
|
||||
kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y);
|
||||
}
|
||||
|
||||
/*__kernel void kernel_ocl_displace(__global uint4 *input, __global float3 *offset, int sx)
|
||||
|
||||
@@ -269,16 +269,16 @@ void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t
|
||||
|
||||
/* Path Tracing */
|
||||
|
||||
void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int pass, int x, int y)
|
||||
void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y)
|
||||
{
|
||||
kernel_path_trace(kg, buffer, rng_state, pass, x, y);
|
||||
kernel_path_trace(kg, buffer, rng_state, sample, x, y);
|
||||
}
|
||||
|
||||
/* Tonemapping */
|
||||
|
||||
void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int pass, int resolution, int x, int y)
|
||||
void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y)
|
||||
{
|
||||
kernel_film_tonemap(kg, rgba, buffer, pass, resolution, x, y);
|
||||
kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y);
|
||||
}
|
||||
|
||||
/* Displacement */
|
||||
|
||||
@@ -26,22 +26,22 @@
|
||||
#include "kernel_path.h"
|
||||
#include "kernel_displace.h"
|
||||
|
||||
extern "C" __global__ void kernel_cuda_path_trace(float4 *buffer, uint *rng_state, int pass, int sx, int sy, int sw, int sh)
|
||||
extern "C" __global__ void kernel_cuda_path_trace(float4 *buffer, uint *rng_state, int sample, int sx, int sy, int sw, int sh)
|
||||
{
|
||||
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
|
||||
int y = sy + blockDim.y*blockIdx.y + threadIdx.y;
|
||||
|
||||
if(x < sx + sw && y < sy + sh)
|
||||
kernel_path_trace(NULL, buffer, rng_state, pass, x, y);
|
||||
kernel_path_trace(NULL, buffer, rng_state, sample, x, y);
|
||||
}
|
||||
|
||||
extern "C" __global__ void kernel_cuda_tonemap(uchar4 *rgba, float4 *buffer, int pass, int resolution, int sx, int sy, int sw, int sh)
|
||||
extern "C" __global__ void kernel_cuda_tonemap(uchar4 *rgba, float4 *buffer, int sample, int resolution, int sx, int sy, int sw, int sh)
|
||||
{
|
||||
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
|
||||
int y = sy + blockDim.y*blockIdx.y + threadIdx.y;
|
||||
|
||||
if(x < sx + sw && y < sy + sh)
|
||||
kernel_film_tonemap(NULL, rgba, buffer, pass, resolution, x, y);
|
||||
kernel_film_tonemap(NULL, rgba, buffer, sample, resolution, x, y);
|
||||
}
|
||||
|
||||
extern "C" __global__ void kernel_cuda_displace(uint4 *input, float3 *offset, int sx)
|
||||
|
||||
@@ -36,8 +36,8 @@ bool kernel_osl_use(KernelGlobals *kg);
|
||||
void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t size);
|
||||
void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height);
|
||||
|
||||
void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int pass, int x, int y);
|
||||
void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int pass, int resolution, int x, int y);
|
||||
void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y);
|
||||
void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y);
|
||||
|
||||
void kernel_cpu_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i);
|
||||
|
||||
|
||||
@@ -20,6 +20,21 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Perspective Camera */
|
||||
|
||||
__device float2 camera_sample_aperture(KernelGlobals *kg, float u, float v)
|
||||
{
|
||||
float blades = kernel_data.cam.blades;
|
||||
|
||||
if(blades == 0.0f) {
|
||||
/* sample disk */
|
||||
return concentric_sample_disk(u, v);
|
||||
}
|
||||
else {
|
||||
/* sample polygon */
|
||||
float rotation = kernel_data.cam.bladesrotation;
|
||||
return regular_polygon_sample(blades, rotation, u, v);
|
||||
}
|
||||
}
|
||||
|
||||
__device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float raster_y, float lens_u, float lens_v, Ray *ray)
|
||||
{
|
||||
/* create ray form raster position */
|
||||
@@ -30,14 +45,11 @@ __device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float
|
||||
ray->D = Pcamera;
|
||||
|
||||
/* modify ray for depth of field */
|
||||
float lensradius = kernel_data.cam.lensradius;
|
||||
float aperturesize = kernel_data.cam.aperturesize;
|
||||
|
||||
if(lensradius > 0.0f) {
|
||||
/* sample point on lens */
|
||||
float2 lensuv;
|
||||
|
||||
lensuv = concentric_sample_disk(lens_u, lens_v);
|
||||
lensuv *= lensradius;
|
||||
if(aperturesize > 0.0f) {
|
||||
/* sample point on aperture */
|
||||
float2 lensuv = camera_sample_aperture(kg, lens_u, lens_v)*aperturesize;
|
||||
|
||||
/* compute point on plane of focus */
|
||||
float ft = kernel_data.cam.focaldistance/ray->D.z;
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
__device float4 film_map(KernelGlobals *kg, float4 irradiance, int pass)
|
||||
__device float4 film_map(KernelGlobals *kg, float4 irradiance, int sample)
|
||||
{
|
||||
float scale = 1.0f/(float)(pass+1);
|
||||
float scale = 1.0f/(float)(sample+1);
|
||||
float exposure = kernel_data.film.exposure;
|
||||
float4 result = irradiance*scale;
|
||||
|
||||
@@ -48,13 +48,13 @@ __device uchar4 film_float_to_byte(float4 color)
|
||||
return result;
|
||||
}
|
||||
|
||||
__device void kernel_film_tonemap(KernelGlobals *kg, __global uchar4 *rgba, __global float4 *buffer, int pass, int resolution, int x, int y)
|
||||
__device void kernel_film_tonemap(KernelGlobals *kg, __global uchar4 *rgba, __global float4 *buffer, int sample, int resolution, int x, int y)
|
||||
{
|
||||
int w = kernel_data.cam.width;
|
||||
int index = x + y*w;
|
||||
float4 irradiance = buffer[index];
|
||||
|
||||
float4 float_result = film_map(kg, irradiance, pass);
|
||||
float4 float_result = film_map(kg, irradiance, sample);
|
||||
uchar4 byte_result = film_float_to_byte(float_result);
|
||||
|
||||
rgba[index] = byte_result;
|
||||
|
||||
@@ -172,6 +172,30 @@ __device float2 concentric_sample_disk(float u1, float u2)
|
||||
return make_float2(r * cosf(theta), r * sinf(theta));
|
||||
}
|
||||
|
||||
__device float2 regular_polygon_sample(float corners, float rotation, float u, float v)
|
||||
{
|
||||
/* sample corner number and reuse u */
|
||||
float corner = floorf(u*corners);
|
||||
u = u*corners - corner;
|
||||
|
||||
/* uniform sampled triangle weights */
|
||||
u = sqrtf(u);
|
||||
v = v*u;
|
||||
u = 1.0f - u;
|
||||
|
||||
/* point in triangle */
|
||||
float angle = M_PI_F/corners;
|
||||
float2 p = make_float2((u + v)*cosf(angle), (u - v)*sinf(angle));
|
||||
|
||||
/* rotate */
|
||||
rotation += corner*2.0f*angle;
|
||||
|
||||
float cr = cosf(rotation);
|
||||
float sr = sinf(rotation);
|
||||
|
||||
return make_float2(cr*p.x - sr*p.y, sr*p.x + cr*p.y);
|
||||
}
|
||||
|
||||
/* Spherical coordinates <-> Cartesion direction */
|
||||
|
||||
__device float2 direction_to_spherical(float3 dir)
|
||||
|
||||
@@ -34,22 +34,22 @@
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
#ifdef __MODIFY_TP__
|
||||
__device float3 path_terminate_modified_throughput(KernelGlobals *kg, __global float3 *buffer, int x, int y, int pass)
|
||||
__device float3 path_terminate_modified_throughput(KernelGlobals *kg, __global float3 *buffer, int x, int y, int sample)
|
||||
{
|
||||
/* modify throughput to influence path termination probability, to avoid
|
||||
darker regions receiving fewer samples than lighter regions. also RGB
|
||||
are weighted differently. proper validation still remains to be done. */
|
||||
const float3 weights = make_float3(1.0f, 1.33f, 0.66f);
|
||||
const float3 one = make_float3(1.0f, 1.0f, 1.0f);
|
||||
const int minpass = 5;
|
||||
const int minsample = 5;
|
||||
const float minL = 0.1f;
|
||||
|
||||
if(pass >= minpass) {
|
||||
if(sample >= minsample) {
|
||||
float3 L = buffer[x + y*kernel_data.cam.width];
|
||||
float3 Lmin = make_float3(minL, minL, minL);
|
||||
float correct = (float)(pass+1)/(float)pass;
|
||||
float correct = (float)(sample+1)/(float)sample;
|
||||
|
||||
L = film_map(L*correct, pass);
|
||||
L = film_map(L*correct, sample);
|
||||
|
||||
return weights/clamp(L, Lmin, one);
|
||||
}
|
||||
@@ -242,7 +242,7 @@ __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ra
|
||||
return result;
|
||||
}
|
||||
|
||||
__device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int pass, Ray ray, float3 throughput)
|
||||
__device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, float3 throughput)
|
||||
{
|
||||
/* initialize */
|
||||
float3 L = make_float3(0.0f, 0.0f, 0.0f);
|
||||
@@ -284,7 +284,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int pass, Ray
|
||||
/* setup shading */
|
||||
ShaderData sd;
|
||||
shader_setup_from_ray(kg, &sd, &isect, &ray);
|
||||
float rbsdf = path_rng(kg, rng, pass, rng_offset + PRNG_BSDF);
|
||||
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
|
||||
shader_eval_surface(kg, &sd, rbsdf, state.flag);
|
||||
|
||||
#ifdef __HOLDOUT__
|
||||
@@ -308,7 +308,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int pass, Ray
|
||||
mainly due to the mixed in MIS that we use. gives too many unneeded
|
||||
shader evaluations, only need emission if we are going to terminate */
|
||||
float probability = path_state_terminate_probability(kg, &state, throughput);
|
||||
float terminate = path_rng(kg, rng, pass, rng_offset + PRNG_TERMINATE);
|
||||
float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE);
|
||||
|
||||
if(terminate >= probability)
|
||||
break;
|
||||
@@ -319,10 +319,10 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int pass, Ray
|
||||
if(kernel_data.integrator.use_emission) {
|
||||
/* sample illumination from lights to find path contribution */
|
||||
if(sd.flag & SD_BSDF_HAS_EVAL) {
|
||||
float light_t = path_rng(kg, rng, pass, rng_offset + PRNG_LIGHT);
|
||||
float light_o = path_rng(kg, rng, pass, rng_offset + PRNG_LIGHT_F);
|
||||
float light_u = path_rng(kg, rng, pass, rng_offset + PRNG_LIGHT_U);
|
||||
float light_v = path_rng(kg, rng, pass, rng_offset + PRNG_LIGHT_V);
|
||||
float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT);
|
||||
float light_o = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_F);
|
||||
float light_u = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_U);
|
||||
float light_v = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_V);
|
||||
|
||||
Ray light_ray;
|
||||
float3 light_L;
|
||||
@@ -356,8 +356,8 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int pass, Ray
|
||||
float3 bsdf_eval;
|
||||
float3 bsdf_omega_in;
|
||||
differential3 bsdf_domega_in;
|
||||
float bsdf_u = path_rng(kg, rng, pass, rng_offset + PRNG_BSDF_U);
|
||||
float bsdf_v = path_rng(kg, rng, pass, rng_offset + PRNG_BSDF_V);
|
||||
float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
|
||||
float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
|
||||
int label;
|
||||
|
||||
label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval,
|
||||
@@ -392,7 +392,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int pass, Ray
|
||||
return make_float4(L.x, L.y, L.z, 1.0f - Ltransparent);
|
||||
}
|
||||
|
||||
__device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __global uint *rng_state, int pass, int x, int y)
|
||||
__device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __global uint *rng_state, int sample, int x, int y)
|
||||
{
|
||||
/* initialize random numbers */
|
||||
RNG rng;
|
||||
@@ -400,29 +400,29 @@ __device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __gl
|
||||
float filter_u;
|
||||
float filter_v;
|
||||
|
||||
path_rng_init(kg, rng_state, pass, &rng, x, y, &filter_u, &filter_v);
|
||||
path_rng_init(kg, rng_state, sample, &rng, x, y, &filter_u, &filter_v);
|
||||
|
||||
/* sample camera ray */
|
||||
Ray ray;
|
||||
|
||||
float lens_u = path_rng(kg, &rng, pass, PRNG_LENS_U);
|
||||
float lens_v = path_rng(kg, &rng, pass, PRNG_LENS_V);
|
||||
float lens_u = path_rng(kg, &rng, sample, PRNG_LENS_U);
|
||||
float lens_v = path_rng(kg, &rng, sample, PRNG_LENS_V);
|
||||
|
||||
camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, &ray);
|
||||
|
||||
/* integrate */
|
||||
#ifdef __MODIFY_TP__
|
||||
float3 throughput = path_terminate_modified_throughput(kg, buffer, x, y, pass);
|
||||
float4 L = kernel_path_integrate(kg, &rng, pass, ray, throughput)/throughput;
|
||||
float3 throughput = path_terminate_modified_throughput(kg, buffer, x, y, sample);
|
||||
float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput)/throughput;
|
||||
#else
|
||||
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
|
||||
float4 L = kernel_path_integrate(kg, &rng, pass, ray, throughput);
|
||||
float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput);
|
||||
#endif
|
||||
|
||||
/* accumulate result in output buffer */
|
||||
int index = x + y*kernel_data.cam.width;
|
||||
|
||||
if(pass == 0)
|
||||
if(sample == 0)
|
||||
buffer[index] = L;
|
||||
else
|
||||
buffer[index] += L;
|
||||
|
||||
@@ -95,7 +95,7 @@ __device uint sobol_lookup(const uint m, const uint frame, const uint ex, const
|
||||
return index;
|
||||
}
|
||||
|
||||
__device_inline float path_rng(KernelGlobals *kg, RNG *rng, int pass, int dimension)
|
||||
__device_inline float path_rng(KernelGlobals *kg, RNG *rng, int sample, int dimension)
|
||||
{
|
||||
#ifdef __SOBOL_FULL_SCREEN__
|
||||
uint result = sobol_dimension(kg, *rng, dimension);
|
||||
@@ -103,7 +103,7 @@ __device_inline float path_rng(KernelGlobals *kg, RNG *rng, int pass, int dimens
|
||||
return r;
|
||||
#else
|
||||
/* compute sobol sequence value using direction vectors */
|
||||
uint result = sobol_dimension(kg, pass, dimension);
|
||||
uint result = sobol_dimension(kg, sample, dimension);
|
||||
float r = (float)result * (1.0f/(float)0xFFFFFFFF);
|
||||
|
||||
/* Cranly-Patterson rotation using rng seed */
|
||||
@@ -118,13 +118,13 @@ __device_inline float path_rng(KernelGlobals *kg, RNG *rng, int pass, int dimens
|
||||
#endif
|
||||
}
|
||||
|
||||
__device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int pass, RNG *rng, int x, int y, float *fx, float *fy)
|
||||
__device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, float *fx, float *fy)
|
||||
{
|
||||
#ifdef __SOBOL_FULL_SCREEN__
|
||||
uint px, py;
|
||||
uint bits = 16; /* limits us to 65536x65536 and 65536 samples */
|
||||
uint size = 1 << bits;
|
||||
uint frame = pass;
|
||||
uint frame = sample;
|
||||
|
||||
*rng = sobol_lookup(bits, frame, x, y, &px, &py);
|
||||
|
||||
@@ -133,8 +133,8 @@ __device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state,
|
||||
#else
|
||||
*rng = rng_state[x + y*kernel_data.cam.width];
|
||||
|
||||
*fx = path_rng(kg, rng, pass, PRNG_FILTER_U);
|
||||
*fy = path_rng(kg, rng, pass, PRNG_FILTER_V);
|
||||
*fx = path_rng(kg, rng, sample, PRNG_FILTER_U);
|
||||
*fy = path_rng(kg, rng, sample, PRNG_FILTER_V);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -147,25 +147,25 @@ __device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng,
|
||||
|
||||
/* Linear Congruential Generator */
|
||||
|
||||
__device float path_rng(KernelGlobals *kg, RNG *rng, int pass, int dimension)
|
||||
__device float path_rng(KernelGlobals *kg, RNG *rng, int sample, int dimension)
|
||||
{
|
||||
/* implicit mod 2^32 */
|
||||
*rng = (1103515245*(*rng) + 12345);
|
||||
return (float)*rng * (1.0f/(float)0xFFFFFFFF);
|
||||
}
|
||||
|
||||
__device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int pass, RNG *rng, int x, int y, float *fx, float *fy)
|
||||
__device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, float *fx, float *fy)
|
||||
{
|
||||
/* load state */
|
||||
*rng = rng_state[x + y*kernel_data.cam.width];
|
||||
|
||||
*fx = path_rng(kg, rng, pass, PRNG_FILTER_U);
|
||||
*fy = path_rng(kg, rng, pass, PRNG_FILTER_V);
|
||||
*fx = path_rng(kg, rng, sample, PRNG_FILTER_U);
|
||||
*fy = path_rng(kg, rng, sample, PRNG_FILTER_V);
|
||||
}
|
||||
|
||||
__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng, int x, int y)
|
||||
{
|
||||
/* store state for next pass */
|
||||
/* store state for next sample */
|
||||
rng_state[x + y*kernel_data.cam.width] = rng;
|
||||
}
|
||||
|
||||
|
||||
@@ -288,14 +288,6 @@ typedef struct KernelCamera {
|
||||
Transform cameratoworld;
|
||||
Transform rastertocamera;
|
||||
|
||||
/* depth of field */
|
||||
float lensradius;
|
||||
float focaldistance;
|
||||
|
||||
/* motion blur */
|
||||
float shutteropen;
|
||||
float shutterclose;
|
||||
|
||||
/* differentials */
|
||||
float3 dx;
|
||||
#ifndef WITH_OPENCL
|
||||
@@ -306,10 +298,19 @@ typedef struct KernelCamera {
|
||||
float pad2;
|
||||
#endif
|
||||
|
||||
/* depth of field */
|
||||
float aperturesize;
|
||||
float blades;
|
||||
float bladesrotation;
|
||||
float focaldistance;
|
||||
|
||||
/* motion blur */
|
||||
float shutteropen;
|
||||
float shutterclose;
|
||||
|
||||
/* clipping */
|
||||
float nearclip;
|
||||
float cliplength;
|
||||
float pad3, pad4;
|
||||
|
||||
/* more matrices */
|
||||
Transform screentoworld;
|
||||
|
||||
@@ -30,6 +30,7 @@ set(osl_sources
|
||||
node_mix.osl
|
||||
node_mix_closure.osl
|
||||
node_musgrave_texture.osl
|
||||
node_blend_weight_texture.osl
|
||||
node_noise_texture.osl
|
||||
node_output_displacement.osl
|
||||
node_output_surface.osl
|
||||
|
||||
42
intern/cycles/kernel/osl/nodes/node_blend_weight.osl
Normal file
42
intern/cycles/kernel/osl/nodes/node_blend_weight.osl
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2011, Blender Foundation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "stdosl.h"
|
||||
#include "node_fresnel.h"
|
||||
|
||||
shader node_blend_weight(
|
||||
float Blend = 0.3,
|
||||
normal Normal = N,
|
||||
output float Fresnel = 0.0,
|
||||
output float Facing = 0.0)
|
||||
{
|
||||
float f = max(1.0 - Blend, 1e-5);
|
||||
Fresnel = fresnel_dielectric(I, Normal, backfacing()? f: 1.0/f);
|
||||
|
||||
Facing = abs(dot(I, Normal));
|
||||
|
||||
if(Blend != 0.5) {
|
||||
Blend = clamp(Blend, 0.0, 1.0);
|
||||
Blend = (Blend < 0.5)? 2.0*Blend: 0.5/(1.0 - Blend);
|
||||
|
||||
Facing = powf(Facing, Blend);
|
||||
}
|
||||
|
||||
Facing = 1.0 - Facing;
|
||||
}
|
||||
|
||||
@@ -23,9 +23,10 @@ shader node_environment_texture(
|
||||
vector Vector = P,
|
||||
string filename = "",
|
||||
string color_space = "sRGB",
|
||||
output color Color = color(0.0, 0.0, 0.0))
|
||||
output color Color = color(0.0, 0.0, 0.0),
|
||||
output float Alpha = 1.0)
|
||||
{
|
||||
Color = (color)environment(filename, Vector);
|
||||
Color = (color)environment(filename, Vector, "alpha", Alpha);
|
||||
|
||||
if(color_space == "sRGB")
|
||||
Color = color_srgb_to_scene_linear(Color);
|
||||
|
||||
@@ -20,11 +20,12 @@
|
||||
#include "node_fresnel.h"
|
||||
|
||||
shader node_fresnel(
|
||||
float Fresnel = 0.3,
|
||||
float IOR = 1.45,
|
||||
normal Normal = N,
|
||||
output float Fac = 0.0)
|
||||
{
|
||||
float f = max(1.0 - Fresnel, 0.00001);
|
||||
Fac = fresnel_dielectric(I, Normal, backfacing()? f: 1.0/f);
|
||||
float f = max(IOR, 1.0 + 1e-5);
|
||||
float eta = backfacing()? 1.0/f: f;
|
||||
Fac = fresnel_dielectric(I, Normal, eta);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,12 +23,12 @@ shader node_glass_bsdf(
|
||||
color Color = color(0.8, 0.8, 0.8),
|
||||
string distribution = "Sharp",
|
||||
float Roughness = 0.2,
|
||||
float Fresnel = 0.3,
|
||||
float IOR = 1.45,
|
||||
normal Normal = N,
|
||||
output closure color BSDF = diffuse(Normal))
|
||||
{
|
||||
float f = clamp(1.0 - Fresnel, 1e-5, 1.0 - 1e-5);
|
||||
float eta = backfacing()? f: 1.0/f;
|
||||
float f = max(IOR, 1.0 + 1e-5);
|
||||
float eta = backfacing()? 1.0/f: f;
|
||||
float Fr = fresnel_dielectric(I, Normal, eta);
|
||||
|
||||
if(distribution == "Sharp")
|
||||
|
||||
@@ -23,23 +23,15 @@ shader node_glossy_bsdf(
|
||||
color Color = color(0.8, 0.8, 0.8),
|
||||
string distribution = "Beckmann",
|
||||
float Roughness = 0.2,
|
||||
float Fresnel = 1.0,
|
||||
normal Normal = N,
|
||||
output closure color BSDF = diffuse(Normal))
|
||||
{
|
||||
float Fr = 1.0;
|
||||
|
||||
if(Fresnel < 1.0) {
|
||||
float eta = 1.0/clamp(1.0 - Fresnel, 1e-5, 1.0 - 1e-5);
|
||||
Fr = fresnel_dielectric(I, Normal, eta);
|
||||
}
|
||||
|
||||
if(distribution == "Sharp")
|
||||
BSDF = (Fr*Color)*reflection(Normal);
|
||||
BSDF = Color*reflection(Normal);
|
||||
else if(distribution == "Beckmann")
|
||||
BSDF = (Fr*Color)*microfacet_beckmann(Normal, Roughness);
|
||||
BSDF = Color*microfacet_beckmann(Normal, Roughness);
|
||||
else if(distribution == "GGX")
|
||||
BSDF = (Fr*Color)*microfacet_ggx(Normal, Roughness);
|
||||
BSDF = Color*microfacet_ggx(Normal, Roughness);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,10 @@ shader node_image_texture(
|
||||
point Vector = P,
|
||||
string filename = "",
|
||||
string color_space = "sRGB",
|
||||
output color Color = color(0.0, 0.0, 0.0))
|
||||
output color Color = color(0.0, 0.0, 0.0),
|
||||
output float Alpha = 1.0)
|
||||
{
|
||||
Color = (color)texture(filename, Vector[0], 1.0-Vector[1], "wrap", "periodic");
|
||||
Color = (color)texture(filename, Vector[0], 1.0-Vector[1], "wrap", "periodic", "alpha", Alpha);
|
||||
|
||||
if(color_space == "sRGB")
|
||||
Color = color_srgb_to_scene_linear(Color);
|
||||
|
||||
@@ -22,19 +22,11 @@
|
||||
shader node_velvet_bsdf(
|
||||
color Color = color(0.8, 0.8, 0.8),
|
||||
float Sigma = 0.0,
|
||||
float Fresnel = 0.3,
|
||||
normal Normal = N,
|
||||
output closure color BSDF = diffuse(Normal))
|
||||
{
|
||||
float Fr = 1.0;
|
||||
|
||||
if(Fresnel < 1.0) {
|
||||
float eta = 1.0/clamp(1.0 - Fresnel, 1e-5, 1.0 - 1e-5);
|
||||
Fr = fresnel_dielectric(I, Normal, eta);
|
||||
}
|
||||
|
||||
float sigma = clamp(Sigma, 0.0, 1.0);
|
||||
|
||||
BSDF = (Fr*Color)*ashikhmin_velvet(Normal, sigma);
|
||||
BSDF = Color*ashikhmin_velvet(Normal, sigma);
|
||||
}
|
||||
|
||||
|
||||
@@ -282,6 +282,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
|
||||
case NODE_FRESNEL:
|
||||
svm_node_fresnel(sd, stack, node.y, node.z, node.w);
|
||||
break;
|
||||
case NODE_BLEND_WEIGHT:
|
||||
svm_node_blend_weight(sd, stack, node);
|
||||
break;
|
||||
case NODE_SET_DISPLACEMENT:
|
||||
svm_node_set_displacement(sd, stack, node.y);
|
||||
break;
|
||||
|
||||
@@ -102,23 +102,19 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
|
||||
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
|
||||
break;
|
||||
#endif
|
||||
|
||||
ShaderClosure *sc = svm_node_closure_get(sd);
|
||||
svm_node_closure_set_mix_weight(sc, mix_weight);
|
||||
|
||||
/* index of refraction */
|
||||
float eta = clamp(1.0f-param2, 1e-5f, 1.0f - 1e-5f);
|
||||
eta = 1.0f/eta;
|
||||
|
||||
/* fresnel */
|
||||
float cosNO = dot(sd->N, sd->I);
|
||||
float fresnel = fresnel_dielectric_cos(cosNO, eta);
|
||||
float roughness = param1;
|
||||
|
||||
sc->weight *= fresnel;
|
||||
|
||||
/* setup bsdf */
|
||||
svm_node_glossy_setup(sd, sc, type, eta, roughness, false);
|
||||
if(type == CLOSURE_BSDF_REFLECTION_ID)
|
||||
bsdf_reflection_setup(sd, sc);
|
||||
else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
|
||||
bsdf_microfacet_beckmann_setup(sd, sc, roughness, 1.0f, false);
|
||||
else
|
||||
bsdf_microfacet_ggx_setup(sd, sc, roughness, 1.0f, false);
|
||||
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_REFRACTION_ID:
|
||||
@@ -128,10 +124,9 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
|
||||
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* index of refraction */
|
||||
float eta = clamp(1.0f-param2, 1e-5f, 1.0f - 1e-5f);
|
||||
eta = (sd->flag & SD_BACKFACING)? eta: 1.0f/eta;
|
||||
float eta = fmaxf(param2, 1.0f + 1e-5f);
|
||||
eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
|
||||
|
||||
/* fresnel */
|
||||
float cosNO = dot(sd->N, sd->I);
|
||||
@@ -173,7 +168,6 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
|
||||
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
|
||||
break;
|
||||
#endif
|
||||
|
||||
ShaderClosure *sc = svm_node_closure_get(sd);
|
||||
svm_node_closure_set_mix_weight(sc, mix_weight);
|
||||
|
||||
@@ -190,17 +184,6 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
|
||||
|
||||
/* sigma */
|
||||
float sigma = clamp(param1, 0.0f, 1.0f);
|
||||
|
||||
/* index of refraction */
|
||||
float eta = clamp(1.0f-param2, 1e-5f, 1.0f - 1e-5f);
|
||||
eta = 1.0f/eta;
|
||||
|
||||
/* fresnel */
|
||||
float cosNO = dot(sd->N, sd->I);
|
||||
float fresnel = fresnel_dielectric_cos(cosNO, eta);
|
||||
|
||||
sc->weight *= fresnel;
|
||||
|
||||
bsdf_ashikhmin_velvet_setup(sd, sc, sigma);
|
||||
break;
|
||||
}
|
||||
@@ -308,7 +291,8 @@ __device void svm_node_emission_weight(KernelGlobals *kg, ShaderData *sd, float
|
||||
uint strength_offset = node.z;
|
||||
uint total_power = node.w;
|
||||
|
||||
float3 weight = stack_load_float3(stack, color_offset)*stack_load_float(stack, strength_offset);
|
||||
float strength = stack_load_float(stack, strength_offset);
|
||||
float3 weight = stack_load_float3(stack, color_offset)*strength;
|
||||
|
||||
if(total_power && sd->object != ~0)
|
||||
weight /= object_surface_area(kg, sd->object);
|
||||
|
||||
@@ -20,12 +20,48 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Fresnel Node */
|
||||
|
||||
__device void svm_node_fresnel(ShaderData *sd, float *stack, uint fresnel_offset, uint fresnel_value, uint out_offset)
|
||||
__device void svm_node_fresnel(ShaderData *sd, float *stack, uint ior_offset, uint ior_value, uint out_offset)
|
||||
{
|
||||
float fresnel = (stack_valid(fresnel_offset))? stack_load_float(stack, fresnel_offset): __int_as_float(fresnel_value);
|
||||
fresnel = fmaxf(1.0f - fresnel, 0.00001f);
|
||||
float eta = (stack_valid(ior_offset))? stack_load_float(stack, ior_offset): __int_as_float(ior_value);
|
||||
eta = fmaxf(eta, 1.0f + 1e-5f);
|
||||
eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
|
||||
|
||||
float f = fresnel_dielectric_cos(dot(sd->I, sd->N), (sd->flag & SD_BACKFACING)? fresnel: 1.0f/fresnel);
|
||||
float f = fresnel_dielectric_cos(dot(sd->I, sd->N), eta);
|
||||
|
||||
stack_store_float(stack, out_offset, f);
|
||||
}
|
||||
|
||||
/* Blend Weight Node */
|
||||
|
||||
__device void svm_node_blend_weight(ShaderData *sd, float *stack, uint4 node)
|
||||
{
|
||||
uint blend_offset = node.y;
|
||||
uint blend_value = node.z;
|
||||
float blend = (stack_valid(blend_offset))? stack_load_float(stack, blend_offset): __int_as_float(blend_value);
|
||||
|
||||
uint type, out_offset;
|
||||
decode_node_uchar4(node.w, &type, &out_offset, NULL, NULL);
|
||||
|
||||
float f;
|
||||
|
||||
if(type == NODE_BLEND_WEIGHT_FRESNEL) {
|
||||
float eta = fmaxf(1.0f - blend, 1e-5f);
|
||||
eta = (sd->flag & SD_BACKFACING)? eta: 1.0f/eta;
|
||||
|
||||
f = fresnel_dielectric_cos(dot(sd->I, sd->N), eta);
|
||||
}
|
||||
else {
|
||||
f = fabsf(dot(sd->I, sd->N));
|
||||
|
||||
if(blend != 0.5f) {
|
||||
blend = clamp(blend, 0.0f, 1.0f);
|
||||
blend = (blend < 0.5f)? 2.0f*blend: 0.5f/(1.0f - blend);
|
||||
|
||||
f = powf(f, blend);
|
||||
}
|
||||
|
||||
f = 1.0f - f;
|
||||
}
|
||||
|
||||
stack_store_float(stack, out_offset, f);
|
||||
}
|
||||
|
||||
@@ -147,9 +147,9 @@ __device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y)
|
||||
__device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
|
||||
{
|
||||
uint id = node.y;
|
||||
uint co_offset, out_offset, srgb;
|
||||
uint co_offset, out_offset, alpha_offset, srgb;
|
||||
|
||||
decode_node_uchar4(node.z, &co_offset, &out_offset, &srgb, NULL);
|
||||
decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
|
||||
|
||||
float3 co = stack_load_float3(stack, co_offset);
|
||||
float4 f = svm_image_texture(kg, id, co.x, co.y);
|
||||
@@ -161,15 +161,18 @@ __device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *stack
|
||||
r.z = color_srgb_to_scene_linear(r.z);
|
||||
}
|
||||
|
||||
stack_store_float3(stack, out_offset, r);
|
||||
if(stack_valid(out_offset))
|
||||
stack_store_float3(stack, out_offset, r);
|
||||
if(stack_valid(alpha_offset))
|
||||
stack_store_float(stack, alpha_offset, f.w);
|
||||
}
|
||||
|
||||
__device void svm_node_tex_environment(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
|
||||
{
|
||||
uint id = node.y;
|
||||
uint co_offset, out_offset, srgb;
|
||||
uint co_offset, out_offset, alpha_offset, srgb;
|
||||
|
||||
decode_node_uchar4(node.z, &co_offset, &out_offset, &srgb, NULL);
|
||||
decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
|
||||
|
||||
float3 co = stack_load_float3(stack, co_offset);
|
||||
float u = (atan2f(co.y, co.x) + M_PI_F)/(2*M_PI_F);
|
||||
@@ -183,7 +186,10 @@ __device void svm_node_tex_environment(KernelGlobals *kg, ShaderData *sd, float
|
||||
r.z = color_srgb_to_scene_linear(r.z);
|
||||
}
|
||||
|
||||
stack_store_float3(stack, out_offset, r);
|
||||
if(stack_valid(out_offset))
|
||||
stack_store_float3(stack, out_offset, r);
|
||||
if(stack_valid(alpha_offset))
|
||||
stack_store_float(stack, alpha_offset, f.w);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -82,7 +82,8 @@ typedef enum NodeType {
|
||||
NODE_ATTR_BUMP_DX = 4400,
|
||||
NODE_ATTR_BUMP_DY = 4500,
|
||||
NODE_TEX_ENVIRONMENT = 4600,
|
||||
NODE_CLOSURE_HOLDOUT = 4700
|
||||
NODE_CLOSURE_HOLDOUT = 4700,
|
||||
NODE_BLEND_WEIGHT = 4800
|
||||
} NodeType;
|
||||
|
||||
typedef enum NodeAttributeType {
|
||||
@@ -249,6 +250,11 @@ typedef enum NodeVoronoiColoring {
|
||||
NODE_VORONOI_POSITION_OUTLINE_INTENSITY
|
||||
} NodeVoronoiColoring;
|
||||
|
||||
typedef enum NodeBlendWeightType {
|
||||
NODE_BLEND_WEIGHT_FRESNEL,
|
||||
NODE_BLEND_WEIGHT_FACING
|
||||
} NodeBlendWeightType;
|
||||
|
||||
typedef enum ShaderType {
|
||||
SHADER_TYPE_SURFACE,
|
||||
SHADER_TYPE_VOLUME,
|
||||
|
||||
@@ -85,7 +85,7 @@ void RenderBuffers::reset(Device *device, int width_, int height_)
|
||||
device->mem_copy_to(rng_state);
|
||||
}
|
||||
|
||||
float4 *RenderBuffers::copy_from_device(float exposure, int pass)
|
||||
float4 *RenderBuffers::copy_from_device(float exposure, int sample)
|
||||
{
|
||||
if(!buffer.device_pointer)
|
||||
return NULL;
|
||||
@@ -94,7 +94,7 @@ float4 *RenderBuffers::copy_from_device(float exposure, int pass)
|
||||
|
||||
float4 *out = new float4[width*height];
|
||||
float4 *in = (float4*)buffer.data_pointer;
|
||||
float scale = 1.0f/(float)pass;
|
||||
float scale = 1.0f/(float)sample;
|
||||
|
||||
for(int i = width*height - 1; i >= 0; i--) {
|
||||
float4 rgba = in[i]*scale;
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
~RenderBuffers();
|
||||
|
||||
void reset(Device *device, int width, int height);
|
||||
float4 *copy_from_device(float exposure, int pass);
|
||||
float4 *copy_from_device(float exposure, int sample);
|
||||
|
||||
protected:
|
||||
void device_free();
|
||||
|
||||
@@ -28,8 +28,10 @@ Camera::Camera()
|
||||
shutteropen = 0.0f;
|
||||
shutterclose = 1.0f;
|
||||
|
||||
lensradius = 0.0f;
|
||||
aperturesize = 0.0f;
|
||||
focaldistance = 10.0f;
|
||||
blades = 0;
|
||||
bladesrotation = 0.0f;
|
||||
|
||||
matrix = transform_identity();
|
||||
|
||||
@@ -134,8 +136,10 @@ void Camera::device_update(Device *device, DeviceScene *dscene)
|
||||
kcam->worldtocamera = transform_inverse(cameratoworld);
|
||||
|
||||
/* depth of field */
|
||||
kcam->lensradius = lensradius;
|
||||
kcam->aperturesize = aperturesize;
|
||||
kcam->focaldistance = focaldistance;
|
||||
kcam->blades = (blades < 3)? 0.0f: blades;
|
||||
kcam->bladesrotation = bladesrotation;
|
||||
|
||||
/* motion blur */
|
||||
kcam->shutteropen = shutteropen;
|
||||
@@ -168,7 +172,9 @@ bool Camera::modified(const Camera& cam)
|
||||
{
|
||||
return !((shutteropen == cam.shutteropen) &&
|
||||
(shutterclose == cam.shutterclose) &&
|
||||
(lensradius == cam.lensradius) &&
|
||||
(aperturesize == cam.aperturesize) &&
|
||||
(blades == cam.blades) &&
|
||||
(bladesrotation == cam.bladesrotation) &&
|
||||
(focaldistance == cam.focaldistance) &&
|
||||
(ortho == cam.ortho) &&
|
||||
(fov == cam.fov) &&
|
||||
|
||||
@@ -39,8 +39,10 @@ public:
|
||||
float shutterclose;
|
||||
|
||||
/* depth of field */
|
||||
float lensradius;
|
||||
float focaldistance;
|
||||
float aperturesize;
|
||||
uint blades;
|
||||
float bladesrotation;
|
||||
|
||||
/* orthographic/perspective */
|
||||
bool ortho;
|
||||
|
||||
@@ -49,6 +49,7 @@ ImageTextureNode::ImageTextureNode()
|
||||
|
||||
add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_COORDINATE);
|
||||
add_output("Color", SHADER_SOCKET_COLOR);
|
||||
add_output("Alpha", SHADER_SOCKET_FLOAT);
|
||||
}
|
||||
|
||||
ImageTextureNode::~ImageTextureNode()
|
||||
@@ -69,12 +70,16 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
|
||||
{
|
||||
ShaderInput *vector_in = input("Vector");
|
||||
ShaderOutput *color_out = output("Color");
|
||||
ShaderOutput *alpha_out = output("Alpha");
|
||||
|
||||
image_manager = compiler.image_manager;
|
||||
if(slot == -1)
|
||||
slot = image_manager->add_image(filename);
|
||||
|
||||
compiler.stack_assign(color_out);
|
||||
if(!color_out->links.empty())
|
||||
compiler.stack_assign(color_out);
|
||||
if(!alpha_out->links.empty())
|
||||
compiler.stack_assign(alpha_out);
|
||||
|
||||
if(slot != -1) {
|
||||
compiler.stack_assign(vector_in);
|
||||
@@ -83,12 +88,17 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
|
||||
compiler.encode_uchar4(
|
||||
vector_in->stack_offset,
|
||||
color_out->stack_offset,
|
||||
alpha_out->stack_offset,
|
||||
color_space_enum[color_space]));
|
||||
}
|
||||
else {
|
||||
/* image not found */
|
||||
compiler.add_node(NODE_VALUE_V, color_out->stack_offset);
|
||||
compiler.add_node(NODE_VALUE_V, make_float3(0, 0, 0));
|
||||
if(!color_out->links.empty()) {
|
||||
compiler.add_node(NODE_VALUE_V, color_out->stack_offset);
|
||||
compiler.add_node(NODE_VALUE_V, make_float3(0, 0, 0));
|
||||
}
|
||||
if(!alpha_out->links.empty())
|
||||
compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), alpha_out->stack_offset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +123,7 @@ EnvironmentTextureNode::EnvironmentTextureNode()
|
||||
|
||||
add_input("Vector", SHADER_SOCKET_VECTOR, ShaderInput::POSITION);
|
||||
add_output("Color", SHADER_SOCKET_COLOR);
|
||||
add_output("Alpha", SHADER_SOCKET_FLOAT);
|
||||
}
|
||||
|
||||
EnvironmentTextureNode::~EnvironmentTextureNode()
|
||||
@@ -133,12 +144,16 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
|
||||
{
|
||||
ShaderInput *vector_in = input("Vector");
|
||||
ShaderOutput *color_out = output("Color");
|
||||
ShaderOutput *alpha_out = output("Alpha");
|
||||
|
||||
image_manager = compiler.image_manager;
|
||||
if(slot == -1)
|
||||
slot = image_manager->add_image(filename);
|
||||
|
||||
compiler.stack_assign(color_out);
|
||||
if(!color_out->links.empty())
|
||||
compiler.stack_assign(color_out);
|
||||
if(!alpha_out->links.empty())
|
||||
compiler.stack_assign(alpha_out);
|
||||
|
||||
if(slot != -1) {
|
||||
compiler.stack_assign(vector_in);
|
||||
@@ -147,12 +162,17 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
|
||||
compiler.encode_uchar4(
|
||||
vector_in->stack_offset,
|
||||
color_out->stack_offset,
|
||||
alpha_out->stack_offset,
|
||||
color_space_enum[color_space]));
|
||||
}
|
||||
else {
|
||||
/* image not found */
|
||||
compiler.add_node(NODE_VALUE_V, color_out->stack_offset);
|
||||
compiler.add_node(NODE_VALUE_V, make_float3(0, 0, 0));
|
||||
if(!color_out->links.empty()) {
|
||||
compiler.add_node(NODE_VALUE_V, color_out->stack_offset);
|
||||
compiler.add_node(NODE_VALUE_V, make_float3(0, 0, 0));
|
||||
}
|
||||
if(!alpha_out->links.empty())
|
||||
compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), alpha_out->stack_offset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1080,7 +1100,6 @@ GlossyBsdfNode::GlossyBsdfNode()
|
||||
distribution = ustring("Beckmann");
|
||||
|
||||
add_input("Roughness", SHADER_SOCKET_FLOAT, 0.2f);
|
||||
add_input("Fresnel", SHADER_SOCKET_FLOAT, 1.0f);
|
||||
}
|
||||
|
||||
void GlossyBsdfNode::compile(SVMCompiler& compiler)
|
||||
@@ -1088,9 +1107,9 @@ void GlossyBsdfNode::compile(SVMCompiler& compiler)
|
||||
closure = (ClosureType)distribution_enum[distribution];
|
||||
|
||||
if(closure == CLOSURE_BSDF_REFLECTION_ID)
|
||||
BsdfNode::compile(compiler, NULL, input("Fresnel"));
|
||||
BsdfNode::compile(compiler, NULL, NULL);
|
||||
else
|
||||
BsdfNode::compile(compiler, input("Roughness"), input("Fresnel"));
|
||||
BsdfNode::compile(compiler, input("Roughness"), NULL);
|
||||
}
|
||||
|
||||
void GlossyBsdfNode::compile(OSLCompiler& compiler)
|
||||
@@ -1119,7 +1138,7 @@ GlassBsdfNode::GlassBsdfNode()
|
||||
distribution = ustring("Sharp");
|
||||
|
||||
add_input("Roughness", SHADER_SOCKET_FLOAT, 0.0f);
|
||||
add_input("Fresnel", SHADER_SOCKET_FLOAT, 0.3f);
|
||||
add_input("IOR", SHADER_SOCKET_FLOAT, 0.3f);
|
||||
}
|
||||
|
||||
void GlassBsdfNode::compile(SVMCompiler& compiler)
|
||||
@@ -1127,9 +1146,9 @@ void GlassBsdfNode::compile(SVMCompiler& compiler)
|
||||
closure = (ClosureType)distribution_enum[distribution];
|
||||
|
||||
if(closure == CLOSURE_BSDF_REFRACTION_ID)
|
||||
BsdfNode::compile(compiler, NULL, input("Fresnel"));
|
||||
BsdfNode::compile(compiler, NULL, input("IOR"));
|
||||
else
|
||||
BsdfNode::compile(compiler, input("Roughness"), input("Fresnel"));
|
||||
BsdfNode::compile(compiler, input("Roughness"), input("IOR"));
|
||||
}
|
||||
|
||||
void GlassBsdfNode::compile(OSLCompiler& compiler)
|
||||
@@ -1145,12 +1164,11 @@ VelvetBsdfNode::VelvetBsdfNode()
|
||||
closure = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID;
|
||||
|
||||
add_input("Sigma", SHADER_SOCKET_FLOAT, 1.0f);
|
||||
add_input("Fresnel", SHADER_SOCKET_FLOAT, 1.0f);
|
||||
}
|
||||
|
||||
void VelvetBsdfNode::compile(SVMCompiler& compiler)
|
||||
{
|
||||
BsdfNode::compile(compiler, input("Sigma"), input("Fresnel"));
|
||||
BsdfNode::compile(compiler, input("Sigma"), NULL);
|
||||
}
|
||||
|
||||
void VelvetBsdfNode::compile(OSLCompiler& compiler)
|
||||
@@ -1781,18 +1799,18 @@ FresnelNode::FresnelNode()
|
||||
: ShaderNode("Fresnel")
|
||||
{
|
||||
add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
|
||||
add_input("Fresnel", SHADER_SOCKET_FLOAT, 0.3f);
|
||||
add_input("IOR", SHADER_SOCKET_FLOAT, 1.45f);
|
||||
add_output("Fac", SHADER_SOCKET_FLOAT);
|
||||
}
|
||||
|
||||
void FresnelNode::compile(SVMCompiler& compiler)
|
||||
{
|
||||
ShaderInput *fresnel_in = input("Fresnel");
|
||||
ShaderInput *ior_in = input("IOR");
|
||||
ShaderOutput *fac_out = output("Fac");
|
||||
|
||||
compiler.stack_assign(fresnel_in);
|
||||
compiler.stack_assign(ior_in);
|
||||
compiler.stack_assign(fac_out);
|
||||
compiler.add_node(NODE_FRESNEL, fresnel_in->stack_offset, __float_as_int(fresnel_in->value.x), fac_out->stack_offset);
|
||||
compiler.add_node(NODE_FRESNEL, ior_in->stack_offset, __float_as_int(ior_in->value.x), fac_out->stack_offset);
|
||||
}
|
||||
|
||||
void FresnelNode::compile(OSLCompiler& compiler)
|
||||
@@ -1800,6 +1818,45 @@ void FresnelNode::compile(OSLCompiler& compiler)
|
||||
compiler.add(this, "node_fresnel");
|
||||
}
|
||||
|
||||
/* Blend Weight */
|
||||
|
||||
BlendWeightNode::BlendWeightNode()
|
||||
: ShaderNode("BlendWeight")
|
||||
{
|
||||
add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
|
||||
add_input("Blend", SHADER_SOCKET_FLOAT, 0.5f);
|
||||
|
||||
add_output("Fresnel", SHADER_SOCKET_FLOAT);
|
||||
add_output("Facing", SHADER_SOCKET_FLOAT);
|
||||
}
|
||||
|
||||
void BlendWeightNode::compile(SVMCompiler& compiler)
|
||||
{
|
||||
ShaderInput *blend_in = input("Blend");
|
||||
|
||||
if(blend_in->link)
|
||||
compiler.stack_assign(blend_in);
|
||||
|
||||
ShaderOutput *fresnel_out = output("Fresnel");
|
||||
if(!fresnel_out->links.empty()) {
|
||||
compiler.stack_assign(fresnel_out);
|
||||
compiler.add_node(NODE_BLEND_WEIGHT, blend_in->stack_offset, __float_as_int(blend_in->value.x),
|
||||
compiler.encode_uchar4(NODE_BLEND_WEIGHT_FRESNEL, fresnel_out->stack_offset));
|
||||
}
|
||||
|
||||
ShaderOutput *facing_out = output("Facing");
|
||||
if(!facing_out->links.empty()) {
|
||||
compiler.stack_assign(facing_out);
|
||||
compiler.add_node(NODE_BLEND_WEIGHT, blend_in->stack_offset, __float_as_int(blend_in->value.x),
|
||||
compiler.encode_uchar4(NODE_BLEND_WEIGHT_FACING, facing_out->stack_offset));
|
||||
}
|
||||
}
|
||||
|
||||
void BlendWeightNode::compile(OSLCompiler& compiler)
|
||||
{
|
||||
compiler.add(this, "node_blend_weight");
|
||||
}
|
||||
|
||||
/* Output */
|
||||
|
||||
OutputNode::OutputNode()
|
||||
|
||||
@@ -323,6 +323,11 @@ public:
|
||||
SHADER_NODE_CLASS(FresnelNode)
|
||||
};
|
||||
|
||||
class BlendWeightNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(BlendWeightNode)
|
||||
};
|
||||
|
||||
class MathNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(MathNode)
|
||||
|
||||
@@ -99,6 +99,7 @@ public:
|
||||
class SceneParams {
|
||||
public:
|
||||
enum { OSL, SVM } shadingsystem;
|
||||
bool use_multi_closure;
|
||||
enum BVHType { BVH_DYNAMIC, BVH_STATIC } bvh_type;
|
||||
bool use_bvh_cache;
|
||||
bool use_bvh_spatial_split;
|
||||
@@ -107,6 +108,7 @@ public:
|
||||
SceneParams()
|
||||
{
|
||||
shadingsystem = SVM;
|
||||
use_multi_closure = false;
|
||||
bvh_type = BVH_DYNAMIC;
|
||||
use_bvh_cache = false;
|
||||
use_bvh_spatial_split = false;
|
||||
|
||||
@@ -33,7 +33,7 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
Session::Session(const SessionParams& params_)
|
||||
: params(params_),
|
||||
tile_manager(params.progressive, params.passes, params.tile_size, params.min_size)
|
||||
tile_manager(params.progressive, params.samples, params.tile_size, params.min_size)
|
||||
{
|
||||
device_use_gl = ((params.device_type != DEVICE_CPU) && !params.background);
|
||||
|
||||
@@ -48,12 +48,12 @@ Session::Session(const SessionParams& params_)
|
||||
reset_time = 0.0;
|
||||
preview_time = 0.0;
|
||||
paused_time = 0.0;
|
||||
pass = 0;
|
||||
sample = 0;
|
||||
|
||||
delayed_reset.do_reset = false;
|
||||
delayed_reset.w = 0;
|
||||
delayed_reset.h = 0;
|
||||
delayed_reset.passes = 0;
|
||||
delayed_reset.samples = 0;
|
||||
|
||||
display_outdated = false;
|
||||
gpu_draw_ready = false;
|
||||
@@ -108,7 +108,7 @@ bool Session::ready_to_reset()
|
||||
|
||||
/* GPU Session */
|
||||
|
||||
void Session::reset_gpu(int w, int h, int passes)
|
||||
void Session::reset_gpu(int w, int h, int samples)
|
||||
{
|
||||
/* block for buffer acces and reset immediately. we can't do this
|
||||
in the thread, because we need to allocate an OpenGL buffer, and
|
||||
@@ -119,7 +119,7 @@ void Session::reset_gpu(int w, int h, int passes)
|
||||
display_outdated = true;
|
||||
reset_time = time_dt();
|
||||
|
||||
reset_(w, h, passes);
|
||||
reset_(w, h, samples);
|
||||
|
||||
gpu_need_tonemap = false;
|
||||
gpu_need_tonemap_cond.notify_all();
|
||||
@@ -207,7 +207,7 @@ void Session::run_gpu()
|
||||
|
||||
if(!no_tiles) {
|
||||
/* buffers mutex is locked entirely while rendering each
|
||||
pass, and released/reacquired on each iteration to allow
|
||||
sample, and released/reacquired on each iteration to allow
|
||||
reset and draw in between */
|
||||
thread_scoped_lock buffers_lock(buffers->mutex);
|
||||
|
||||
@@ -249,7 +249,7 @@ void Session::run_gpu()
|
||||
|
||||
/* CPU Session */
|
||||
|
||||
void Session::reset_cpu(int w, int h, int passes)
|
||||
void Session::reset_cpu(int w, int h, int samples)
|
||||
{
|
||||
thread_scoped_lock reset_lock(delayed_reset.mutex);
|
||||
|
||||
@@ -258,7 +258,7 @@ void Session::reset_cpu(int w, int h, int passes)
|
||||
|
||||
delayed_reset.w = w;
|
||||
delayed_reset.h = h;
|
||||
delayed_reset.passes = passes;
|
||||
delayed_reset.samples = samples;
|
||||
delayed_reset.do_reset = true;
|
||||
device->task_cancel();
|
||||
|
||||
@@ -294,7 +294,7 @@ void Session::run_cpu()
|
||||
thread_scoped_lock buffers_lock(buffers->mutex);
|
||||
thread_scoped_lock display_lock(display->mutex);
|
||||
|
||||
reset_(delayed_reset.w, delayed_reset.h, delayed_reset.passes);
|
||||
reset_(delayed_reset.w, delayed_reset.h, delayed_reset.samples);
|
||||
delayed_reset.do_reset = false;
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@ void Session::run_cpu()
|
||||
|
||||
if(!no_tiles) {
|
||||
/* buffers mutex is locked entirely while rendering each
|
||||
pass, and released/reacquired on each iteration to allow
|
||||
sample, and released/reacquired on each iteration to allow
|
||||
reset and draw in between */
|
||||
thread_scoped_lock buffers_lock(buffers->mutex);
|
||||
|
||||
@@ -368,11 +368,11 @@ void Session::run_cpu()
|
||||
if(delayed_reset.do_reset) {
|
||||
/* reset rendering if request from main thread */
|
||||
delayed_reset.do_reset = false;
|
||||
reset_(delayed_reset.w, delayed_reset.h, delayed_reset.passes);
|
||||
reset_(delayed_reset.w, delayed_reset.h, delayed_reset.samples);
|
||||
}
|
||||
else if(need_tonemap) {
|
||||
/* tonemap only if we do not reset, we don't we don't
|
||||
want to show the result of an incomplete pass*/
|
||||
want to show the result of an incomplete sample*/
|
||||
tonemap();
|
||||
}
|
||||
}
|
||||
@@ -418,7 +418,7 @@ bool Session::draw(int w, int h)
|
||||
return draw_cpu(w, h);
|
||||
}
|
||||
|
||||
void Session::reset_(int w, int h, int passes)
|
||||
void Session::reset_(int w, int h, int samples)
|
||||
{
|
||||
if(w != buffers->width || h != buffers->height) {
|
||||
gpu_draw_ready = false;
|
||||
@@ -426,27 +426,27 @@ void Session::reset_(int w, int h, int passes)
|
||||
display->reset(device, w, h);
|
||||
}
|
||||
|
||||
tile_manager.reset(w, h, passes);
|
||||
tile_manager.reset(w, h, samples);
|
||||
|
||||
start_time = time_dt();
|
||||
preview_time = 0.0;
|
||||
paused_time = 0.0;
|
||||
pass = 0;
|
||||
sample = 0;
|
||||
}
|
||||
|
||||
void Session::reset(int w, int h, int passes)
|
||||
void Session::reset(int w, int h, int samples)
|
||||
{
|
||||
if(device_use_gl)
|
||||
reset_gpu(w, h, passes);
|
||||
reset_gpu(w, h, samples);
|
||||
else
|
||||
reset_cpu(w, h, passes);
|
||||
reset_cpu(w, h, samples);
|
||||
}
|
||||
|
||||
void Session::set_passes(int passes)
|
||||
void Session::set_samples(int samples)
|
||||
{
|
||||
if(passes != params.passes) {
|
||||
params.passes = passes;
|
||||
tile_manager.set_passes(passes);
|
||||
if(samples != params.samples) {
|
||||
params.samples = samples;
|
||||
tile_manager.set_samples(samples);
|
||||
|
||||
{
|
||||
thread_scoped_lock pause_lock(pause_mutex);
|
||||
@@ -504,7 +504,7 @@ void Session::update_scene()
|
||||
|
||||
void Session::update_status_time(bool show_pause, bool show_done)
|
||||
{
|
||||
int pass = tile_manager.state.pass;
|
||||
int sample = tile_manager.state.sample;
|
||||
int resolution = tile_manager.state.resolution;
|
||||
|
||||
/* update status */
|
||||
@@ -512,10 +512,10 @@ void Session::update_status_time(bool show_pause, bool show_done)
|
||||
|
||||
if(!params.progressive)
|
||||
substatus = "Path Tracing";
|
||||
else if(params.passes == INT_MAX)
|
||||
substatus = string_printf("Path Tracing Pass %d", pass+1);
|
||||
else if(params.samples == INT_MAX)
|
||||
substatus = string_printf("Path Tracing Sample %d", sample+1);
|
||||
else
|
||||
substatus = string_printf("Path Tracing Pass %d/%d", pass+1, params.passes);
|
||||
substatus = string_printf("Path Tracing Sample %d/%d", sample+1, params.samples);
|
||||
|
||||
if(show_pause)
|
||||
status = "Paused";
|
||||
@@ -531,13 +531,13 @@ void Session::update_status_time(bool show_pause, bool show_done)
|
||||
preview_time = time_dt();
|
||||
|
||||
double total_time = time_dt() - start_time - paused_time;
|
||||
double pass_time = (pass == 0)? 0.0: (time_dt() - preview_time - paused_time)/(pass);
|
||||
double sample_time = (sample == 0)? 0.0: (time_dt() - preview_time - paused_time)/(sample);
|
||||
|
||||
/* negative can happen when we pause a bit before rendering, can discard that */
|
||||
if(total_time < 0.0) total_time = 0.0;
|
||||
if(preview_time < 0.0) preview_time = 0.0;
|
||||
|
||||
progress.set_pass(pass + 1, total_time, pass_time);
|
||||
progress.set_sample(sample + 1, total_time, sample_time);
|
||||
}
|
||||
|
||||
void Session::path_trace(Tile& tile)
|
||||
@@ -551,7 +551,7 @@ void Session::path_trace(Tile& tile)
|
||||
task.h = tile.h;
|
||||
task.buffer = buffers->buffer.device_pointer;
|
||||
task.rng_state = buffers->rng_state.device_pointer;
|
||||
task.pass = tile_manager.state.pass;
|
||||
task.sample = tile_manager.state.sample;
|
||||
task.resolution = tile_manager.state.resolution;
|
||||
|
||||
device->task_add(task);
|
||||
@@ -568,7 +568,7 @@ void Session::tonemap()
|
||||
task.h = tile_manager.state.height;
|
||||
task.rgba = display->rgba.device_pointer;
|
||||
task.buffer = buffers->buffer.device_pointer;
|
||||
task.pass = tile_manager.state.pass;
|
||||
task.sample = tile_manager.state.sample;
|
||||
task.resolution = tile_manager.state.resolution;
|
||||
|
||||
if(task.w > 0 && task.h > 0) {
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
string output_path;
|
||||
|
||||
bool progressive;
|
||||
int passes;
|
||||
int samples;
|
||||
int tile_size;
|
||||
int min_size;
|
||||
int threads;
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
output_path = "";
|
||||
|
||||
progressive = false;
|
||||
passes = INT_MAX;
|
||||
samples = INT_MAX;
|
||||
tile_size = 64;
|
||||
min_size = 64;
|
||||
threads = 0;
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
{ return !(device_type == params.device_type
|
||||
&& background == params.background
|
||||
&& output_path == params.output_path
|
||||
/* && passes == params.passes */
|
||||
/* && samples == params.samples */
|
||||
&& progressive == params.progressive
|
||||
&& tile_size == params.tile_size
|
||||
&& min_size == params.min_size
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
DisplayBuffer *display;
|
||||
Progress progress;
|
||||
SessionParams params;
|
||||
int pass;
|
||||
int sample;
|
||||
|
||||
Session(const SessionParams& params);
|
||||
~Session();
|
||||
@@ -107,8 +107,8 @@ public:
|
||||
void wait();
|
||||
|
||||
bool ready_to_reset();
|
||||
void reset(int w, int h, int passes);
|
||||
void set_passes(int passes);
|
||||
void reset(int w, int h, int samples);
|
||||
void set_samples(int samples);
|
||||
void set_pause(bool pause);
|
||||
|
||||
protected:
|
||||
@@ -116,7 +116,7 @@ protected:
|
||||
thread_mutex mutex;
|
||||
bool do_reset;
|
||||
int w, h;
|
||||
int passes;
|
||||
int samples;
|
||||
} delayed_reset;
|
||||
|
||||
void run();
|
||||
@@ -126,15 +126,15 @@ protected:
|
||||
|
||||
void tonemap();
|
||||
void path_trace(Tile& tile);
|
||||
void reset_(int w, int h, int passes);
|
||||
void reset_(int w, int h, int samples);
|
||||
|
||||
void run_cpu();
|
||||
bool draw_cpu(int w, int h);
|
||||
void reset_cpu(int w, int h, int passes);
|
||||
void reset_cpu(int w, int h, int samples);
|
||||
|
||||
void run_gpu();
|
||||
bool draw_gpu(int w, int h);
|
||||
void reset_gpu(int w, int h, int passes);
|
||||
void reset_gpu(int w, int h, int samples);
|
||||
|
||||
TileManager tile_manager;
|
||||
bool device_use_gl;
|
||||
|
||||
@@ -69,7 +69,8 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
|
||||
if(shader->has_surface_emission)
|
||||
scene->light_manager->need_update = true;
|
||||
|
||||
SVMCompiler compiler(scene->shader_manager, scene->image_manager);
|
||||
SVMCompiler compiler(scene->shader_manager, scene->image_manager,
|
||||
scene->params.use_multi_closure);
|
||||
compiler.sunsky = (sunsky_done)? NULL: &dscene->data.sunsky;
|
||||
compiler.background = ((int)i == scene->default_background);
|
||||
compiler.compile(shader, svm_nodes, i);
|
||||
@@ -96,7 +97,7 @@ void SVMShaderManager::device_free(Device *device, DeviceScene *dscene)
|
||||
|
||||
/* Graph Compiler */
|
||||
|
||||
SVMCompiler::SVMCompiler(ShaderManager *shader_manager_, ImageManager *image_manager_)
|
||||
SVMCompiler::SVMCompiler(ShaderManager *shader_manager_, ImageManager *image_manager_, bool use_multi_closure_)
|
||||
{
|
||||
shader_manager = shader_manager_;
|
||||
image_manager = image_manager_;
|
||||
@@ -106,6 +107,7 @@ SVMCompiler::SVMCompiler(ShaderManager *shader_manager_, ImageManager *image_man
|
||||
current_shader = NULL;
|
||||
background = false;
|
||||
mix_weight_offset = SVM_STACK_INVALID;
|
||||
use_multi_closure = use_multi_closure_;
|
||||
}
|
||||
|
||||
int SVMCompiler::stack_size(ShaderSocketType type)
|
||||
@@ -573,9 +575,8 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
|
||||
|
||||
if(generate) {
|
||||
set<ShaderNode*> done;
|
||||
bool multi_closure = false; /* __MULTI_CLOSURE__ */
|
||||
|
||||
if(multi_closure) {
|
||||
if(use_multi_closure) {
|
||||
generate_multi_closure(clin->link->parent, done, SVM_STACK_INVALID);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -53,7 +53,8 @@ public:
|
||||
|
||||
class SVMCompiler {
|
||||
public:
|
||||
SVMCompiler(ShaderManager *shader_manager, ImageManager *image_manager);
|
||||
SVMCompiler(ShaderManager *shader_manager, ImageManager *image_manager,
|
||||
bool use_multi_closure_);
|
||||
void compile(Shader *shader, vector<int4>& svm_nodes, int index);
|
||||
|
||||
void stack_assign(ShaderOutput *output);
|
||||
@@ -123,6 +124,7 @@ protected:
|
||||
Stack active_stack;
|
||||
int max_stack_use;
|
||||
uint mix_weight_offset;
|
||||
bool use_multi_closure;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
TileManager::TileManager(bool progressive_, int passes_, int tile_size_, int min_size_)
|
||||
TileManager::TileManager(bool progressive_, int samples_, int tile_size_, int min_size_)
|
||||
{
|
||||
progressive = progressive_;
|
||||
tile_size = tile_size_;
|
||||
@@ -35,7 +35,7 @@ TileManager::~TileManager()
|
||||
{
|
||||
}
|
||||
|
||||
void TileManager::reset(int width_, int height_, int passes_)
|
||||
void TileManager::reset(int width_, int height_, int samples_)
|
||||
{
|
||||
full_width = width_;
|
||||
full_height = height_;
|
||||
@@ -53,18 +53,18 @@ void TileManager::reset(int width_, int height_, int passes_)
|
||||
}
|
||||
}
|
||||
|
||||
passes = passes_;
|
||||
samples = samples_;
|
||||
|
||||
state.width = 0;
|
||||
state.height = 0;
|
||||
state.pass = -1;
|
||||
state.sample = -1;
|
||||
state.resolution = start_resolution;
|
||||
state.tiles.clear();
|
||||
}
|
||||
|
||||
void TileManager::set_passes(int passes_)
|
||||
void TileManager::set_samples(int samples_)
|
||||
{
|
||||
passes = passes_;
|
||||
samples = samples_;
|
||||
}
|
||||
|
||||
void TileManager::set_tiles()
|
||||
@@ -96,7 +96,7 @@ void TileManager::set_tiles()
|
||||
|
||||
bool TileManager::done()
|
||||
{
|
||||
return (state.pass+1 >= passes);
|
||||
return (state.sample+1 >= samples && state.resolution == 1);
|
||||
}
|
||||
|
||||
bool TileManager::next()
|
||||
@@ -105,12 +105,12 @@ bool TileManager::next()
|
||||
return false;
|
||||
|
||||
if(progressive && state.resolution > 1) {
|
||||
state.pass = 0;
|
||||
state.sample = 0;
|
||||
state.resolution /= 2;
|
||||
set_tiles();
|
||||
}
|
||||
else {
|
||||
state.pass++;
|
||||
state.sample++;
|
||||
state.resolution = 1;
|
||||
set_tiles();
|
||||
}
|
||||
|
||||
@@ -42,16 +42,16 @@ public:
|
||||
struct State {
|
||||
int width;
|
||||
int height;
|
||||
int pass;
|
||||
int sample;
|
||||
int resolution;
|
||||
list<Tile> tiles;
|
||||
} state;
|
||||
|
||||
TileManager(bool progressive, int passes, int tile_size, int min_size);
|
||||
TileManager(bool progressive, int samples, int tile_size, int min_size);
|
||||
~TileManager();
|
||||
|
||||
void reset(int width, int height, int passes);
|
||||
void set_passes(int passes);
|
||||
void reset(int width, int height, int samples);
|
||||
void set_samples(int samples);
|
||||
bool next();
|
||||
bool done();
|
||||
|
||||
@@ -59,7 +59,7 @@ protected:
|
||||
void set_tiles();
|
||||
|
||||
bool progressive;
|
||||
int passes;
|
||||
int samples;
|
||||
int tile_size;
|
||||
int min_size;
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@ class Progress {
|
||||
public:
|
||||
Progress()
|
||||
{
|
||||
pass = 0;
|
||||
sample = 0;
|
||||
total_time = 0.0f;
|
||||
pass_time = 0.0f;
|
||||
sample_time = 0.0f;
|
||||
status = "Initializing";
|
||||
substatus = "";
|
||||
update_cb = NULL;
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
{
|
||||
thread_scoped_lock lock(progress.progress_mutex);
|
||||
|
||||
progress.get_pass(pass, total_time, pass_time);
|
||||
progress.get_sample(sample, total_time, sample_time);
|
||||
progress.get_status(status, substatus);
|
||||
|
||||
return *this;
|
||||
@@ -88,24 +88,24 @@ public:
|
||||
cancel_cb = function;
|
||||
}
|
||||
|
||||
/* pass and timing information */
|
||||
/* sample and timing information */
|
||||
|
||||
void set_pass(int pass_, double total_time_, double pass_time_)
|
||||
void set_sample(int sample_, double total_time_, double sample_time_)
|
||||
{
|
||||
thread_scoped_lock lock(progress_mutex);
|
||||
|
||||
pass = pass_;
|
||||
sample = sample_;
|
||||
total_time = total_time_;
|
||||
pass_time = pass_time_;
|
||||
sample_time = sample_time_;
|
||||
}
|
||||
|
||||
void get_pass(int& pass_, double& total_time_, double& pass_time_)
|
||||
void get_sample(int& sample_, double& total_time_, double& sample_time_)
|
||||
{
|
||||
thread_scoped_lock lock(progress_mutex);
|
||||
|
||||
pass_ = pass;
|
||||
sample_ = sample;
|
||||
total_time_ = total_time;
|
||||
pass_time_ = pass_time;
|
||||
sample_time_ = sample_time;
|
||||
}
|
||||
|
||||
/* status messages */
|
||||
@@ -156,10 +156,10 @@ protected:
|
||||
boost::function<void(void)> update_cb;
|
||||
boost::function<void(void)> cancel_cb;
|
||||
|
||||
int pass;
|
||||
int sample;
|
||||
|
||||
double total_time;
|
||||
double pass_time;
|
||||
double sample_time;
|
||||
|
||||
string status;
|
||||
string substatus;
|
||||
|
||||
@@ -100,18 +100,23 @@ class DATA_PT_camera(CameraButtonsPanel, Panel):
|
||||
col.prop(cam, "clip_start", text="Start")
|
||||
col.prop(cam, "clip_end", text="End")
|
||||
|
||||
layout.label(text="Depth of Field:")
|
||||
class DATA_PT_camera_dof(CameraButtonsPanel, Panel):
|
||||
bl_label = "Depth of Field"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
cam = context.camera
|
||||
|
||||
split = layout.split()
|
||||
split.prop(cam, "dof_object", text="")
|
||||
|
||||
col = split.column()
|
||||
|
||||
if cam.dof_object is not None:
|
||||
col.enabled = False
|
||||
col.active = cam.dof_object is None
|
||||
col.prop(cam, "dof_distance", text="Distance")
|
||||
|
||||
|
||||
class DATA_PT_camera_display(CameraButtonsPanel, Panel):
|
||||
bl_label = "Display"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
|
||||
|
||||
@@ -128,7 +128,7 @@ typedef struct bNodeType {
|
||||
#define NODE_CLASS_OP_DYNAMIC 11
|
||||
#define NODE_CLASS_PATTERN 12
|
||||
#define NODE_CLASS_TEXTURE 13
|
||||
#define NODE_CLASS_CLOSURE 14
|
||||
#define NODE_CLASS_SHADER 14
|
||||
|
||||
/* bNodeSocketType flag */
|
||||
#define SOCK_NO_VALUE 1
|
||||
@@ -282,7 +282,7 @@ struct ShadeResult;
|
||||
#define SH_NODE_OUTPUT_WORLD 125
|
||||
#define SH_NODE_OUTPUT_LAMP 126
|
||||
#define SH_NODE_FRESNEL 127
|
||||
#define SH_NODE_MIX_CLOSURE 128
|
||||
#define SH_NODE_MIX_SHADER 128
|
||||
#define SH_NODE_ATTRIBUTE 129
|
||||
#define SH_NODE_BACKGROUND 130
|
||||
#define SH_NODE_BSDF_ANISOTROPIC 131
|
||||
@@ -308,10 +308,11 @@ struct ShadeResult;
|
||||
#define SH_NODE_TEX_STUCCI 153
|
||||
#define SH_NODE_TEX_DISTNOISE 154
|
||||
#define SH_NODE_TEX_COORD 155
|
||||
#define SH_NODE_ADD_CLOSURE 156
|
||||
#define SH_NODE_ADD_SHADER 156
|
||||
#define SH_NODE_TEX_ENVIRONMENT 157
|
||||
#define SH_NODE_OUTPUT_TEXTURE 158
|
||||
#define SH_NODE_HOLDOUT 159
|
||||
#define SH_NODE_BLEND_WEIGHT 160
|
||||
|
||||
/* custom defines options for Material node */
|
||||
#define SH_NODE_MAT_DIFF 1
|
||||
|
||||
@@ -3122,7 +3122,7 @@ static void gpu_from_node_stack(ListBase *sockets, bNodeStack **ns, GPUNodeStack
|
||||
gs[i].type= GPU_VEC3;
|
||||
else if (sock->type == SOCK_RGBA)
|
||||
gs[i].type= GPU_VEC4;
|
||||
else if (sock->type == SOCK_CLOSURE)
|
||||
else if (sock->type == SOCK_SHADER)
|
||||
gs[i].type= GPU_VEC4;
|
||||
else
|
||||
gs[i].type= GPU_NONE;
|
||||
@@ -3219,9 +3219,9 @@ static void ntreeGPUOutputLink(GPUMaterial *mat, bNode *node, bNodeStack *nsout[
|
||||
if(nsout[i]->data) {
|
||||
GPUNodeLink *result= nsout[i]->data;
|
||||
|
||||
/* for closures, we can output the color directly, for others we
|
||||
/* for shader sockets, we can output the color directly, for others we
|
||||
apply diffuse shading so we don't have flat colors */
|
||||
if(sock->type != SOCK_CLOSURE)
|
||||
if(sock->type != SOCK_SHADER)
|
||||
GPU_link(mat, "node_bsdf_diffuse", result, GPU_builtin(GPU_VIEW_NORMAL), &result);
|
||||
|
||||
GPU_material_output_link(mat, result);
|
||||
@@ -3690,6 +3690,7 @@ static void registerShaderNodes(ListBase *ntypelist)
|
||||
register_node_type_sh_geometry(ntypelist);
|
||||
register_node_type_sh_light_path(ntypelist);
|
||||
register_node_type_sh_fresnel(ntypelist);
|
||||
register_node_type_sh_blend_weight(ntypelist);
|
||||
register_node_type_sh_tex_coord(ntypelist);
|
||||
|
||||
register_node_type_sh_background(ntypelist);
|
||||
@@ -3700,8 +3701,8 @@ static void registerShaderNodes(ListBase *ntypelist)
|
||||
register_node_type_sh_bsdf_transparent(ntypelist);
|
||||
register_node_type_sh_bsdf_velvet(ntypelist);
|
||||
register_node_type_sh_emission(ntypelist);
|
||||
register_node_type_sh_mix_closure(ntypelist);
|
||||
register_node_type_sh_add_closure(ntypelist);
|
||||
register_node_type_sh_mix_shader(ntypelist);
|
||||
register_node_type_sh_add_shader(ntypelist);
|
||||
register_node_type_sh_holdout(ntypelist);
|
||||
|
||||
register_node_type_sh_output_lamp(ntypelist);
|
||||
|
||||
@@ -2103,6 +2103,44 @@ static void lib_nodetree_do_versions_group(bNodeTree *ntree)
|
||||
}
|
||||
}
|
||||
|
||||
static void ntree_tmp_cycles_version_patch(bNodeTree *ntree)
|
||||
{
|
||||
bNode *node;
|
||||
bNodeSocket *sock;
|
||||
|
||||
for(node=ntree->nodes.first; node; node=node->next) {
|
||||
if(node->type == SH_NODE_FRESNEL) {
|
||||
node->type = SH_NODE_BLEND_WEIGHT;
|
||||
|
||||
for(sock=node->inputs.first; sock; sock=sock->next)
|
||||
if(strcmp(sock->name, "Fresnel") == 0)
|
||||
strcpy(sock->name, "Blend");
|
||||
|
||||
for(sock=node->outputs.first; sock; sock=sock->next)
|
||||
if(strcmp(sock->name, "Fac") == 0)
|
||||
strcpy(sock->name, "Fresnel");
|
||||
}
|
||||
else {
|
||||
for(sock=node->inputs.first; sock; sock=sock->next) {
|
||||
if(strcmp(sock->name, "Closure1") == 0)
|
||||
strcpy(sock->name, "Shader1");
|
||||
|
||||
if(strcmp(sock->name, "Closure2") == 0)
|
||||
strcpy(sock->name, "Shader2");
|
||||
|
||||
if(strcmp(sock->name, "Fresnel") == 0) {
|
||||
strcpy(sock->name, "IOR");
|
||||
sock->ns.vec[0] = 1.0f/MAX2(1.0f - sock->ns.vec[0], 1e-5f);
|
||||
}
|
||||
}
|
||||
|
||||
for(sock=node->outputs.first; sock; sock=sock->next)
|
||||
if(strcmp(sock->name, "Closure") == 0)
|
||||
strcpy(sock->name, "Shader");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* verify types for nodes and groups, all data has to be read */
|
||||
/* open = 0: appending/linking, open = 1: open new file (need to clean out dynamic
|
||||
* typedefs*/
|
||||
@@ -2123,6 +2161,7 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
|
||||
/* now create the own typeinfo structs an verify nodes */
|
||||
/* here we still assume no groups in groups */
|
||||
for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) {
|
||||
ntree_tmp_cycles_version_patch(ntree);
|
||||
ntreeVerifyTypes(ntree); /* internal nodes, no groups! */
|
||||
}
|
||||
|
||||
@@ -2142,8 +2181,10 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
|
||||
}
|
||||
/* now verify all types in material trees, groups are set OK now */
|
||||
for(ma= main->mat.first; ma; ma= ma->id.next) {
|
||||
if(ma->nodetree)
|
||||
if(ma->nodetree) {
|
||||
ntree_tmp_cycles_version_patch(ma->nodetree);
|
||||
lib_nodetree_do_versions_group(ma->nodetree);
|
||||
}
|
||||
}
|
||||
/* and scene trees */
|
||||
for(sce= main->scene.first; sce; sce= sce->id.next) {
|
||||
@@ -2155,7 +2196,21 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
|
||||
if(tx->nodetree)
|
||||
lib_nodetree_do_versions_group(tx->nodetree);
|
||||
}
|
||||
|
||||
/* and world trees */
|
||||
for(wrld= main->world.first; wrld; wrld= wrld->id.next) {
|
||||
if(wrld->nodetree) {
|
||||
ntree_tmp_cycles_version_patch(wrld->nodetree);
|
||||
lib_nodetree_do_versions_group(wrld->nodetree);
|
||||
}
|
||||
}
|
||||
/* and lamp trees */
|
||||
for(la= main->lamp.first; la; la= la->id.next) {
|
||||
if(la->nodetree) {
|
||||
ntree_tmp_cycles_version_patch(la->nodetree);
|
||||
lib_nodetree_do_versions_group(la->nodetree);
|
||||
}
|
||||
}
|
||||
|
||||
for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
|
||||
ntree->flag &= ~NTREE_DO_VERSIONS;
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ static void ui_node_sock_name(bNodeSocket *sock, char name[UI_MAX_NAME_STR])
|
||||
!(node->typeinfo->flag & NODE_OPTIONS))
|
||||
BLI_snprintf(name, UI_MAX_NAME_STR, "%s | %s", name, sock->link->fromsock->name);
|
||||
}
|
||||
else if(sock->type == SOCK_CLOSURE)
|
||||
else if(sock->type == SOCK_SHADER)
|
||||
BLI_strncpy(name, "None", UI_MAX_NAME_STR);
|
||||
else
|
||||
BLI_strncpy(name, "Default", UI_MAX_NAME_STR);
|
||||
@@ -252,7 +252,7 @@ static void ui_node_link(bContext *C, void *arg_p, void *event_p)
|
||||
|
||||
static int ui_compatible_sockets(int typeA, int typeB)
|
||||
{
|
||||
if(typeA == SOCK_CLOSURE || typeB == SOCK_CLOSURE)
|
||||
if(typeA == SOCK_SHADER || typeB == SOCK_SHADER)
|
||||
return (typeA == typeB);
|
||||
|
||||
return (typeA == typeB);
|
||||
@@ -396,7 +396,7 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_
|
||||
|
||||
ui_node_menu_column(bmain, arg, split, "Input", NODE_CLASS_INPUT);
|
||||
ui_node_menu_column(bmain, arg, split, "Output", NODE_CLASS_OUTPUT);
|
||||
ui_node_menu_column(bmain, arg, split, "Closure", NODE_CLASS_CLOSURE);
|
||||
ui_node_menu_column(bmain, arg, split, "Shader", NODE_CLASS_SHADER);
|
||||
ui_node_menu_column(bmain, arg, split, "Texture", NODE_CLASS_TEXTURE);
|
||||
ui_node_menu_column(bmain, arg, split, "Color", NODE_CLASS_OP_COLOR);
|
||||
ui_node_menu_column(bmain, arg, split, "Vector", NODE_CLASS_OP_VECTOR);
|
||||
@@ -438,7 +438,7 @@ void uiTemplateNodeLink(uiLayout *layout, bNodeTree *ntree, bNode *node, bNodeSo
|
||||
|
||||
uiBlockSetCurLayout(block, layout);
|
||||
|
||||
if(sock->link || sock->type == SOCK_CLOSURE || (stype && (stype->flag & SOCK_NO_VALUE))) {
|
||||
if(sock->link || sock->type == SOCK_SHADER || (stype && (stype->flag & SOCK_NO_VALUE))) {
|
||||
char name[UI_MAX_NAME_STR];
|
||||
ui_node_sock_name(sock, name);
|
||||
but= uiDefMenuBut(block, ui_template_node_link_menu, NULL, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, "");
|
||||
@@ -543,7 +543,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree,
|
||||
bNodeSocketType *stype = ui_node_input_socket_type(node, input);
|
||||
|
||||
/* input not linked, show value */
|
||||
if(input->type != SOCK_CLOSURE && (!stype || !(stype->flag & SOCK_NO_VALUE))) {
|
||||
if(input->type != SOCK_SHADER && (!stype || !(stype->flag & SOCK_NO_VALUE))) {
|
||||
if(input->type == SOCK_VECTOR) {
|
||||
row = uiLayoutRow(split, 0);
|
||||
col = uiLayoutColumn(row, 0);
|
||||
|
||||
@@ -882,7 +882,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
|
||||
socket_circle_draw(sock, socket_size);
|
||||
|
||||
if(node->block && sock->link==NULL) {
|
||||
if((stype && stype->flag & SOCK_NO_VALUE) || sock->type==SOCK_CLOSURE) {
|
||||
if((stype && stype->flag & SOCK_NO_VALUE) || sock->type==SOCK_SHADER) {
|
||||
uiDefBut(node->block, LABEL, 0, sock->name, (short)(sock->locx+7), (short)(sock->locy-9.0f),
|
||||
(short)(node->width-NODE_DY), NODE_DY, NULL, 0, 0, 0, 0, "");
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ void ED_node_shader_default(ID *id)
|
||||
bNode *in, *out;
|
||||
bNodeSocket *fromsock, *tosock;
|
||||
bNodeTree *ntree;
|
||||
int output_type, closure_type;
|
||||
int output_type, shader_type;
|
||||
|
||||
ntree= ntreeAddTree("Shader Nodetree", NTREE_SHADER, FALSE);
|
||||
|
||||
@@ -282,22 +282,22 @@ void ED_node_shader_default(ID *id)
|
||||
case ID_MA:
|
||||
((Material*)id)->nodetree = ntree;
|
||||
output_type = SH_NODE_OUTPUT_MATERIAL;
|
||||
closure_type = SH_NODE_BSDF_DIFFUSE;
|
||||
shader_type = SH_NODE_BSDF_DIFFUSE;
|
||||
break;
|
||||
case ID_WO:
|
||||
((World*)id)->nodetree = ntree;
|
||||
output_type = SH_NODE_OUTPUT_WORLD;
|
||||
closure_type = SH_NODE_BACKGROUND;
|
||||
shader_type = SH_NODE_BACKGROUND;
|
||||
break;
|
||||
case ID_LA:
|
||||
((Lamp*)id)->nodetree = ntree;
|
||||
output_type = SH_NODE_OUTPUT_LAMP;
|
||||
closure_type = SH_NODE_EMISSION;
|
||||
shader_type = SH_NODE_EMISSION;
|
||||
break;
|
||||
case ID_TE:
|
||||
((Tex*)id)->nodetree = ntree;
|
||||
output_type = SH_NODE_OUTPUT_TEXTURE;
|
||||
closure_type = SH_NODE_TEX_CLOUDS;
|
||||
shader_type = SH_NODE_TEX_CLOUDS;
|
||||
break;
|
||||
default:
|
||||
printf("ED_node_shader_default called on wrong ID type.\n");
|
||||
@@ -307,7 +307,7 @@ void ED_node_shader_default(ID *id)
|
||||
out= nodeAddNodeType(ntree, output_type, NULL, NULL);
|
||||
out->locx= 300.0f; out->locy= 300.0f;
|
||||
|
||||
in= nodeAddNodeType(ntree, closure_type, NULL, NULL);
|
||||
in= nodeAddNodeType(ntree, shader_type, NULL, NULL);
|
||||
in->locx= 10.0f; in->locy= 300.0f;
|
||||
nodeSetActive(ntree, in);
|
||||
|
||||
|
||||
@@ -186,13 +186,13 @@ static void node_menu_add(const bContext *C, Menu *menu)
|
||||
uiItemMenuF(layout, "Input", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT));
|
||||
uiItemMenuF(layout, "Output", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT));
|
||||
if(scene_use_new_shading_system(scene))
|
||||
uiItemMenuF(layout, "Closure", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CLOSURE));
|
||||
uiItemMenuF(layout, "Shader", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_SHADER));
|
||||
if(scene_use_new_shading_system(scene))
|
||||
uiItemMenuF(layout, "Texture", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_TEXTURE));
|
||||
uiItemMenuF(layout, "Color", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR));
|
||||
uiItemMenuF(layout, "Vector", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_VECTOR));
|
||||
uiItemMenuF(layout, "Convertor", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR));
|
||||
uiItemMenuF(layout, "Group", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP));
|
||||
if(scene_use_new_shading_system(scene))
|
||||
uiItemMenuF(layout, "Texture", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_TEXTURE));
|
||||
//uiItemMenuF(layout, "Dynamic", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_DYNAMIC));
|
||||
}
|
||||
else if(snode->treetype==NTREE_COMPOSIT) {
|
||||
|
||||
@@ -1853,7 +1853,7 @@ void node_bsdf_diffuse(vec4 color, vec3 N, out vec4 result)
|
||||
result = vec4(L*color.rgb, 1.0);
|
||||
}
|
||||
|
||||
void node_bsdf_glossy(vec4 color, float roughness, float fresnel, vec3 N, vec3 I, out vec4 result)
|
||||
void node_bsdf_glossy(vec4 color, float roughness, vec3 N, vec3 I, out vec4 result)
|
||||
{
|
||||
vec3 L = vec3(0.0);
|
||||
|
||||
@@ -1874,7 +1874,7 @@ void node_bsdf_anisotropic(vec4 color, float roughnessU, float roughnessV, vec3
|
||||
node_bsdf_diffuse(color, N, result);
|
||||
}
|
||||
|
||||
void node_bsdf_glass(vec4 color, float roughness, float fresnel, vec3 N, vec3 I, out vec4 result)
|
||||
void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, vec3 I, out vec4 result)
|
||||
{
|
||||
node_bsdf_diffuse(color, N, result);
|
||||
}
|
||||
@@ -1893,7 +1893,7 @@ void node_bsdf_transparent(vec4 color, out vec4 result)
|
||||
result.a = 0.0;
|
||||
}
|
||||
|
||||
void node_bsdf_velvet(vec4 color, float sigma, float fresnel, vec3 N, out vec4 result)
|
||||
void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out vec4 result)
|
||||
{
|
||||
node_bsdf_diffuse(color, N, result);
|
||||
}
|
||||
@@ -1907,22 +1907,22 @@ void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
|
||||
|
||||
/* closures */
|
||||
|
||||
void node_mix_closure(float fac, vec4 closure1, vec4 closure2, out vec4 closure)
|
||||
void node_mix_shader(float fac, vec4 shader1, vec4 shader2, out vec4 shader)
|
||||
{
|
||||
closure = mix(closure1, closure2, fac);
|
||||
shader = mix(shader1, shader2, fac);
|
||||
}
|
||||
|
||||
void node_add_closure(vec4 closure1, vec4 closure2, out vec4 closure)
|
||||
void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader)
|
||||
{
|
||||
closure = closure1 + closure2;
|
||||
shader = shader1 + shader2;
|
||||
}
|
||||
|
||||
/* fresnel */
|
||||
|
||||
void node_fresnel(float f, vec3 N, vec3 I, out float result)
|
||||
void node_fresnel(float ior, vec3 N, vec3 I, out float result)
|
||||
{
|
||||
f = max(1.0 - f, 0.00001);
|
||||
result = fresnel_dielectric(I, N, 1.0/f); //backfacing()? f: 1.0/f);
|
||||
float eta = max(ior, 0.00001);
|
||||
result = fresnel_dielectric(I, N, eta); //backfacing()? 1.0/eta: eta);
|
||||
}
|
||||
|
||||
/* geometry */
|
||||
|
||||
@@ -100,7 +100,7 @@ typedef struct bNodeSocket {
|
||||
#define SOCK_VALUE 0
|
||||
#define SOCK_VECTOR 1
|
||||
#define SOCK_RGBA 2
|
||||
#define SOCK_CLOSURE 3
|
||||
#define SOCK_SHADER 3
|
||||
|
||||
/* sock->flag, first bit is select */
|
||||
/* hidden is user defined, to hide unused */
|
||||
|
||||
@@ -164,8 +164,8 @@ static StructRNA *rna_NodeSocketType_refine(struct PointerRNA *ptr)
|
||||
return &RNA_VectorNodeSocket;
|
||||
case SOCK_RGBA:
|
||||
return &RNA_RGBANodeSocket;
|
||||
case SOCK_CLOSURE:
|
||||
return &RNA_ClosureNodeSocket;
|
||||
case SOCK_SHADER:
|
||||
return &RNA_ShaderNodeSocket;
|
||||
default:
|
||||
return &RNA_NodeSocket;
|
||||
}
|
||||
@@ -2979,12 +2979,12 @@ static void rna_def_node_socket_rgba(BlenderRNA *brna)
|
||||
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocket_defvalue_range");
|
||||
}
|
||||
|
||||
static void rna_def_node_socket_closure(BlenderRNA *brna)
|
||||
static void rna_def_node_socket_shader(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
srna = RNA_def_struct(brna, "ClosureNodeSocket", "NodeSocket");
|
||||
RNA_def_struct_ui_text(srna, "Closure Node Socket", "Input or output socket of a node");
|
||||
srna = RNA_def_struct(brna, "ShaderNodeSocket", "NodeSocket");
|
||||
RNA_def_struct_ui_text(srna, "Shader Node Socket", "Input or output socket of a node");
|
||||
RNA_def_struct_sdna(srna, "bNodeSocket");
|
||||
RNA_def_struct_ui_icon(srna, ICON_PLUG);
|
||||
RNA_def_struct_path_func(srna, "rna_NodeSocket_path");
|
||||
@@ -3224,7 +3224,7 @@ void RNA_def_nodetree(BlenderRNA *brna)
|
||||
rna_def_node_socket_value(brna);
|
||||
rna_def_node_socket_vector(brna);
|
||||
rna_def_node_socket_rgba(brna);
|
||||
rna_def_node_socket_closure(brna);
|
||||
rna_def_node_socket_shader(brna);
|
||||
rna_def_node(brna);
|
||||
rna_def_node_link(brna);
|
||||
rna_def_shader_node(brna);
|
||||
|
||||
@@ -55,8 +55,9 @@ DefNode( ShaderNode, SH_NODE_OUTPUT_LAMP, 0, "OUTPU
|
||||
//DefNode( ShaderNode, SH_NODE_OUTPUT_TEXTURE, 0, "OUTPUT_TEXTURE", OutputTexture, "Texture Output", "" )
|
||||
DefNode( ShaderNode, SH_NODE_OUTPUT_WORLD, 0, "OUTPUT_WORLD", OutputWorld, "World Output", "" )
|
||||
DefNode( ShaderNode, SH_NODE_FRESNEL, 0, "FRESNEL", Fresnel, "Fresnel", "" )
|
||||
DefNode( ShaderNode, SH_NODE_MIX_CLOSURE, 0, "MIX_CLOSURE", MixClosure, "Mix Closure", "" )
|
||||
DefNode( ShaderNode, SH_NODE_ADD_CLOSURE, 0, "ADD_CLOSURE", AddClosure, "Add Closure", "" )
|
||||
DefNode( ShaderNode, SH_NODE_BLEND_WEIGHT, 0, "BLEND_WEIGHT", BlendWeight, "BlendWeight", "" )
|
||||
DefNode( ShaderNode, SH_NODE_MIX_SHADER, 0, "MIX_SHADER", MixShader, "Mix Shader", "" )
|
||||
DefNode( ShaderNode, SH_NODE_ADD_SHADER, 0, "ADD_SHADER", AddShader, "Add Shader", "" )
|
||||
|
||||
DefNode( ShaderNode, SH_NODE_ATTRIBUTE, 0, "ATTRIBUTE", Attribute, "Attribute", "")
|
||||
DefNode( ShaderNode, SH_NODE_BACKGROUND, 0, "BACKGROUND", Background, "Background", "")
|
||||
|
||||
@@ -127,11 +127,12 @@ set(SRC
|
||||
intern/SHD_nodes/SHD_bsdf_velvet.c
|
||||
intern/SHD_nodes/SHD_emission.c
|
||||
intern/SHD_nodes/SHD_fresnel.c
|
||||
intern/SHD_nodes/SHD_blend_weight.c
|
||||
intern/SHD_nodes/SHD_geometry.c
|
||||
intern/SHD_nodes/SHD_holdout.c
|
||||
intern/SHD_nodes/SHD_light_path.c
|
||||
intern/SHD_nodes/SHD_mix_closure.c
|
||||
intern/SHD_nodes/SHD_add_closure.c
|
||||
intern/SHD_nodes/SHD_mix_shader.c
|
||||
intern/SHD_nodes/SHD_add_shader.c
|
||||
intern/SHD_nodes/SHD_output_lamp.c
|
||||
intern/SHD_nodes/SHD_output_material.c
|
||||
intern/SHD_nodes/SHD_output_texture.c
|
||||
|
||||
@@ -56,6 +56,7 @@ void register_node_type_sh_attribute(ListBase *lb);
|
||||
void register_node_type_sh_geometry(ListBase *lb);
|
||||
void register_node_type_sh_light_path(ListBase *lb);
|
||||
void register_node_type_sh_fresnel(ListBase *lb);
|
||||
void register_node_type_sh_blend_weight(ListBase *lb);
|
||||
void register_node_type_sh_tex_coord(ListBase *lb);
|
||||
|
||||
void register_node_type_sh_background(ListBase *lb);
|
||||
@@ -68,8 +69,8 @@ void register_node_type_sh_bsdf_transparent(ListBase *lb);
|
||||
void register_node_type_sh_bsdf_velvet(ListBase *lb);
|
||||
void register_node_type_sh_emission(ListBase *lb);
|
||||
void register_node_type_sh_holdout(ListBase *lb);
|
||||
void register_node_type_sh_mix_closure(ListBase *lb);
|
||||
void register_node_type_sh_add_closure(ListBase *lb);
|
||||
void register_node_type_sh_mix_shader(ListBase *lb);
|
||||
void register_node_type_sh_add_shader(ListBase *lb);
|
||||
|
||||
void register_node_type_sh_output_lamp(ListBase *lb);
|
||||
void register_node_type_sh_output_material(ListBase *lb);
|
||||
|
||||
@@ -31,38 +31,38 @@
|
||||
|
||||
/* **************** OUTPUT ******************** */
|
||||
|
||||
static bNodeSocketType sh_node_add_closure_in[]= {
|
||||
{ SOCK_CLOSURE, 1, "Closure1", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_CLOSURE, 1, "Closure2", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
static bNodeSocketType sh_node_add_shader_in[]= {
|
||||
{ SOCK_SHADER, 1, "Shader1", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 1, "Shader2", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static bNodeSocketType sh_node_add_closure_out[]= {
|
||||
{ SOCK_CLOSURE, 0, "Closure", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
static bNodeSocketType sh_node_add_shader_out[]= {
|
||||
{ SOCK_SHADER, 0, "Shader", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void node_shader_exec_add_closure(void *UNUSED(data), bNode *UNUSED(node), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out))
|
||||
static void node_shader_exec_add_shader(void *UNUSED(data), bNode *UNUSED(node), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out))
|
||||
{
|
||||
}
|
||||
|
||||
static int node_shader_gpu_add_closure(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out)
|
||||
static int node_shader_gpu_add_shader(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out)
|
||||
{
|
||||
return GPU_stack_link(mat, "node_add_closure", in, out);
|
||||
return GPU_stack_link(mat, "node_add_shader", in, out);
|
||||
}
|
||||
|
||||
/* node type definition */
|
||||
void register_node_type_sh_add_closure(ListBase *lb)
|
||||
void register_node_type_sh_add_shader(ListBase *lb)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
node_type_base(&ntype, SH_NODE_ADD_CLOSURE, "Add Closure", NODE_CLASS_CLOSURE, 0,
|
||||
sh_node_add_closure_in, sh_node_add_closure_out);
|
||||
node_type_base(&ntype, SH_NODE_ADD_SHADER, "Add Shader", NODE_CLASS_SHADER, 0,
|
||||
sh_node_add_shader_in, sh_node_add_shader_out);
|
||||
node_type_size(&ntype, 150, 60, 200);
|
||||
node_type_init(&ntype, NULL);
|
||||
node_type_storage(&ntype, "", NULL, NULL);
|
||||
node_type_exec(&ntype, node_shader_exec_add_closure);
|
||||
node_type_gpu(&ntype, node_shader_gpu_add_closure);
|
||||
node_type_exec(&ntype, node_shader_exec_add_shader);
|
||||
node_type_gpu(&ntype, node_shader_gpu_add_shader);
|
||||
|
||||
nodeRegisterType(lb, &ntype);
|
||||
};
|
||||
@@ -38,7 +38,7 @@ static bNodeSocketType sh_node_background_in[]= {
|
||||
};
|
||||
|
||||
static bNodeSocketType sh_node_background_out[]= {
|
||||
{ SOCK_CLOSURE, 0, "Background", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 0, "Background", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
@@ -52,7 +52,7 @@ void register_node_type_sh_background(ListBase *lb)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
node_type_base(&ntype, SH_NODE_BACKGROUND, "Background", NODE_CLASS_CLOSURE, 0,
|
||||
node_type_base(&ntype, SH_NODE_BACKGROUND, "Background", NODE_CLASS_SHADER, 0,
|
||||
sh_node_background_in, sh_node_background_out);
|
||||
node_type_size(&ntype, 150, 60, 200);
|
||||
node_type_init(&ntype, NULL);
|
||||
|
||||
68
source/blender/nodes/intern/SHD_nodes/SHD_blend_weight.c
Normal file
68
source/blender/nodes/intern/SHD_nodes/SHD_blend_weight.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* $Id: SHD_blend_weight.c 32517 2010-10-16 14:32:17Z campbellbarton $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "../SHD_util.h"
|
||||
|
||||
/* **************** BlendWeight ******************** */
|
||||
static bNodeSocketType sh_node_blend_weight_in[]= {
|
||||
{ SOCK_VALUE, 1, "Blend", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static bNodeSocketType sh_node_blend_weight_out[]= {
|
||||
{ SOCK_VALUE, 0, "Fresnel", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 0, "Facing", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void node_shader_exec_blend_weight(void *UNUSED(data), bNode *UNUSED(node), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out))
|
||||
{
|
||||
}
|
||||
|
||||
static int node_shader_gpu_blend_weight(GPUMaterial *UNUSED(mat), bNode *UNUSED(node), GPUNodeStack *UNUSED(in), GPUNodeStack *UNUSED(out))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* node type definition */
|
||||
void register_node_type_sh_blend_weight(ListBase *lb)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
node_type_base(&ntype, SH_NODE_BLEND_WEIGHT, "Blend Weight", NODE_CLASS_INPUT, 0,
|
||||
sh_node_blend_weight_in, sh_node_blend_weight_out);
|
||||
node_type_size(&ntype, 150, 60, 200);
|
||||
node_type_init(&ntype, NULL);
|
||||
node_type_storage(&ntype, "", NULL, NULL);
|
||||
node_type_exec(&ntype, node_shader_exec_blend_weight);
|
||||
node_type_gpu(&ntype, node_shader_gpu_blend_weight);
|
||||
|
||||
nodeRegisterType(lb, &ntype);
|
||||
};
|
||||
|
||||
@@ -39,7 +39,7 @@ static bNodeSocketType sh_node_bsdf_anisotropic_in[]= {
|
||||
};
|
||||
|
||||
static bNodeSocketType sh_node_bsdf_anisotropic_out[]= {
|
||||
{ SOCK_CLOSURE, 0, "BSDF", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 0, "BSDF", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
@@ -57,7 +57,7 @@ void register_node_type_sh_bsdf_anisotropic(ListBase *lb)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
node_type_base(&ntype, SH_NODE_BSDF_ANISOTROPIC, "Glossy Anisotropic BSDF", NODE_CLASS_CLOSURE, 0,
|
||||
node_type_base(&ntype, SH_NODE_BSDF_ANISOTROPIC, "Glossy Anisotropic BSDF", NODE_CLASS_SHADER, 0,
|
||||
sh_node_bsdf_anisotropic_in, sh_node_bsdf_anisotropic_out);
|
||||
node_type_size(&ntype, 150, 60, 200);
|
||||
node_type_init(&ntype, NULL);
|
||||
|
||||
@@ -37,7 +37,7 @@ static bNodeSocketType sh_node_bsdf_diffuse_in[]= {
|
||||
};
|
||||
|
||||
static bNodeSocketType sh_node_bsdf_diffuse_out[]= {
|
||||
{ SOCK_CLOSURE, 0, "BSDF", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 0, "BSDF", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
@@ -55,7 +55,7 @@ void register_node_type_sh_bsdf_diffuse(ListBase *lb)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
node_type_base(&ntype, SH_NODE_BSDF_DIFFUSE, "Diffuse BSDF", NODE_CLASS_CLOSURE, 0,
|
||||
node_type_base(&ntype, SH_NODE_BSDF_DIFFUSE, "Diffuse BSDF", NODE_CLASS_SHADER, 0,
|
||||
sh_node_bsdf_diffuse_in, sh_node_bsdf_diffuse_out);
|
||||
node_type_size(&ntype, 150, 60, 200);
|
||||
node_type_init(&ntype, NULL);
|
||||
|
||||
@@ -34,12 +34,12 @@
|
||||
static bNodeSocketType sh_node_bsdf_glass_in[]= {
|
||||
{ SOCK_RGBA, 1, "Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 1, "Roughness", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 1, "Fresnel", 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 1, "IOR", 1.45f, 0.0f, 0.0f, 0.0f, 1.0f, 1000.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static bNodeSocketType sh_node_bsdf_glass_out[]= {
|
||||
{ SOCK_CLOSURE, 0, "BSDF", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 0, "BSDF", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
@@ -57,7 +57,7 @@ void register_node_type_sh_bsdf_glass(ListBase *lb)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
node_type_base(&ntype, SH_NODE_BSDF_GLASS, "Glass BSDF", NODE_CLASS_CLOSURE, 0,
|
||||
node_type_base(&ntype, SH_NODE_BSDF_GLASS, "Glass BSDF", NODE_CLASS_SHADER, 0,
|
||||
sh_node_bsdf_glass_in, sh_node_bsdf_glass_out);
|
||||
node_type_size(&ntype, 150, 60, 200);
|
||||
node_type_init(&ntype, NULL);
|
||||
|
||||
@@ -34,12 +34,11 @@
|
||||
static bNodeSocketType sh_node_bsdf_glossy_in[]= {
|
||||
{ SOCK_RGBA, 1, "Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 1, "Roughness", 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 1, "Fresnel", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static bNodeSocketType sh_node_bsdf_glossy_out[]= {
|
||||
{ SOCK_CLOSURE, 0, "BSDF", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 0, "BSDF", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
@@ -58,7 +57,7 @@ void register_node_type_sh_bsdf_glossy(ListBase *lb)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
node_type_base(&ntype, SH_NODE_BSDF_GLOSSY, "Glossy BSDF", NODE_CLASS_CLOSURE, 0,
|
||||
node_type_base(&ntype, SH_NODE_BSDF_GLOSSY, "Glossy BSDF", NODE_CLASS_SHADER, 0,
|
||||
sh_node_bsdf_glossy_in, sh_node_bsdf_glossy_out);
|
||||
node_type_size(&ntype, 150, 60, 200);
|
||||
node_type_init(&ntype, NULL);
|
||||
|
||||
@@ -37,7 +37,7 @@ static bNodeSocketType sh_node_bsdf_translucent_in[]= {
|
||||
};
|
||||
|
||||
static bNodeSocketType sh_node_bsdf_translucent_out[]= {
|
||||
{ SOCK_CLOSURE, 0, "BSDF", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 0, "BSDF", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
@@ -55,7 +55,7 @@ void register_node_type_sh_bsdf_translucent(ListBase *lb)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
node_type_base(&ntype, SH_NODE_BSDF_TRANSLUCENT, "Translucent BSDF", NODE_CLASS_CLOSURE, 0,
|
||||
node_type_base(&ntype, SH_NODE_BSDF_TRANSLUCENT, "Translucent BSDF", NODE_CLASS_SHADER, 0,
|
||||
sh_node_bsdf_translucent_in, sh_node_bsdf_translucent_out);
|
||||
node_type_size(&ntype, 150, 60, 200);
|
||||
node_type_init(&ntype, NULL);
|
||||
|
||||
@@ -37,7 +37,7 @@ static bNodeSocketType sh_node_bsdf_transparent_in[]= {
|
||||
};
|
||||
|
||||
static bNodeSocketType sh_node_bsdf_transparent_out[]= {
|
||||
{ SOCK_CLOSURE, 0, "BSDF", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 0, "BSDF", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
@@ -55,7 +55,7 @@ void register_node_type_sh_bsdf_transparent(ListBase *lb)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
node_type_base(&ntype, SH_NODE_BSDF_TRANSPARENT, "Transparent BSDF", NODE_CLASS_CLOSURE, 0,
|
||||
node_type_base(&ntype, SH_NODE_BSDF_TRANSPARENT, "Transparent BSDF", NODE_CLASS_SHADER, 0,
|
||||
sh_node_bsdf_transparent_in, sh_node_bsdf_transparent_out);
|
||||
node_type_size(&ntype, 150, 60, 200);
|
||||
node_type_init(&ntype, NULL);
|
||||
|
||||
@@ -34,12 +34,11 @@
|
||||
static bNodeSocketType sh_node_bsdf_velvet_in[]= {
|
||||
{ SOCK_RGBA, 1, "Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 1, "Sigma", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 1, "Fresnel", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static bNodeSocketType sh_node_bsdf_velvet_out[]= {
|
||||
{ SOCK_CLOSURE, 0, "BSDF", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 0, "BSDF", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
@@ -57,7 +56,7 @@ void register_node_type_sh_bsdf_velvet(ListBase *lb)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
node_type_base(&ntype, SH_NODE_BSDF_VELVET, "Velvet BSDF", NODE_CLASS_CLOSURE, 0,
|
||||
node_type_base(&ntype, SH_NODE_BSDF_VELVET, "Velvet BSDF", NODE_CLASS_SHADER, 0,
|
||||
sh_node_bsdf_velvet_in, sh_node_bsdf_velvet_out);
|
||||
node_type_size(&ntype, 150, 60, 200);
|
||||
node_type_init(&ntype, NULL);
|
||||
|
||||
@@ -33,12 +33,12 @@
|
||||
|
||||
static bNodeSocketType sh_node_emission_in[]= {
|
||||
{ SOCK_RGBA, 1, "Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 1, "Strength", 100.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000000.0f},
|
||||
{ SOCK_VALUE, 1, "Strength", 30.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000000.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static bNodeSocketType sh_node_emission_out[]= {
|
||||
{ SOCK_CLOSURE, 0, "Emission", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 0, "Emission", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
@@ -56,7 +56,7 @@ void register_node_type_sh_emission(ListBase *lb)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
node_type_base(&ntype, SH_NODE_EMISSION, "Emission", NODE_CLASS_CLOSURE, 0,
|
||||
node_type_base(&ntype, SH_NODE_EMISSION, "Emission", NODE_CLASS_SHADER, 0,
|
||||
sh_node_emission_in, sh_node_emission_out);
|
||||
node_type_size(&ntype, 150, 60, 200);
|
||||
node_type_init(&ntype, NULL);
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
|
||||
/* **************** Fresnel ******************** */
|
||||
static bNodeSocketType sh_node_fresnel_in[]= {
|
||||
{ SOCK_VALUE, 1, "Fresnel", 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 1, "IOR", 1.45f, 0.0f, 0.0f, 0.0f, 1.0f, 1000.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static bNodeSocketType sh_node_fresnel_out[]= {
|
||||
{ SOCK_VALUE, 0, "Fac", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 0, "Fac", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ static bNodeSocketType sh_node_holdout_in[]= {
|
||||
};
|
||||
|
||||
static bNodeSocketType sh_node_holdout_out[]= {
|
||||
{ SOCK_CLOSURE, 0, "Holdout", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 0, "Holdout", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
@@ -50,7 +50,7 @@ void register_node_type_sh_holdout(ListBase *lb)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
node_type_base(&ntype, SH_NODE_HOLDOUT, "Holdout", NODE_CLASS_CLOSURE, 0,
|
||||
node_type_base(&ntype, SH_NODE_HOLDOUT, "Holdout", NODE_CLASS_SHADER, 0,
|
||||
sh_node_holdout_in, sh_node_holdout_out);
|
||||
node_type_size(&ntype, 150, 60, 200);
|
||||
node_type_init(&ntype, NULL);
|
||||
|
||||
@@ -31,39 +31,39 @@
|
||||
|
||||
/* **************** OUTPUT ******************** */
|
||||
|
||||
static bNodeSocketType sh_node_mix_closure_in[]= {
|
||||
static bNodeSocketType sh_node_mix_shader_in[]= {
|
||||
{ SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_CLOSURE, 1, "Closure1", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_CLOSURE, 1, "Closure2", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 1, "Shader1", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 1, "Shader2", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static bNodeSocketType sh_node_mix_closure_out[]= {
|
||||
{ SOCK_CLOSURE, 0, "Closure", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
static bNodeSocketType sh_node_mix_shader_out[]= {
|
||||
{ SOCK_SHADER, 0, "Shader", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void node_shader_exec_mix_closure(void *UNUSED(data), bNode *UNUSED(node), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out))
|
||||
static void node_shader_exec_mix_shader(void *UNUSED(data), bNode *UNUSED(node), bNodeStack **UNUSED(in), bNodeStack **UNUSED(out))
|
||||
{
|
||||
}
|
||||
|
||||
static int node_shader_gpu_mix_closure(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out)
|
||||
static int node_shader_gpu_mix_shader(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out)
|
||||
{
|
||||
return GPU_stack_link(mat, "node_mix_closure", in, out);
|
||||
return GPU_stack_link(mat, "node_mix_shader", in, out);
|
||||
}
|
||||
|
||||
/* node type definition */
|
||||
void register_node_type_sh_mix_closure(ListBase *lb)
|
||||
void register_node_type_sh_mix_shader(ListBase *lb)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
node_type_base(&ntype, SH_NODE_MIX_CLOSURE, "Mix Closure", NODE_CLASS_CLOSURE, 0,
|
||||
sh_node_mix_closure_in, sh_node_mix_closure_out);
|
||||
node_type_base(&ntype, SH_NODE_MIX_SHADER, "Mix Shader", NODE_CLASS_SHADER, 0,
|
||||
sh_node_mix_shader_in, sh_node_mix_shader_out);
|
||||
node_type_size(&ntype, 150, 60, 200);
|
||||
node_type_init(&ntype, NULL);
|
||||
node_type_storage(&ntype, "", NULL, NULL);
|
||||
node_type_exec(&ntype, node_shader_exec_mix_closure);
|
||||
node_type_gpu(&ntype, node_shader_gpu_mix_closure);
|
||||
node_type_exec(&ntype, node_shader_exec_mix_shader);
|
||||
node_type_gpu(&ntype, node_shader_gpu_mix_shader);
|
||||
|
||||
nodeRegisterType(lb, &ntype);
|
||||
};
|
||||
@@ -32,7 +32,7 @@
|
||||
/* **************** OUTPUT ******************** */
|
||||
|
||||
static bNodeSocketType sh_node_output_lamp_in[]= {
|
||||
{ SOCK_CLOSURE, 1, "Surface", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 1, "Surface", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
/* **************** OUTPUT ******************** */
|
||||
|
||||
static bNodeSocketType sh_node_output_material_in[]= {
|
||||
{ SOCK_CLOSURE, 1, "Surface", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_CLOSURE, 1, "Volume", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 1, "Surface", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 1, "Volume", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_VALUE, 1, "Displacement", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, SOCK_NO_VALUE},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
/* **************** OUTPUT ******************** */
|
||||
|
||||
static bNodeSocketType sh_node_output_world_in[]= {
|
||||
{ SOCK_CLOSURE, 1, "Surface", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_CLOSURE, 1, "Volume", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 1, "Surface", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ SOCK_SHADER, 1, "Volume", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user