diff options
Diffstat (limited to 'intern/cycles')
76 files changed, 1086 insertions, 706 deletions
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index c936b900d75..030f0dbbf14 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -30,8 +30,8 @@ def _is_using_buggy_driver(): version = bgl.glGetString(bgl.GL_VERSION) if version.endswith("Compatibility Profile Context"): # Old HD 4xxx and 5xxx series drivers did not have driver version - # in the version string, but thsoe cards do not quite work and - # cusing crashes. + # in the version string, but those cards do not quite work and + # causing crashes. return True regex = re.compile(".*Compatibility Profile Context ([0-9]+(\.[0-9]+)+)$") if not regex.match(version): @@ -49,12 +49,13 @@ def _workaround_buggy_drivers(): print("Cycles: OpenGL driver known to be buggy, disabling OpenCL platform.") _cycles.opencl_disable() + def init(): import bpy import _cycles import os.path - # Workaroud posibly buggy legacy drivers which crashes on the OpenCL + # Workaround possibly buggy legacy drivers which crashes on the OpenCL # device enumeration. # # This checks are not really correct because they might still fail diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 3417435fcbd..c3139831ca2 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -463,11 +463,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): description="Use BVH spatial splits: longer builder time, faster render", default=False, ) - cls.use_cache = BoolProperty( - name="Cache BVH", - description="Cache last built BVH to disk for faster re-render if no geometry changed", - default=False, - ) cls.tile_order = EnumProperty( name="Tile Order", description="Tile order for rendering", @@ -524,6 +519,17 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): min=0.0, max=5.0 ) + cls.motion_blur_position = EnumProperty( + name="Motion Blur Position", + default='CENTER', + description="Offset for the shutter's time interval, allows to change the motion blur trails", + items=( + ('START', "Start on Frame", "The shutter opens at the current frame"), + ('CENTER', "Center on Frame", "The shutter is open during the current frame"), + ('END', "End on Frame", "The shutter closes at the current frame"), + ), + ) + @classmethod def unregister(cls): del bpy.types.Scene.cycles @@ -743,7 +749,7 @@ class CyclesWorldSettings(bpy.types.PropertyGroup): name="Map Resolution", description="Importance map size is resolution x resolution; " "higher values potentially produce less noise, at the cost of memory and speed", - min=4, max=8096, + min=4, max=8192, default=256, ) cls.samples = IntProperty( diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index fdb2afdb5e9..3700da3263e 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -259,11 +259,14 @@ class CyclesRender_PT_motion_blur(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout - rd = context.scene.render + scene = context.scene + cscene = scene.cycles + rd = scene.render layout.active = rd.use_motion_blur - row = layout.row() - row.prop(rd, "motion_blur_shutter") + col = layout.column() + col.prop(cscene, "motion_blur_position", text="Position") + col.prop(rd, "motion_blur_shutter") class CyclesRender_PT_film(CyclesButtonsPanel, Panel): @@ -332,7 +335,6 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel): col.separator() col.label(text="Final Render:") - col.prop(cscene, "use_cache") col.prop(rd, "use_persistent_data", text="Persistent Images") col.separator() @@ -438,6 +440,7 @@ class CyclesRender_PT_layer_passes(CyclesButtonsPanel, Panel): class CyclesRender_PT_views(CyclesButtonsPanel, Panel): bl_label = "Views" bl_context = "render_layer" + bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): rd = context.scene.render @@ -1163,13 +1166,17 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel): col.prop(mat, "alpha") col.separator() - col.prop(mat, "pass_index") + col.label("Viewport Alpha:") + col.prop(mat.game_settings, "alpha_blend", text="") col = split.column(align=True) col.label("Viewport Specular:") col.prop(mat, "specular_color", text="") col.prop(mat, "specular_hardness", text="Hardness") + col.separator() + col.prop(mat, "pass_index") + class CyclesTexture_PT_context(CyclesButtonsPanel, Panel): bl_label = "" diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index 0a79bfbf793..491b5632ed5 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -36,6 +36,7 @@ struct BlenderCamera { float lens; float shuttertime; + Camera::MotionPosition motion_position; float aperturesize; uint apertureblades; @@ -83,6 +84,7 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings b_render bcam->sensor_height = 18.0f; bcam->sensor_fit = BlenderCamera::AUTO; bcam->shuttertime = 1.0f; + bcam->motion_position = Camera::MOTION_POSITION_CENTER; bcam->border.right = 1.0f; bcam->border.top = 1.0f; bcam->pano_viewplane.right = 1.0f; @@ -107,9 +109,9 @@ static float blender_camera_focal_distance(BL::RenderEngine b_engine, BL::Object b_engine.camera_model_matrix(b_ob, b_ob_matrix); Transform obmat = get_transform(b_ob_matrix); Transform dofmat = get_transform(b_dof_object.matrix_world()); - Transform mat = transform_inverse(obmat) * dofmat; - - return fabsf(transform_get_column(&mat, 3).z); + float3 view_dir = normalize(transform_get_column(&obmat, 2)); + float3 dof_dir = transform_get_column(&obmat, 3) - transform_get_column(&dofmat, 3); + return fabsf(dot(view_dir, dof_dir)); } static void blender_camera_from_object(BlenderCamera *bcam, BL::RenderEngine b_engine, BL::Object b_ob, bool skip_panorama = false) @@ -409,6 +411,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int cam->shuttertime = bcam->shuttertime; cam->fov_pre = cam->fov; cam->fov_post = cam->fov; + cam->motion_position = bcam->motion_position; /* border */ cam->border = bcam->border; @@ -431,6 +434,22 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override bcam.pixelaspect.y = b_render.pixel_aspect_y(); bcam.shuttertime = b_render.motion_blur_shutter(); + PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); + switch(RNA_enum_get(&cscene, "motion_blur_position")) { + case 0: + bcam.motion_position = Camera::MOTION_POSITION_START; + break; + case 1: + bcam.motion_position = Camera::MOTION_POSITION_CENTER; + break; + case 2: + bcam.motion_position = Camera::MOTION_POSITION_END; + break; + default: + bcam.motion_position = Camera::MOTION_POSITION_CENTER; + break; + } + /* border */ if(b_render.use_border()) { bcam.border.left = b_render.border_min_x(); @@ -487,6 +506,11 @@ void BlenderSync::sync_camera_motion(BL::RenderSettings b_render, BlenderCamera bcam; float aspectratio, sensor_size; blender_camera_init(&bcam, b_render); + + /* TODO(sergey): Consider making it a part of blender_camera_init(). */ + bcam.pixelaspect.x = b_render.pixel_aspect_x(); + bcam.pixelaspect.y = b_render.pixel_aspect_y(); + blender_camera_from_object(&bcam, b_engine, b_ob); blender_camera_viewplane(&bcam, width, height, diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index dba801fc4df..6a119081bfd 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -145,7 +145,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f); int totcurves = totchild; - if(b_part.child_type() == 0) + if(b_part.child_type() == 0 || totchild == 0) totcurves += totparts; if(totcurves == 0) @@ -169,7 +169,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par CData->psys_closetip.push_back(get_boolean(cpsys, "use_closetip")); int pa_no = 0; - if(!(b_part.child_type() == 0)) + if(!(b_part.child_type() == 0) && totchild != 0) pa_no = totparts; int num_add = (totparts+totchild - pa_no); @@ -233,14 +233,14 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f); int totcurves = totchild; - if(b_part.child_type() == 0) + if(b_part.child_type() == 0 || totchild == 0) totcurves += totparts; if(totcurves == 0) continue; int pa_no = 0; - if(!(b_part.child_type() == 0)) + if(!(b_part.child_type() == 0) && totchild != 0) pa_no = totparts; int num_add = (totparts+totchild - pa_no); @@ -287,14 +287,14 @@ bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f); int totcurves = totchild; - if(b_part.child_type() == 0) + if(b_part.child_type() == 0 || totchild == 0) totcurves += totparts; if(totcurves == 0) continue; int pa_no = 0; - if(!(b_part.child_type() == 0)) + if(!(b_part.child_type() == 0) && totchild != 0) pa_no = totparts; int num_add = (totparts+totchild - pa_no); diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index e81170ac411..c2ccef548c7 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -85,7 +85,7 @@ static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context, float BL::MeshTextureFace tf = userdata->layer->data[face_num]; float3 tfuv; - switch (vert_num) { + switch(vert_num) { case 0: tfuv = get_float3(tf.uv1()); break; @@ -842,6 +842,7 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Object *object, float motion return; } + /* TODO(sergey): Perform preliminary check for number of verticies. */ if(numverts) { /* find attributes */ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); @@ -873,7 +874,9 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Object *object, float motion /* in case of new attribute, we verify if there really was any motion */ if(new_attribute) { - if(i != numverts || memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0) { + if(b_mesh.vertices.length() != numverts || + memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0) + { /* no motion, remove attributes again */ VLOG(1) << "No actual deformation motion for object " << b_ob.name(); mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION); diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 432c4aaa078..11593807a00 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -558,11 +558,20 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time) bool cancel = false; bool use_portal = false; + uint layer_override = get_layer(b_engine.layer_override()); for(; b_sce && !cancel; b_sce = b_sce.background_set()) { + /* Render layer's scene_layer is affected by local view already, + * which is not a desired behavior here. + */ + uint scene_layers = layer_override ? layer_override : get_layer(b_scene.layers()); for(b_sce.object_bases.begin(b_base); b_base != b_sce.object_bases.end() && !cancel; ++b_base) { BL::Object b_ob = b_base->object(); bool hide = (render_layer.use_viewport_visibility)? b_ob.hide(): b_ob.hide_render(); - uint ob_layer = get_layer(b_base->layers(), b_base->layers_local_view(), render_layer.use_localview, object_is_light(b_ob)); + uint ob_layer = get_layer(b_base->layers(), + b_base->layers_local_view(), + render_layer.use_localview, + object_is_light(b_ob), + scene_layers); hide = hide || !(ob_layer & scene_layer); if(!hide) { @@ -676,6 +685,28 @@ void BlenderSync::sync_motion(BL::RenderSettings b_render, Camera prevcam = *(scene->camera); int frame_center = b_scene.frame_current(); + float frame_center_delta = 0.0f; + + if(scene->need_motion() != Scene::MOTION_PASS && + scene->camera->motion_position != Camera::MOTION_POSITION_CENTER) + { + float shuttertime = scene->camera->shuttertime; + if(scene->camera->motion_position == Camera::MOTION_POSITION_END) { + frame_center_delta = -shuttertime * 0.5f; + } + else { + assert(scene->camera->motion_position == Camera::MOTION_POSITION_START); + frame_center_delta = shuttertime * 0.5f; + } + float time = frame_center + frame_center_delta; + int frame = (int)floorf(time); + float subframe = time - frame; + python_thread_state_restore(python_thread_state); + b_engine.frame_set(frame, subframe); + python_thread_state_save(python_thread_state); + sync_camera_motion(b_render, b_cam, width, height, 0.0f); + sync_objects(b_v3d, 0.0f); + } /* always sample these times for camera motion */ motion_times.insert(-1.0f); @@ -695,7 +726,7 @@ void BlenderSync::sync_motion(BL::RenderSettings b_render, shuttertime = scene->camera->shuttertime; /* compute frame and subframe time */ - float time = frame_center + relative_time * shuttertime * 0.5f; + float time = frame_center + frame_center_delta + relative_time * shuttertime * 0.5f; int frame = (int)floorf(time); float subframe = time - frame; diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 04d05ee7b3c..088748cc0ae 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -1194,7 +1194,8 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) { BL::ShaderNodeTexPointDensity b_point_density_node(b_node); int length; - b_point_density_node.calc_point_density(b_scene, &length, &pixels); + int settings = background ? 1 : 0; /* 1 - render settings, 0 - vewport settings. */ + b_point_density_node.calc_point_density(b_scene, settings, &length, &pixels); } } diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 0f0be78abd8..2beeaa5e07a 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -88,7 +88,7 @@ static float3 get_node_output_vector(BL::Node b_node, const string& name) static ShaderSocketType convert_socket_type(BL::NodeSocket b_socket) { - switch (b_socket.type()) { + switch(b_socket.type()) { case BL::NodeSocket::type_VALUE: return SHADER_SOCKET_FLOAT; case BL::NodeSocket::type_INT: @@ -283,7 +283,7 @@ static ShaderNode *add_node(Scene *scene, else if(b_node.is_a(&RNA_ShaderNodeVectorTransform)) { BL::ShaderNodeVectorTransform b_vector_transform_node(b_node); VectorTransformNode *vtransform = new VectorTransformNode(); - vtransform->type = VectorTransformNode::type_enum[b_vector_transform_node.type()]; + vtransform->type = VectorTransformNode::type_enum[b_vector_transform_node.vector_type()]; vtransform->convert_from = VectorTransformNode::convert_space_enum[b_vector_transform_node.convert_from()]; vtransform->convert_to = VectorTransformNode::convert_space_enum[b_vector_transform_node.convert_to()]; node = vtransform; @@ -332,17 +332,16 @@ static ShaderNode *add_node(Scene *scene, BL::ShaderNodeBsdfAnisotropic b_aniso_node(b_node); AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode(); - switch (b_aniso_node.distribution()) - { - case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN: - aniso->distribution = ustring("Beckmann"); - break; - case BL::ShaderNodeBsdfAnisotropic::distribution_GGX: - aniso->distribution = ustring("GGX"); - break; - case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY: - aniso->distribution = ustring("Ashikhmin-Shirley"); - break; + switch(b_aniso_node.distribution()) { + case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN: + aniso->distribution = ustring("Beckmann"); + break; + case BL::ShaderNodeBsdfAnisotropic::distribution_GGX: + aniso->distribution = ustring("GGX"); + break; + case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY: + aniso->distribution = ustring("Ashikhmin-Shirley"); + break; } node = aniso; @@ -633,11 +632,12 @@ static ShaderNode *add_node(Scene *scene, if(b_image.is_updated()) { scene->image_manager->tag_reload_image(env->filename, env->builtin_data, - INTERPOLATION_LINEAR, + (InterpolationType)b_env_node.interpolation(), EXTENSION_REPEAT); } } env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()]; + env->interpolation = (InterpolationType)b_env_node.interpolation(); env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()]; get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping()); node = env; @@ -767,7 +767,7 @@ static ShaderNode *add_node(Scene *scene, point_density->filename, point_density->builtin_data, point_density->interpolation, - EXTENSION_REPEAT); + EXTENSION_CLIP); } node = point_density; } @@ -1176,7 +1176,7 @@ void BlenderSync::sync_world(bool update_all) PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); /* when doing preview render check for BI's transparency settings, - * this is so because bledner's preview render routines are not able + * this is so because Blender's preview render routines are not able * to tweak all cycles's settings depending on different circumstances */ if(b_engine.is_preview() == false) diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 8888d219aac..986e90c59f7 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -161,7 +161,12 @@ void BlenderSync::sync_data(BL::RenderSettings b_render, mesh_synced.clear(); /* use for objects and motion sync */ - sync_objects(b_v3d); + if(scene->need_motion() == Scene::MOTION_PASS || + scene->need_motion() == Scene::MOTION_NONE || + scene->camera->motion_position == Camera::MOTION_POSITION_CENTER) + { + sync_objects(b_v3d); + } sync_motion(b_render, b_v3d, b_override, @@ -427,7 +432,6 @@ SceneParams BlenderSync::get_scene_params(BL::Scene b_scene, bool background, bo params.bvh_type = (SceneParams::BVHType)RNA_enum_get(&cscene, "debug_bvh_type"); params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits"); - params.use_bvh_cache = (background)? RNA_boolean_get(&cscene, "use_cache"): false; if(background && params.shadingsystem != SHADINGSYSTEM_OSL) params.persistent_data = r.use_persistent_data(); diff --git a/intern/cycles/blender/blender_texture.cpp b/intern/cycles/blender/blender_texture.cpp index cb4dd1792d0..18f66560b10 100644 --- a/intern/cycles/blender/blender_texture.cpp +++ b/intern/cycles/blender/blender_texture.cpp @@ -68,10 +68,12 @@ static void density_particle_system_texture_space( float3 particle_size = make_float3(radius, radius, radius); for(int i = 0; i < b_particle_system.particles.length(); ++i) { BL::Particle particle = b_particle_system.particles[i]; - float3 location = get_float3(particle.location()); - location = transform_point(&itfm, location); - min = ccl::min(min, location - particle_size); - max = ccl::max(max, location + particle_size); + if(particle.alive_state() == BL::Particle::alive_state_ALIVE) { + float3 location = get_float3(particle.location()); + location = transform_point(&itfm, location); + min = ccl::min(min, location - particle_size); + max = ccl::max(max, location + particle_size); + } } /* Calculate texture space from the particle bounds. */ loc = (min + max) * 0.5f; diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 165242d0dff..bd1c37a7560 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -196,7 +196,11 @@ static inline uint get_layer(BL::Array<int, 20> array) return layer; } -static inline uint get_layer(BL::Array<int, 20> array, BL::Array<int, 8> local_array, bool use_local, bool is_light = false) +static inline uint get_layer(BL::Array<int, 20> array, + BL::Array<int, 8> local_array, + bool use_local, + bool is_light = false, + uint scene_layers = (1 << 20) - 1) { uint layer = 0; @@ -205,9 +209,13 @@ static inline uint get_layer(BL::Array<int, 20> array, BL::Array<int, 8> local_a layer |= (1 << i); if(is_light) { - /* consider lamps on all local view layers */ - for(uint i = 0; i < 8; i++) - layer |= (1 << (20+i)); + /* Consider light is visible if it was visible without layer + * override, which matches behavior of Blender Internal. + */ + if(layer & scene_layers) { + for(uint i = 0; i < 8; i++) + layer |= (1 << (20+i)); + } } else { for(uint i = 0; i < 8; i++) diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index 350ca16f6e2..4a5f8b1bda6 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -25,7 +25,6 @@ #include "bvh_node.h" #include "bvh_params.h" -#include "util_cache.h" #include "util_debug.h" #include "util_foreach.h" #include "util_logging.h" @@ -70,125 +69,12 @@ BVH *BVH::create(const BVHParams& params, const vector<Object*>& objects) return new RegularBVH(params, objects); } -/* Cache */ - -bool BVH::cache_read(CacheData& key) -{ - key.add(system_cpu_bits()); - key.add(¶ms, sizeof(params)); - - foreach(Object *ob, objects) { - Mesh *mesh = ob->mesh; - - key.add(mesh->verts); - key.add(mesh->triangles); - key.add(mesh->curve_keys); - key.add(mesh->curves); - key.add(&ob->bounds, sizeof(ob->bounds)); - key.add(&ob->visibility, sizeof(ob->visibility)); - key.add(&mesh->transform_applied, sizeof(bool)); - - if(mesh->use_motion_blur) { - Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - if(attr) - key.add(attr->buffer); - - attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - if(attr) - key.add(attr->buffer); - } - } - - CacheData value; - - if(Cache::global.lookup(key, value)) { - cache_filename = key.get_filename(); - - if(!(value.read(pack.root_index) && - value.read(pack.SAH) && - value.read(pack.nodes) && - value.read(pack.leaf_nodes) && - value.read(pack.object_node) && - value.read(pack.tri_woop) && - value.read(pack.prim_type) && - value.read(pack.prim_visibility) && - value.read(pack.prim_index) && - value.read(pack.prim_object))) - { - /* Clear the pack if load failed. */ - pack.root_index = 0; - pack.SAH = 0.0f; - pack.nodes.clear(); - pack.leaf_nodes.clear(); - pack.object_node.clear(); - pack.tri_woop.clear(); - pack.prim_type.clear(); - pack.prim_visibility.clear(); - pack.prim_index.clear(); - pack.prim_object.clear(); - return false; - } - return true; - } - - return false; -} - -void BVH::cache_write(CacheData& key) -{ - CacheData value; - - value.add(pack.root_index); - value.add(pack.SAH); - - value.add(pack.nodes); - value.add(pack.leaf_nodes); - value.add(pack.object_node); - value.add(pack.tri_woop); - value.add(pack.prim_type); - value.add(pack.prim_visibility); - value.add(pack.prim_index); - value.add(pack.prim_object); - - Cache::global.insert(key, value); - - cache_filename = key.get_filename(); -} - -void BVH::clear_cache_except() -{ - set<string> except; - - if(!cache_filename.empty()) - except.insert(cache_filename); - - foreach(Object *ob, objects) { - Mesh *mesh = ob->mesh; - BVH *bvh = mesh->bvh; - - if(bvh && !bvh->cache_filename.empty()) - except.insert(bvh->cache_filename); - } - - Cache::global.clear_except("bvh", except); -} - /* Building */ void BVH::build(Progress& progress) { progress.set_substatus("Building BVH"); - /* cache read */ - CacheData key("bvh"); - - if(params.use_cache) { - progress.set_substatus("Looking in BVH cache"); - - if(cache_read(key)) - return; - } - /* build nodes */ BVHBuild bvh_build(objects, pack.prim_type, @@ -227,18 +113,6 @@ void BVH::build(Progress& progress) /* free build nodes */ root->deleteSubtree(); - - if(progress.get_cancel()) return; - - /* cache write */ - if(params.use_cache) { - progress.set_substatus("Writing BVH cache"); - cache_write(key); - - /* clear other bvh files from cache */ - if(params.top_level) - clear_cache_except(); - } } /* Refitting */ diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h index 669d2ccdcd5..272a3fa1514 100644 --- a/intern/cycles/bvh/bvh.h +++ b/intern/cycles/bvh/bvh.h @@ -20,7 +20,6 @@ #include "bvh_params.h" -#include "util_string.h" #include "util_types.h" #include "util_vector.h" @@ -30,7 +29,6 @@ class BVHNode; struct BVHStackEntry; class BVHParams; class BoundBox; -class CacheData; class LeafNode; class Object; class Progress; @@ -87,7 +85,6 @@ public: PackedBVH pack; BVHParams params; vector<Object*> objects; - string cache_filename; static BVH *create(const BVHParams& params, const vector<Object*>& objects); virtual ~BVH() {} @@ -95,15 +92,9 @@ public: void build(Progress& progress); void refit(Progress& progress); - void clear_cache_except(); - protected: BVH(const BVHParams& params, const vector<Object*>& objects); - /* cache */ - bool cache_read(CacheData& key); - void cache_write(CacheData& key); - /* triangles and strands*/ void pack_primitives(); void pack_triangle(int idx, float4 woop[3]); diff --git a/intern/cycles/bvh/bvh_binning.cpp b/intern/cycles/bvh/bvh_binning.cpp index db96490a36f..8745e39c21e 100644 --- a/intern/cycles/bvh/bvh_binning.cpp +++ b/intern/cycles/bvh/bvh_binning.cpp @@ -76,8 +76,8 @@ BVHObjectBinning::BVHObjectBinning(const BVHRange& job, BVHReference *prims) prefetch_L2(&prims[start() + i + 8]); /* map even and odd primitive to bin */ - BVHReference prim0 = prims[start() + i + 0]; - BVHReference prim1 = prims[start() + i + 1]; + const BVHReference& prim0 = prims[start() + i + 0]; + const BVHReference& prim1 = prims[start() + i + 1]; int4 bin0 = get_bin(prim0.bounds()); int4 bin1 = get_bin(prim1.bounds()); @@ -96,7 +96,7 @@ BVHObjectBinning::BVHObjectBinning(const BVHRange& job, BVHReference *prims) /* for uneven number of primitives */ if(i < ssize_t(size())) { /* map primitive to bin */ - BVHReference prim0 = prims[start() + i]; + const BVHReference& prim0 = prims[start() + i]; int4 bin0 = get_bin(prim0.bounds()); /* increase bounds of bins */ diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp index a44ad656316..45b0aaa2d63 100644 --- a/intern/cycles/bvh/bvh_build.cpp +++ b/intern/cycles/bvh/bvh_build.cpp @@ -234,8 +234,14 @@ BVHNode* BVHBuild::run() return NULL; /* init spatial splits */ - if(params.top_level) /* todo: get rid of this */ + if(params.top_level) { + /* NOTE: Technically it is supported by the builder but it's not really + * optimized for speed yet and not really clear yet if it has measurable + * improvement on render time. Needs some extra investigation before + * enabling spatial split for top level BVH. + */ params.use_spatial_split = false; + } spatial_min_overlap = root.bounds().safe_area() * params.spatial_split_alpha; spatial_right_bounds.clear(); @@ -276,6 +282,8 @@ BVHNode* BVHBuild::run() else if(!params.use_spatial_split) { /*rotate(rootnode, 4, 5);*/ rootnode->update_visibility(); + } + if(rootnode != NULL) { VLOG(1) << "BVH build statistics:\n" << " Build time: " << time_dt() - build_start_time << "\n" << " Total number of nodes: " @@ -525,11 +533,9 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range) /* Extend an array when needed. */ if(prim_type.size() < range.end()) { assert(params.use_spatial_split); - /* TODO(sergey): We might want to look into different policies of - * re-allocation here, so on the one hand we would not do as much - * re-allocations and on the other hand will have small memory - * overhead. - */ + prim_type.reserve(references.size()); + prim_index.reserve(references.size()); + prim_object.reserve(references.size()); prim_type.resize(range.end()); prim_index.resize(range.end()); prim_object.resize(range.end()); diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h index af8d8eeb3ee..faa995c3f29 100644 --- a/intern/cycles/bvh/bvh_params.h +++ b/intern/cycles/bvh/bvh_params.h @@ -43,9 +43,6 @@ public: /* object or mesh level bvh */ bool top_level; - /* disk cache */ - bool use_cache; - /* QBVH */ bool use_qbvh; @@ -71,7 +68,6 @@ public: max_curve_leaf_size = 2; top_level = false; - use_cache = false; use_qbvh = false; } diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp index 2290c4143ad..534c1aa73b5 100644 --- a/intern/cycles/bvh/bvh_split.cpp +++ b/intern/cycles/bvh/bvh_split.cpp @@ -191,11 +191,16 @@ void BVHSpatialSplit::split(BVHBuild *builder, BVHRange& left, BVHRange& right, } } - /* duplicate or unsplit references intersecting both sides. */ + /* Duplicate or unsplit references intersecting both sides. + * + * Duplication happens into a temporary pre-allocated vector in order to + * reduce number of memmove() calls happening in vector.insert(). + */ + vector<BVHReference> new_refs; + new_refs.reserve(right_start - left_end); while(left_end < right_start) { /* split reference. */ BVHReference lref, rref; - split_reference(builder, lref, rref, refs[left_end], this->dim, this->pos); /* compute SAH for duplicate/unsplit candidates. */ @@ -234,61 +239,36 @@ void BVHSpatialSplit::split(BVHBuild *builder, BVHRange& left, BVHRange& right, left_bounds = ldb; right_bounds = rdb; refs[left_end++] = lref; - refs.insert(refs.begin() + right_end, rref); + new_refs.push_back(rref); right_end++; } } - + /* Insert duplicated references into actual array in one go. */ + if(new_refs.size() != 0) { + refs.insert(refs.begin() + right_end - new_refs.size(), + new_refs.begin(), + new_refs.end()); + } left = BVHRange(left_bounds, left_start, left_end - left_start); right = BVHRange(right_bounds, right_start, right_end - right_start); } -void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVHReference& right, const BVHReference& ref, int dim, float pos) +void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh, + const Transform *tfm, + int prim_index, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds) { - /* initialize boundboxes */ - BoundBox left_bounds = BoundBox::empty; - BoundBox right_bounds = BoundBox::empty; - - /* loop over vertices/edges. */ - Object *ob = builder->objects[ref.prim_object()]; - const Mesh *mesh = ob->mesh; - - if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) { - const int *inds = mesh->triangles[ref.prim_index()].v; - const float3 *verts = &mesh->verts[0]; - const float3* v1 = &verts[inds[2]]; - - for(int i = 0; i < 3; i++) { - const float3* v0 = v1; - int vindex = inds[i]; - v1 = &verts[vindex]; - float v0p = (*v0)[dim]; - float v1p = (*v1)[dim]; - - /* insert vertex to the boxes it belongs to. */ - if(v0p <= pos) - left_bounds.grow(*v0); - - if(v0p >= pos) - right_bounds.grow(*v0); - - /* edge intersects the plane => insert intersection to both boxes. */ - if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) { - float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f)); - left_bounds.grow(t); - right_bounds.grow(t); - } - } - } - else { - /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/ - const int k0 = mesh->curves[ref.prim_index()].first_key + PRIMITIVE_UNPACK_SEGMENT(ref.prim_type()); - const int k1 = k0 + 1; - const float4 key0 = mesh->curve_keys[k0]; - const float4 key1 = mesh->curve_keys[k1]; - const float3 v0 = float4_to_float3(key0); - const float3 v1 = float4_to_float3(key1); - + const int *inds = mesh->triangles[prim_index].v; + const float3 *verts = &mesh->verts[0]; + float3 v1 = tfm ? transform_point(tfm, verts[inds[2]]) : verts[inds[2]]; + + for(int i = 0; i < 3; i++) { + float3 v0 = v1; + int vindex = inds[i]; + v1 = tfm ? transform_point(tfm, verts[vindex]) : verts[vindex]; float v0p = v0[dim]; float v1p = v1[dim]; @@ -299,12 +279,6 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH if(v0p >= pos) right_bounds.grow(v0); - if(v1p <= pos) - left_bounds.grow(v1); - - if(v1p >= pos) - right_bounds.grow(v1); - /* edge intersects the plane => insert intersection to both boxes. */ if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) { float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f)); @@ -312,6 +286,159 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH right_bounds.grow(t); } } +} + +void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh, + const Transform *tfm, + int prim_index, + int segment_index, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds) +{ + /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/ + const int k0 = mesh->curves[prim_index].first_key + segment_index; + const int k1 = k0 + 1; + const float4& key0 = mesh->curve_keys[k0]; + const float4& key1 = mesh->curve_keys[k1]; + float3 v0 = float4_to_float3(key0); + float3 v1 = float4_to_float3(key1); + + if(tfm != NULL) { + v0 = transform_point(tfm, v0); + v1 = transform_point(tfm, v1); + } + + float v0p = v0[dim]; + float v1p = v1[dim]; + + /* insert vertex to the boxes it belongs to. */ + if(v0p <= pos) + left_bounds.grow(v0); + + if(v0p >= pos) + right_bounds.grow(v0); + + if(v1p <= pos) + left_bounds.grow(v1); + + if(v1p >= pos) + right_bounds.grow(v1); + + /* edge intersects the plane => insert intersection to both boxes. */ + if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) { + float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f)); + left_bounds.grow(t); + right_bounds.grow(t); + } +} + +void BVHSpatialSplit::split_triangle_reference(const BVHReference& ref, + const Mesh *mesh, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds) +{ + split_triangle_primitive(mesh, + NULL, + ref.prim_index(), + dim, + pos, + left_bounds, + right_bounds); +} + +void BVHSpatialSplit::split_curve_reference(const BVHReference& ref, + const Mesh *mesh, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds) +{ + split_curve_primitive(mesh, + NULL, + ref.prim_index(), + PRIMITIVE_UNPACK_SEGMENT(ref.prim_type()), + dim, + pos, + left_bounds, + right_bounds); +} + +void BVHSpatialSplit::split_object_reference(const Object *object, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds) +{ + Mesh *mesh = object->mesh; + for(int tri_idx = 0; tri_idx < mesh->triangles.size(); ++tri_idx) { + split_triangle_primitive(mesh, + &object->tfm, + tri_idx, + dim, + pos, + left_bounds, + right_bounds); + } + for(int curve_idx = 0; curve_idx < mesh->curves.size(); ++curve_idx) { + Mesh::Curve &curve = mesh->curves[curve_idx]; + for(int segment_idx = 0; + segment_idx < curve.num_keys - 1; + ++segment_idx) + { + split_curve_primitive(mesh, + &object->tfm, + curve_idx, + segment_idx, + dim, + pos, + left_bounds, + right_bounds); + } + } +} + +void BVHSpatialSplit::split_reference(BVHBuild *builder, + BVHReference& left, + BVHReference& right, + const BVHReference& ref, + int dim, + float pos) +{ + /* initialize boundboxes */ + BoundBox left_bounds = BoundBox::empty; + BoundBox right_bounds = BoundBox::empty; + + /* loop over vertices/edges. */ + Object *ob = builder->objects[ref.prim_object()]; + const Mesh *mesh = ob->mesh; + + if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) { + split_triangle_reference(ref, + mesh, + dim, + pos, + left_bounds, + right_bounds); + } + else if(ref.prim_type() & PRIMITIVE_ALL_CURVE) { + split_curve_reference(ref, + mesh, + dim, + pos, + left_bounds, + right_bounds); + } + else { + split_object_reference(ob, + dim, + pos, + left_bounds, + right_bounds); + } /* intersect with original bounds. */ left_bounds.max[dim] = pos; diff --git a/intern/cycles/bvh/bvh_split.h b/intern/cycles/bvh/bvh_split.h index 5b739311e5f..1e46bb66203 100644 --- a/intern/cycles/bvh/bvh_split.h +++ b/intern/cycles/bvh/bvh_split.h @@ -55,7 +55,58 @@ public: BVHSpatialSplit(BVHBuild *builder, const BVHRange& range, float nodeSAH); void split(BVHBuild *builder, BVHRange& left, BVHRange& right, const BVHRange& range); - void split_reference(BVHBuild *builder, BVHReference& left, BVHReference& right, const BVHReference& ref, int dim, float pos); + void split_reference(BVHBuild *builder, + BVHReference& left, + BVHReference& right, + const BVHReference& ref, + int dim, + float pos); + +protected: + /* Lower-level functions which calculates boundaries of left and right nodes + * needed for spatial split. + * + * Operates directly with primitive specified by it's index, reused by higher + * level splitting functions. + */ + void split_triangle_primitive(const Mesh *mesh, + const Transform *tfm, + int prim_index, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds); + void split_curve_primitive(const Mesh *mesh, + const Transform *tfm, + int prim_index, + int segment_index, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds); + + /* Lower-level functions which calculates boundaries of left and right nodes + * needed for spatial split. + * + * Operates with BVHReference, internally uses lower level API functions. + */ + void split_triangle_reference(const BVHReference& ref, + const Mesh *mesh, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds); + void split_curve_reference(const BVHReference& ref, + const Mesh *mesh, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds); + void split_object_reference(const Object *object, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds); }; /* Mixed Object-Spatial Split */ diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake index d7c59f42a5e..10a166b6e44 100644 --- a/intern/cycles/cmake/external_libs.cmake +++ b/intern/cycles/cmake/external_libs.cmake @@ -87,6 +87,13 @@ if(CYCLES_STANDALONE_REPOSITORY) find_package(OpenEXR) #### + # OpenShadingLanguage + if(WITH_CYCLES_OSL) + find_package(OpenShadingLanguage REQUIRED) + find_package(LLVM REQUIRED) + endif() + + #### # Boost set(__boost_packages filesystem regex system thread date_time) if(WITH_CYCLES_NETWORK) @@ -97,6 +104,8 @@ if(CYCLES_STANDALONE_REPOSITORY) # libraries works, could be different for someone's else libs.. if(APPLE OR MSVC) list(APPEND __boost_packages wave) + elseif(NOT (${OSL_LIBRARY_VERSION_MAJOR} EQUAL "1" AND ${OSL_LIBRARY_VERSION_MINOR} LESS "6")) + list(APPEND __boost_packages wave) endif() endif() find_package(Boost 1.48 COMPONENTS ${__boost_packages} REQUIRED) @@ -114,13 +123,6 @@ if(CYCLES_STANDALONE_REPOSITORY) set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB") #### - # OpenShadingLanguage - if(WITH_CYCLES_OSL) - find_package(OpenShadingLanguage REQUIRED) - find_package(LLVM REQUIRED) - endif() - - #### # Logging if(WITH_CYCLES_LOGGING) find_package(Glog REQUIRED) diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h index ba79f8c88ae..8c32d03135e 100644 --- a/intern/cycles/device/device_memory.h +++ b/intern/cycles/device/device_memory.h @@ -211,7 +211,10 @@ public: T *resize(size_t width, size_t height = 0, size_t depth = 0) { data_size = width * ((height == 0)? 1: height) * ((depth == 0)? 1: depth); - data.resize(data_size); + if(data.resize(data_size) == NULL) { + clear(); + return NULL; + } data_width = width; data_height = height; data_depth = depth; @@ -226,7 +229,9 @@ public: T *copy(T *ptr, size_t width, size_t height = 0, size_t depth = 0) { T *mem = resize(width, height, depth); - memcpy(mem, ptr, memory_size()); + if(mem != NULL) { + memcpy(mem, ptr, memory_size()); + } return mem; } diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp index d1f941ad9f2..afa35224aba 100644 --- a/intern/cycles/device/device_network.cpp +++ b/intern/cycles/device/device_network.cpp @@ -574,13 +574,13 @@ protected: network_device_memory mem; string name; InterpolationType interpolation; - ExtensionType extension_typr; + ExtensionType extension_type; device_ptr client_pointer; rcv.read(name); rcv.read(mem); rcv.read(interpolation); - rcv.read(extension); + rcv.read(extension_type); lock.unlock(); client_pointer = mem.device_pointer; @@ -596,7 +596,7 @@ protected: rcv.read_buffer((uint8_t*)mem.data_pointer, data_size); - device->tex_alloc(name.c_str(), mem, interpolation, extension); + device->tex_alloc(name.c_str(), mem, interpolation, extension_type); pointer_mapping_insert(client_pointer, mem.device_pointer); } diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index fee9a8a803d..7f16a73d966 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -313,7 +313,7 @@ void opencl_get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices) continue; } if(!opencl_device_version_check(device_id)) { - FIRST_VLOG(2) << "Ignoting device " << device_name + FIRST_VLOG(2) << "Ignoring device " << device_name << " due to old compiler version."; continue; } @@ -327,8 +327,8 @@ void opencl_get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices) &device_type, NULL) != CL_SUCCESS) { - FIRST_VLOG(2) << "Ignoting device " << device_name - << ", faield to fetch device type."; + FIRST_VLOG(2) << "Ignoring device " << device_name + << ", failed to fetch device type."; continue; } FIRST_VLOG(2) << "Adding new device " << device_name << "."; @@ -339,7 +339,7 @@ void opencl_get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices) device_name)); } else { - FIRST_VLOG(2) << "Ignoting device " << device_name + FIRST_VLOG(2) << "Ignoring device " << device_name << ", not officially supported yet."; } } @@ -581,7 +581,7 @@ public: ProgramName program_name, thread_scoped_lock& slot_locker) { - switch (program_name) { + switch(program_name) { case OCL_DEV_BASE_PROGRAM: store_something<cl_program>(platform, device, @@ -995,6 +995,7 @@ public: VLOG(2) << "Loaded kernel from " << clbin << "."; } else { + VLOG(2) << "Kernel file " << clbin << " either doesn't exist or failed to be loaded by driver."; string init_kernel_source = "#include \"kernels/opencl/kernel.cl\" // " + kernel_md5 + "\n"; /* If does not exist or loading binary failed, compile kernel. */ @@ -1605,7 +1606,7 @@ protected: * mega kernel is not getting feature-based optimizations. * * Ideally we need always compile kernel with as less features - * enabed as possible to keep performance at it's max. + * enabled as possible to keep performance at it's max. */ return ""; } @@ -3689,7 +3690,7 @@ string device_opencl_capabilities(void) APPEND_STRING_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what) vector<cl_device_id> device_ids; - for (cl_uint platform = 0; platform < num_platforms; ++platform) { + for(cl_uint platform = 0; platform < num_platforms; ++platform) { cl_platform_id platform_id = platform_ids[platform]; result += string_printf("Platform #%u\n", platform); @@ -3714,7 +3715,7 @@ string device_opencl_capabilities(void) num_devices, &device_ids[0], NULL)); - for (cl_uint device = 0; device < num_devices; ++device) { + for(cl_uint device = 0; device < num_devices; ++device) { cl_device_id device_id = device_ids[device]; result += string_printf("\t\tDevice: #%u\n", device); diff --git a/intern/cycles/kernel/geom/geom_bvh_shadow.h b/intern/cycles/kernel/geom/geom_bvh_shadow.h index e4cba99dc96..cb3f75f2a8f 100644 --- a/intern/cycles/kernel/geom/geom_bvh_shadow.h +++ b/intern/cycles/kernel/geom/geom_bvh_shadow.h @@ -59,7 +59,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, float isect_t = tmax; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #if BVH_FEATURE(BVH_INSTANCING) @@ -302,7 +302,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, object = kernel_tex_fetch(__prim_object, -primAddr-1); #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -338,7 +338,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, float t_fac; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm); + bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm); #else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); #endif @@ -353,7 +353,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, float ignore_t = FLT_MAX; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t); #endif diff --git a/intern/cycles/kernel/geom/geom_bvh_subsurface.h b/intern/cycles/kernel/geom/geom_bvh_subsurface.h index a73139f9c88..a093b9b55aa 100644 --- a/intern/cycles/kernel/geom/geom_bvh_subsurface.h +++ b/intern/cycles/kernel/geom/geom_bvh_subsurface.h @@ -63,7 +63,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, uint num_hits = 0; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #if defined(__KERNEL_SSE2__) @@ -240,7 +240,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, object = subsurface_object; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -278,7 +278,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, /* instance pop */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect_t); #endif diff --git a/intern/cycles/kernel/geom/geom_bvh_traversal.h b/intern/cycles/kernel/geom/geom_bvh_traversal.h index 73d79fd78ee..13d118b6d19 100644 --- a/intern/cycles/kernel/geom/geom_bvh_traversal.h +++ b/intern/cycles/kernel/geom/geom_bvh_traversal.h @@ -65,7 +65,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, int object = OBJECT_NONE; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif isect->t = ray->t; @@ -342,7 +342,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, object = kernel_tex_fetch(__prim_object, -primAddr-1); #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t); #endif @@ -378,7 +378,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, /* instance pop */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t); #endif diff --git a/intern/cycles/kernel/geom/geom_bvh_volume.h b/intern/cycles/kernel/geom/geom_bvh_volume.h index 41c784869f2..656cd6e7a0e 100644 --- a/intern/cycles/kernel/geom/geom_bvh_volume.h +++ b/intern/cycles/kernel/geom/geom_bvh_volume.h @@ -59,7 +59,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, const uint visibility = PATH_RAY_ALL_VISIBILITY; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif isect->t = ray->t; @@ -267,7 +267,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(object_flag & SD_OBJECT_HAS_VOLUME) { #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t); #endif @@ -307,7 +307,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, /* instance pop */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t); #endif diff --git a/intern/cycles/kernel/geom/geom_bvh_volume_all.h b/intern/cycles/kernel/geom/geom_bvh_volume_all.h index b6db36f4b17..8f7e3adae51 100644 --- a/intern/cycles/kernel/geom/geom_bvh_volume_all.h +++ b/intern/cycles/kernel/geom/geom_bvh_volume_all.h @@ -62,7 +62,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, const uint visibility = PATH_RAY_ALL_VISIBILITY; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #if BVH_FEATURE(BVH_INSTANCING) @@ -230,10 +230,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) #if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); #else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -268,10 +268,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -311,10 +311,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -341,7 +341,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(object_flag & SD_OBJECT_HAS_VOLUME) { #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -384,7 +384,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(num_hits_in_instance) { float t_fac; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm); + bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm); #else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); #endif @@ -397,7 +397,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, else { float ignore_t = FLT_MAX; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t); #endif diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h index 9d0a008fff1..ffd2f3b778f 100644 --- a/intern/cycles/kernel/geom/geom_object.h +++ b/intern/cycles/kernel/geom/geom_object.h @@ -428,8 +428,8 @@ ccl_device_inline void qbvh_instance_push(KernelGlobals *kg, ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t) { if(*t != FLT_MAX) { - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - *t *= len(transform_direction(&tfm, 1.0f/(*idir))); + Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + *t /= len(transform_direction(&tfm, ray->D)); } *P = ray->P; @@ -441,8 +441,8 @@ ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray ccl_device_inline void bvh_instance_pop_factor(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t_fac) { - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - *t_fac = len(transform_direction(&tfm, 1.0f/(*idir))); + Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + *t_fac = 1.0f / len(transform_direction(&tfm, ray->D)); *P = ray->P; *dir = bvh_clamp_direction(ray->D); @@ -453,15 +453,21 @@ ccl_device_inline void bvh_instance_pop_factor(KernelGlobals *kg, int object, co #ifdef __OBJECT_MOTION__ /* Transform ray into object space to enter motion blurred object in BVH */ -ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t, Transform *tfm) +ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + ccl_addr_space float *t, + Transform *itfm) { - Transform itfm; - *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm); + object_fetch_transform_motion_test(kg, object, ray->time, itfm); - *P = transform_point(&itfm, ray->P); + *P = transform_point(itfm, ray->P); float len; - *dir = bvh_clamp_direction(normalize_len(transform_direction(&itfm, ray->D), &len)); + *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len)); *idir = bvh_inverse_direction(*dir); if(*t != FLT_MAX) @@ -475,18 +481,24 @@ ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, c * TODO(sergey): Investigate if passing NULL instead of t1 gets optimized * so we can avoid having this duplication. */ -ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t, float *t1, Transform *tfm) +ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + float *t, + float *t1, + Transform *itfm) { - Transform itfm; - *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm); + object_fetch_transform_motion_test(kg, object, ray->time, itfm); - *P = transform_point(&itfm, ray->P); + *P = transform_point(itfm, ray->P); float len; - *dir = bvh_clamp_direction(normalize_len(transform_direction(&itfm, ray->D), &len)); + *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len)); *idir = bvh_inverse_direction(*dir); - if(*t != FLT_MAX) *t *= len; @@ -497,10 +509,18 @@ ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg, int object, /* Transorm ray to exit motion blurred object in BVH */ -ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t, Transform *tfm) +ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + ccl_addr_space float *t, + Transform *itfm) { - if(*t != FLT_MAX) - *t *= len(transform_direction(tfm, 1.0f/(*idir))); + if(*t != FLT_MAX) { + *t /= len(transform_direction(itfm, ray->D)); + } *P = ray->P; *dir = bvh_clamp_direction(ray->D); @@ -509,10 +529,16 @@ ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, co /* Same as above, but returns scale factor to apply to multiple intersection distances */ -ccl_device_inline void bvh_instance_motion_pop_factor(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t_fac, Transform *tfm) +ccl_device_inline void bvh_instance_motion_pop_factor(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + float *t_fac, + Transform *itfm) { - *t_fac = len(transform_direction(tfm, 1.0f/(*idir))); - + *t_fac /= len(transform_direction(itfm, ray->D)); *P = ray->P; *dir = bvh_clamp_direction(ray->D); *idir = bvh_inverse_direction(*dir); diff --git a/intern/cycles/kernel/geom/geom_qbvh_shadow.h b/intern/cycles/kernel/geom/geom_qbvh_shadow.h index dc37e6ecfa4..4564d5baf5e 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_shadow.h +++ b/intern/cycles/kernel/geom/geom_qbvh_shadow.h @@ -55,7 +55,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, float isect_t = tmax; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif *num_hits = 0; @@ -317,7 +317,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, object = kernel_tex_fetch(__prim_object, -primAddr-1); #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -357,7 +357,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, float t_fac; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm); + bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm); #else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); #endif @@ -370,7 +370,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, float ignore_t = FLT_MAX; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t); #endif diff --git a/intern/cycles/kernel/geom/geom_qbvh_subsurface.h b/intern/cycles/kernel/geom/geom_qbvh_subsurface.h index d85e1a4691e..fe231720cf7 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_subsurface.h +++ b/intern/cycles/kernel/geom/geom_qbvh_subsurface.h @@ -58,7 +58,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, uint num_hits = 0; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #ifndef __KERNEL_SSE41__ @@ -256,7 +256,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, object = subsurface_object; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -297,7 +297,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Instance pop. */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect_t); #endif diff --git a/intern/cycles/kernel/geom/geom_qbvh_traversal.h b/intern/cycles/kernel/geom/geom_qbvh_traversal.h index 7e356ea062b..4e1678665c0 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_traversal.h +++ b/intern/cycles/kernel/geom/geom_qbvh_traversal.h @@ -63,7 +63,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, int object = OBJECT_NONE; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #ifndef __KERNEL_SSE41__ @@ -356,7 +356,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, object = kernel_tex_fetch(__prim_object, -primAddr-1); #if BVH_FEATURE(BVH_MOTION) - qbvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &nodeDist, &ob_tfm); + qbvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &nodeDist, &ob_itfm); #else qbvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t, &nodeDist); #endif @@ -395,7 +395,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Instance pop. */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t); #endif diff --git a/intern/cycles/kernel/geom/geom_qbvh_volume.h b/intern/cycles/kernel/geom/geom_qbvh_volume.h index d8cfa3a4061..40864471d13 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_volume.h +++ b/intern/cycles/kernel/geom/geom_qbvh_volume.h @@ -54,7 +54,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, const uint visibility = PATH_RAY_ALL_VISIBILITY; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #ifndef __KERNEL_SSE41__ @@ -281,7 +281,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(object_flag & SD_OBJECT_HAS_VOLUME) { #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t); #endif @@ -322,7 +322,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Instance pop. */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t); #endif diff --git a/intern/cycles/kernel/geom/geom_qbvh_volume_all.h b/intern/cycles/kernel/geom/geom_qbvh_volume_all.h index 056ca9a1ad9..75e4c4e8d96 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_volume_all.h +++ b/intern/cycles/kernel/geom/geom_qbvh_volume_all.h @@ -57,7 +57,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, const uint visibility = PATH_RAY_ALL_VISIBILITY; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif uint num_hits = 0; @@ -247,10 +247,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) #if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); #else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -285,10 +285,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -328,10 +328,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -355,7 +355,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(object_flag & SD_OBJECT_HAS_VOLUME) { #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -400,7 +400,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(num_hits_in_instance) { float t_fac; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm); + bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm); #else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); #endif @@ -413,7 +413,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, else { float ignore_t = FLT_MAX; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t); #endif diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h index 3ef918dc842..ba309a1dc53 100644 --- a/intern/cycles/kernel/geom/geom_triangle_intersect.h +++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h @@ -98,7 +98,7 @@ void triangle_intersect_precalc(float3 dir, } /* TODO(sergey): Make it general utility function. */ -ccl_device_inline float xor_signmast(float x, int y) +ccl_device_inline float xor_signmask(float x, int y) { return __int_as_float(__float_as_int(x) ^ y); } @@ -140,13 +140,15 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, /* Calculate scaled barycentric coordinates. */ float U = Cx * By - Cy * Bx; - int sign_mask = (__float_as_int(U) & 0x80000000); float V = Ax * Cy - Ay * Cx; - if(sign_mask != (__float_as_int(V) & 0x80000000)) { - return false; - } float W = Bx * Ay - By * Ax; - if(sign_mask != (__float_as_int(W) & 0x80000000)) { + const int sign_mask = (__float_as_int(U) & 0x80000000); + /* TODO(sergey): Check if multiplication plus sign check is faster + * or at least same speed (but robust for endian types). + */ + if(sign_mask != (__float_as_int(V) & 0x80000000) || + sign_mask != (__float_as_int(W) & 0x80000000)) + { return false; } @@ -156,13 +158,13 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, return false; } - /* Calculate scaled z−coordinates of vertices and use them to calculate + /* Calculate scaled z-coordinates of vertices and use them to calculate * the hit distance. */ const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz; - const float sign_T = xor_signmast(T, sign_mask); + const float sign_T = xor_signmask(T, sign_mask); if((sign_T < 0.0f) || - (sign_T > isect->t * xor_signmast(det, sign_mask))) + (sign_T > isect->t * xor_signmask(det, sign_mask))) { return false; } @@ -173,6 +175,16 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility) #endif { +#ifdef __KERNEL_GPU__ + float4 a = tri_b - tri_a, b = tri_c - tri_a; + if(len_squared(make_float3(a.y*b.z - a.z*b.y, + a.z*b.x - a.x*b.z, + a.x*b.y - a.y*b.x)) == 0.0f) + { + return false; + } +#endif + /* Normalize U, V, W, and T. */ const float inv_det = 1.0f / det; isect->prim = triAddr; @@ -253,9 +265,9 @@ ccl_device_inline void triangle_intersect_subsurface( * the hit distance. */ const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz; - const float sign_T = xor_signmast(T, sign_mask); + const float sign_T = xor_signmask(T, sign_mask); if((sign_T < 0.0f) || - (sign_T > tmax * xor_signmast(det, sign_mask))) + (sign_T > tmax * xor_signmask(det, sign_mask))) { return; } diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h index 2fca83c615f..0cb56461f29 100644 --- a/intern/cycles/kernel/kernel_bake.h +++ b/intern/cycles/kernel/kernel_bake.h @@ -31,6 +31,13 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian float3 throughput = make_float3(1.0f, 1.0f, 1.0f); bool is_sss_sample = is_sss; + ray.P = sd->P + sd->Ng; + ray.D = -sd->Ng; + ray.t = FLT_MAX; +#ifdef __CAMERA_MOTION__ + ray.time = TIME_INVALID; +#endif + /* init radiance */ path_radiance_init(&L_sample, kernel_data.film.use_light_pass); @@ -143,7 +150,7 @@ ccl_device bool is_aa_pass(ShaderEvalType type) ccl_device bool is_light_pass(ShaderEvalType type) { - switch (type) { + switch(type) { case SHADER_EVAL_AO: case SHADER_EVAL_COMBINED: case SHADER_EVAL_SHADOW: @@ -255,7 +262,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, sample); } - switch (type) { + switch(type) { /* data passes */ case SHADER_EVAL_NORMAL: { diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h index 67651f96544..8d439ceb0d7 100644 --- a/intern/cycles/kernel/kernel_camera.h +++ b/intern/cycles/kernel/kernel_camera.h @@ -267,11 +267,14 @@ ccl_device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float /* ray differential */ ray->dP = differential3_zero(); + Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f)); + float3 Ddiff = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))); + Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x + 1.0f, raster_y, 0.0f)); - ray->dD.dx = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - ray->D; + ray->dD.dx = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - Ddiff; Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f)); - ray->dD.dy = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - ray->D; + ray->dD.dy = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - Ddiff; #endif } diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h index d02670f630a..04c4cf35587 100644 --- a/intern/cycles/kernel/kernel_compat_cpu.h +++ b/intern/cycles/kernel/kernel_compat_cpu.h @@ -144,7 +144,7 @@ template<typename T> struct texture_image { iy = wrap_periodic(iy, height); break; case EXTENSION_CLIP: - if (x < 0.0f || y < 0.0f || x >= width || y >= height) { + if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } /* Fall through. */ @@ -168,16 +168,16 @@ template<typename T> struct texture_image { niy = wrap_periodic(iy+1, height); break; case EXTENSION_CLIP: - if (x < 0.0f || y < 0.0f || x >= width || y >= height) { + if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } /* Fall through. */ case EXTENSION_EXTEND: - ix = wrap_clamp(ix, width); - iy = wrap_clamp(iy, height); - nix = wrap_clamp(ix+1, width); niy = wrap_clamp(iy+1, height); + + ix = wrap_clamp(ix, width); + iy = wrap_clamp(iy, height); break; } @@ -190,8 +190,8 @@ template<typename T> struct texture_image { } else { /* Bicubic b-spline interpolation. */ - const float tx = frac(x*(float)width - 0.5f, &ix); - const float ty = frac(y*(float)height - 0.5f, &iy); + float tx = frac(x*(float)width - 0.5f, &ix); + float ty = frac(y*(float)height - 0.5f, &iy); int pix, piy, nnix, nniy; switch(extension) { case EXTENSION_REPEAT: @@ -208,14 +208,11 @@ template<typename T> struct texture_image { nniy = wrap_periodic(iy+2, height); break; case EXTENSION_CLIP: - if (x < 0.0f || y < 0.0f || x >= width || y >= height) { + if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } /* Fall through. */ case EXTENSION_EXTEND: - ix = wrap_clamp(ix, width); - iy = wrap_clamp(iy, height); - pix = wrap_clamp(ix-1, width); piy = wrap_clamp(iy-1, height); @@ -224,6 +221,9 @@ template<typename T> struct texture_image { nnix = wrap_clamp(ix+2, width); nniy = wrap_clamp(iy+2, height); + + ix = wrap_clamp(ix, width); + iy = wrap_clamp(iy, height); break; } @@ -279,7 +279,9 @@ template<typename T> struct texture_image { iz = wrap_periodic(iz, depth); break; case EXTENSION_CLIP: - if (x < 0.0f || y < 0.0f || x >= width || y >= height) { + if(x < 0.0f || y < 0.0f || z < 0.0f || + x > 1.0f || y > 1.0f || z > 1.0f) + { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } /* Fall through. */ @@ -308,18 +310,20 @@ template<typename T> struct texture_image { niz = wrap_periodic(iz+1, depth); break; case EXTENSION_CLIP: - if (x < 0.0f || y < 0.0f || x >= width || y >= height) { + if(x < 0.0f || y < 0.0f || z < 0.0f || + x > 1.0f || y > 1.0f || z > 1.0f) + { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } /* Fall through. */ case EXTENSION_EXTEND: - ix = wrap_clamp(ix, width); - iy = wrap_clamp(iy, height); - iz = wrap_clamp(iz, depth); - nix = wrap_clamp(ix+1, width); niy = wrap_clamp(iy+1, height); niz = wrap_clamp(iz+1, depth); + + ix = wrap_clamp(ix, width); + iy = wrap_clamp(iy, height); + iz = wrap_clamp(iz, depth); break; } @@ -363,15 +367,13 @@ template<typename T> struct texture_image { nniz = wrap_periodic(iz+2, depth); break; case EXTENSION_CLIP: - if (x < 0.0f || y < 0.0f || x >= width || y >= height) { + if(x < 0.0f || y < 0.0f || z < 0.0f || + x > 1.0f || y > 1.0f || z > 1.0f) + { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } /* Fall through. */ case EXTENSION_EXTEND: - ix = wrap_clamp(ix, width); - iy = wrap_clamp(iy, height); - iz = wrap_clamp(iz, depth); - pix = wrap_clamp(ix-1, width); piy = wrap_clamp(iy-1, height); piz = wrap_clamp(iz-1, depth); @@ -383,6 +385,10 @@ template<typename T> struct texture_image { nnix = wrap_clamp(ix+2, width); nniy = wrap_clamp(iy+2, height); nniz = wrap_clamp(iz+2, depth); + + ix = wrap_clamp(ix, width); + iy = wrap_clamp(iy, height); + iz = wrap_clamp(iz, depth); break; } diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index eb2d39d5020..7590ec2d706 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -620,7 +620,7 @@ ccl_device void lamp_light_sample(KernelGlobals *kg, int lamp, } } -#if defined(__KERNEL_CUDA__) && (defined(i386) || defined(_M_IX86)) +#if defined(__KERNEL_CUDA__) && (__CUDA_ARCH__ >= 500) && (defined(i386) || defined(_M_IX86)) ccl_device_noinline #else ccl_device diff --git a/intern/cycles/kernel/kernel_path_surface.h b/intern/cycles/kernel/kernel_path_surface.h index fe85a6b6e4b..4485be8a5b3 100644 --- a/intern/cycles/kernel/kernel_path_surface.h +++ b/intern/cycles/kernel/kernel_path_surface.h @@ -150,7 +150,7 @@ ccl_device bool kernel_branched_path_surface_bounce(KernelGlobals *kg, RNG *rng, /* setup ray */ ray->P = ray_offset(ccl_fetch(sd, P), (label & LABEL_TRANSMIT)? -ccl_fetch(sd, Ng): ccl_fetch(sd, Ng)); - ray->D = bsdf_omega_in; + ray->D = normalize(bsdf_omega_in); ray->t = FLT_MAX; #ifdef __RAY_DIFFERENTIALS__ ray->dP = ccl_fetch(sd, dP); @@ -257,7 +257,7 @@ ccl_device_inline bool kernel_path_surface_bounce(KernelGlobals *kg, ccl_addr_sp /* setup ray */ ray->P = ray_offset(ccl_fetch(sd, P), (label & LABEL_TRANSMIT)? -ccl_fetch(sd, Ng): ccl_fetch(sd, Ng)); - ray->D = bsdf_omega_in; + ray->D = normalize(bsdf_omega_in); if(state->bounce == 0) ray->t -= ccl_fetch(sd, ray_length); /* clipping works through transparent */ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index acd2f5d0673..740a5f1f5d3 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -1036,7 +1036,7 @@ enum QueueNumber { * contribution for AO are enqueued here. */ QUEUE_SHADOW_RAY_CAST_DL_RAYS = 3, /* All rays for which a shadow ray should be cast to determine radiance - * contributuin for direct lighting are enqueued here. + * contributing for direct lighting are enqueued here. */ }; diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h index 27c0b44a80d..0a74a9deba9 100644 --- a/intern/cycles/kernel/kernel_volume.h +++ b/intern/cycles/kernel/kernel_volume.h @@ -374,7 +374,7 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGloba /* distance sampling */ sample_t = kernel_volume_distance_sample(ray->t, sigma_t, channel, xi, &transmittance, &pdf); - /* modifiy pdf for hit/miss decision */ + /* modify pdf for hit/miss decision */ if(probalistic_scatter) pdf *= make_float3(1.0f, 1.0f, 1.0f) - volume_color_transmittance(sigma_t, t); @@ -422,7 +422,7 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGloba /* heterogeneous volume distance sampling: integrate stepping through the * volume until we reach the end, get absorbed entirely, or run out of - * iterations. this does probalistically scatter or get transmitted through + * iterations. this does probabilistically scatter or get transmitted through * for path tracing where we don't want to branch. */ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(KernelGlobals *kg, PathState *state, Ray *ray, ShaderData *sd, PathRadiance *L, float3 *throughput, RNG *rng) @@ -610,7 +610,7 @@ typedef struct VolumeSegment { /* record volume steps to the end of the volume. * * it would be nice if we could only record up to the point that we need to scatter, - * but the entire segment is needed to do always scattering, rather than probalistically + * but the entire segment is needed to do always scattering, rather than probabilistically * hitting or missing the volume. if we don't know the transmittance at the end of the * volume we can't generate stratified distance samples up to that transmittance */ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *state, @@ -766,7 +766,7 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter( sd->randb_closure = rphase*3.0f - channel; float xi = rscatter; - /* probalistic scattering decision based on transmittance */ + /* probabilistic scattering decision based on transmittance */ if(probalistic_scatter) { float sample_transmittance = kernel_volume_channel_get(segment->accum_transmittance, channel); @@ -846,7 +846,7 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter( float3 distance_pdf; sample_t = prev_t + kernel_volume_distance_sample(step_t, step->sigma_t, channel, xi, &transmittance, &distance_pdf); - /* modifiy pdf for hit/miss decision */ + /* modify pdf for hit/miss decision */ if(probalistic_scatter) distance_pdf *= make_float3(1.0f, 1.0f, 1.0f) - segment->accum_transmittance; @@ -942,7 +942,7 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter( /* decide if we need to use decoupled or not */ ccl_device bool kernel_volume_use_decoupled(KernelGlobals *kg, bool heterogeneous, bool direct, int sampling_method) { - /* decoupled ray marching for heterogenous volumes not supported on the GPU, + /* decoupled ray marching for heterogeneous volumes not supported on the GPU, * which also means equiangular and multiple importance sampling is not * support for that case */ #ifdef __KERNEL_GPU__ diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp index 2facced0914..4d70bc80006 100644 --- a/intern/cycles/kernel/osl/background.cpp +++ b/intern/cycles/kernel/osl/background.cpp @@ -77,7 +77,7 @@ public: ClosureParam *closure_background_params() { static ClosureParam params[] = { - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(GenericBackgroundClosure, label, "label"), CLOSURE_FINISH_PARAM(GenericBackgroundClosure) }; return params; @@ -98,7 +98,7 @@ CCLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure) ClosureParam *closure_ambient_occlusion_params() { static ClosureParam params[] = { - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(AmbientOcclusionClosure, label, "label"), CLOSURE_FINISH_PARAM(AmbientOcclusionClosure) }; return params; diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp index 43929fbe928..b3c71e4a706 100644 --- a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp +++ b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp @@ -93,7 +93,7 @@ ClosureParam *closure_bsdf_diffuse_ramp_params() static ClosureParam params[] = { CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, sc.N), CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8), - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(DiffuseRampClosure, label, "label"), CLOSURE_FINISH_PARAM(DiffuseRampClosure) }; return params; diff --git a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp index 497c4f0dc5c..99f510d31ed 100644 --- a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp +++ b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp @@ -93,7 +93,7 @@ ClosureParam *closure_bsdf_phong_ramp_params() CLOSURE_FLOAT3_PARAM(PhongRampClosure, sc.N), CLOSURE_FLOAT_PARAM(PhongRampClosure, sc.data0), CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8), - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(PhongRampClosure, label, "label"), CLOSURE_FINISH_PARAM(PhongRampClosure) }; return params; diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp index 02935542c56..9a95fa57a81 100644 --- a/intern/cycles/kernel/osl/emissive.cpp +++ b/intern/cycles/kernel/osl/emissive.cpp @@ -77,7 +77,7 @@ public: ClosureParam *closure_emission_params() { static ClosureParam params[] = { - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(GenericEmissiveClosure, label, "label"), CLOSURE_FINISH_PARAM(GenericEmissiveClosure) }; return params; diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp index 88998037751..bc395922077 100644 --- a/intern/cycles/kernel/osl/osl_bssrdf.cpp +++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp @@ -69,7 +69,7 @@ ClosureParam *closure_bssrdf_cubic_params() CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, radius), CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, sc.data1), CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, sc.T.x), - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(CubicBSSRDFClosure, label, "label"), CLOSURE_FINISH_PARAM(CubicBSSRDFClosure) }; return params; @@ -97,7 +97,7 @@ ClosureParam *closure_bssrdf_gaussian_params() CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, sc.N), CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, radius), CLOSURE_FLOAT_PARAM(GaussianBSSRDFClosure, sc.data1), - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(GaussianBSSRDFClosure, label, "label"), CLOSURE_FINISH_PARAM(GaussianBSSRDFClosure) }; return params; diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index ef67ef52fc0..c0bf25ac1c7 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -72,12 +72,17 @@ void name(RendererServices *, int id, void *data) \ #define CCLOSURE_PREPARE_STATIC(name, classname) static CCLOSURE_PREPARE(name, classname) #define CLOSURE_FLOAT3_PARAM(st, fld) \ - { TypeDesc::TypeVector, reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) } + { TypeDesc::TypeVector, (int)reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) } #define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z) #define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z) #define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) +#if OSL_LIBRARY_VERSION_CODE < 10700 +# undef CLOSURE_STRING_KEYPARAM +# define CLOSURE_STRING_KEYPARAM(st, fld, key) { TypeDesc::TypeString, 0, key, 0 } +#endif + /* Closure */ class CClosurePrimitive { @@ -97,6 +102,10 @@ public: virtual void setup() {} Category category; + +#if OSL_LIBRARY_VERSION_CODE >= 10700 + OSL::ustring label; +#endif }; /* BSDF */ @@ -175,7 +184,7 @@ static ClosureParam *bsdf_##lower##_params() \ /* parameters */ #define BSDF_CLOSURE_CLASS_END(Upper, lower) \ - CLOSURE_STRING_KEYPARAM("label"), \ + CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), \ CLOSURE_FINISH_PARAM(Upper##Closure) \ }; \ return params; \ @@ -223,7 +232,7 @@ static ClosureParam *volume_##lower##_params() \ /* parameters */ #define VOLUME_CLOSURE_CLASS_END(Upper, lower) \ - CLOSURE_STRING_KEYPARAM("label"), \ + CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), \ CLOSURE_FINISH_PARAM(Upper##Closure) \ }; \ return params; \ diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h index 190234a7706..aa2befd6e98 100644 --- a/intern/cycles/kernel/osl/osl_services.h +++ b/intern/cycles/kernel/osl/osl_services.h @@ -104,6 +104,55 @@ public: const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy, const OSL::Vec3 &dPdz, int nchannels, float *result); +#if OSL_LIBRARY_VERSION_CODE >= 10600 + bool texture(ustring filename, + TextureHandle * /*texture_handle*/, + TexturePerthread * /*texture_thread_info*/, + TextureOpt &options, + OSL::ShaderGlobals *sg, + float s, float t, + float dsdx, float dtdx, float dsdy, float dtdy, + int nchannels, + float *result, + float * /*dresultds*/, + float * /*dresultdt*/) + { + /* TODO(sergey): Support derivatives. */ + return texture(filename, + options, + sg, + s, t, + dsdx, dtdx, dsdy, dtdy, + nchannels, + result); + } + + bool texture3d(ustring filename, + TextureHandle * /*texture_handle*/, + TexturePerthread * /*texture_thread_info*/, + TextureOpt &options, + OSL::ShaderGlobals *sg, + const OSL::Vec3 &P, + const OSL::Vec3 &dPdx, + const OSL::Vec3 &dPdy, + const OSL::Vec3 &dPdz, + int nchannels, + float *result, + float * /*dresultds*/, + float * /*dresultdt*/, + float * /*dresultdr*/) + { + /* TODO(sergey): Support derivatives. */ + return texture3d(filename, + options, + sg, + P, + dPdx, dPdy, dPdz, + nchannels, + result); + } +#endif + bool environment(ustring filename, TextureOpt &options, OSL::ShaderGlobals *sg, const OSL::Vec3 &R, const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index 8cfe0cbcbd4..2f234aa25ea 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -146,165 +146,175 @@ static void flatten_surface_closure_tree(ShaderData *sd, int path_flag, /* OSL gives us a closure tree, we flatten it into arrays per * closure type, for evaluation, sampling, etc later on. */ - if(closure->type == OSL::ClosureColor::COMPONENT) { - OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; - CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); +#if OSL_LIBRARY_VERSION_CODE < 10700 + switch(closure->type) { +#else + switch(closure->id) { +#endif + case OSL::ClosureColor::MUL: { + OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; + flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight); + break; + } + case OSL::ClosureColor::ADD: { + OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; + flatten_surface_closure_tree(sd, path_flag, add->closureA, weight); + flatten_surface_closure_tree(sd, path_flag, add->closureB, weight); + break; + } + default: { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); - if(prim) { - ShaderClosure sc; + if(prim) { + ShaderClosure sc; #ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS - weight = weight*TO_FLOAT3(comp->w); + weight = weight*TO_FLOAT3(comp->w); #endif - sc.weight = weight; + sc.weight = weight; - prim->setup(); + prim->setup(); - switch (prim->category) { - case CClosurePrimitive::BSDF: { - CBSDFClosure *bsdf = (CBSDFClosure *)prim; - int scattering = bsdf->scattering(); + switch(prim->category) { + case CClosurePrimitive::BSDF: { + CBSDFClosure *bsdf = (CBSDFClosure *)prim; + int scattering = bsdf->scattering(); - /* caustic options */ - if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { - KernelGlobals *kg = sd->osl_globals; + /* caustic options */ + if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { + KernelGlobals *kg = sd->osl_globals; - if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || - (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) { - return; + if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || + (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) + { + return; + } } - } - /* sample weight */ - float sample_weight = fabsf(average(weight)); + /* sample weight */ + float sample_weight = fabsf(average(weight)); - sc.sample_weight = sample_weight; + sc.sample_weight = sample_weight; - sc.type = bsdf->sc.type; - sc.N = bsdf->sc.N; - sc.T = bsdf->sc.T; - sc.data0 = bsdf->sc.data0; - sc.data1 = bsdf->sc.data1; - sc.data2 = bsdf->sc.data2; - sc.prim = bsdf->sc.prim; + sc.type = bsdf->sc.type; + sc.N = bsdf->sc.N; + sc.T = bsdf->sc.T; + sc.data0 = bsdf->sc.data0; + sc.data1 = bsdf->sc.data1; + sc.data2 = bsdf->sc.data2; + sc.prim = bsdf->sc.prim; - /* add */ - if(sc.sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= bsdf->shaderdata_flag(); - } - break; - } - case CClosurePrimitive::Emissive: { - /* sample weight */ - float sample_weight = fabsf(average(weight)); - - sc.sample_weight = sample_weight; - sc.type = CLOSURE_EMISSION_ID; - sc.data0 = 0.0f; - sc.data1 = 0.0f; - sc.data2 = 0.0f; - sc.prim = NULL; - - /* flag */ - if(sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= SD_EMISSION; - } - break; - } - case CClosurePrimitive::AmbientOcclusion: { - /* sample weight */ - float sample_weight = fabsf(average(weight)); - - sc.sample_weight = sample_weight; - sc.type = CLOSURE_AMBIENT_OCCLUSION_ID; - sc.data0 = 0.0f; - sc.data1 = 0.0f; - sc.data2 = 0.0f; - sc.prim = NULL; - - if(sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= SD_AO; - } - break; - } - case CClosurePrimitive::Holdout: { - sc.sample_weight = 0.0f; - sc.type = CLOSURE_HOLDOUT_ID; - sc.data0 = 0.0f; - sc.data1 = 0.0f; - sc.data2 = 0.0f; - sc.prim = NULL; - - if(sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= SD_HOLDOUT; + /* add */ + if(sc.sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure < MAX_CLOSURE) { + sd->closure[sd->num_closure++] = sc; + sd->flag |= bsdf->shaderdata_flag(); + } + break; } - break; - } - case CClosurePrimitive::BSSRDF: { - CBSSRDFClosure *bssrdf = (CBSSRDFClosure *)prim; - float sample_weight = fabsf(average(weight)); + case CClosurePrimitive::Emissive: { + /* sample weight */ + float sample_weight = fabsf(average(weight)); - if(sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure+2 < MAX_CLOSURE) { sc.sample_weight = sample_weight; - - sc.type = bssrdf->sc.type; - sc.N = bssrdf->sc.N; - sc.data1 = bssrdf->sc.data1; - sc.T.x = bssrdf->sc.T.x; + sc.type = CLOSURE_EMISSION_ID; + sc.data0 = 0.0f; + sc.data1 = 0.0f; + sc.data2 = 0.0f; sc.prim = NULL; - /* disable in case of diffuse ancestor, can't see it well then and - * adds considerably noise due to probabilities of continuing path - * getting lower and lower */ - if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) - bssrdf->radius = make_float3(0.0f, 0.0f, 0.0f); - - /* create one closure for each color channel */ - if(fabsf(weight.x) > 0.0f) { - sc.weight = make_float3(weight.x, 0.0f, 0.0f); - sc.data0 = bssrdf->radius.x; - sc.data1 = 0.0f; - sd->flag |= bssrdf_setup(&sc, sc.type); + /* flag */ + if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; + sd->flag |= SD_EMISSION; } + break; + } + case CClosurePrimitive::AmbientOcclusion: { + /* sample weight */ + float sample_weight = fabsf(average(weight)); - if(fabsf(weight.y) > 0.0f) { - sc.weight = make_float3(0.0f, weight.y, 0.0f); - sc.data0 = bssrdf->radius.y; - sc.data1 = 0.0f; - sd->flag |= bssrdf_setup(&sc, sc.type); + sc.sample_weight = sample_weight; + sc.type = CLOSURE_AMBIENT_OCCLUSION_ID; + sc.data0 = 0.0f; + sc.data1 = 0.0f; + sc.data2 = 0.0f; + sc.prim = NULL; + + if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; + sd->flag |= SD_AO; } + break; + } + case CClosurePrimitive::Holdout: { + sc.sample_weight = 0.0f; + sc.type = CLOSURE_HOLDOUT_ID; + sc.data0 = 0.0f; + sc.data1 = 0.0f; + sc.data2 = 0.0f; + sc.prim = NULL; - if(fabsf(weight.z) > 0.0f) { - sc.weight = make_float3(0.0f, 0.0f, weight.z); - sc.data0 = bssrdf->radius.z; - sc.data1 = 0.0f; - sd->flag |= bssrdf_setup(&sc, sc.type); + if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; + sd->flag |= SD_HOLDOUT; + } + break; + } + case CClosurePrimitive::BSSRDF: { + CBSSRDFClosure *bssrdf = (CBSSRDFClosure *)prim; + float sample_weight = fabsf(average(weight)); + + if(sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure+2 < MAX_CLOSURE) { + sc.sample_weight = sample_weight; + + sc.type = bssrdf->sc.type; + sc.N = bssrdf->sc.N; + sc.data1 = bssrdf->sc.data1; + sc.T.x = bssrdf->sc.T.x; + sc.prim = NULL; + + /* disable in case of diffuse ancestor, can't see it well then and + * adds considerably noise due to probabilities of continuing path + * getting lower and lower */ + if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) + bssrdf->radius = make_float3(0.0f, 0.0f, 0.0f); + + /* create one closure for each color channel */ + if(fabsf(weight.x) > 0.0f) { + sc.weight = make_float3(weight.x, 0.0f, 0.0f); + sc.data0 = bssrdf->radius.x; + sc.data1 = 0.0f; + sd->flag |= bssrdf_setup(&sc, sc.type); + sd->closure[sd->num_closure++] = sc; + } + + if(fabsf(weight.y) > 0.0f) { + sc.weight = make_float3(0.0f, weight.y, 0.0f); + sc.data0 = bssrdf->radius.y; + sc.data1 = 0.0f; + sd->flag |= bssrdf_setup(&sc, sc.type); + sd->closure[sd->num_closure++] = sc; + } + + if(fabsf(weight.z) > 0.0f) { + sc.weight = make_float3(0.0f, 0.0f, weight.z); + sc.data0 = bssrdf->radius.z; + sc.data1 = 0.0f; + sd->flag |= bssrdf_setup(&sc, sc.type); + sd->closure[sd->num_closure++] = sc; + } } + break; } - break; + case CClosurePrimitive::Background: + case CClosurePrimitive::Volume: + break; /* not relevant */ } - case CClosurePrimitive::Background: - case CClosurePrimitive::Volume: - break; /* not relevant */ } + break; } } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; - flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight); - } - else if(closure->type == OSL::ClosureColor::ADD) { - OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; - flatten_surface_closure_tree(sd, path_flag, add->closureA, weight); - flatten_surface_closure_tree(sd, path_flag, add->closureB, weight); - } } void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx) @@ -335,27 +345,33 @@ static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure) * is only one supported closure type at the moment, which has no evaluation * functions, so we just sum the weights */ - if(closure->type == OSL::ClosureColor::COMPONENT) { - OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; - CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); - - if(prim && prim->category == CClosurePrimitive::Background) -#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS - return TO_FLOAT3(comp->w); +#if OSL_LIBRARY_VERSION_CODE < 10700 + switch(closure->type) { #else - return make_float3(1.0f, 1.0f, 1.0f); + switch(closure->id) { #endif - } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; + case OSL::ClosureColor::MUL: { + OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; - return TO_FLOAT3(mul->weight) * flatten_background_closure_tree(mul->closure); - } - else if(closure->type == OSL::ClosureColor::ADD) { - OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; + return TO_FLOAT3(mul->weight) * flatten_background_closure_tree(mul->closure); + } + case OSL::ClosureColor::ADD: { + OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; - return flatten_background_closure_tree(add->closureA) + - flatten_background_closure_tree(add->closureB); + return flatten_background_closure_tree(add->closureA) + + flatten_background_closure_tree(add->closureB); + } + default: { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); + + if(prim && prim->category == CClosurePrimitive::Background) +#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS + return TO_FLOAT3(comp->w); +#else + return make_float3(1.0f, 1.0f, 1.0f); +#endif + } } return make_float3(0.0f, 0.0f, 0.0f); @@ -390,76 +406,84 @@ static void flatten_volume_closure_tree(ShaderData *sd, /* OSL gives us a closure tree, we flatten it into arrays per * closure type, for evaluation, sampling, etc later on. */ - if(closure->type == OSL::ClosureColor::COMPONENT) { - OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; - CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); +#if OSL_LIBRARY_VERSION_CODE < 10700 + switch(closure->type) { +#else + switch(closure->id) { +#endif + case OSL::ClosureColor::MUL: { + OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; + flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight); + break; + } + case OSL::ClosureColor::ADD: { + OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; + flatten_volume_closure_tree(sd, add->closureA, weight); + flatten_volume_closure_tree(sd, add->closureB, weight); + break; + } + default: { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); - if(prim) { - ShaderClosure sc; + if(prim) { + ShaderClosure sc; #ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS - weight = weight*TO_FLOAT3(comp->w); + weight = weight*TO_FLOAT3(comp->w); #endif - sc.weight = weight; - - prim->setup(); - - switch (prim->category) { - case CClosurePrimitive::Volume: { - CVolumeClosure *volume = (CVolumeClosure *)prim; - /* sample weight */ - float sample_weight = fabsf(average(weight)); - - sc.sample_weight = sample_weight; - sc.type = volume->sc.type; - sc.data0 = volume->sc.data0; - sc.data1 = volume->sc.data1; - - /* add */ - if((sc.sample_weight > CLOSURE_WEIGHT_CUTOFF) && - (sd->num_closure < MAX_CLOSURE)) - { - sd->closure[sd->num_closure++] = sc; - sd->flag |= volume->shaderdata_flag(); + sc.weight = weight; + + prim->setup(); + + switch(prim->category) { + case CClosurePrimitive::Volume: { + CVolumeClosure *volume = (CVolumeClosure *)prim; + /* sample weight */ + float sample_weight = fabsf(average(weight)); + + sc.sample_weight = sample_weight; + sc.type = volume->sc.type; + sc.data0 = volume->sc.data0; + sc.data1 = volume->sc.data1; + + /* add */ + if((sc.sample_weight > CLOSURE_WEIGHT_CUTOFF) && + (sd->num_closure < MAX_CLOSURE)) + { + sd->closure[sd->num_closure++] = sc; + sd->flag |= volume->shaderdata_flag(); + } + break; } - break; - } - case CClosurePrimitive::Emissive: { - /* sample weight */ - float sample_weight = fabsf(average(weight)); - - sc.sample_weight = sample_weight; - sc.type = CLOSURE_EMISSION_ID; - sc.data0 = 0.0f; - sc.data1 = 0.0f; - sc.prim = NULL; - - /* flag */ - if(sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= SD_EMISSION; + case CClosurePrimitive::Emissive: { + /* sample weight */ + float sample_weight = fabsf(average(weight)); + + sc.sample_weight = sample_weight; + sc.type = CLOSURE_EMISSION_ID; + sc.data0 = 0.0f; + sc.data1 = 0.0f; + sc.prim = NULL; + + /* flag */ + if(sd->num_closure < MAX_CLOSURE) { + sd->closure[sd->num_closure++] = sc; + sd->flag |= SD_EMISSION; + } + break; } - break; + case CClosurePrimitive::Holdout: + break; /* not implemented */ + case CClosurePrimitive::Background: + case CClosurePrimitive::BSDF: + case CClosurePrimitive::BSSRDF: + case CClosurePrimitive::AmbientOcclusion: + break; /* not relevant */ } - case CClosurePrimitive::Holdout: - break; /* not implemented */ - case CClosurePrimitive::Background: - case CClosurePrimitive::BSDF: - case CClosurePrimitive::BSSRDF: - case CClosurePrimitive::AmbientOcclusion: - break; /* not relevant */ } } } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; - flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight); - } - else if(closure->type == OSL::ClosureColor::ADD) { - OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; - flatten_volume_closure_tree(sd, add->closureA, weight); - flatten_volume_closure_tree(sd, add->closureB, weight); - } } void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx) diff --git a/intern/cycles/kernel/shaders/node_brick_texture.osl b/intern/cycles/kernel/shaders/node_brick_texture.osl index e26e8dbff2c..35e01178ba8 100644 --- a/intern/cycles/kernel/shaders/node_brick_texture.osl +++ b/intern/cycles/kernel/shaders/node_brick_texture.osl @@ -22,6 +22,7 @@ float brick_noise(int n) /* fast integer noise */ { int nn; + n = (n + 1013) & 2147483647; n = (n >> 13) ^ n; nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 2147483647; return 0.5 * ((float)nn / 1073741824.0); diff --git a/intern/cycles/kernel/shaders/node_environment_texture.osl b/intern/cycles/kernel/shaders/node_environment_texture.osl index 14f0226a0e5..3a0b782c98e 100644 --- a/intern/cycles/kernel/shaders/node_environment_texture.osl +++ b/intern/cycles/kernel/shaders/node_environment_texture.osl @@ -45,6 +45,7 @@ shader node_environment_texture( vector Vector = P, string filename = "", string projection = "Equirectangular", + string interpolation = "linear", string color_space = "sRGB", int is_float = 1, int use_alpha = 1, @@ -64,7 +65,7 @@ shader node_environment_texture( p = environment_texture_direction_to_mirrorball(p); /* todo: use environment for better texture filtering of equirectangular */ - Color = (color)texture(filename, p[0], 1.0 - p[1], "wrap", "periodic", "alpha", Alpha); + Color = (color)texture(filename, p[0], 1.0 - p[1], "wrap", "periodic", "interp", interpolation, "alpha", Alpha); if (use_alpha) { Color = color_unpremultiply(Color, Alpha); diff --git a/intern/cycles/kernel/split/kernel_data_init.h b/intern/cycles/kernel/split/kernel_data_init.h index 421e2356f9b..4dab79a5c67 100644 --- a/intern/cycles/kernel/split/kernel_data_init.h +++ b/intern/cycles/kernel/split/kernel_data_init.h @@ -31,7 +31,7 @@ * Un-initialized Ray --------------| |--- Initialized Ray * Un-initialized PathState --------| |--- Initialized PathState * Un-initialized QueueData --------| |--- Initialized QueueData (to QUEUE_EMPTY_SLOT) - * Un-initilaized QueueIndex -------| |--- Initialized QueueIndex (to 0) + * Un-initialized QueueIndex -------| |--- Initialized QueueIndex (to 0) * Un-initialized use_queues_flag---| |--- Initialized use_queues_flag (to false) * Un-initialized ray_state --------| |--- Initialized ray_state * parallel_samples --------------- | |--- Initialized per_sample_output_buffers @@ -383,7 +383,7 @@ ccl_device void kernel_data_init( &Ray_coop[ray_index]); if(Ray_coop[ray_index].t != 0.0f) { - /* Initialize throuput, L_transparent, Ray, PathState; + /* Initialize throughput, L_transparent, Ray, PathState; * These rays proceed with path-iteration. */ throughput_coop[ray_index] = make_float3(1.0f, 1.0f, 1.0f); diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h index 025ae96f59d..63bbb27d873 100644 --- a/intern/cycles/kernel/svm/svm_attribute.h +++ b/intern/cycles/kernel/svm/svm_attribute.h @@ -22,6 +22,8 @@ ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd, uint4 node, NodeAttributeType *type, NodeAttributeType *mesh_type, AttributeElement *elem, int *offset, uint *out_offset) { + *out_offset = node.z; + *type = (NodeAttributeType)node.w; if(ccl_fetch(sd, object) != OBJECT_NONE) { /* find attribute by unique id */ uint id = node.y; @@ -32,6 +34,12 @@ ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd, uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset); while(attr_map.x != id) { + if(UNLIKELY(attr_map.x == ATTR_STD_NONE)) { + *elem = ATTR_ELEMENT_NONE; + *offset = 0; + *mesh_type = (NodeAttributeType)node.w; + return; + } attr_offset += ATTR_PRIM_TYPES; attr_map = kernel_tex_fetch(__attributes_map, attr_offset); } @@ -47,9 +55,6 @@ ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd, *offset = 0; *mesh_type = (NodeAttributeType)node.w; } - - *out_offset = node.z; - *type = (NodeAttributeType)node.w; } ccl_device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) diff --git a/intern/cycles/kernel/svm/svm_brick.h b/intern/cycles/kernel/svm/svm_brick.h index fcf8f47b77e..9b0cf5ab8c4 100644 --- a/intern/cycles/kernel/svm/svm_brick.h +++ b/intern/cycles/kernel/svm/svm_brick.h @@ -21,6 +21,7 @@ CCL_NAMESPACE_BEGIN ccl_device_noinline float brick_noise(int n) /* fast integer noise */ { int nn; + n = (n + 1013) & 0x7fffffff; n = (n >> 13) ^ n; nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; return 0.5f * ((float)nn / 1073741824.0f); diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 20105fd84f0..2120c892490 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -63,6 +63,9 @@ ccl_device_inline ShaderClosure *svm_node_closure_get_non_bsdf(ShaderData *sd, C if(ccl_fetch(sd, num_closure) < MAX_CLOSURE) { sc->weight *= mix_weight; sc->type = type; + sc->data0 = 0.0f; + sc->data1 = 0.0f; + sc->data2 = 0.0f; #ifdef __OSL__ sc->prim = NULL; #endif @@ -408,7 +411,10 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * sc->data1 = param2; sc->data2 = -stack_load_float(stack, data_node.z); - if(!(ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE)) { + if(stack_valid(data_node.y)) { + sc->T = normalize(stack_load_float3(stack, data_node.y)); + } + else if(!(ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE)) { sc->T = normalize(ccl_fetch(sd, dPdv)); sc->data2 = 0.0f; } diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 641d30a5737..bf7e067616f 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -46,7 +46,7 @@ CCL_NAMESPACE_BEGIN #define NODE_FEATURE_HAIR (1 << 1) #define NODE_FEATURE_BUMP (1 << 2) /* TODO(sergey): Consider using something like ((uint)(-1)). - * Need to ceck carefully operand types around usage of this + * Need to check carefully operand types around usage of this * define first. */ #define NODE_FEATURE_ALL (NODE_FEATURE_VOLUME|NODE_FEATURE_HAIR|NODE_FEATURE_BUMP) diff --git a/intern/cycles/kernel/svm/svm_voxel.h b/intern/cycles/kernel/svm/svm_voxel.h index bbb687dfce5..31cad5ec887 100644 --- a/intern/cycles/kernel/svm/svm_voxel.h +++ b/intern/cycles/kernel/svm/svm_voxel.h @@ -43,15 +43,6 @@ ccl_device void svm_node_tex_voxel(KernelGlobals *kg, tfm.w = read_node_float(kg, offset); co = transform_point(&tfm, co); } - if(co.x < 0.0f || co.y < 0.0f || co.z < 0.0f || - co.x > 1.0f || co.y > 1.0f || co.z > 1.0f) - { - if (stack_valid(density_out_offset)) - stack_store_float(stack, density_out_offset, 0.0f); - if (stack_valid(color_out_offset)) - stack_store_float3(stack, color_out_offset, make_float3(0.0f, 0.0f, 0.0f)); - return; - } float4 r = kernel_tex_image_interp_3d(id, co.x, co.y, co.z); if (stack_valid(density_out_offset)) stack_store_float(stack, density_out_offset, r.w); diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index df2a1d348d6..88ff7fbb70a 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -29,6 +29,7 @@ CCL_NAMESPACE_BEGIN Camera::Camera() { shuttertime = 1.0f; + motion_position = MOTION_POSITION_CENTER; aperturesize = 0.0f; focaldistance = 10.0f; @@ -53,6 +54,7 @@ Camera::Camera() longitude_min = -M_PI_F; longitude_max = M_PI_F; fov = M_PI_4_F; + fov_pre = fov_post = fov; sensorwidth = 0.036f; sensorheight = 0.024f; @@ -91,19 +93,26 @@ Camera::~Camera() void Camera::compute_auto_viewplane() { - float aspect = (float)width/(float)height; - - if(width >= height) { - viewplane.left = -aspect; - viewplane.right = aspect; - viewplane.bottom = -1.0f; + if(type == CAMERA_PANORAMA) { + viewplane.left = 0.0f; + viewplane.right = 1.0f; + viewplane.bottom = 0.0f; viewplane.top = 1.0f; } else { - viewplane.left = -1.0f; - viewplane.right = 1.0f; - viewplane.bottom = -1.0f/aspect; - viewplane.top = 1.0f/aspect; + float aspect = (float)width/(float)height; + if(width >= height) { + viewplane.left = -aspect; + viewplane.right = aspect; + viewplane.bottom = -1.0f; + viewplane.top = 1.0f; + } + else { + viewplane.left = -1.0f; + viewplane.right = 1.0f; + viewplane.bottom = -1.0f/aspect; + viewplane.top = 1.0f/aspect; + } } } @@ -417,9 +426,9 @@ BoundBox Camera::viewplane_bounds_get() BoundBox bounds = BoundBox::empty; if(type == CAMERA_PANORAMA) { - bounds.grow(make_float3(cameratoworld.w.x, - cameratoworld.w.y, - cameratoworld.w.z)); + bounds.grow(make_float3(cameratoworld.x.w, + cameratoworld.y.w, + cameratoworld.z.w)); } else { bounds.grow(transform_raster_to_world(0.0f, 0.0f)); diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index 1bedb051112..53bd4f0bc14 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -32,12 +32,24 @@ class Scene; /* Camera * * The camera parameters are quite standard, tested to be both compatible with - * Renderman, and Blender after remapping. */ + * Renderman, and Blender after remapping. + */ class Camera { public: + /* Specifies an offset for the shutter's time interval. */ + enum MotionPosition { + /* Shutter opens at the current frame. */ + MOTION_POSITION_START, + /* Shutter is fully open at the current frame. */ + MOTION_POSITION_CENTER, + /* Shutter closes at the current frame. */ + MOTION_POSITION_END, + }; + /* motion blur */ float shuttertime; + MotionPosition motion_position; /* depth of field */ float focaldistance; diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index 7282b04a22e..58080289633 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -144,7 +144,13 @@ void Pass::add(PassType type, vector<Pass>& passes) pass.exposure = false; break; case PASS_LIGHT: - /* ignores */ + /* This isn't a real pass, used by baking to see whether + * light data is needed or not. + * + * Set components to 0 so pass sort below happens in a + * determined way. + */ + pass.components = 0; break; #ifdef WITH_CYCLES_DEBUG case PASS_BVH_TRAVERSAL_STEPS: diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index e0537101247..f5ff091623b 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -336,6 +336,8 @@ void ShaderGraph::remove_unneeded_nodes() vector<bool> removed(num_node_ids, false); bool any_node_removed = false; + ShaderNode *geom = NULL; + /* find and unlink proxy nodes */ foreach(ShaderNode *node, nodes) { if(node->special_type == SHADER_SPECIAL_TYPE_PROXY) { @@ -423,12 +425,19 @@ void ShaderGraph::remove_unneeded_nodes() BumpNode *bump = static_cast<BumpNode*>(node); if(bump->outputs[0]->links.size()) { - /* Height input not connected */ - /* ToDo: Strength zero? */ - if(!bump->inputs[0]->link) { + /* Height inputs is not connected. */ + /* TODO(sergey): Ignore bump with zero strength. */ + if(bump->inputs[0]->link == NULL) { vector<ShaderInput*> inputs = bump->outputs[0]->links; - - relink(bump->inputs, inputs, NULL); + if(bump->inputs[4]->link == NULL) { + if(geom == NULL) { + geom = new GeometryNode(); + } + relink(bump->inputs, inputs, geom->output("Normal")); + } + else { + relink(bump->inputs, inputs, bump->input("Normal")->link); + } removed[bump->id] = true; any_node_removed = true; } @@ -511,6 +520,10 @@ void ShaderGraph::remove_unneeded_nodes() nodes = newnodes; } + + if(geom != NULL) { + add(geom); + } } void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack) diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 7bceb8a8bfa..486ae5b597f 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -69,6 +69,9 @@ void ImageManager::set_extended_image_limits(const DeviceInfo& info) else if((info.type == DEVICE_CUDA || info.type == DEVICE_MULTI) && info.extended_images) { tex_num_images = TEX_EXTENDED_NUM_IMAGES_GPU; } + else if(info.pack_images) { + tex_num_images = TEX_PACKED_NUM_IMAGES; + } } bool ImageManager::set_animation_frame_update(int frame) @@ -447,6 +450,9 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img) /* read RGBA pixels */ uchar *pixels = (uchar*)tex_img.resize(width, height, depth); + if(pixels == NULL) { + return false; + } bool cmyk = false; if(in) { @@ -570,6 +576,9 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_ /* read RGBA pixels */ float *pixels = (float*)tex_img.resize(width, height, depth); + if(pixels == NULL) { + return false; + } bool cmyk = false; if(in) { diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index bcc58ae951b..c79c152afde 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -40,6 +40,13 @@ CCL_NAMESPACE_BEGIN #define TEX_EXTENDED_NUM_IMAGES_CPU 1024 #define TEX_EXTENDED_IMAGE_BYTE_START TEX_EXTENDED_NUM_FLOAT_IMAGES +/* Limitations for packed images. + * + * Technically number of textures is unlimited, but it should in + * fact be in sync with CPU limitations. + */ +#define TEX_PACKED_NUM_IMAGES 1024 + /* color to use when textures are not found */ #define TEX_IMAGE_MISSING_R 1 #define TEX_IMAGE_MISSING_G 0 diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp index 465d7ea02c6..9f8d5b50ccd 100644 --- a/intern/cycles/render/integrator.cpp +++ b/intern/cycles/render/integrator.cpp @@ -100,6 +100,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene * transparent shaders in the scene. Otherwise we can disable it * to improve performance a bit. */ if(transparent_shadows) { + kintegrator->transparent_shadows = false; foreach(Shader *shader, scene->shaders) { /* keep this in sync with SD_HAS_TRANSPARENT_SHADOW in shader.cpp */ if((shader->has_surface_transparent && shader->use_transparent_shadow) || shader->has_volume) { diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 45685fe5927..57f194651f8 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -513,7 +513,6 @@ void Mesh::compute_bvh(SceneParams *params, Progress *progress, int n, int total progress->set_status(msg, "Building BVH"); BVHParams bparams; - bparams.use_cache = params->use_bvh_cache; bparams.use_spatial_split = params->use_bvh_spatial_split; bparams.use_qbvh = params->use_qbvh; @@ -1084,7 +1083,6 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene * bparams.top_level = true; bparams.use_qbvh = scene->params.use_qbvh; bparams.use_spatial_split = scene->params.use_bvh_spatial_split; - bparams.use_cache = scene->params.use_bvh_cache; delete bvh; bvh = BVH::create(bparams, scene->objects); diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp index 1ba0c7f7291..801fffc774c 100644 --- a/intern/cycles/render/mesh_displace.cpp +++ b/intern/cycles/render/mesh_displace.cpp @@ -78,7 +78,7 @@ bool MeshManager::displace(Device *device, DeviceScene *dscene, Scene *scene, Me int prim = mesh->tri_offset + i; float u, v; - switch (j) { + switch(j) { case 0: u = 1.0f; v = 0.0f; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 7ed07ab6453..7ac872b8416 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -182,6 +182,21 @@ static ShaderEnum image_projection_init() return enm; } +static const char* get_osl_interpolation_parameter(InterpolationType interpolation) +{ + switch(interpolation) { + case INTERPOLATION_CLOSEST: + return "closest"; + case INTERPOLATION_CUBIC: + return "cubic"; + case INTERPOLATION_SMART: + return "smart"; + case INTERPOLATION_LINEAR: + default: + return "linear"; + } +} + ShaderEnum ImageTextureNode::color_space_enum = color_space_init(); ShaderEnum ImageTextureNode::projection_enum = image_projection_init(); @@ -362,22 +377,7 @@ void ImageTextureNode::compile(OSLCompiler& compiler) compiler.parameter("projection_blend", projection_blend); compiler.parameter("is_float", is_float); compiler.parameter("use_alpha", !alpha_out->links.empty()); - - switch (interpolation) { - case INTERPOLATION_CLOSEST: - compiler.parameter("interpolation", "closest"); - break; - case INTERPOLATION_CUBIC: - compiler.parameter("interpolation", "cubic"); - break; - case INTERPOLATION_SMART: - compiler.parameter("interpolation", "smart"); - break; - case INTERPOLATION_LINEAR: - default: - compiler.parameter("interpolation", "linear"); - break; - } + compiler.parameter("interpolation", get_osl_interpolation_parameter(interpolation)); switch(extension) { case EXTENSION_EXTEND: @@ -421,6 +421,7 @@ EnvironmentTextureNode::EnvironmentTextureNode() filename = ""; builtin_data = NULL; color_space = ustring("Color"); + interpolation = INTERPOLATION_LINEAR; projection = ustring("Equirectangular"); animated = false; @@ -434,7 +435,7 @@ EnvironmentTextureNode::~EnvironmentTextureNode() if(image_manager) { image_manager->remove_image(filename, builtin_data, - INTERPOLATION_LINEAR, + interpolation, EXTENSION_REPEAT); } } @@ -477,7 +478,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler) 0, is_float_bool, is_linear, - INTERPOLATION_LINEAR, + interpolation, EXTENSION_REPEAT, use_alpha); is_float = (int)is_float_bool; @@ -546,7 +547,7 @@ void EnvironmentTextureNode::compile(OSLCompiler& compiler) 0, is_float_bool, is_linear, - INTERPOLATION_LINEAR, + interpolation, EXTENSION_REPEAT, use_alpha); is_float = (int)is_float_bool; @@ -564,6 +565,9 @@ void EnvironmentTextureNode::compile(OSLCompiler& compiler) compiler.parameter("color_space", "Linear"); else compiler.parameter("color_space", "sRGB"); + + compiler.parameter("interpolation", get_osl_interpolation_parameter(interpolation)); + compiler.parameter("is_float", is_float); compiler.parameter("use_alpha", !alpha_out->links.empty()); compiler.add(this, "node_environment_texture"); @@ -1381,7 +1385,7 @@ PointDensityTextureNode::~PointDensityTextureNode() image_manager->remove_image(filename, builtin_data, interpolation, - EXTENSION_REPEAT); + EXTENSION_CLIP); } } @@ -1413,10 +1417,10 @@ void PointDensityTextureNode::compile(SVMCompiler& compiler) image_manager = compiler.image_manager; - if (use_density || use_color) { - if (use_density) + if(use_density || use_color) { + if(use_density) compiler.stack_assign(density_out); - if (use_color) + if(use_color) compiler.stack_assign(color_out); if(slot == -1) { @@ -1425,7 +1429,7 @@ void PointDensityTextureNode::compile(SVMCompiler& compiler) false, 0, is_float, is_linear, interpolation, - EXTENSION_REPEAT, + EXTENSION_CLIP, true); } @@ -1466,14 +1470,14 @@ void PointDensityTextureNode::compile(OSLCompiler& compiler) image_manager = compiler.image_manager; - if (use_density || use_color) { + if(use_density || use_color) { if(slot == -1) { bool is_float, is_linear; slot = image_manager->add_image(filename, builtin_data, false, 0, is_float, is_linear, interpolation, - EXTENSION_REPEAT, + EXTENSION_CLIP, true); } @@ -1484,7 +1488,7 @@ void PointDensityTextureNode::compile(OSLCompiler& compiler) compiler.parameter("mapping", transform_transpose(tfm)); compiler.parameter("use_mapping", 1); } - switch (interpolation) { + switch(interpolation) { case INTERPOLATION_CLOSEST: compiler.parameter("interpolation", "closest"); break; @@ -1675,7 +1679,7 @@ void ConvertNode::compile(SVMCompiler& compiler) compiler.stack_assign(in); compiler.stack_assign(out); - compiler.add_node(NODE_VALUE_V, in->stack_offset); + compiler.add_node(NODE_VALUE_V, out->stack_offset); compiler.add_node(NODE_VALUE_V, in->value); } } @@ -2354,6 +2358,7 @@ HairBsdfNode::HairBsdfNode() add_input("Offset", SHADER_SOCKET_FLOAT); add_input("RoughnessU", SHADER_SOCKET_FLOAT); add_input("RoughnessV", SHADER_SOCKET_FLOAT); + add_input("Tangent", SHADER_SOCKET_VECTOR); } void HairBsdfNode::compile(SVMCompiler& compiler) diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 5065e68345a..39709c26398 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -116,6 +116,7 @@ public: void *builtin_data; ustring color_space; ustring projection; + InterpolationType interpolation; bool animated; static ShaderEnum color_space_enum; diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 31be2a3d3f4..aba3e7237d2 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -18,6 +18,7 @@ #include "camera.h" #include "device.h" #include "graph.h" +#include "integrator.h" #include "light.h" #include "mesh.h" #include "nodes.h" @@ -338,6 +339,7 @@ void ShaderManager::device_update_common(Device *device, uint *shader_flag = dscene->shader_flag.resize(shader_flag_size); uint i = 0; bool has_volumes = false; + bool has_transparent_shadow = false; foreach(Shader *shader, scene->shaders) { uint flag = 0; @@ -355,8 +357,8 @@ void ShaderManager::device_update_common(Device *device, flag |= SD_HAS_ONLY_VOLUME; /* todo: this could check more fine grained, to skip useless volumes - * enclosed inside an opaque bsdf, although we still need to handle - * the case with camera inside volumes too */ + * enclosed inside an opaque bsdf. + */ flag |= SD_HAS_TRANSPARENT_SHADOW; } if(shader->heterogeneous_volume && shader->has_heterogeneous_volume) @@ -382,6 +384,8 @@ void ShaderManager::device_update_common(Device *device, shader_flag[i++] = flag; shader_flag[i++] = shader->pass_id; + + has_transparent_shadow |= (flag & SD_HAS_TRANSPARENT_SHADOW); } device->tex_alloc("__shader_flag", dscene->shader_flag); @@ -404,6 +408,10 @@ void ShaderManager::device_update_common(Device *device, /* integrator */ KernelIntegrator *kintegrator = &dscene->data.integrator; kintegrator->use_volumes = has_volumes; + /* TODO(sergey): De-duplicate with flags set in integrator.cpp. */ + if(scene->integrator->transparent_shadows) { + kintegrator->transparent_shadows = has_transparent_shadow; + } } void ShaderManager::device_free_common(Device *device, DeviceScene *dscene, Scene *scene) diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index d0bd34915df..e81b2f3a827 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -121,7 +121,7 @@ int SVMCompiler::stack_size(ShaderSocketType type) { int size = 0; - switch (type) { + switch(type) { case SHADER_SOCKET_FLOAT: case SHADER_SOCKET_INT: size = 1; @@ -624,7 +624,7 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty ShaderNode *node = graph->output(); ShaderInput *clin = NULL; - switch (type) { + switch(type) { case SHADER_TYPE_SURFACE: clin = node->input("Surface"); break; @@ -654,7 +654,7 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty if(clin->link) { bool generate = false; - switch (type) { + switch(type) { case SHADER_TYPE_SURFACE: /* generate surface shader */ generate = true; shader->has_surface = true; diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp index 7e68ce84d94..1bec39431d8 100644 --- a/intern/cycles/render/tile.cpp +++ b/intern/cycles/render/tile.cpp @@ -199,7 +199,7 @@ list<Tile>::iterator TileManager::next_background_tile(int device, TileOrder til int64_t distx = cordx; int64_t disty = cordy; - switch (tile_order) { + switch(tile_order) { case TILE_CENTER: distx = centx - (cur_tile.x + (cur_tile.w / 2)); disty = centy - (cur_tile.y + (cur_tile.h / 2)); diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 97c93516496..7d6dfd34e0e 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -1447,14 +1447,9 @@ ccl_device bool ray_triangle_intersect_uv( return true; } -#if defined(__KERNEL_CUDA__) && (defined(i386) || defined(_M_IX86)) && (defined(__KERNEL_EXPERIMENTAL__) || __CUDA_ARCH__ == 500) -ccl_device_noinline -#else -ccl_device -#endif -bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_t, - float3 quad_P, float3 quad_u, float3 quad_v, - float3 *isect_P, float *isect_t) +ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_t, + float3 quad_P, float3 quad_u, float3 quad_v, + float3 *isect_P, float *isect_t) { float3 v0 = quad_P - quad_u*0.5f - quad_v*0.5f; float3 v1 = quad_P + quad_u*0.5f - quad_v*0.5f; diff --git a/intern/cycles/util/util_optimization.h b/intern/cycles/util/util_optimization.h index c951c35fc76..42d3ca69b3a 100644 --- a/intern/cycles/util/util_optimization.h +++ b/intern/cycles/util/util_optimization.h @@ -101,7 +101,7 @@ #ifdef _MSC_VER #include <intrin.h> -#else +#elif (defined(__x86_64__) || defined(__i386__)) #include <x86intrin.h> #endif diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index ba8d04b5c16..f01db64a79b 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -347,7 +347,12 @@ ccl_device_inline Transform transform_quick_inverse(Transform M) * scale can be inverted but what about shearing? */ Transform R; float det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z); - + if(det == 0.0f) { + M.x.x += 1e-8f; + M.y.y += 1e-8f; + M.z.z += 1e-8f; + det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z); + } det = (det != 0.0f)? 1.0f/det: 0.0f; float3 Rx = det*make_float3(M.z.z*M.y.y - M.z.y*M.y.z, M.z.y*M.x.z - M.z.z*M.x.y, M.y.z*M.x.y - M.y.y*M.x.z); diff --git a/intern/cycles/util/util_vector.h b/intern/cycles/util/util_vector.h index 15a65be0ef0..623436483a0 100644 --- a/intern/cycles/util/util_vector.h +++ b/intern/cycles/util/util_vector.h @@ -105,6 +105,7 @@ public: { data = NULL; datasize = 0; + capacity = 0; } array(size_t newsize) @@ -112,10 +113,12 @@ public: if(newsize == 0) { data = NULL; datasize = 0; + capacity = 0; } else { data = (T*)util_aligned_malloc(sizeof(T)*newsize, alignment); datasize = newsize; + capacity = datasize; } } @@ -129,11 +132,13 @@ public: if(from.datasize == 0) { data = NULL; datasize = 0; + capacity = 0; } else { data = (T*)util_aligned_malloc(sizeof(T)*from.datasize, alignment); memcpy(data, from.data, from.datasize*sizeof(T)); datasize = from.datasize; + capacity = datasize; } return *this; @@ -142,6 +147,7 @@ public: array& operator=(const vector<T>& from) { datasize = from.size(); + capacity = datasize; data = NULL; if(datasize > 0) { @@ -157,28 +163,39 @@ public: util_aligned_free(data); } - void resize(size_t newsize) + T* resize(size_t newsize) { if(newsize == 0) { clear(); } else if(newsize != datasize) { - T *newdata = (T*)util_aligned_malloc(sizeof(T)*newsize, alignment); - if(data) { - memcpy(newdata, data, ((datasize < newsize)? datasize: newsize)*sizeof(T)); - util_aligned_free(data); + if(newsize > capacity) { + T *newdata = (T*)util_aligned_malloc(sizeof(T)*newsize, alignment); + if(newdata == NULL) { + /* Allocation failed, likely out of memory. */ + clear(); + return NULL; + } + else if(data) { + memcpy(newdata, data, ((datasize < newsize)? datasize: newsize)*sizeof(T)); + util_aligned_free(data); + } + data = newdata; + capacity = newsize; } - - data = newdata; datasize = newsize; } + return data; } void clear() { - util_aligned_free(data); - data = NULL; + if(data != NULL) { + util_aligned_free(data); + data = NULL; + } datasize = 0; + capacity = 0; } size_t size() const @@ -192,9 +209,22 @@ public: return data[i]; } + void reserve(size_t newcapacity) { + if(newcapacity > capacity) { + T *newdata = (T*)util_aligned_malloc(sizeof(T)*newcapacity, alignment); + if(data) { + memcpy(newdata, data, ((datasize < newcapacity)? datasize: newcapacity)*sizeof(T)); + util_aligned_free(data); + } + data = newdata; + capacity = newcapacity; + } + } + protected: T *data; size_t datasize; + size_t capacity; }; CCL_NAMESPACE_END |