From eacdcb2dd80e9e2340fa7a4b8509448b0c72b77a Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Wed, 17 Jun 2020 20:27:10 +0200 Subject: Cycles: Add new Sky Texture method including direct sunlight This commit adds a new model to the Sky Texture node, which is based on a method by Nishita et al. and works by basically simulating volumetric scattering in the atmosphere. By making some approximations (such as only considering single scattering), we get a fairly simple and fast simulation code that takes into account Rayleigh and Mie scattering as well as Ozone absorption. This code is used to precompute a 512x128 texture which is then looked up during render time, and is fast enough to allow real-time tweaking in the viewport. Due to the nature of the simulation, it exposes several parameters that allow for lots of flexibility in choosing the look and matching real-world conditions (such as Air/Dust/Ozone density and altitude). Additionally, the same volumetric approach can be used to compute absorption of the direct sunlight, so the model also supports adding direct sunlight. This makes it significantly easier to set up Sun+Sky illumination where the direction, intensity and color of the sun actually matches the sky. In order to support properly sampling the direct sun component, the commit also adds logic for sampling a specific area to the kernel light sampling code. This is combined with portal and background map sampling using MIS. This sampling logic works for the common case of having one Sky texture going into the Background shader, but if a custom input to the Vector node is used or if there are multiple Sky textures, it falls back to using only background map sampling (while automatically setting the resolution to 4096x2048 if auto resolution is used). More infos and preview can be found here: https://docs.google.com/document/d/1gQta0ygFWXTrl5Pmvl_nZRgUw0mWg0FJeRuNKS36m08/view Underlying model, implementation and documentation by Marco (@nacioss). Improvements, cleanup and sun sampling by @lukasstockner. Differential Revision: https://developer.blender.org/D7896 --- intern/cycles/blender/blender_shader.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index f207d8ae07f..19d2730dc93 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -813,6 +813,14 @@ static ShaderNode *add_node(Scene *scene, sky->sun_direction = normalize(get_float3(b_sky_node.sun_direction())); sky->turbidity = b_sky_node.turbidity(); sky->ground_albedo = b_sky_node.ground_albedo(); + sky->sun_disc = b_sky_node.sun_disc(); + sky->sun_size = b_sky_node.sun_size(); + sky->sun_elevation = b_sky_node.sun_elevation(); + sky->sun_rotation = b_sky_node.sun_rotation(); + sky->altitude = b_sky_node.altitude(); + sky->air_density = b_sky_node.air_density(); + sky->dust_density = b_sky_node.dust_density(); + sky->ozone_density = b_sky_node.ozone_density(); BL::TexMapping b_texture_mapping(b_sky_node.texture_mapping()); get_tex_mapping(&sky->tex_mapping, b_texture_mapping); node = sky; -- cgit v1.2.3 From ace3268482c6bfd9986815aaa6b027c99fa8e3f4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 5 Jun 2020 11:39:11 +0200 Subject: Cleanup: minor refactoring around DeviceTask --- intern/cycles/blender/blender_python.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index 0be19dbffd1..5595d657640 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -33,6 +33,7 @@ #include "util/util_opengl.h" #include "util/util_path.h" #include "util/util_string.h" +#include "util/util_task.h" #include "util/util_types.h" #ifdef WITH_OSL -- cgit v1.2.3 From c7d940278b16bb357a848f176d070e1784ccdde2 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 4 Jun 2020 15:12:31 +0200 Subject: Cycles: remove support for rendering hair as triangle and lines Triangles were very memory intensive. The only reason they were not removed yet is that they gave more accurate results, but there will be an accurate 3D curve primitive added for this. Line rendering was always poor quality since the ends do not match up. To keep CPU and GPU compatibility we just remove them entirely. They could be brought back if an Embree compatible implementation is added, but it's not clear to me that there is a use case for these that we'd consider important. Ref T73778 Reviewers: #cycles Subscribers: --- intern/cycles/blender/addon/properties.py | 29 +- intern/cycles/blender/addon/ui.py | 11 +- intern/cycles/blender/blender_curves.cpp | 619 +++-------------------------- intern/cycles/blender/blender_geometry.cpp | 14 +- intern/cycles/blender/blender_sync.h | 9 +- 5 files changed, 72 insertions(+), 610 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 1635afab210..29ef1814294 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -78,20 +78,9 @@ enum_panorama_types = ( ('MIRRORBALL', "Mirror Ball", "Uses the mirror ball mapping"), ) -enum_curve_primitives = ( - ('TRIANGLES', "Triangles", "Create triangle geometry around strands"), - ('LINE_SEGMENTS', "Line Segments", "Use line segment primitives"), - ('CURVE_SEGMENTS', "Curve Segments", "Use segmented cardinal curve primitives"), -) - -enum_triangle_curves = ( - ('CAMERA_TRIANGLES', "Planes", "Create individual triangles forming planes that face camera"), - ('TESSELLATED_TRIANGLES', "Tessellated", "Create mesh surrounding each strand"), -) - enum_curve_shape = ( - ('RIBBONS', "Ribbons", "Ignore thickness of each strand"), - ('THICK', "Thick", "Use thickness of strand when rendering"), + ('RIBBONS', "Ribbons", "Ignore thickness of each hair"), + ('THICK', "Thick", "Use thickness of hair when rendering"), ) enum_tile_order = ( @@ -1241,12 +1230,6 @@ class CyclesObjectSettings(bpy.types.PropertyGroup): class CyclesCurveRenderSettings(bpy.types.PropertyGroup): - primitive: EnumProperty( - name="Primitive", - description="Type of primitive used for hair rendering", - items=enum_curve_primitives, - default='LINE_SEGMENTS', - ) shape: EnumProperty( name="Shape", description="Form of hair", @@ -1255,7 +1238,7 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup): ) cull_backfacing: BoolProperty( name="Cull Back-faces", - description="Do not test the back-face of each strand", + description="Do not test the back-face of each hair", default=True, ) use_curves: BoolProperty( @@ -1263,12 +1246,6 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup): description="Activate Cycles hair rendering for particle system", default=True, ) - resolution: IntProperty( - name="Resolution", - description="Resolution of generated mesh", - min=3, max=64, - default=3, - ) subdivisions: IntProperty( name="Subdivisions", description="Number of subdivisions used in Cardinal curve intersection (power of 2)", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 78a44881743..b6d19b1d4a7 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -406,14 +406,11 @@ class CYCLES_RENDER_PT_hair(CyclesButtonsPanel, Panel): col = layout.column() col.prop(ccscene, "shape", text="Shape") - if not (ccscene.primitive in {'CURVE_SEGMENTS', 'LINE_SEGMENTS'} and ccscene.shape == 'RIBBONS'): - col.prop(ccscene, "cull_backfacing", text="Cull back-faces") - col.prop(ccscene, "primitive", text="Primitive") - - if ccscene.primitive == 'TRIANGLES' and ccscene.shape == 'THICK': - col.prop(ccscene, "resolution", text="Resolution") - elif ccscene.primitive == 'CURVE_SEGMENTS': + if ccscene.shape == 'RIBBONS': + # TODO: use for embree col.prop(ccscene, "subdivisions", text="Curve subdivisions") + else: + col.prop(ccscene, "cull_backfacing", text="Cull back-faces") class CYCLES_RENDER_PT_volumes(CyclesButtonsPanel, Panel): diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 847a43c5f34..43fe653fda4 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -18,7 +18,6 @@ #include "render/camera.h" #include "render/curves.h" #include "render/hair.h" -#include "render/mesh.h" #include "render/object.h" #include "render/scene.h" @@ -39,27 +38,6 @@ ParticleCurveData::~ParticleCurveData() { } -static void interp_weights(float t, float data[4]) -{ - /* Cardinal curve interpolation */ - float t2 = t * t; - float t3 = t2 * t; - float fc = 0.71f; - - data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t; - data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f; - data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t; - data[3] = fc * t3 - fc * t2; -} - -static void curveinterp_v3_v3v3v3v3( - float3 *p, float3 *v1, float3 *v2, float3 *v3, float3 *v4, const float w[4]) -{ - p->x = v1->x * w[0] + v2->x * w[1] + v3->x * w[2] + v4->x * w[3]; - p->y = v1->y * w[0] + v2->y * w[1] + v3->y * w[2] + v4->y * w[3]; - p->z = v1->z * w[0] + v2->z * w[1] + v3->z * w[2] + v4->z * w[3]; -} - static float shaperadius(float shape, float root, float tip, float time) { assert(time >= 0.0f); @@ -77,43 +55,13 @@ static float shaperadius(float shape, float root, float tip, float time) /* curve functions */ -static void InterpolateKeySegments( - int seg, int segno, int key, int curve, float3 *keyloc, float *time, ParticleCurveData *CData) -{ - float3 ckey_loc1 = CData->curvekey_co[key]; - float3 ckey_loc2 = ckey_loc1; - float3 ckey_loc3 = CData->curvekey_co[key + 1]; - float3 ckey_loc4 = ckey_loc3; - - if (key > CData->curve_firstkey[curve]) - ckey_loc1 = CData->curvekey_co[key - 1]; - - if (key < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) - ckey_loc4 = CData->curvekey_co[key + 2]; - - float time1 = CData->curvekey_time[key] / CData->curve_length[curve]; - float time2 = CData->curvekey_time[key + 1] / CData->curve_length[curve]; - - float dfra = (time2 - time1) / (float)segno; - - if (time) - *time = (dfra * seg) + time1; - - float t[4]; - - interp_weights((float)seg / (float)segno, t); - - if (keyloc) - curveinterp_v3_v3v3v3v3(keyloc, &ckey_loc1, &ckey_loc2, &ckey_loc3, &ckey_loc4, t); -} - static bool ObtainCacheParticleData( - Geometry *geom, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background) + Hair *hair, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background) { int curvenum = 0; int keyno = 0; - if (!(geom && b_mesh && b_ob && CData)) + if (!(hair && b_mesh && b_ob && CData)) return false; Transform tfm = get_transform(b_ob->matrix_world()); @@ -129,7 +77,7 @@ static bool ObtainCacheParticleData( if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) { - int shader = clamp(b_part.material() - 1, 0, geom->used_shaders.size() - 1); + int shader = clamp(b_part.material() - 1, 0, hair->used_shaders.size() - 1); int display_step = background ? b_part.render_step() : b_part.display_step(); int totparts = b_psys.particles.length(); int totchild = background ? b_psys.child_particles.length() : @@ -203,14 +151,14 @@ static bool ObtainCacheParticleData( return true; } -static bool ObtainCacheParticleUV(Geometry *geom, +static bool ObtainCacheParticleUV(Hair *hair, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int uv_num) { - if (!(geom && b_mesh && b_ob && CData)) + if (!(hair && b_mesh && b_ob && CData)) return false; CData->curve_uv.clear(); @@ -266,14 +214,14 @@ static bool ObtainCacheParticleUV(Geometry *geom, return true; } -static bool ObtainCacheParticleVcol(Geometry *geom, +static bool ObtainCacheParticleVcol(Hair *hair, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int vcol_num) { - if (!(geom && b_mesh && b_ob && CData)) + if (!(hair && b_mesh && b_ob && CData)) return false; CData->curve_vcol.clear(); @@ -329,272 +277,6 @@ static bool ObtainCacheParticleVcol(Geometry *geom, return true; } -static void ExportCurveTrianglePlanes(Mesh *mesh, - ParticleCurveData *CData, - float3 RotCam, - bool is_ortho) -{ - int vertexno = mesh->verts.size(); - int vertexindex = vertexno; - int numverts = 0, numtris = 0; - - /* compute and reserve size of arrays */ - for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { - for (int curve = CData->psys_firstcurve[sys]; - curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; - curve++) { - numverts += 2 + (CData->curve_keynum[curve] - 1) * 2; - numtris += (CData->curve_keynum[curve] - 1) * 2; - } - } - - mesh->reserve_mesh(mesh->verts.size() + numverts, mesh->num_triangles() + numtris); - - /* actually export */ - for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { - for (int curve = CData->psys_firstcurve[sys]; - curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; - curve++) { - float3 xbasis; - float3 v1; - float time = 0.0f; - float3 ickey_loc = CData->curvekey_co[CData->curve_firstkey[curve]]; - float radius = shaperadius( - CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.0f); - v1 = CData->curvekey_co[CData->curve_firstkey[curve] + 1] - - CData->curvekey_co[CData->curve_firstkey[curve]]; - if (is_ortho) - xbasis = normalize(cross(RotCam, v1)); - else - xbasis = normalize(cross(RotCam - ickey_loc, v1)); - float3 ickey_loc_shfl = ickey_loc - radius * xbasis; - float3 ickey_loc_shfr = ickey_loc + radius * xbasis; - mesh->add_vertex(ickey_loc_shfl); - mesh->add_vertex(ickey_loc_shfr); - vertexindex += 2; - - for (int curvekey = CData->curve_firstkey[curve] + 1; - curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; - curvekey++) { - ickey_loc = CData->curvekey_co[curvekey]; - - if (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) - v1 = CData->curvekey_co[curvekey] - - CData->curvekey_co[max(curvekey - 1, CData->curve_firstkey[curve])]; - else - v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey - 1]; - - time = CData->curvekey_time[curvekey] / CData->curve_length[curve]; - radius = shaperadius( - CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time); - - if (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) - radius = shaperadius(CData->psys_shape[sys], - CData->psys_rootradius[sys], - CData->psys_tipradius[sys], - 0.95f); - - if (CData->psys_closetip[sys] && - (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)) - radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f); - - if (is_ortho) - xbasis = normalize(cross(RotCam, v1)); - else - xbasis = normalize(cross(RotCam - ickey_loc, v1)); - float3 ickey_loc_shfl = ickey_loc - radius * xbasis; - float3 ickey_loc_shfr = ickey_loc + radius * xbasis; - mesh->add_vertex(ickey_loc_shfl); - mesh->add_vertex(ickey_loc_shfr); - mesh->add_triangle( - vertexindex - 2, vertexindex, vertexindex - 1, CData->psys_shader[sys], true); - mesh->add_triangle( - vertexindex + 1, vertexindex - 1, vertexindex, CData->psys_shader[sys], true); - vertexindex += 2; - } - } - } - - mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles()); - mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL); - mesh->attributes.remove(ATTR_STD_FACE_NORMAL); - mesh->add_face_normals(); - mesh->add_vertex_normals(); - mesh->attributes.remove(ATTR_STD_FACE_NORMAL); - - /* texture coords still needed */ -} - -static void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int resolution) -{ - int vertexno = mesh->verts.size(); - int vertexindex = vertexno; - int numverts = 0, numtris = 0; - - /* compute and reserve size of arrays */ - for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { - for (int curve = CData->psys_firstcurve[sys]; - curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; - curve++) { - numverts += (CData->curve_keynum[curve] - 1) * resolution + resolution; - numtris += (CData->curve_keynum[curve] - 1) * 2 * resolution; - } - } - - mesh->reserve_mesh(mesh->verts.size() + numverts, mesh->num_triangles() + numtris); - - /* actually export */ - for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { - for (int curve = CData->psys_firstcurve[sys]; - curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; - curve++) { - float3 firstxbasis = cross(make_float3(1.0f, 0.0f, 0.0f), - CData->curvekey_co[CData->curve_firstkey[curve] + 1] - - CData->curvekey_co[CData->curve_firstkey[curve]]); - if (!is_zero(firstxbasis)) - firstxbasis = normalize(firstxbasis); - else - firstxbasis = normalize(cross(make_float3(0.0f, 1.0f, 0.0f), - CData->curvekey_co[CData->curve_firstkey[curve] + 1] - - CData->curvekey_co[CData->curve_firstkey[curve]])); - - for (int curvekey = CData->curve_firstkey[curve]; - curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; - curvekey++) { - float3 xbasis = firstxbasis; - float3 v1; - float3 v2; - - if (curvekey == CData->curve_firstkey[curve]) { - v1 = CData->curvekey_co[min( - curvekey + 2, CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - - CData->curvekey_co[curvekey + 1]; - v2 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey]; - } - else if (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) { - v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 1]; - v2 = CData->curvekey_co[curvekey - 1] - - CData->curvekey_co[max(curvekey - 2, CData->curve_firstkey[curve])]; - } - else { - v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey]; - v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 1]; - } - - xbasis = cross(v1, v2); - - if (len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) { - firstxbasis = normalize(xbasis); - break; - } - } - - for (int curvekey = CData->curve_firstkey[curve]; - curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; - curvekey++) { - int subv = 1; - float3 xbasis; - float3 ybasis; - float3 v1; - float3 v2; - - if (curvekey == CData->curve_firstkey[curve]) { - subv = 0; - v1 = CData->curvekey_co[min( - curvekey + 2, CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - - CData->curvekey_co[curvekey + 1]; - v2 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey]; - } - else if (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) { - v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 1]; - v2 = CData->curvekey_co[curvekey - 1] - - CData->curvekey_co[max(curvekey - 2, CData->curve_firstkey[curve])]; - } - else { - v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey]; - v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey - 1]; - } - - xbasis = cross(v1, v2); - - if (len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) { - xbasis = normalize(xbasis); - firstxbasis = xbasis; - } - else - xbasis = firstxbasis; - - ybasis = normalize(cross(xbasis, v2)); - - for (; subv <= 1; subv++) { - float3 ickey_loc = make_float3(0.0f, 0.0f, 0.0f); - float time = 0.0f; - - InterpolateKeySegments(subv, 1, curvekey, curve, &ickey_loc, &time, CData); - - float radius = shaperadius(CData->psys_shape[sys], - CData->psys_rootradius[sys], - CData->psys_tipradius[sys], - time); - - if ((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) && - (subv == 1)) - radius = shaperadius(CData->psys_shape[sys], - CData->psys_rootradius[sys], - CData->psys_tipradius[sys], - 0.95f); - - if (CData->psys_closetip[sys] && (subv == 1) && - (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)) - radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f); - - float angle = M_2PI_F / (float)resolution; - for (int section = 0; section < resolution; section++) { - float3 ickey_loc_shf = ickey_loc + radius * (cosf(angle * section) * xbasis + - sinf(angle * section) * ybasis); - mesh->add_vertex(ickey_loc_shf); - } - - if (subv != 0) { - for (int section = 0; section < resolution - 1; section++) { - mesh->add_triangle(vertexindex - resolution + section, - vertexindex + section, - vertexindex - resolution + section + 1, - CData->psys_shader[sys], - true); - mesh->add_triangle(vertexindex + section + 1, - vertexindex - resolution + section + 1, - vertexindex + section, - CData->psys_shader[sys], - true); - } - mesh->add_triangle(vertexindex - 1, - vertexindex + resolution - 1, - vertexindex - resolution, - CData->psys_shader[sys], - true); - mesh->add_triangle(vertexindex, - vertexindex - resolution, - vertexindex + resolution - 1, - CData->psys_shader[sys], - true); - } - vertexindex += resolution; - } - } - } - } - - mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles()); - mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL); - mesh->attributes.remove(ATTR_STD_FACE_NORMAL); - mesh->add_face_normals(); - mesh->add_vertex_normals(); - mesh->attributes.remove(ATTR_STD_FACE_NORMAL); - - /* texture coords still needed */ -} - static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CData) { int num_keys = 0; @@ -823,78 +505,6 @@ static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int } } -static void ExportCurveTriangleUV(ParticleCurveData *CData, int resol, float2 *uvdata) -{ - if (uvdata == NULL) - return; - int vertexindex = 0; - - for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { - for (int curve = CData->psys_firstcurve[sys]; - curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; - curve++) { - for (int curvekey = CData->curve_firstkey[curve]; - curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; - curvekey++) { - for (int section = 0; section < resol; section++) { - uvdata[vertexindex] = CData->curve_uv[curve]; - vertexindex++; - uvdata[vertexindex] = CData->curve_uv[curve]; - vertexindex++; - uvdata[vertexindex] = CData->curve_uv[curve]; - vertexindex++; - uvdata[vertexindex] = CData->curve_uv[curve]; - vertexindex++; - uvdata[vertexindex] = CData->curve_uv[curve]; - vertexindex++; - uvdata[vertexindex] = CData->curve_uv[curve]; - vertexindex++; - } - } - } - } -} - -static void ExportCurveTriangleVcol(ParticleCurveData *CData, int resol, uchar4 *cdata) -{ - if (cdata == NULL) - return; - - int vertexindex = 0; - - for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { - for (int curve = CData->psys_firstcurve[sys]; - curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; - curve++) { - for (int curvekey = CData->curve_firstkey[curve]; - curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; - curvekey++) { - for (int section = 0; section < resol; section++) { - /* Encode vertex color using the sRGB curve. */ - cdata[vertexindex] = color_float_to_byte( - color_srgb_to_linear_v3(CData->curve_vcol[curve])); - vertexindex++; - cdata[vertexindex] = color_float_to_byte( - color_srgb_to_linear_v3(CData->curve_vcol[curve])); - vertexindex++; - cdata[vertexindex] = color_float_to_byte( - color_srgb_to_linear_v3(CData->curve_vcol[curve])); - vertexindex++; - cdata[vertexindex] = color_float_to_byte( - color_srgb_to_linear_v3(CData->curve_vcol[curve])); - vertexindex++; - cdata[vertexindex] = color_float_to_byte( - color_srgb_to_linear_v3(CData->curve_vcol[curve])); - vertexindex++; - cdata[vertexindex] = color_float_to_byte( - color_srgb_to_linear_v3(CData->curve_vcol[curve])); - vertexindex++; - } - } - } - } -} - /* Hair Curve Sync */ void BlenderSync::sync_curve_settings(BL::Depsgraph &b_depsgraph) @@ -906,48 +516,11 @@ void BlenderSync::sync_curve_settings(BL::Depsgraph &b_depsgraph) curve_system_manager->use_curves = get_boolean(csscene, "use_curves"); - curve_system_manager->primitive = (CurvePrimitiveType)get_enum( - csscene, "primitive", CURVE_NUM_PRIMITIVE_TYPES, CURVE_LINE_SEGMENTS); curve_system_manager->curve_shape = (CurveShapeType)get_enum( csscene, "shape", CURVE_NUM_SHAPE_TYPES, CURVE_THICK); - curve_system_manager->resolution = get_int(csscene, "resolution"); curve_system_manager->subdivisions = get_int(csscene, "subdivisions"); curve_system_manager->use_backfacing = !get_boolean(csscene, "cull_backfacing"); - /* Triangles */ - if (curve_system_manager->primitive == CURVE_TRIANGLES) { - /* camera facing planes */ - if (curve_system_manager->curve_shape == CURVE_RIBBON) { - curve_system_manager->triangle_method = CURVE_CAMERA_TRIANGLES; - curve_system_manager->resolution = 1; - } - else if (curve_system_manager->curve_shape == CURVE_THICK) { - curve_system_manager->triangle_method = CURVE_TESSELATED_TRIANGLES; - } - } - /* Line Segments */ - else if (curve_system_manager->primitive == CURVE_LINE_SEGMENTS) { - if (curve_system_manager->curve_shape == CURVE_RIBBON) { - /* tangent shading */ - curve_system_manager->line_method = CURVE_UNCORRECTED; - curve_system_manager->use_encasing = true; - curve_system_manager->use_backfacing = false; - curve_system_manager->use_tangent_normal_geometry = true; - } - else if (curve_system_manager->curve_shape == CURVE_THICK) { - curve_system_manager->line_method = CURVE_ACCURATE; - curve_system_manager->use_encasing = false; - curve_system_manager->use_tangent_normal_geometry = false; - } - } - /* Curve Segments */ - else if (curve_system_manager->primitive == CURVE_SEGMENTS) { - if (curve_system_manager->curve_shape == CURVE_RIBBON) { - curve_system_manager->primitive = CURVE_RIBBONS; - curve_system_manager->use_backfacing = false; - } - } - if (curve_system_manager->modified_mesh(prev_curve_system_manager)) { BL::Depsgraph::objects_iterator b_ob; @@ -994,78 +567,38 @@ bool BlenderSync::object_has_particle_hair(BL::Object b_ob) /* Old particle hair. */ void BlenderSync::sync_particle_hair( - Geometry *geom, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step) + Hair *hair, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step) { - Hair *hair = (geom->type == Geometry::HAIR) ? static_cast(geom) : NULL; - Mesh *mesh = (geom->type == Geometry::MESH) ? static_cast(geom) : NULL; - /* obtain general settings */ if (b_ob.mode() == b_ob.mode_PARTICLE_EDIT || b_ob.mode() == b_ob.mode_EDIT) { return; } - const int triangle_method = scene->curve_system_manager->triangle_method; - const int resolution = scene->curve_system_manager->resolution; - int used_res = 1; - /* extract particle hair data - should be combined with connecting to mesh later*/ ParticleCurveData CData; - ObtainCacheParticleData(geom, &b_mesh, &b_ob, &CData, !preview); - - /* add hair geometry to mesh */ - if (mesh) { - if (triangle_method == CURVE_CAMERA_TRIANGLES) { - /* obtain camera parameters */ - float3 RotCam; - Camera *camera = scene->camera; - Transform &ctfm = camera->matrix; - if (camera->type == CAMERA_ORTHOGRAPHIC) { - RotCam = -make_float3(ctfm.x.z, ctfm.y.z, ctfm.z.z); - } - else { - Transform tfm = get_transform(b_ob.matrix_world()); - Transform itfm = transform_quick_inverse(tfm); - RotCam = transform_point(&itfm, make_float3(ctfm.x.w, ctfm.y.w, ctfm.z.w)); - } - bool is_ortho = camera->type == CAMERA_ORTHOGRAPHIC; - ExportCurveTrianglePlanes(mesh, &CData, RotCam, is_ortho); - } - else { - ExportCurveTriangleGeometry(mesh, &CData, resolution); - used_res = resolution; - } - } - else { - if (motion) - ExportCurveSegmentsMotion(hair, &CData, motion_step); - else - ExportCurveSegments(scene, hair, &CData); - } + ObtainCacheParticleData(hair, &b_mesh, &b_ob, &CData, !preview); + + /* add hair geometry */ + if (motion) + ExportCurveSegmentsMotion(hair, &CData, motion_step); + else + ExportCurveSegments(scene, hair, &CData); /* generated coordinates from first key. we should ideally get this from * blender to handle deforming objects */ if (!motion) { - if (geom->need_attribute(scene, ATTR_STD_GENERATED)) { + if (hair->need_attribute(scene, ATTR_STD_GENERATED)) { float3 loc, size; mesh_texture_space(b_mesh, loc, size); - if (mesh) { - Attribute *attr_generated = mesh->attributes.add(ATTR_STD_GENERATED); - float3 *generated = attr_generated->data_float3(); + Attribute *attr_generated = hair->attributes.add(ATTR_STD_GENERATED); + float3 *generated = attr_generated->data_float3(); - for (size_t i = 0; i < mesh->verts.size(); i++) - generated[i] = mesh->verts[i] * size - loc; - } - else { - Attribute *attr_generated = hair->attributes.add(ATTR_STD_GENERATED); - float3 *generated = attr_generated->data_float3(); - - for (size_t i = 0; i < hair->num_curves(); i++) { - float3 co = hair->curve_keys[hair->get_curve(i).first_key]; - generated[i] = co * size - loc; - } + for (size_t i = 0; i < hair->num_curves(); i++) { + float3 co = hair->curve_keys[hair->get_curve(i).first_key]; + generated[i] = co * size - loc; } } } @@ -1076,32 +609,22 @@ void BlenderSync::sync_particle_hair( int vcol_num = 0; for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l, vcol_num++) { - if (!geom->need_attribute(scene, ustring(l->name().c_str()))) + if (!hair->need_attribute(scene, ustring(l->name().c_str()))) continue; - ObtainCacheParticleVcol(geom, &b_mesh, &b_ob, &CData, !preview, vcol_num); - - if (mesh) { - Attribute *attr_vcol = mesh->attributes.add( - ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE); + ObtainCacheParticleVcol(hair, &b_mesh, &b_ob, &CData, !preview, vcol_num); - uchar4 *cdata = attr_vcol->data_uchar4(); + Attribute *attr_vcol = hair->attributes.add( + ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE); - ExportCurveTriangleVcol(&CData, used_res, cdata); - } - else { - Attribute *attr_vcol = hair->attributes.add( - ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE); + float3 *fdata = attr_vcol->data_float3(); - float3 *fdata = attr_vcol->data_float3(); + if (fdata) { + size_t i = 0; - if (fdata) { - size_t i = 0; - - /* Encode vertex color using the sRGB curve. */ - for (size_t curve = 0; curve < CData.curve_vcol.size(); curve++) { - fdata[i++] = color_srgb_to_linear_v3(CData.curve_vcol[curve]); - } + /* Encode vertex color using the sRGB curve. */ + for (size_t curve = 0; curve < CData.curve_vcol.size(); curve++) { + fdata[i++] = color_srgb_to_linear_v3(CData.curve_vcol[curve]); } } } @@ -1118,35 +641,23 @@ void BlenderSync::sync_particle_hair( ustring name = ustring(l->name().c_str()); /* UV map */ - if (geom->need_attribute(scene, name) || geom->need_attribute(scene, std)) { + if (hair->need_attribute(scene, name) || hair->need_attribute(scene, std)) { Attribute *attr_uv; - ObtainCacheParticleUV(geom, &b_mesh, &b_ob, &CData, !preview, uv_num); - - if (mesh) { - if (active_render) - attr_uv = mesh->attributes.add(std, name); - else - attr_uv = mesh->attributes.add(name, TypeFloat2, ATTR_ELEMENT_CORNER); + ObtainCacheParticleUV(hair, &b_mesh, &b_ob, &CData, !preview, uv_num); - float2 *uv = attr_uv->data_float2(); - - ExportCurveTriangleUV(&CData, used_res, uv); - } - else { - if (active_render) - attr_uv = hair->attributes.add(std, name); - else - attr_uv = hair->attributes.add(name, TypeFloat2, ATTR_ELEMENT_CURVE); + if (active_render) + attr_uv = hair->attributes.add(std, name); + else + attr_uv = hair->attributes.add(name, TypeFloat2, ATTR_ELEMENT_CURVE); - float2 *uv = attr_uv->data_float2(); + float2 *uv = attr_uv->data_float2(); - if (uv) { - size_t i = 0; + if (uv) { + size_t i = 0; - for (size_t curve = 0; curve < CData.curve_uv.size(); curve++) { - uv[i++] = CData.curve_uv[curve]; - } + for (size_t curve = 0; curve < CData.curve_uv.size(); curve++) { + uv[i++] = CData.curve_uv[curve]; } } } @@ -1344,27 +855,18 @@ void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motio void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, - Geometry *geom, + Hair *hair, const vector &used_shaders) { - Hair *hair = (geom->type == Geometry::HAIR) ? static_cast(geom) : NULL; - Mesh *mesh = (geom->type == Geometry::MESH) ? static_cast(geom) : NULL; - /* Compares curve_keys rather than strands in order to handle quick hair * adjustments in dynamic BVH - other methods could probably do this better. */ array oldcurve_keys; array oldcurve_radius; - array oldtriangles; - if (hair) { - oldcurve_keys.steal_data(hair->curve_keys); - oldcurve_radius.steal_data(hair->curve_radius); - } - else { - oldtriangles.steal_data(mesh->triangles); - } + oldcurve_keys.steal_data(hair->curve_keys); + oldcurve_radius.steal_data(hair->curve_radius); - geom->clear(); - geom->used_shaders = used_shaders; + hair->clear(); + hair->used_shaders = used_shaders; if (view_layer.use_hair && scene->curve_system_manager->use_curves) { #ifdef WITH_NEW_OBJECT_TYPES @@ -1377,35 +879,31 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, #endif { /* Particle hair. */ - bool need_undeformed = geom->need_attribute(scene, ATTR_STD_GENERATED); + bool need_undeformed = hair->need_attribute(scene, ATTR_STD_GENERATED); BL::Mesh b_mesh = object_to_mesh( b_data, b_ob, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE); if (b_mesh) { - sync_particle_hair(geom, b_mesh, b_ob, false); + sync_particle_hair(hair, b_mesh, b_ob, false); free_object_to_mesh(b_data, b_ob, b_mesh); } } } /* tag update */ - const bool rebuild = (hair && ((oldcurve_keys != hair->curve_keys) || - (oldcurve_radius != hair->curve_radius))) || - (mesh && (oldtriangles != mesh->triangles)); + const bool rebuild = ((oldcurve_keys != hair->curve_keys) || + (oldcurve_radius != hair->curve_radius)); - geom->tag_update(scene, rebuild); + hair->tag_update(scene, rebuild); } void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, - Geometry *geom, + Hair *hair, int motion_step) { - Hair *hair = (geom->type == Geometry::HAIR) ? static_cast(geom) : NULL; - Mesh *mesh = (geom->type == Geometry::MESH) ? static_cast(geom) : NULL; - /* Skip if nothing exported. */ - if ((hair && hair->num_keys() == 0) || (mesh && mesh->verts.size() == 0)) { + if (hair->num_keys() == 0) { return; } @@ -1424,7 +922,7 @@ void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph, /* Particle hair. */ BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE); if (b_mesh) { - sync_particle_hair(geom, b_mesh, b_ob, true, motion_step); + sync_particle_hair(hair, b_mesh, b_ob, true, motion_step); free_object_to_mesh(b_data, b_ob, b_mesh); return; } @@ -1432,12 +930,7 @@ void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph, } /* No deformation on this frame, copy coordinates if other frames did have it. */ - if (hair) { - hair->copy_center_to_motion_step(motion_step); - } - else { - mesh->copy_center_to_motion_step(motion_step); - } + hair->copy_center_to_motion_step(motion_step); } CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_geometry.cpp b/intern/cycles/blender/blender_geometry.cpp index 7ca35cff961..7d63899cb99 100644 --- a/intern/cycles/blender/blender_geometry.cpp +++ b/intern/cycles/blender/blender_geometry.cpp @@ -41,15 +41,11 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, Shader *default_shader = (b_ob.type() == BL::Object::type_VOLUME) ? scene->default_volume : scene->default_surface; #ifdef WITH_NEW_OBJECT_TYPES - Geometry::Type geom_type = ((b_ob.type() == BL::Object::type_HAIR || use_particle_hair) && - (scene->curve_system_manager->primitive != CURVE_TRIANGLES)) ? + Geometry::Type geom_type = (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) ? Geometry::HAIR : Geometry::MESH; #else - Geometry::Type geom_type = ((use_particle_hair) && - (scene->curve_system_manager->primitive != CURVE_TRIANGLES)) ? - Geometry::HAIR : - Geometry::MESH; + Geometry::Type geom_type = (use_particle_hair) ? Geometry::HAIR : Geometry::MESH; #endif /* Find shader indices. */ @@ -134,7 +130,8 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, #else if (use_particle_hair) { #endif - sync_hair(b_depsgraph, b_ob, geom, used_shaders); + Hair *hair = static_cast(geom); + sync_hair(b_depsgraph, b_ob, hair, used_shaders); } else if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) { Mesh *mesh = static_cast(geom); @@ -178,7 +175,8 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph, #else if (use_particle_hair) { #endif - sync_hair_motion(b_depsgraph, b_ob, geom, motion_step); + Hair *hair = static_cast(geom); + sync_hair_motion(b_depsgraph, b_ob, hair, motion_step); } else if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) { /* No volume motion blur support yet. */ diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 341281b18ee..3c39cfd9446 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -153,15 +153,12 @@ class BlenderSync { /* Hair */ void sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, - Geometry *geom, + Hair *hair, const vector &used_shaders); - void sync_hair_motion(BL::Depsgraph b_depsgraph, - BL::Object b_ob, - Geometry *geom, - int motion_step); + void sync_hair_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *hair, int motion_step); void sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step = 0); void sync_particle_hair( - Geometry *geom, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0); + Hair *hair, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0); void sync_curve_settings(BL::Depsgraph &b_depsgraph); bool object_has_particle_hair(BL::Object b_ob); -- cgit v1.2.3 From fed101a7be119f2e0c4ed64d13fd65f7a1c16118 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 10 Jun 2020 18:34:18 +0200 Subject: Cycles: always perform backface culling for curve, remove option The hair BSDFs are already designed to assume this, and disabling backface culling would break them in some cases. Ref T73778 Depends on D8009 Maniphest Tasks: T73778 Differential Revision: https://developer.blender.org/D8010 --- intern/cycles/blender/addon/properties.py | 5 ----- intern/cycles/blender/addon/ui.py | 2 -- intern/cycles/blender/blender_curves.cpp | 1 - 3 files changed, 8 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 29ef1814294..89ed059af21 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1236,11 +1236,6 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup): items=enum_curve_shape, default='THICK', ) - cull_backfacing: BoolProperty( - name="Cull Back-faces", - description="Do not test the back-face of each hair", - default=True, - ) use_curves: BoolProperty( name="Use Cycles Hair Rendering", description="Activate Cycles hair rendering for particle system", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index b6d19b1d4a7..9680bd04751 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -409,8 +409,6 @@ class CYCLES_RENDER_PT_hair(CyclesButtonsPanel, Panel): if ccscene.shape == 'RIBBONS': # TODO: use for embree col.prop(ccscene, "subdivisions", text="Curve subdivisions") - else: - col.prop(ccscene, "cull_backfacing", text="Cull back-faces") class CYCLES_RENDER_PT_volumes(CyclesButtonsPanel, Panel): diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 43fe653fda4..a2a0392d4d5 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -519,7 +519,6 @@ void BlenderSync::sync_curve_settings(BL::Depsgraph &b_depsgraph) curve_system_manager->curve_shape = (CurveShapeType)get_enum( csscene, "shape", CURVE_NUM_SHAPE_TYPES, CURVE_THICK); curve_system_manager->subdivisions = get_int(csscene, "subdivisions"); - curve_system_manager->use_backfacing = !get_boolean(csscene, "cull_backfacing"); if (curve_system_manager->modified_mesh(prev_curve_system_manager)) { BL::Depsgraph::objects_iterator b_ob; -- cgit v1.2.3 From d1ef5146d72d40f97fdcbf28e96da49193c21dea Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 10 Jun 2020 18:55:33 +0200 Subject: Cycles: remove SIMD BVH optimizations, to be replaced by Embree Ref T73778 Depends on D8011 Maniphest Tasks: T73778 Differential Revision: https://developer.blender.org/D8012 --- intern/cycles/blender/addon/properties.py | 11 ----------- intern/cycles/blender/addon/ui.py | 16 ++++++++++------ intern/cycles/blender/blender_sync.cpp | 10 +--------- 3 files changed, 11 insertions(+), 26 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 89ed059af21..f0f7d24002f 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -53,12 +53,6 @@ enum_displacement_methods = ( ('BOTH', "Displacement and Bump", "Combination of true displacement and bump mapping for finer detail"), ) -enum_bvh_layouts = ( - ('BVH2', "BVH2", "", 1), - ('BVH4', "BVH4", "", 2), - ('BVH8', "BVH8", "", 4), -) - enum_bvh_types = ( ('DYNAMIC_BVH', "Dynamic BVH", "Objects can be individually updated, at the cost of slower render time"), ('STATIC_BVH', "Static BVH", "Any object modification requires a complete BVH rebuild, but renders faster"), @@ -772,11 +766,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): debug_use_cpu_sse41: BoolProperty(name="SSE41", default=True) debug_use_cpu_sse3: BoolProperty(name="SSE3", default=True) debug_use_cpu_sse2: BoolProperty(name="SSE2", default=True) - debug_bvh_layout: EnumProperty( - name="BVH Layout", - items=enum_bvh_layouts, - default='BVH8', - ) debug_use_cpu_split_kernel: BoolProperty(name="Split Kernel", default=False) debug_use_cuda_adaptive_compile: BoolProperty(name="Adaptive Compile", default=False) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 9680bd04751..0859a8a82b0 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -688,16 +688,20 @@ class CYCLES_RENDER_PT_performance_acceleration_structure(CyclesButtonsPanel, Pa col = layout.column() - if _cycles.with_embree: - row = col.row() - row.active = use_cpu(context) - row.prop(cscene, "use_bvh_embree") + use_embree = False + if use_cpu(context): + use_embree = _cycles.with_embree + if not use_embree: + sub = col.column(align=True) + sub.label(text="Cycles built without Embree support") + sub.label(text="CPU raytracing performance will be poor") + col.prop(cscene, "debug_use_spatial_splits") sub = col.column() - sub.active = not cscene.use_bvh_embree or not _cycles.with_embree + sub.active = not use_embree sub.prop(cscene, "debug_use_hair_bvh") sub = col.column() - sub.active = not cscene.debug_use_spatial_splits and not cscene.use_bvh_embree + sub.active = not cscene.debug_use_spatial_splits and not use_embree sub.prop(cscene, "debug_bvh_time_steps") diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 09813dc8c05..f5fd6f31c75 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -751,15 +751,7 @@ SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background) params.texture_limit = 0; } - /* TODO(sergey): Once OSL supports per-microarchitecture optimization get - * rid of this. - */ - if (params.shadingsystem == SHADINGSYSTEM_OSL) { - params.bvh_layout = BVH_LAYOUT_BVH4; - } - else { - params.bvh_layout = DebugFlags().cpu.bvh_layout; - } + params.bvh_layout = DebugFlags().cpu.bvh_layout; #ifdef WITH_EMBREE params.bvh_layout = RNA_boolean_get(&cscene, "use_bvh_embree") ? BVH_LAYOUT_EMBREE : -- cgit v1.2.3 From 207338bb58b1a44c531e6d78fad68672c6d3b2e1 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 18 Feb 2020 20:54:41 +0100 Subject: Cycles: port curve-ray intersection from Embree for use in Cycles GPU This keeps render results compatible for combined CPU + GPU rendering. Peformance and quality primitives is quite different than before. There are now two options: * Rounded Ribbon: render hair as flat ribbon with (fake) rounded normals, for fast rendering. Hair curves are subdivided with a fixed number of user specified subdivisions. This gives relatively good results, especially when used with the Principled Hair BSDF and hair viewed from a typical distance. There are artifacts when viewed closed up, though this was also the case with all previous primitives (but different ones). * 3D Curve: render hair as 3D curve, for accurate results when viewing hair close up. This automatically subdivides the curve until it is smooth. This gives higher quality than any of the previous primitives, but does come at a performance cost and is somewhat slower than our previous Thick curves. The main problem here is performance. For CPU and OpenCL rendering performance seems usually quite close or better for similar quality results. However for CUDA and Optix, performance of 3D curve intersection is problematic, with e.g. 1.45x longer render time in Koro (though there is no equivalent quality and rounded ribbons seem fine for that scene). Any help or ideas to optimize this are welcome. Ref T73778 Depends on D8012 Maniphest Tasks: T73778 Differential Revision: https://developer.blender.org/D8013 --- intern/cycles/blender/addon/properties.py | 8 ++++---- intern/cycles/blender/addon/ui.py | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index f0f7d24002f..ceaeda6e798 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -73,8 +73,8 @@ enum_panorama_types = ( ) enum_curve_shape = ( - ('RIBBONS', "Ribbons", "Ignore thickness of each hair"), - ('THICK', "Thick", "Use thickness of hair when rendering"), + ('RIBBONS', "Rounded Ribbons", "Render hair as flat ribbon with rounded normals, for fast rendering"), + ('THICK', "3D Curves", "Render hair as 3D curve, for accurate results when viewing hair close up"), ) enum_tile_order = ( @@ -1223,7 +1223,7 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup): name="Shape", description="Form of hair", items=enum_curve_shape, - default='THICK', + default='RIBBONS', ) use_curves: BoolProperty( name="Use Cycles Hair Rendering", @@ -1234,7 +1234,7 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup): name="Subdivisions", description="Number of subdivisions used in Cardinal curve intersection (power of 2)", min=0, max=24, - default=4, + default=2, ) @classmethod diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 0859a8a82b0..daab26d8ec0 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -407,7 +407,6 @@ class CYCLES_RENDER_PT_hair(CyclesButtonsPanel, Panel): col = layout.column() col.prop(ccscene, "shape", text="Shape") if ccscene.shape == 'RIBBONS': - # TODO: use for embree col.prop(ccscene, "subdivisions", text="Curve subdivisions") -- cgit v1.2.3 From 2c41c8e94fa8740f67dc39150dd1ab66b506adc9 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 10 Jun 2020 19:07:07 +0200 Subject: Cycles: internal refactoring to make thick/ribbon curve separate primitives Also removing the curve system manager which only stored a few curve intersection settings. These are all changes towards making shape and subdivision settings per-object instead of per-scene, but there is more work to do here. Ref T73778 Depends on D8013 Maniphest Tasks: T73778 Differential Revision: https://developer.blender.org/D8014 --- intern/cycles/blender/addon/properties.py | 5 ---- intern/cycles/blender/addon/ui.py | 9 -------- intern/cycles/blender/blender_curves.cpp | 38 +------------------------------ intern/cycles/blender/blender_sync.cpp | 6 ++++- intern/cycles/blender/blender_sync.h | 1 - 5 files changed, 6 insertions(+), 53 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index ceaeda6e798..269ad8ecc5b 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1225,11 +1225,6 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup): items=enum_curve_shape, default='RIBBONS', ) - use_curves: BoolProperty( - name="Use Cycles Hair Rendering", - description="Activate Cycles hair rendering for particle system", - default=True, - ) subdivisions: IntProperty( name="Subdivisions", description="Number of subdivisions used in Cardinal curve intersection (power of 2)", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index daab26d8ec0..592c59cc661 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -387,13 +387,6 @@ class CYCLES_RENDER_PT_hair(CyclesButtonsPanel, Panel): bl_label = "Hair" bl_options = {'DEFAULT_CLOSED'} - def draw_header(self, context): - layout = self.layout - scene = context.scene - ccscene = scene.cycles_curves - - layout.prop(ccscene, "use_curves", text="") - def draw(self, context): layout = self.layout layout.use_property_split = True @@ -402,8 +395,6 @@ class CYCLES_RENDER_PT_hair(CyclesButtonsPanel, Panel): scene = context.scene ccscene = scene.cycles_curves - layout.active = ccscene.use_curves - col = layout.column() col.prop(ccscene, "shape", text="Shape") if ccscene.shape == 'RIBBONS': diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index a2a0392d4d5..e1f84925987 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -507,42 +507,6 @@ static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int /* Hair Curve Sync */ -void BlenderSync::sync_curve_settings(BL::Depsgraph &b_depsgraph) -{ - PointerRNA csscene = RNA_pointer_get(&b_scene.ptr, "cycles_curves"); - - CurveSystemManager *curve_system_manager = scene->curve_system_manager; - CurveSystemManager prev_curve_system_manager = *curve_system_manager; - - curve_system_manager->use_curves = get_boolean(csscene, "use_curves"); - - curve_system_manager->curve_shape = (CurveShapeType)get_enum( - csscene, "shape", CURVE_NUM_SHAPE_TYPES, CURVE_THICK); - curve_system_manager->subdivisions = get_int(csscene, "subdivisions"); - - if (curve_system_manager->modified_mesh(prev_curve_system_manager)) { - BL::Depsgraph::objects_iterator b_ob; - - for (b_depsgraph.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) { - if (object_is_mesh(*b_ob)) { - BL::Object::particle_systems_iterator b_psys; - for (b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); - ++b_psys) { - if ((b_psys->settings().render_type() == BL::ParticleSettings::render_type_PATH) && - (b_psys->settings().type() == BL::ParticleSettings::type_HAIR)) { - BL::ID key = BKE_object_is_modified(*b_ob) ? *b_ob : b_ob->data(); - geometry_map.set_recalc(key); - object_map.set_recalc(*b_ob); - } - } - } - } - } - - if (curve_system_manager->modified(prev_curve_system_manager)) - curve_system_manager->tag_update(scene); -} - bool BlenderSync::object_has_particle_hair(BL::Object b_ob) { /* Test if the object has a particle modifier with hair. */ @@ -867,7 +831,7 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, hair->clear(); hair->used_shaders = used_shaders; - if (view_layer.use_hair && scene->curve_system_manager->use_curves) { + if (view_layer.use_hair) { #ifdef WITH_NEW_OBJECT_TYPES if (b_ob.type() == BL::Object::type_HAIR) { /* Hair object. */ diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index f5fd6f31c75..7a6047ca6a6 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -212,7 +212,6 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render, sync_film(b_v3d); sync_shaders(b_depsgraph, b_v3d); sync_images(); - sync_curve_settings(b_depsgraph); geometry_synced.clear(); /* use for objects and motion sync */ @@ -732,6 +731,11 @@ SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background) params.use_bvh_unaligned_nodes = RNA_boolean_get(&cscene, "debug_use_hair_bvh"); params.num_bvh_time_steps = RNA_int_get(&cscene, "debug_bvh_time_steps"); + PointerRNA csscene = RNA_pointer_get(&b_scene.ptr, "cycles_curves"); + params.hair_subdivisions = get_int(csscene, "subdivisions"); + params.hair_shape = (CurveShapeType)get_enum( + csscene, "shape", CURVE_NUM_SHAPE_TYPES, CURVE_THICK); + if (background && params.shadingsystem != SHADINGSYSTEM_OSL) params.persistent_data = r.use_persistent_data(); else diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 3c39cfd9446..25032e8d0fa 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -159,7 +159,6 @@ class BlenderSync { void sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step = 0); void sync_particle_hair( Hair *hair, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0); - void sync_curve_settings(BL::Depsgraph &b_depsgraph); bool object_has_particle_hair(BL::Object b_ob); /* Camera */ -- cgit v1.2.3 From 99436acde8fbb7381f095922bb61455b0c8fb9a9 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 23 Feb 2020 09:14:52 +0100 Subject: Cycles: enable Embree by default for CPU rendering For GPU debugging purposes, it is still possible to render with the same BVH2 on the CPU using the Debug panel in the render properties. Note that building Blender without Embree will now lead to significantly reduced performance in CPU rendering, and a few of the Cycles regression tests will fail due to small pixel differences. Ref T73778 Depends on D8014 Maniphest Tasks: T73778 Differential Revision: https://developer.blender.org/D8015 --- intern/cycles/blender/addon/properties.py | 15 ++++++++++----- intern/cycles/blender/blender_sync.cpp | 5 ----- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 269ad8ecc5b..b7e9b1511ec 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -53,6 +53,11 @@ enum_displacement_methods = ( ('BOTH', "Displacement and Bump", "Combination of true displacement and bump mapping for finer detail"), ) +enum_bvh_layouts = ( + ('BVH2', "BVH2", "", 1), + ('EMBREE', "Embree", "", 4), +) + enum_bvh_types = ( ('DYNAMIC_BVH', "Dynamic BVH", "Objects can be individually updated, at the cost of slower render time"), ('STATIC_BVH', "Static BVH", "Any object modification requires a complete BVH rebuild, but renders faster"), @@ -612,11 +617,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): items=enum_bvh_types, default='DYNAMIC_BVH', ) - use_bvh_embree: BoolProperty( - name="Use Embree", - description="Use Embree as ray accelerator", - default=False, - ) debug_use_spatial_splits: BoolProperty( name="Use Spatial Splits", description="Use BVH spatial splits: longer builder time, faster render", @@ -766,6 +766,11 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): debug_use_cpu_sse41: BoolProperty(name="SSE41", default=True) debug_use_cpu_sse3: BoolProperty(name="SSE3", default=True) debug_use_cpu_sse2: BoolProperty(name="SSE2", default=True) + debug_bvh_layout: EnumProperty( + name="BVH Layout", + items=enum_bvh_layouts, + default='EMBREE', + ) debug_use_cpu_split_kernel: BoolProperty(name="Split Kernel", default=False) debug_use_cuda_adaptive_compile: BoolProperty(name="Adaptive Compile", default=False) diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 7a6047ca6a6..b40c8434395 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -757,11 +757,6 @@ SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background) params.bvh_layout = DebugFlags().cpu.bvh_layout; -#ifdef WITH_EMBREE - params.bvh_layout = RNA_boolean_get(&cscene, "use_bvh_embree") ? BVH_LAYOUT_EMBREE : - params.bvh_layout; -#endif - params.background = background; return params; -- cgit v1.2.3 From 461ba2c74cf25a20cc25ab9edd7aace82e5557d2 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 22 Jun 2020 16:36:07 +0200 Subject: Fix random crash in Cycles smoke volume loading Don't access evaluated mesh data after freeing Blender depsgraph. Potentially related to T77954. --- intern/cycles/blender/blender_volume.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp index 4eed6be8c7c..ad199807752 100644 --- a/intern/cycles/blender/blender_volume.cpp +++ b/intern/cycles/blender/blender_volume.cpp @@ -35,8 +35,10 @@ CCL_NAMESPACE_BEGIN class BlenderSmokeLoader : public ImageLoader { public: BlenderSmokeLoader(BL::Object &b_ob, AttributeStandard attribute) - : b_domain(object_fluid_gas_domain_find(b_ob)), b_mesh(b_ob.data()), attribute(attribute) + : b_domain(object_fluid_gas_domain_find(b_ob)), attribute(attribute) { + BL::Mesh b_mesh(b_ob.data()); + mesh_texture_space(b_mesh, texspace_loc, texspace_size); } bool load_metadata(ImageMetaData &metadata) override @@ -77,9 +79,7 @@ class BlenderSmokeLoader : public ImageLoader { /* Create a matrix to transform from object space to mesh texture space. * This does not work with deformations but that can probably only be done * well with a volume grid mapping of coordinates. */ - float3 loc, size; - mesh_texture_space(b_mesh, loc, size); - metadata.transform_3d = transform_translate(-loc) * transform_scale(size); + metadata.transform_3d = transform_translate(-texspace_loc) * transform_scale(texspace_size); metadata.use_transform_3d = true; return true; @@ -177,7 +177,7 @@ class BlenderSmokeLoader : public ImageLoader { } BL::FluidDomainSettings b_domain; - BL::Mesh b_mesh; + float3 texspace_loc, texspace_size; AttributeStandard attribute; }; -- cgit v1.2.3 From 87ceff3d1b5805658622a314a84620b52ab98c7d Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 23 Jun 2020 11:30:46 +0200 Subject: Preferences: New experimental settings for particle system and hair This replaces the cmake options `WITH_NEW_OBJECT_TYPES` and `WITH_NEW_SIMULATION_TYPE` with two experimental userpref settings: * `use_new_particle_system`: Enables the point cloud type and the simulation editor. * `use_new_hair_type`: Only displays the add-operator in the add menu for now. Note, in the current state you can't do anything productive with the new particle system or the new hair type. Features will be added step by step in the upcoming weeks and months. Reviewers: brecht Differential Revision: https://developer.blender.org/D8096 --- intern/cycles/blender/CMakeLists.txt | 4 ---- intern/cycles/blender/blender_curves.cpp | 21 ++------------------- intern/cycles/blender/blender_geometry.cpp | 12 ------------ intern/cycles/blender/blender_object.cpp | 4 ---- 4 files changed, 2 insertions(+), 39 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt index 496e8e9310b..4589f4573d9 100644 --- a/intern/cycles/blender/CMakeLists.txt +++ b/intern/cycles/blender/CMakeLists.txt @@ -92,10 +92,6 @@ if(WITH_MOD_FLUID) add_definitions(-DWITH_FLUID) endif() -if(WITH_NEW_OBJECT_TYPES) - add_definitions(-DWITH_NEW_OBJECT_TYPES) -endif() - if(WITH_OPENVDB) add_definitions(-DWITH_OPENVDB ${OPENVDB_DEFINITIONS}) list(APPEND INC_SYS diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index e1f84925987..7eb76c8bd8f 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -628,7 +628,6 @@ void BlenderSync::sync_particle_hair( } } -#ifdef WITH_NEW_OBJECT_TYPES static float4 hair_point_as_float4(BL::HairPoint b_point) { float4 mP = float3_to_float4(get_float3(b_point.co())); @@ -794,12 +793,10 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st export_hair_motion_validate_attribute(hair, motion_step, num_motion_keys, have_motion); } } -#endif /* WITH_NEW_OBJECT_TYPES */ /* Hair object. */ void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step) { -#ifdef WITH_NEW_OBJECT_TYPES /* Convert Blender hair to Cycles curves. */ BL::Hair b_hair(b_ob.data()); if (motion) { @@ -808,12 +805,6 @@ void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motio else { export_hair_curves(scene, hair, b_hair); } -#else - (void)hair; - (void)b_ob; - (void)motion; - (void)motion_step; -#endif /* WITH_NEW_OBJECT_TYPES */ } void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, @@ -832,15 +823,11 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, hair->used_shaders = used_shaders; if (view_layer.use_hair) { -#ifdef WITH_NEW_OBJECT_TYPES if (b_ob.type() == BL::Object::type_HAIR) { /* Hair object. */ sync_hair(hair, b_ob, false); - assert(mesh == NULL); } - else -#endif - { + else { /* Particle hair. */ bool need_undeformed = hair->need_attribute(scene, ATTR_STD_GENERATED); BL::Mesh b_mesh = object_to_mesh( @@ -872,16 +859,12 @@ void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph, /* Export deformed coordinates. */ if (ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) { -#ifdef WITH_NEW_OBJECT_TYPES if (b_ob.type() == BL::Object::type_HAIR) { /* Hair object. */ sync_hair(hair, b_ob, true, motion_step); - assert(mesh == NULL); return; } - else -#endif - { + else { /* Particle hair. */ BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE); if (b_mesh) { diff --git a/intern/cycles/blender/blender_geometry.cpp b/intern/cycles/blender/blender_geometry.cpp index 7d63899cb99..f7e4623024d 100644 --- a/intern/cycles/blender/blender_geometry.cpp +++ b/intern/cycles/blender/blender_geometry.cpp @@ -40,13 +40,9 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, BL::Material material_override = view_layer.material_override; Shader *default_shader = (b_ob.type() == BL::Object::type_VOLUME) ? scene->default_volume : scene->default_surface; -#ifdef WITH_NEW_OBJECT_TYPES Geometry::Type geom_type = (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) ? Geometry::HAIR : Geometry::MESH; -#else - Geometry::Type geom_type = (use_particle_hair) ? Geometry::HAIR : Geometry::MESH; -#endif /* Find shader indices. */ vector used_shaders; @@ -125,11 +121,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, geom->name = ustring(b_ob_data.name().c_str()); -#ifdef WITH_NEW_OBJECT_TYPES if (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) { -#else - if (use_particle_hair) { -#endif Hair *hair = static_cast(geom); sync_hair(b_depsgraph, b_ob, hair, used_shaders); } @@ -170,11 +162,7 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph, return; } -#ifdef WITH_NEW_OBJECT_TYPES if (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) { -#else - if (use_particle_hair) { -#endif Hair *hair = static_cast(geom); sync_hair_motion(b_depsgraph, b_ob, hair, motion_step); } diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index c28586d0f63..d3a37563ef4 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -69,11 +69,7 @@ bool BlenderSync::object_is_mesh(BL::Object &b_ob) BL::Object::type_enum type = b_ob.type(); -#ifdef WITH_NEW_OBJECT_TYPES if (type == BL::Object::type_VOLUME || type == BL::Object::type_HAIR) { -#else - if (type == BL::Object::type_VOLUME) { -#endif /* Will be exported attached to mesh. */ return true; } -- cgit v1.2.3 From 49234c15e29989ab8d67b5728098398d5b22a812 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Tue, 23 Jun 2020 17:51:25 -0400 Subject: UI: Cycles: Use Title Case --- intern/cycles/blender/addon/ui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 592c59cc661..85da1a17c2b 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -398,7 +398,7 @@ class CYCLES_RENDER_PT_hair(CyclesButtonsPanel, Panel): col = layout.column() col.prop(ccscene, "shape", text="Shape") if ccscene.shape == 'RIBBONS': - col.prop(ccscene, "subdivisions", text="Curve subdivisions") + col.prop(ccscene, "subdivisions", text="Curve Subdivisions") class CYCLES_RENDER_PT_volumes(CyclesButtonsPanel, Panel): -- cgit v1.2.3 From 0a3bde63006c66b8b8531ed5eccca9bdf5e5dc20 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 31 May 2020 23:49:10 +0200 Subject: Cycles: add denoising settings to the render properties Enabling render and viewport denoising is now both done from the render properties. View layers still can individually be enabled/disabled for denoising and have their own denoising parameters. Note that the denoising engine also affects how denoising data passes are output even if no denoising happens on the render itself, to make the passes compatible with the engine. This includes internal refactoring for how denoising parameters are passed along, trying to avoid code duplication and unclear naming. Ref T76259 --- intern/cycles/blender/addon/properties.py | 58 +++++++++----- intern/cycles/blender/addon/ui.py | 68 +++++++++++------ intern/cycles/blender/blender_camera.cpp | 6 +- intern/cycles/blender/blender_device.cpp | 50 ------------ intern/cycles/blender/blender_session.cpp | 118 +++++++++++++++++------------ intern/cycles/blender/blender_sync.cpp | 116 +++++++++++++++++++++------- intern/cycles/blender/blender_sync.h | 20 +++-- intern/cycles/blender/blender_viewport.cpp | 16 ---- intern/cycles/blender/blender_viewport.h | 4 - 9 files changed, 260 insertions(+), 196 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index b7e9b1511ec..061e3784b0d 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -182,10 +182,20 @@ enum_aov_types = ( ('COLOR', "Color", "Write a Color pass", 1), ) -enum_viewport_denoising = ( - ('NONE', "None", "Disable viewport denoising", 0), - ('OPTIX', "OptiX AI-Accelerated", "Use the OptiX denoiser running on the GPU (requires at least one compatible OptiX device)", 1), -) +def enum_optix_denoiser(self, context): + if not context or bool(context.preferences.addons[__package__].preferences.get_devices_for_type('OPTIX')): + return [('OPTIX', "OptiX", "Use the OptiX AI denoiser with GPU acceleration, only available on NVIDIA GPUs", 2)] + return [] + +def enum_preview_denoiser(self, context): + items = [('AUTO', "Auto", "Use the fastest available denoiser for viewport rendering", 0)] + items += enum_optix_denoiser(self, context) + return items + +def enum_denoiser(self, context): + items = [('NLM', "NLM", "Cycles native non-local means denoiser, running on any compute device", 1)] + items += enum_optix_denoiser(self, context) + return items enum_denoising_optix_input_passes = ( ('RGB', "Color", "Use only color as input", 1), @@ -224,11 +234,29 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): description="Pause all viewport preview renders", default=False, ) - preview_denoising: EnumProperty( - name="Viewport Denoising", - description="Denoise the image after each preview update with the selected denoiser engine", - items=enum_viewport_denoising, - default='NONE', + + use_denoising: BoolProperty( + name="Use Denoising", + description="Denoise the rendered image", + default=False, + ) + use_preview_denoising: BoolProperty( + name="Use Viewport Denoising", + description="Denoise the image in the 3D viewport", + default=False, + ) + + denoiser: EnumProperty( + name="Denoiser", + description="Denoise the image with the selected denoiser", + items=enum_denoiser, + default=1, + ) + preview_denoiser: EnumProperty( + name="Viewport Denoiser", + description="Denoise the image after each preview update with the selected denoiser", + items=enum_preview_denoiser, + default=0, ) use_square_samples: BoolProperty( @@ -244,7 +272,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): default=128, ) preview_samples: IntProperty( - name="Preview Samples", + name="Viewport Samples", description="Number of samples to render in the viewport, unlimited if 0", min=0, max=(1 << 24), default=32, @@ -464,7 +492,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): subtype='PIXEL' ) preview_dicing_rate: FloatProperty( - name="Preview Dicing Rate", + name="Viewport Dicing Rate", description="Size of a micropolygon in pixels during preview render", min=0.1, max=1000.0, soft_min=0.5, default=8.0, @@ -1330,7 +1358,7 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup): use_denoising: BoolProperty( name="Use Denoising", description="Denoise the rendered image", - default=False, + default=True, update=update_render_passes, ) denoising_diffuse_direct: BoolProperty( @@ -1400,12 +1428,6 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup): default=0, ) - use_optix_denoising: BoolProperty( - name="OptiX AI-Accelerated", - description="Use the OptiX denoiser to denoise the rendered image", - default=False, - update=update_render_passes, - ) denoising_optix_input_passes: EnumProperty( name="Input Passes", description="Passes handed over to the OptiX denoiser (this can have different effects on the denoised image)", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 85da1a17c2b..e689ec90983 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -112,10 +112,6 @@ def show_device_active(context): return True return context.preferences.addons[__package__].preferences.has_active_device() -def show_optix_denoising(context): - # OptiX AI denoiser can be used when at least one device supports OptiX - return bool(context.preferences.addons[__package__].preferences.get_devices_for_type('OPTIX')) - def draw_samples_info(layout, context): cscene = context.scene.cycles @@ -190,11 +186,6 @@ class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel): col.prop(cscene, "aa_samples", text="Render") col.prop(cscene, "preview_aa_samples", text="Viewport") - # Viewport denoising is currently only supported with OptiX - if show_optix_denoising(context): - col = layout.column() - col.prop(cscene, "preview_denoising") - if not use_branched_path(context): draw_samples_info(layout, context) @@ -256,6 +247,39 @@ class CYCLES_RENDER_PT_sampling_adaptive(CyclesButtonsPanel, Panel): col.prop(cscene, "adaptive_threshold", text="Noise Threshold") col.prop(cscene, "adaptive_min_samples", text="Min Samples") + +class CYCLES_RENDER_PT_sampling_denoising(CyclesButtonsPanel, Panel): + bl_label = "Denoising" + bl_parent_id = "CYCLES_RENDER_PT_sampling" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + scene = context.scene + cscene = scene.cycles + + heading = layout.column(align=True, heading="Render") + row = heading.row(align=True) + row.prop(cscene, "use_denoising", text="") + sub = row.row() + sub.active = cscene.use_denoising + sub.prop(cscene, "denoiser", text="") + + heading = layout.column(align=True, heading="Viewport") + row = heading.row(align=True) + row.prop(cscene, "use_preview_denoising", text="") + sub = row.row() + sub.active = cscene.use_preview_denoising + sub.prop(cscene, "preview_denoiser", text="") + + sub = heading.row(align=True) + sub.active = cscene.use_preview_denoising + sub.prop(cscene, "preview_denoising_start_sample", text="Start Sample") + + class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel): bl_label = "Advanced" bl_parent_id = "CYCLES_RENDER_PT_sampling" @@ -730,11 +754,6 @@ class CYCLES_RENDER_PT_performance_viewport(CyclesButtonsPanel, Panel): col.prop(rd, "preview_pixel_size", text="Pixel Size") col.prop(cscene, "preview_start_resolution", text="Start Pixels") - if show_optix_denoising(context): - sub = col.row(align=True) - sub.active = cscene.preview_denoising != 'NONE' - sub.prop(cscene, "preview_denoising_start_sample", text="Denoising Start Sample") - class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel): bl_label = "Filter" @@ -957,12 +976,17 @@ class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel): bl_context = "view_layer" bl_options = {'DEFAULT_CLOSED'} + @classmethod + def poll(cls, context): + cscene = context.scene.cycles + return CyclesButtonsPanel.poll(context) and cscene.use_denoising + def draw_header(self, context): scene = context.scene view_layer = context.view_layer cycles_view_layer = view_layer.cycles - layout = self.layout + layout = self.layout layout.prop(cycles_view_layer, "use_denoising", text="") def draw(self, context): @@ -973,18 +997,15 @@ class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel): scene = context.scene view_layer = context.view_layer cycles_view_layer = view_layer.cycles + denoiser = scene.cycles.denoiser - layout.active = cycles_view_layer.use_denoising + layout.active = denoiser != 'NONE' and cycles_view_layer.use_denoising col = layout.column() - if show_optix_denoising(context): - col.prop(cycles_view_layer, "use_optix_denoising") - col.separator(factor=2.0) - - if cycles_view_layer.use_optix_denoising: - col.prop(cycles_view_layer, "denoising_optix_input_passes") - return + if denoiser == 'OPTIX': + col.prop(cycles_view_layer, "denoising_optix_input_passes") + return col.prop(cycles_view_layer, "denoising_radius", text="Radius") @@ -2237,6 +2258,7 @@ classes = ( CYCLES_RENDER_PT_sampling, CYCLES_RENDER_PT_sampling_sub_samples, CYCLES_RENDER_PT_sampling_adaptive, + CYCLES_RENDER_PT_sampling_denoising, CYCLES_RENDER_PT_sampling_advanced, CYCLES_RENDER_PT_light_paths, CYCLES_RENDER_PT_light_paths_max_bounces, diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index 40a1a2c2edc..d9c63bec737 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -873,7 +873,8 @@ BufferParams BlenderSync::get_buffer_params(BL::Scene &b_scene, BL::RegionView3D &b_rv3d, Camera *cam, int width, - int height) + int height, + const bool use_denoiser) { BufferParams params; bool use_border = false; @@ -907,8 +908,7 @@ BufferParams BlenderSync::get_buffer_params(BL::Scene &b_scene, PassType display_pass = update_viewport_display_passes(b_v3d, params.passes); /* Can only denoise the combined image pass */ - params.denoising_data_pass = display_pass == PASS_COMBINED && - update_viewport_display_denoising(b_v3d, b_scene); + params.denoising_data_pass = display_pass == PASS_COMBINED && use_denoiser; return params; } diff --git a/intern/cycles/blender/blender_device.cpp b/intern/cycles/blender/blender_device.cpp index ac52948806c..fb9ab9e8c97 100644 --- a/intern/cycles/blender/blender_device.cpp +++ b/intern/cycles/blender/blender_device.cpp @@ -21,13 +21,6 @@ CCL_NAMESPACE_BEGIN -enum DenoiserType { - DENOISER_NONE = 0, - DENOISER_OPTIX = 1, - - DENOISER_NUM -}; - enum ComputeDevice { COMPUTE_DEVICE_CPU = 0, COMPUTE_DEVICE_CUDA = 1, @@ -120,49 +113,6 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen } } - /* Ensure there is an OptiX device when using the OptiX denoiser. */ - bool use_optix_denoising = get_enum(cscene, "preview_denoising", DENOISER_NUM, DENOISER_NONE) == - DENOISER_OPTIX && - !background; - BL::Scene::view_layers_iterator b_view_layer; - for (b_scene.view_layers.begin(b_view_layer); b_view_layer != b_scene.view_layers.end(); - ++b_view_layer) { - PointerRNA crl = RNA_pointer_get(&b_view_layer->ptr, "cycles"); - if (get_boolean(crl, "use_optix_denoising")) { - use_optix_denoising = true; - } - } - - if (use_optix_denoising && device.type != DEVICE_OPTIX) { - vector optix_devices = Device::available_devices(DEVICE_MASK_OPTIX); - if (!optix_devices.empty()) { - /* Convert to a special multi device with separate denoising devices. */ - if (device.multi_devices.empty()) { - device.multi_devices.push_back(device); - } - - /* Try to use the same physical devices for denoising. */ - for (const DeviceInfo &cuda_device : device.multi_devices) { - if (cuda_device.type == DEVICE_CUDA) { - for (const DeviceInfo &optix_device : optix_devices) { - if (cuda_device.num == optix_device.num) { - device.id += optix_device.id; - device.denoising_devices.push_back(optix_device); - break; - } - } - } - } - - if (device.denoising_devices.empty()) { - /* Simply use the first available OptiX device. */ - const DeviceInfo optix_device = optix_devices.front(); - device.id += optix_device.id; /* Uniquely identify this special multi device. */ - device.denoising_devices.push_back(optix_device); - } - } - } - return device; } diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index dbe87ce2b13..2874ccb6470 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -157,8 +157,14 @@ void BlenderSession::create_session() } /* set buffer parameters */ - BufferParams buffer_params = BlenderSync::get_buffer_params( - b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, + b_render, + b_v3d, + b_rv3d, + scene->camera, + width, + height, + session_params.denoising.use); session->reset(buffer_params, session_params.samples); b_engine.use_highlight_tiles(session_params.progressive_refine == false); @@ -239,8 +245,14 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL); BL::RegionView3D b_null_region_view3d(PointerRNA_NULL); - BufferParams buffer_params = BlenderSync::get_buffer_params( - b_scene, b_render, b_null_space_view3d, b_null_region_view3d, scene->camera, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, + b_render, + b_null_space_view3d, + b_null_region_view3d, + scene->camera, + width, + height, + session_params.denoising.use); session->reset(buffer_params, session_params.samples); b_engine.use_highlight_tiles(session_params.progressive_refine == false); @@ -468,14 +480,19 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_) session->update_render_tile_cb = function_bind( &BlenderSession::update_render_tile, this, _1, _2); + BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval(); + /* get buffer parameters */ SessionParams session_params = BlenderSync::get_session_params( - b_engine, b_userpref, b_scene, background); - BufferParams buffer_params = BlenderSync::get_buffer_params( - b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height); - - /* render each layer */ - BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval(); + b_engine, b_userpref, b_scene, background, b_view_layer); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, + b_render, + b_v3d, + b_rv3d, + scene->camera, + width, + height, + session_params.denoising.use); /* temporary render result to find needed passes and views */ BL::RenderResult b_rr = begin_render_result( @@ -485,35 +502,26 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_) BL::RenderLayer b_rlay = *b_single_rlay; b_rlay_name = b_view_layer.name(); - /* add passes */ - vector passes = sync->sync_render_passes( - b_rlay, b_view_layer, session_params.adaptive_sampling); - buffer_params.passes = passes; + /* Update denoising parameters. */ + session->set_denoising(session_params.denoising); - PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles"); - bool use_denoising = get_boolean(crl, "use_denoising"); - bool use_optix_denoising = get_boolean(crl, "use_optix_denoising"); - bool write_denoising_passes = get_boolean(crl, "denoising_store_passes"); + bool use_denoising = session_params.denoising.use; + bool store_denoising_passes = session_params.denoising.store_passes; - buffer_params.denoising_data_pass = use_denoising || write_denoising_passes; + buffer_params.denoising_data_pass = use_denoising || store_denoising_passes; buffer_params.denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES); - buffer_params.denoising_prefiltered_pass = write_denoising_passes && !use_optix_denoising; - - session->params.run_denoising = use_denoising || write_denoising_passes; - session->params.full_denoising = use_denoising && !use_optix_denoising; - session->params.optix_denoising = use_denoising && use_optix_denoising; - session->params.write_denoising_passes = write_denoising_passes && !use_optix_denoising; - session->params.denoising.radius = get_int(crl, "denoising_radius"); - session->params.denoising.strength = get_float(crl, "denoising_strength"); - session->params.denoising.feature_strength = get_float(crl, "denoising_feature_strength"); - session->params.denoising.relative_pca = get_boolean(crl, "denoising_relative_pca"); - session->params.denoising.optix_input_passes = get_enum(crl, "denoising_optix_input_passes"); - session->tile_manager.schedule_denoising = session->params.run_denoising; + buffer_params.denoising_prefiltered_pass = store_denoising_passes && + session_params.denoising.type == DENOISER_NLM; scene->film->denoising_data_pass = buffer_params.denoising_data_pass; scene->film->denoising_clean_pass = buffer_params.denoising_clean_pass; scene->film->denoising_prefiltered_pass = buffer_params.denoising_prefiltered_pass; + /* Add passes */ + vector passes = sync->sync_render_passes( + b_rlay, b_view_layer, session_params.adaptive_sampling, session_params.denoising); + buffer_params.passes = passes; + scene->film->pass_alpha_threshold = b_view_layer.pass_alpha_threshold(); scene->film->tag_passes_update(scene, passes); scene->film->tag_update(scene); @@ -798,7 +806,7 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_) /* increase samples, but never decrease */ session->set_samples(session_params.samples); - session->set_denoising_start_sample(session_params.denoising_start_sample); + session->set_denoising_start_sample(session_params.denoising.start_sample); session->set_pause(session_pause); /* copy recalc flags, outside of mutex so we can decide to do the real @@ -830,22 +838,24 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_) sync->sync_camera(b_render, b_camera_override, width, height, ""); /* get buffer parameters */ - BufferParams buffer_params = BlenderSync::get_buffer_params( - b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height); - - if (session_params.device.type != DEVICE_OPTIX && - session_params.device.denoising_devices.empty()) { - /* cannot use OptiX denoising when it is not supported by the device. */ - buffer_params.denoising_data_pass = false; - } - else { - session->set_denoising(buffer_params.denoising_data_pass, true); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, + b_render, + b_v3d, + b_rv3d, + scene->camera, + width, + height, + session_params.denoising.use); + + if (!buffer_params.denoising_data_pass) { + session_params.denoising.use = false; } + session->set_denoising(session_params.denoising); + + /* Update film if denoising data was enabled or disabled. */ if (scene->film->denoising_data_pass != buffer_params.denoising_data_pass) { scene->film->denoising_data_pass = buffer_params.denoising_data_pass; - - /* Force a scene and session reset below. */ scene->film->tag_update(scene); } @@ -916,8 +926,14 @@ bool BlenderSession::draw(int w, int h) if (reset) { SessionParams session_params = BlenderSync::get_session_params( b_engine, b_userpref, b_scene, background); - BufferParams buffer_params = BlenderSync::get_buffer_params( - b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, + b_render, + b_v3d, + b_rv3d, + scene->camera, + width, + height, + session_params.denoising.use); bool session_pause = BlenderSync::get_session_pause(b_scene, background); if (session_pause == false) { @@ -934,8 +950,14 @@ bool BlenderSession::draw(int w, int h) update_status_progress(); /* draw */ - BufferParams buffer_params = BlenderSync::get_buffer_params( - b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, + b_render, + b_v3d, + b_rv3d, + scene->camera, + width, + height, + session->params.denoising.use); DeviceDrawParams draw_params; if (session->params.display_buffer_linear) { diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index b40c8434395..aed92cf1376 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -537,7 +537,8 @@ int BlenderSync::get_denoising_pass(BL::RenderPass &b_pass) vector BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_view_layer, - bool adaptive_sampling) + bool adaptive_sampling, + const DenoiseParams &denoising) { vector passes; @@ -554,16 +555,13 @@ vector BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, Pass::add(pass_type, passes, b_pass.name().c_str()); } - PointerRNA crp = RNA_pointer_get(&b_view_layer.ptr, "cycles"); - bool use_denoising = get_boolean(crp, "use_denoising"); - bool use_optix_denoising = get_boolean(crp, "use_optix_denoising"); - bool write_denoising_passes = get_boolean(crp, "denoising_store_passes"); + PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles"); scene->film->denoising_flags = 0; - if (use_denoising || write_denoising_passes) { - if (!use_optix_denoising) { + if (denoising.use || denoising.store_passes) { + if (denoising.type == DENOISER_NLM) { #define MAP_OPTION(name, flag) \ - if (!get_boolean(crp, name)) \ + if (!get_boolean(crl, name)) \ scene->film->denoising_flags |= flag; MAP_OPTION("denoising_diffuse_direct", DENOISING_CLEAN_DIFFUSE_DIR); MAP_OPTION("denoising_diffuse_indirect", DENOISING_CLEAN_DIFFUSE_IND); @@ -576,11 +574,11 @@ vector BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str()); } - if (write_denoising_passes) { + if (denoising.store_passes) { b_engine.add_pass("Denoising Normal", 3, "XYZ", b_view_layer.name().c_str()); b_engine.add_pass("Denoising Albedo", 3, "RGB", b_view_layer.name().c_str()); b_engine.add_pass("Denoising Depth", 1, "Z", b_view_layer.name().c_str()); - if (!use_optix_denoising) { + if (denoising.type == DENOISER_NLM) { b_engine.add_pass("Denoising Shadowing", 1, "X", b_view_layer.name().c_str()); b_engine.add_pass("Denoising Variance", 3, "RGB", b_view_layer.name().c_str()); b_engine.add_pass("Denoising Intensity", 1, "X", b_view_layer.name().c_str()); @@ -592,46 +590,46 @@ vector BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, } #ifdef __KERNEL_DEBUG__ - if (get_boolean(crp, "pass_debug_bvh_traversed_nodes")) { + if (get_boolean(crl, "pass_debug_bvh_traversed_nodes")) { b_engine.add_pass("Debug BVH Traversed Nodes", 1, "X", b_view_layer.name().c_str()); Pass::add(PASS_BVH_TRAVERSED_NODES, passes, "Debug BVH Traversed Nodes"); } - if (get_boolean(crp, "pass_debug_bvh_traversed_instances")) { + if (get_boolean(crl, "pass_debug_bvh_traversed_instances")) { b_engine.add_pass("Debug BVH Traversed Instances", 1, "X", b_view_layer.name().c_str()); Pass::add(PASS_BVH_TRAVERSED_INSTANCES, passes, "Debug BVH Traversed Instances"); } - if (get_boolean(crp, "pass_debug_bvh_intersections")) { + if (get_boolean(crl, "pass_debug_bvh_intersections")) { b_engine.add_pass("Debug BVH Intersections", 1, "X", b_view_layer.name().c_str()); Pass::add(PASS_BVH_INTERSECTIONS, passes, "Debug BVH Intersections"); } - if (get_boolean(crp, "pass_debug_ray_bounces")) { + if (get_boolean(crl, "pass_debug_ray_bounces")) { b_engine.add_pass("Debug Ray Bounces", 1, "X", b_view_layer.name().c_str()); Pass::add(PASS_RAY_BOUNCES, passes, "Debug Ray Bounces"); } #endif - if (get_boolean(crp, "pass_debug_render_time")) { + if (get_boolean(crl, "pass_debug_render_time")) { b_engine.add_pass("Debug Render Time", 1, "X", b_view_layer.name().c_str()); Pass::add(PASS_RENDER_TIME, passes, "Debug Render Time"); } - if (get_boolean(crp, "pass_debug_sample_count")) { + if (get_boolean(crl, "pass_debug_sample_count")) { b_engine.add_pass("Debug Sample Count", 1, "X", b_view_layer.name().c_str()); Pass::add(PASS_SAMPLE_COUNT, passes, "Debug Sample Count"); } - if (get_boolean(crp, "use_pass_volume_direct")) { + if (get_boolean(crl, "use_pass_volume_direct")) { b_engine.add_pass("VolumeDir", 3, "RGB", b_view_layer.name().c_str()); Pass::add(PASS_VOLUME_DIRECT, passes, "VolumeDir"); } - if (get_boolean(crp, "use_pass_volume_indirect")) { + if (get_boolean(crl, "use_pass_volume_indirect")) { b_engine.add_pass("VolumeInd", 3, "RGB", b_view_layer.name().c_str()); Pass::add(PASS_VOLUME_INDIRECT, passes, "VolumeInd"); } /* Cryptomatte stores two ID/weight pairs per RGBA layer. * User facing parameter is the number of pairs. */ - int crypto_depth = divide_up(min(16, get_int(crp, "pass_crypto_depth")), 2); + int crypto_depth = divide_up(min(16, get_int(crl, "pass_crypto_depth")), 2); scene->film->cryptomatte_depth = crypto_depth; scene->film->cryptomatte_passes = CRYPT_NONE; - if (get_boolean(crp, "use_pass_crypto_object")) { + if (get_boolean(crl, "use_pass_crypto_object")) { for (int i = 0; i < crypto_depth; i++) { string passname = cryptomatte_prefix + string_printf("Object%02d", i); b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str()); @@ -640,7 +638,7 @@ vector BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_OBJECT); } - if (get_boolean(crp, "use_pass_crypto_material")) { + if (get_boolean(crl, "use_pass_crypto_material")) { for (int i = 0; i < crypto_depth; i++) { string passname = cryptomatte_prefix + string_printf("Material%02d", i); b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str()); @@ -649,7 +647,7 @@ vector BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_MATERIAL); } - if (get_boolean(crp, "use_pass_crypto_asset")) { + if (get_boolean(crl, "use_pass_crypto_asset")) { for (int i = 0; i < crypto_depth; i++) { string passname = cryptomatte_prefix + string_printf("Asset%02d", i); b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str()); @@ -658,19 +656,19 @@ vector BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_ASSET); } - if (get_boolean(crp, "pass_crypto_accurate") && scene->film->cryptomatte_passes != CRYPT_NONE) { + if (get_boolean(crl, "pass_crypto_accurate") && scene->film->cryptomatte_passes != CRYPT_NONE) { scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_ACCURATE); } if (adaptive_sampling) { Pass::add(PASS_ADAPTIVE_AUX_BUFFER, passes); - if (!get_boolean(crp, "pass_debug_sample_count")) { + if (!get_boolean(crl, "pass_debug_sample_count")) { Pass::add(PASS_SAMPLE_COUNT, passes); } } - RNA_BEGIN (&crp, b_aov, "aovs") { + RNA_BEGIN (&crl, b_aov, "aovs") { bool is_color = (get_enum(b_aov, "type") == 1); string name = get_string(b_aov, "name"); @@ -773,7 +771,8 @@ bool BlenderSync::get_session_pause(BL::Scene &b_scene, bool background) SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine, BL::Preferences &b_preferences, BL::Scene &b_scene, - bool background) + bool background, + BL::ViewLayer b_view_layer) { SessionParams params; PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); @@ -851,9 +850,22 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine, params.tile_order = TILE_BOTTOM_TO_TOP; } - /* other parameters */ + /* Denoising */ + params.denoising = get_denoise_params(b_scene, b_view_layer, background); + + if (params.denoising.use) { + /* Add additional denoising devices if we are rendering and denoising + * with different devices. */ + params.device.add_denoising_devices(params.denoising.type); + + /* Check if denoiser is supported by device. */ + if (!(params.device.denoisers & params.denoising.type)) { + params.denoising.use = false; + } + } + + /* Viewport Performance */ params.start_resolution = get_int(cscene, "preview_start_resolution"); - params.denoising_start_sample = get_int(cscene, "preview_denoising_start_sample"); params.pixel_size = b_engine.get_preview_pixel_size(b_scene); /* other parameters */ @@ -906,4 +918,52 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine, return params; } +DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene, + BL::ViewLayer &b_view_layer, + bool background) +{ + DenoiseParams denoising; + PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); + + if (background) { + /* Final Render Denoising */ + denoising.use = get_boolean(cscene, "use_denoising"); + denoising.type = (DenoiserType)get_enum(cscene, "denoiser", DENOISER_NUM, DENOISER_NONE); + + if (b_view_layer) { + PointerRNA clayer = RNA_pointer_get(&b_view_layer.ptr, "cycles"); + if (!get_boolean(clayer, "use_denoising")) { + denoising.use = false; + } + + denoising.radius = get_int(clayer, "denoising_radius"); + denoising.strength = get_float(clayer, "denoising_strength"); + denoising.feature_strength = get_float(clayer, "denoising_feature_strength"); + denoising.relative_pca = get_boolean(clayer, "denoising_relative_pca"); + denoising.optix_input_passes = get_enum(clayer, "denoising_optix_input_passes"); + + denoising.store_passes = get_boolean(clayer, "denoising_store_passes"); + } + } + else { + /* Viewport Denoising */ + denoising.use = get_boolean(cscene, "use_preview_denoising"); + denoising.type = (DenoiserType)get_enum( + cscene, "preview_denoiser", DENOISER_NUM, DENOISER_NONE); + denoising.start_sample = get_int(cscene, "preview_denoising_start_sample"); + + /* Auto select fastest denoiser. */ + if (denoising.type == DENOISER_NONE) { + if (!Device::available_devices(DEVICE_MASK_OPTIX).empty()) { + denoising.type = DENOISER_OPTIX; + } + else { + denoising.use = false; + } + } + } + + return denoising; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 25032e8d0fa..85789cd00f6 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -75,7 +75,8 @@ class BlenderSync { void sync_view_layer(BL::SpaceView3D &b_v3d, BL::ViewLayer &b_view_layer); vector sync_render_passes(BL::RenderLayer &b_render_layer, BL::ViewLayer &b_view_layer, - bool adaptive_sampling); + bool adaptive_sampling, + const DenoiseParams &denoising); void sync_integrator(); void sync_camera(BL::RenderSettings &b_render, BL::Object &b_override, @@ -94,10 +95,12 @@ class BlenderSync { /* get parameters */ static SceneParams get_scene_params(BL::Scene &b_scene, bool background); - static SessionParams get_session_params(BL::RenderEngine &b_engine, - BL::Preferences &b_userpref, - BL::Scene &b_scene, - bool background); + static SessionParams get_session_params( + BL::RenderEngine &b_engine, + BL::Preferences &b_userpref, + BL::Scene &b_scene, + bool background, + BL::ViewLayer b_view_layer = BL::ViewLayer(PointerRNA_NULL)); static bool get_session_pause(BL::Scene &b_scene, bool background); static BufferParams get_buffer_params(BL::Scene &b_scene, BL::RenderSettings &b_render, @@ -105,12 +108,17 @@ class BlenderSync { BL::RegionView3D &b_rv3d, Camera *cam, int width, - int height); + int height, + const bool use_denoiser); static PassType get_pass_type(BL::RenderPass &b_pass); static int get_denoising_pass(BL::RenderPass &b_pass); private: + static DenoiseParams get_denoise_params(BL::Scene &b_scene, + BL::ViewLayer &b_view_layer, + bool background); + /* sync */ void sync_lights(BL::Depsgraph &b_depsgraph, bool update_all); void sync_materials(BL::Depsgraph &b_depsgraph, bool update_all); diff --git a/intern/cycles/blender/blender_viewport.cpp b/intern/cycles/blender/blender_viewport.cpp index 93e84e28032..73ef5f94720 100644 --- a/intern/cycles/blender/blender_viewport.cpp +++ b/intern/cycles/blender/blender_viewport.cpp @@ -61,17 +61,6 @@ const bool BlenderViewportParameters::custom_viewport_parameters() const return !(use_scene_world && use_scene_lights); } -bool BlenderViewportParameters::get_viewport_display_denoising(BL::SpaceView3D &b_v3d, - BL::Scene &b_scene) -{ - bool use_denoising = false; - if (b_v3d) { - PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); - use_denoising = get_enum(cscene, "preview_denoising") != 0; - } - return use_denoising; -} - PassType BlenderViewportParameters::get_viewport_display_render_pass(BL::SpaceView3D &b_v3d) { PassType display_pass = PASS_NONE; @@ -83,11 +72,6 @@ PassType BlenderViewportParameters::get_viewport_display_render_pass(BL::SpaceVi return display_pass; } -bool update_viewport_display_denoising(BL::SpaceView3D &b_v3d, BL::Scene &b_scene) -{ - return BlenderViewportParameters::get_viewport_display_denoising(b_v3d, b_scene); -} - PassType update_viewport_display_passes(BL::SpaceView3D &b_v3d, vector &passes) { if (b_v3d) { diff --git a/intern/cycles/blender/blender_viewport.h b/intern/cycles/blender/blender_viewport.h index 3e44e552f1d..7c6c9c4d274 100644 --- a/intern/cycles/blender/blender_viewport.h +++ b/intern/cycles/blender/blender_viewport.h @@ -44,15 +44,11 @@ class BlenderViewportParameters { friend class BlenderSync; public: - /* Get whether to enable denoising data pass in viewport. */ - static bool get_viewport_display_denoising(BL::SpaceView3D &b_v3d, BL::Scene &b_scene); /* Retrieve the render pass that needs to be displayed on the given `SpaceView3D` * When the `b_v3d` parameter is not given `PASS_NONE` will be returned. */ static PassType get_viewport_display_render_pass(BL::SpaceView3D &b_v3d); }; -bool update_viewport_display_denoising(BL::SpaceView3D &b_v3d, BL::Scene &b_scene); - PassType update_viewport_display_passes(BL::SpaceView3D &b_v3d, vector &passes); CCL_NAMESPACE_END -- cgit v1.2.3 From 669befdfbe487f76c65f54e3da0013d140d56893 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 1 Jun 2020 00:11:17 +0200 Subject: Cycles: add Intel OpenImageDenoise support for viewport denoising Compared to Optix denoise, this is usually slower since there is no GPU acceleration. Some optimizations may still be possible, in avoid copies to the GPU and/or denoising less often. The main thing is that this adds viewport denoising support for computers without an NVIDIA GPU (as long as the CPU supports SSE 4.1, which is nearly all of them). Ref T76259 --- intern/cycles/blender/CMakeLists.txt | 7 +++++++ intern/cycles/blender/addon/properties.py | 20 ++++++++++++++++++-- intern/cycles/blender/addon/ui.py | 2 ++ intern/cycles/blender/blender_python.cpp | 10 ++++++++++ intern/cycles/blender/blender_sync.cpp | 4 ++++ 5 files changed, 41 insertions(+), 2 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt index 4589f4573d9..2316800e21e 100644 --- a/intern/cycles/blender/CMakeLists.txt +++ b/intern/cycles/blender/CMakeLists.txt @@ -102,6 +102,13 @@ if(WITH_OPENVDB) ) endif() +if(WITH_OPENIMAGEDENOISE) + add_definitions(-DWITH_OPENIMAGEDENOISE) + list(APPEND INC_SYS + ${OPENIMAGEDENOISE_INCLUDE_DIRS} + ) +endif() + blender_add_lib(bf_intern_cycles "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") # avoid link failure with clang 3.4 debug diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 061e3784b0d..053de16529c 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -182,14 +182,30 @@ enum_aov_types = ( ('COLOR', "Color", "Write a Color pass", 1), ) +def enum_openimagedenoise_denoiser(self, context): + if _cycles.with_openimagedenoise: + return [('OPENIMAGEDENOISE', "OpenImageDenoise", "Use Intel OpenImageDenoise AI denoiser running on the CPU", 4)] + return [] + def enum_optix_denoiser(self, context): if not context or bool(context.preferences.addons[__package__].preferences.get_devices_for_type('OPTIX')): return [('OPTIX', "OptiX", "Use the OptiX AI denoiser with GPU acceleration, only available on NVIDIA GPUs", 2)] return [] def enum_preview_denoiser(self, context): - items = [('AUTO', "Auto", "Use the fastest available denoiser for viewport rendering", 0)] - items += enum_optix_denoiser(self, context) + optix_items = enum_optix_denoiser(self, context) + oidn_items = enum_openimagedenoise_denoiser(self, context) + + if len(optix_items): + auto_label = "Fastest (Optix)" + elif len(oidn_items): + auto_label = "Fatest (OpenImageDenoise)" + else: + auto_label = "None" + + items = [('AUTO', auto_label, "Use the fastest available denoiser for viewport rendering", 0)] + items += optix_items + items += oidn_items return items def enum_denoiser(self, context): diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index e689ec90983..aa0a47eb9c7 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1006,6 +1006,8 @@ class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel): if denoiser == 'OPTIX': col.prop(cycles_view_layer, "denoising_optix_input_passes") return + elif denoiser == 'OPENIMAGEDENOISE': + return col.prop(cycles_view_layer, "denoising_radius", text="Radius") diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index 5595d657640..3e595c3ee52 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -31,6 +31,7 @@ #include "util/util_logging.h" #include "util/util_md5.h" #include "util/util_opengl.h" +#include "util/util_openimagedenoise.h" #include "util/util_path.h" #include "util/util_string.h" #include "util/util_task.h" @@ -1076,5 +1077,14 @@ void *CCL_python_module_init() Py_INCREF(Py_False); #endif /* WITH_EMBREE */ + if (ccl::openimagedenoise_supported()) { + PyModule_AddObject(mod, "with_openimagedenoise", Py_True); + Py_INCREF(Py_True); + } + else { + PyModule_AddObject(mod, "with_openimagedenoise", Py_False); + Py_INCREF(Py_False); + } + return (void *)mod; } diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index aed92cf1376..bf065cc5492 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -38,6 +38,7 @@ #include "util/util_foreach.h" #include "util/util_hash.h" #include "util/util_opengl.h" +#include "util/util_openimagedenoise.h" CCL_NAMESPACE_BEGIN @@ -957,6 +958,9 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene, if (!Device::available_devices(DEVICE_MASK_OPTIX).empty()) { denoising.type = DENOISER_OPTIX; } + else if (openimagedenoise_supported()) { + denoising.type = DENOISER_OPENIMAGEDENOISE; + } else { denoising.use = false; } -- cgit v1.2.3 From 6fec2e4db05f6acdfc2b1b0ba365af143201277c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 24 Jun 2020 16:01:23 +0200 Subject: Cleanup: fix typo in denoiser menu --- intern/cycles/blender/addon/properties.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 053de16529c..840efb65d96 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -199,7 +199,7 @@ def enum_preview_denoiser(self, context): if len(optix_items): auto_label = "Fastest (Optix)" elif len(oidn_items): - auto_label = "Fatest (OpenImageDenoise)" + auto_label = "Fastest (OpenImageDenoise)" else: auto_label = "None" -- cgit v1.2.3 From b4e1571d0bcf186df979455cf9852dccd325345b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 24 Jun 2020 17:08:01 +0200 Subject: Cleanup: compiler warnings --- intern/cycles/blender/blender_camera.cpp | 3 +- intern/cycles/blender/blender_session.cpp | 53 +++++++------------------------ intern/cycles/blender/blender_sync.h | 3 +- 3 files changed, 13 insertions(+), 46 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index d9c63bec737..011678a7a65 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -867,8 +867,7 @@ void BlenderSync::sync_view(BL::SpaceView3D &b_v3d, } } -BufferParams BlenderSync::get_buffer_params(BL::Scene &b_scene, - BL::RenderSettings &b_render, +BufferParams BlenderSync::get_buffer_params(BL::RenderSettings &b_render, BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d, Camera *cam, diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 2874ccb6470..391a1b8f473 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -157,14 +157,8 @@ void BlenderSession::create_session() } /* set buffer parameters */ - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, - b_render, - b_v3d, - b_rv3d, - scene->camera, - width, - height, - session_params.denoising.use); + BufferParams buffer_params = BlenderSync::get_buffer_params( + b_render, b_v3d, b_rv3d, scene->camera, width, height, session_params.denoising.use); session->reset(buffer_params, session_params.samples); b_engine.use_highlight_tiles(session_params.progressive_refine == false); @@ -245,8 +239,7 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL); BL::RegionView3D b_null_region_view3d(PointerRNA_NULL); - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, - b_render, + BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_null_space_view3d, b_null_region_view3d, scene->camera, @@ -485,14 +478,8 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_) /* get buffer parameters */ SessionParams session_params = BlenderSync::get_session_params( b_engine, b_userpref, b_scene, background, b_view_layer); - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, - b_render, - b_v3d, - b_rv3d, - scene->camera, - width, - height, - session_params.denoising.use); + BufferParams buffer_params = BlenderSync::get_buffer_params( + b_render, b_v3d, b_rv3d, scene->camera, width, height, session_params.denoising.use); /* temporary render result to find needed passes and views */ BL::RenderResult b_rr = begin_render_result( @@ -838,14 +825,8 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_) sync->sync_camera(b_render, b_camera_override, width, height, ""); /* get buffer parameters */ - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, - b_render, - b_v3d, - b_rv3d, - scene->camera, - width, - height, - session_params.denoising.use); + BufferParams buffer_params = BlenderSync::get_buffer_params( + b_render, b_v3d, b_rv3d, scene->camera, width, height, session_params.denoising.use); if (!buffer_params.denoising_data_pass) { session_params.denoising.use = false; @@ -926,14 +907,8 @@ bool BlenderSession::draw(int w, int h) if (reset) { SessionParams session_params = BlenderSync::get_session_params( b_engine, b_userpref, b_scene, background); - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, - b_render, - b_v3d, - b_rv3d, - scene->camera, - width, - height, - session_params.denoising.use); + BufferParams buffer_params = BlenderSync::get_buffer_params( + b_render, b_v3d, b_rv3d, scene->camera, width, height, session_params.denoising.use); bool session_pause = BlenderSync::get_session_pause(b_scene, background); if (session_pause == false) { @@ -950,14 +925,8 @@ bool BlenderSession::draw(int w, int h) update_status_progress(); /* draw */ - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, - b_render, - b_v3d, - b_rv3d, - scene->camera, - width, - height, - session->params.denoising.use); + BufferParams buffer_params = BlenderSync::get_buffer_params( + b_render, b_v3d, b_rv3d, scene->camera, width, height, session->params.denoising.use); DeviceDrawParams draw_params; if (session->params.display_buffer_linear) { diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 85789cd00f6..0214d9eb3b8 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -102,8 +102,7 @@ class BlenderSync { bool background, BL::ViewLayer b_view_layer = BL::ViewLayer(PointerRNA_NULL)); static bool get_session_pause(BL::Scene &b_scene, bool background); - static BufferParams get_buffer_params(BL::Scene &b_scene, - BL::RenderSettings &b_render, + static BufferParams get_buffer_params(BL::RenderSettings &b_render, BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d, Camera *cam, -- cgit v1.2.3 From 890336849071dd716bc254edbbfa474ed9e61432 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 25 Jun 2020 13:48:44 +0200 Subject: Cycles: add support for rendering sculpt vertex colors Ref T78041 --- intern/cycles/blender/blender_mesh.cpp | 76 +++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 28 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index a6f380a9ae7..49407799fcd 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -278,25 +278,59 @@ static void mikk_compute_tangents( genTangSpaceDefault(&context); } +/* Create sculpt vertex color attributes. */ +static void attr_create_sculpt_vertex_color(Scene *scene, + Mesh *mesh, + BL::Mesh &b_mesh, + bool subdivision) +{ + BL::Mesh::sculpt_vertex_colors_iterator l; + + for (b_mesh.sculpt_vertex_colors.begin(l); l != b_mesh.sculpt_vertex_colors.end(); ++l) { + const bool active_render = l->active_render(); + AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE; + ustring vcol_name = ustring(l->name().c_str()); + + const bool need_vcol = mesh->need_attribute(scene, vcol_name) || + mesh->need_attribute(scene, vcol_std); + + if (!need_vcol) { + continue; + } + + AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes; + Attribute *vcol_attr = attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_VERTEX); + vcol_attr->std = vcol_std; + + float4 *cdata = vcol_attr->data_float4(); + int numverts = b_mesh.vertices.length(); + + for (int i = 0; i < numverts; i++) { + *(cdata++) = get_float4(l->data[i].color()); + } + } +} + /* Create vertex color attributes. */ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision) { - if (subdivision) { - BL::Mesh::vertex_colors_iterator l; + BL::Mesh::vertex_colors_iterator l; - for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) { - const bool active_render = l->active_render(); - AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE; - ustring vcol_name = ustring(l->name().c_str()); + for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) { + const bool active_render = l->active_render(); + AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE; + ustring vcol_name = ustring(l->name().c_str()); - const bool need_vcol = mesh->need_attribute(scene, vcol_name) || - mesh->need_attribute(scene, vcol_std); + const bool need_vcol = mesh->need_attribute(scene, vcol_name) || + mesh->need_attribute(scene, vcol_std); - if (!need_vcol) { - continue; - } + if (!need_vcol) { + continue; + } - Attribute *vcol_attr = NULL; + Attribute *vcol_attr = NULL; + + if (subdivision) { if (active_render) { vcol_attr = mesh->subd_attributes.add(vcol_std, vcol_name); } @@ -316,22 +350,7 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, } } } - } - else { - BL::Mesh::vertex_colors_iterator l; - for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) { - const bool active_render = l->active_render(); - AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE; - ustring vcol_name = ustring(l->name().c_str()); - - const bool need_vcol = mesh->need_attribute(scene, vcol_name) || - mesh->need_attribute(scene, vcol_std); - - if (!need_vcol) { - continue; - } - - Attribute *vcol_attr = NULL; + else { if (active_render) { vcol_attr = mesh->attributes.add(vcol_std, vcol_name); } @@ -828,6 +847,7 @@ static void create_mesh(Scene *scene, */ attr_create_pointiness(scene, mesh, b_mesh, subdivision); attr_create_vertex_color(scene, mesh, b_mesh, subdivision); + attr_create_sculpt_vertex_color(scene, mesh, b_mesh, subdivision); attr_create_random_per_island(scene, mesh, b_mesh, subdivision); if (subdivision) { -- cgit v1.2.3 From 74c49492c258dfdb92bc243b623f061bca6f3e35 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 11 Jun 2020 20:32:39 +0200 Subject: Cycles: add experimental preference to replace magic debug value 256 Previously you'd have to run with --debug-value 256, now just make it a preference so the Debug panel can be always available for developers. --- intern/cycles/blender/addon/engine.py | 3 ++- intern/cycles/blender/addon/ui.py | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index e7ea5e7a1f6..7566ca28dd7 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -179,7 +179,8 @@ def reset(engine, data, depsgraph): import _cycles import bpy - if bpy.app.debug_value == 256: + prefs = bpy.context.preferences + if prefs.experimental.use_cycles_debug and prefs.view.show_developer_ui: _cycles.debug_flags_update(depsgraph.scene.as_pointer()) else: _cycles.debug_flags_reset() diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index aa0a47eb9c7..cfb22885eab 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1987,7 +1987,10 @@ class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel): @classmethod def poll(cls, context): - return CyclesButtonsPanel.poll(context) and bpy.app.debug_value == 256 + prefs = bpy.context.preferences + return (CyclesButtonsPanel.poll(context) + and prefs.experimental.use_cycles_debug + and prefs.view.show_developer_ui) def draw(self, context): layout = self.layout -- cgit v1.2.3 From da2e71be2fc4dc5b3028ff91cc2c5c4eef341302 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 26 Jun 2020 13:18:27 +0200 Subject: Fix T78310: tweak layout in denoising panel to have more spacing --- intern/cycles/blender/addon/ui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index cfb22885eab..5a8ccc387a8 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -268,7 +268,7 @@ class CYCLES_RENDER_PT_sampling_denoising(CyclesButtonsPanel, Panel): sub.active = cscene.use_denoising sub.prop(cscene, "denoiser", text="") - heading = layout.column(align=True, heading="Viewport") + heading = layout.column(align=False, heading="Viewport") row = heading.row(align=True) row.prop(cscene, "use_preview_denoising", text="") sub = row.row() -- cgit v1.2.3 From f28e59bd742e9cdea5d9cacc848d1759ef59f0a8 Mon Sep 17 00:00:00 2001 From: Adrian Newton Date: Mon, 29 Jun 2020 17:12:19 -0400 Subject: UI: Use single column for cycles ray visibility checkboxes Differential Revision: https://developer.blender.org/D7612 --- intern/cycles/blender/addon/ui.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 5a8ccc387a8..736d16ea8c5 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1587,17 +1587,18 @@ class CYCLES_WORLD_PT_ray_visibility(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False world = context.world visibility = world.cycles_visibility - flow = layout.column_flow() - - flow.prop(visibility, "camera") - flow.prop(visibility, "diffuse") - flow.prop(visibility, "glossy") - flow.prop(visibility, "transmission") - flow.prop(visibility, "scatter") + col = layout.column() + col.prop(visibility, "camera") + col.prop(visibility, "diffuse") + col.prop(visibility, "glossy") + col.prop(visibility, "transmission") + col.prop(visibility, "scatter") class CYCLES_WORLD_PT_settings(CyclesButtonsPanel, Panel): -- cgit v1.2.3 From 4e9ed1dae9647bf45a30d3af546f5a08e7a9b3e3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 30 Jun 2020 14:07:49 +0200 Subject: Fix T78447: Cycles vertex color node not working with hair --- intern/cycles/blender/blender_curves.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 7eb76c8bd8f..82c99631a89 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -262,7 +262,7 @@ static bool ObtainCacheParticleVcol(Hair *hair, BL::Mesh::vertex_colors_iterator l; b_mesh->vertex_colors.begin(l); - float3 vcol = make_float3(0.0f, 0.0f, 0.0f); + float4 vcol = make_float4(0.0f, 0.0f, 0.0f, 1.0f); if (b_mesh->vertex_colors.length()) b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x); CData->curve_vcol.push_back_slow(vcol); @@ -578,16 +578,16 @@ void BlenderSync::sync_particle_hair( ObtainCacheParticleVcol(hair, &b_mesh, &b_ob, &CData, !preview, vcol_num); Attribute *attr_vcol = hair->attributes.add( - ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE); + ustring(l->name().c_str()), TypeRGBA, ATTR_ELEMENT_CURVE); - float3 *fdata = attr_vcol->data_float3(); + float4 *fdata = attr_vcol->data_float4(); if (fdata) { size_t i = 0; /* Encode vertex color using the sRGB curve. */ for (size_t curve = 0; curve < CData.curve_vcol.size(); curve++) { - fdata[i++] = color_srgb_to_linear_v3(CData.curve_vcol[curve]); + fdata[i++] = color_srgb_to_linear_v4(CData.curve_vcol[curve]); } } } -- cgit v1.2.3 From 6ac235a6f75b71ec3d37dabc2e86b032e07c868e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 30 Jun 2020 17:19:45 +0200 Subject: Fix T78038: Cycles crash rendering with volume object and motion blur --- intern/cycles/blender/blender_volume.cpp | 47 ++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp index ad199807752..80591e0eec8 100644 --- a/intern/cycles/blender/blender_volume.cpp +++ b/intern/cycles/blender/blender_volume.cpp @@ -216,25 +216,16 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Mesh *mesh, float class BlenderVolumeLoader : public VDBImageLoader { public: - BlenderVolumeLoader(BL::Volume b_volume, const string &grid_name) - : VDBImageLoader(grid_name), - b_volume(b_volume), - b_volume_grid(PointerRNA_NULL), - unload(false) + BlenderVolumeLoader(BL::BlendData &b_data, BL::Volume &b_volume, const string &grid_name) + : VDBImageLoader(grid_name), b_data(b_data), b_volume(b_volume), unload(false) { -#ifdef WITH_OPENVDB - /* Find grid with matching name. */ - BL::Volume::grids_iterator b_grid_iter; - for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) { - if (b_grid_iter->name() == grid_name) { - b_volume_grid = *b_grid_iter; - } - } -#endif } bool load_metadata(ImageMetaData &metadata) override { + b_volume.grids.load(b_data.ptr.data); + BL::VolumeGrid b_volume_grid = find_grid(); + if (!b_volume_grid) { return false; } @@ -255,6 +246,9 @@ class BlenderVolumeLoader : public VDBImageLoader { const size_t pixel_size, const bool associate_alpha) override { + b_volume.grids.load(b_data.ptr.data); + BL::VolumeGrid b_volume_grid = find_grid(); + if (!b_volume_grid) { return false; } @@ -266,19 +260,38 @@ class BlenderVolumeLoader : public VDBImageLoader { { /* TODO: detect multiple volume datablocks with the same filepath. */ const BlenderVolumeLoader &other_loader = (const BlenderVolumeLoader &)other; - return b_volume == other_loader.b_volume && b_volume_grid == other_loader.b_volume_grid; + return b_volume == other_loader.b_volume && grid_name == other_loader.grid_name; } void cleanup() override { VDBImageLoader::cleanup(); + + BL::VolumeGrid b_volume_grid = find_grid(); if (b_volume_grid && unload) { b_volume_grid.unload(); } } + /* Find grid with matching name. Grid point not stored in the class since + * grids may be unloaded before we load the pixels, for example for motion + * blur where we move between frames. */ + BL::VolumeGrid find_grid() + { +#ifdef WITH_OPENVDB + BL::Volume::grids_iterator b_grid_iter; + for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) { + if (b_grid_iter->name() == grid_name) { + return *b_grid_iter; + } + } +#endif + + return BL::VolumeGrid(PointerRNA_NULL); + } + + BL::BlendData b_data; BL::Volume b_volume; - BL::VolumeGrid b_volume_grid; bool unload; }; @@ -325,7 +338,7 @@ static void sync_volume_object(BL::BlendData &b_data, BL::Object &b_ob, Scene *s mesh->attributes.add(std) : mesh->attributes.add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VOXEL); - ImageLoader *loader = new BlenderVolumeLoader(b_volume, name.string()); + ImageLoader *loader = new BlenderVolumeLoader(b_data, b_volume, name.string()); ImageParams params; params.frame = b_volume.grids.frame(); -- cgit v1.2.3 From 3562be2bdaacb6db37da38b2269fb56d2d838261 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Tue, 30 Jun 2020 13:22:43 -0400 Subject: UI: Cycles: Use Split layout for object motion blur --- intern/cycles/blender/addon/ui.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'intern/cycles/blender') diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 736d16ea8c5..b049d0bf2b4 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1202,6 +1202,7 @@ class CYCLES_OBJECT_PT_motion_blur(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True rd = context.scene.render # scene = context.scene @@ -1211,10 +1212,10 @@ class CYCLES_OBJECT_PT_motion_blur(CyclesButtonsPanel, Panel): layout.active = (rd.use_motion_blur and cob.use_motion_blur) - row = layout.row() + col = layout.column() + col.prop(cob, "motion_steps", text="Steps") if ob.type != 'CAMERA': - row.prop(cob, "use_deform_motion", text="Deformation") - row.prop(cob, "motion_steps", text="Steps") + col.prop(cob, "use_deform_motion", text="Deformation") def has_geometry_visibility(ob): -- cgit v1.2.3