Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-06-16 00:04:35 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-06-16 00:16:49 +0300
commit01f576e87b54159bb360cf1ed85518bb75231107 (patch)
tree0ac38f90154f8ee08a35fb88c5cf742403bbcb3c
parent469408de725353b461d073097d88b6b810c16c38 (diff)
parent799779d432309e518922d23e3a1d1b5baaece71d (diff)
Merge branch 'master' into blender2.8
The Eevee AO node supports the new Normal socket, but ignores Distance, Samples, Inside and Only Local settings.
-rw-r--r--intern/cycles/blender/addon/version_update.py54
-rw-r--r--intern/cycles/blender/blender_shader.cpp7
-rw-r--r--intern/cycles/kernel/CMakeLists.txt1
-rw-r--r--intern/cycles/kernel/bvh/bvh.h2
-rw-r--r--intern/cycles/kernel/bvh/bvh_local.h59
-rw-r--r--intern/cycles/kernel/bvh/qbvh_local.h58
-rw-r--r--intern/cycles/kernel/geom/geom_motion_triangle_intersect.h20
-rw-r--r--intern/cycles/kernel/geom/geom_triangle_intersect.h20
-rw-r--r--intern/cycles/kernel/kernel_path.h4
-rw-r--r--intern/cycles/kernel/kernel_path_branched.h2
-rw-r--r--intern/cycles/kernel/kernel_shader.h4
-rw-r--r--intern/cycles/kernel/kernel_types.h3
-rw-r--r--intern/cycles/kernel/osl/background.cpp26
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp2
-rw-r--r--intern/cycles/kernel/osl/osl_closures.h2
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp20
-rw-r--r--intern/cycles/kernel/osl/osl_services.h1
-rw-r--r--intern/cycles/kernel/shaders/node_ambient_occlusion.osl19
-rw-r--r--intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h2
-rw-r--r--intern/cycles/kernel/svm/svm.h7
-rw-r--r--intern/cycles/kernel/svm/svm_ao.h111
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h18
-rw-r--r--intern/cycles/kernel/svm/svm_types.h10
-rw-r--r--intern/cycles/render/nodes.cpp38
-rw-r--r--intern/cycles/render/nodes.h12
-rw-r--r--release/scripts/startup/nodeitems_builtins.py2
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenloader/intern/versioning_270.c2
-rw-r--r--source/blender/blenloader/intern/versioning_280.c3
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl2
-rw-r--r--source/blender/editors/space_node/drawnode.c10
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl8
-rw-r--r--source/blender/makesdna/DNA_node_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c21
-rw-r--r--source/blender/nodes/NOD_static_types.h2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.c20
36 files changed, 410 insertions, 167 deletions
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py
index 2db4def9dcb..d3948f8fbb5 100644
--- a/intern/cycles/blender/addon/version_update.py
+++ b/intern/cycles/blender/addon/version_update.py
@@ -271,6 +271,40 @@ def custom_bake_remap(scene):
scene.render.bake.use_pass_indirect = False
+def ambient_occlusion_node_relink(material, nodetree, traversed):
+ if nodetree in traversed:
+ return
+ traversed.add(nodetree)
+
+ for node in nodetree.nodes:
+ if node.bl_idname == 'ShaderNodeAmbientOcclusion':
+ node.samples = 1
+ node.only_local = False
+ node.inputs['Distance'].default_value = 0.0
+ elif node.bl_idname == 'ShaderNodeGroup':
+ ambient_occlusion_node_relink(material, node.node_tree, traversed)
+
+ # Gather links to replace
+ ao_links = []
+ for link in nodetree.links:
+ if link.from_node.bl_idname == 'ShaderNodeAmbientOcclusion':
+ ao_links.append(link)
+
+ # Replace links
+ for link in ao_links:
+ from_node = link.from_node
+ to_socket = link.to_socket
+
+ nodetree.links.remove(link)
+ nodetree.links.new(from_node.outputs['Color'], to_socket)
+
+def ambient_occlusion_nodes_relink():
+ traversed = set()
+ for material in bpy.data.materials:
+ if check_is_new_shading_material(material):
+ ambient_occlusion_node_relink(material, material.node_tree, traversed)
+
+
@persistent
def do_versions(self):
if bpy.context.user_preferences.version <= (2, 78, 1):
@@ -441,11 +475,15 @@ def do_versions(self):
part.radius_scale = cpart.get("radius_scale", 0.01)
part.use_close_tip = cpart.get("use_closetip", True)
- for world in bpy.data.worlds:
- cworld = world.cycles
- # World MIS
- if not cworld.is_property_set("sampling_method"):
- if cworld.get("sample_as_light", False):
- cworld.sampling_method = 'MANUAL'
- else:
- cworld.sampling_method = 'NONE'
+ if bpy.data.version <= (2, 79, 4) or \
+ (bpy.data.version >= (2, 80, 0) and bpy.data.version <= (2, 80, 18)):
+ for world in bpy.data.worlds:
+ cworld = world.cycles
+ # World MIS
+ if not cworld.is_property_set("sampling_method"):
+ if cworld.get("sample_as_light", False):
+ cworld.sampling_method = 'MANUAL'
+ else:
+ cworld.sampling_method = 'NONE'
+
+ ambient_occlusion_nodes_relink()
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index f9ba8a6e6b7..66034919145 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -551,7 +551,12 @@ static ShaderNode *add_node(Scene *scene,
node = new EmissionNode();
}
else if(b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) {
- node = new AmbientOcclusionNode();
+ BL::ShaderNodeAmbientOcclusion b_ao_node(b_node);
+ AmbientOcclusionNode *ao = new AmbientOcclusionNode();
+ ao->samples = b_ao_node.samples();
+ ao->inside = b_ao_node.inside();
+ ao->only_local = b_ao_node.only_local();
+ node = ao;
}
else if(b_node.is_a(&RNA_ShaderNodeVolumeScatter)) {
node = new ScatterVolumeNode();
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index b1956bfb13a..c2688cd71f7 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -160,6 +160,7 @@ set(SRC_CLOSURE_HEADERS
set(SRC_SVM_HEADERS
svm/svm.h
+ svm/svm_ao.h
svm/svm_attribute.h
svm/svm_bevel.h
svm/svm_blackbody.h
diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h
index d3e0b25a200..de1503e5564 100644
--- a/intern/cycles/kernel/bvh/bvh.h
+++ b/intern/cycles/kernel/bvh/bvh.h
@@ -203,7 +203,7 @@ ccl_device_intersect bool scene_intersect(KernelGlobals *kg,
#ifdef __BVH_LOCAL__
/* Note: ray is passed by value to work around a possible CUDA compiler bug. */
-ccl_device_intersect void scene_intersect_local(KernelGlobals *kg,
+ccl_device_intersect bool scene_intersect_local(KernelGlobals *kg,
const Ray ray,
LocalIntersection *local_isect,
int local_object,
diff --git a/intern/cycles/kernel/bvh/bvh_local.h b/intern/cycles/kernel/bvh/bvh_local.h
index 9292cc76a5c..6356c197dd1 100644
--- a/intern/cycles/kernel/bvh/bvh_local.h
+++ b/intern/cycles/kernel/bvh/bvh_local.h
@@ -41,7 +41,7 @@ ccl_device
#else
ccl_device_inline
#endif
-void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
+bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
const Ray *ray,
LocalIntersection *local_isect,
int local_object,
@@ -70,7 +70,11 @@ void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
int object = OBJECT_NONE;
float isect_t = ray->t;
- local_isect->num_hits = 0;
+ if(local_isect) {
+ local_isect->num_hits = 0;
+ }
+
+ kernel_assert((local_isect == NULL) == (max_hits == 0));
const int object_flag = kernel_tex_fetch(__object_flag, local_object);
if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
@@ -194,16 +198,18 @@ void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
/* intersect ray against primitive */
for(; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- triangle_intersect_local(kg,
- local_isect,
- P,
- dir,
- object,
- local_object,
- prim_addr,
- isect_t,
- lcg_state,
- max_hits);
+ if(triangle_intersect_local(kg,
+ local_isect,
+ P,
+ dir,
+ object,
+ local_object,
+ prim_addr,
+ isect_t,
+ lcg_state,
+ max_hits)) {
+ return true;
+ }
}
break;
}
@@ -212,17 +218,19 @@ void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
/* intersect ray against primitive */
for(; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- motion_triangle_intersect_local(kg,
- local_isect,
- P,
- dir,
- ray->time,
- object,
- local_object,
- prim_addr,
- isect_t,
- lcg_state,
- max_hits);
+ if(motion_triangle_intersect_local(kg,
+ local_isect,
+ P,
+ dir,
+ ray->time,
+ object,
+ local_object,
+ prim_addr,
+ isect_t,
+ lcg_state,
+ max_hits)) {
+ return true;
+ }
}
break;
}
@@ -234,9 +242,11 @@ void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
}
} while(node_addr != ENTRYPOINT_SENTINEL);
} while(node_addr != ENTRYPOINT_SENTINEL);
+
+ return false;
}
-ccl_device_inline void BVH_FUNCTION_NAME(KernelGlobals *kg,
+ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
const Ray *ray,
LocalIntersection *local_isect,
int local_object,
@@ -262,6 +272,7 @@ ccl_device_inline void BVH_FUNCTION_NAME(KernelGlobals *kg,
max_hits);
}
kernel_assert(!"Should not happen");
+ return false;
}
#undef BVH_FUNCTION_NAME
diff --git a/intern/cycles/kernel/bvh/qbvh_local.h b/intern/cycles/kernel/bvh/qbvh_local.h
index 2386fa1a1e8..0dc0575556c 100644
--- a/intern/cycles/kernel/bvh/qbvh_local.h
+++ b/intern/cycles/kernel/bvh/qbvh_local.h
@@ -29,7 +29,7 @@
# define NODE_INTERSECT qbvh_aligned_node_intersect
#endif
-ccl_device void BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
+ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
const Ray *ray,
LocalIntersection *local_isect,
int local_object,
@@ -59,7 +59,11 @@ ccl_device void BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
int object = OBJECT_NONE;
float isect_t = ray->t;
- local_isect->num_hits = 0;
+ if(local_isect) {
+ local_isect->num_hits = 0;
+ }
+
+ kernel_assert((local_isect == NULL) == (max_hits == 0));
const int object_flag = kernel_tex_fetch(__object_flag, local_object);
if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
@@ -81,7 +85,7 @@ ccl_device void BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
#ifndef __KERNEL_SSE41__
if(!isfinite(P.x)) {
- return;
+ return false;
}
#endif
@@ -250,16 +254,18 @@ ccl_device void BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
/* Intersect ray against primitive, */
for(; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- triangle_intersect_local(kg,
- local_isect,
- P,
- dir,
- object,
- local_object,
- prim_addr,
- isect_t,
- lcg_state,
- max_hits);
+ if(triangle_intersect_local(kg,
+ local_isect,
+ P,
+ dir,
+ object,
+ local_object,
+ prim_addr,
+ isect_t,
+ lcg_state,
+ max_hits)) {
+ return true;
+ }
}
break;
}
@@ -268,17 +274,19 @@ ccl_device void BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
/* Intersect ray against primitive. */
for(; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- motion_triangle_intersect_local(kg,
- local_isect,
- P,
- dir,
- ray->time,
- object,
- local_object,
- prim_addr,
- isect_t,
- lcg_state,
- max_hits);
+ if(motion_triangle_intersect_local(kg,
+ local_isect,
+ P,
+ dir,
+ ray->time,
+ object,
+ local_object,
+ prim_addr,
+ isect_t,
+ lcg_state,
+ max_hits)) {
+ return true;
+ }
}
break;
}
@@ -289,6 +297,8 @@ ccl_device void BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
}
} while(node_addr != ENTRYPOINT_SENTINEL);
} while(node_addr != ENTRYPOINT_SENTINEL);
+
+ return false;
}
#undef NODE_INTERSECT
diff --git a/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h b/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
index 542843edc84..ec7bfad7349 100644
--- a/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
@@ -218,9 +218,10 @@ ccl_device_inline bool motion_triangle_intersect(
/* Special ray intersection routines for local intersections. In that case we
* only want to intersect with primitives in the same object, and if case of
* multiple hits we pick a single random primitive as the intersection point.
+ * Returns whether traversal should be stopped.
*/
#ifdef __BVH_LOCAL__
-ccl_device_inline void motion_triangle_intersect_local(
+ccl_device_inline bool motion_triangle_intersect_local(
KernelGlobals *kg,
LocalIntersection *local_isect,
float3 P,
@@ -237,7 +238,7 @@ ccl_device_inline void motion_triangle_intersect_local(
* already know we are only intersecting the right object. */
if(object == OBJECT_NONE) {
if(kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
- return;
+ return false;
}
}
@@ -258,7 +259,12 @@ ccl_device_inline void motion_triangle_intersect_local(
#endif
&u, &v, &t))
{
- return;
+ return false;
+ }
+
+ /* If no actual hit information is requested, just return here. */
+ if(max_hits == 0) {
+ return true;
}
int hit;
@@ -266,7 +272,7 @@ ccl_device_inline void motion_triangle_intersect_local(
/* Record up to max_hits intersections. */
for(int i = min(max_hits, local_isect->num_hits) - 1; i >= 0; --i) {
if(local_isect->hits[i].t == t) {
- return;
+ return false;
}
}
@@ -282,13 +288,13 @@ ccl_device_inline void motion_triangle_intersect_local(
hit = lcg_step_uint(lcg_state) % local_isect->num_hits;
if(hit >= max_hits)
- return;
+ return false;
}
}
else {
/* Record closest intersection only. */
if(local_isect->num_hits && t > local_isect->hits[0].t) {
- return;
+ return false;
}
hit = 0;
@@ -307,6 +313,8 @@ ccl_device_inline void motion_triangle_intersect_local(
/* Record geometric normal. */
local_isect->Ng[hit] = normalize(cross(verts[1] - verts[0],
verts[2] - verts[0]));
+
+ return false;
}
#endif /* __BVH_LOCAL__ */
diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h
index a3b23115ae4..a2b1e050e58 100644
--- a/intern/cycles/kernel/geom/geom_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h
@@ -73,10 +73,11 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
/* Special ray intersection routines for local intersection. In that case we
* only want to intersect with primitives in the same object, and if case of
* multiple hits we pick a single random primitive as the intersection point.
+ * Returns whether traversal should be stopped.
*/
#ifdef __BVH_LOCAL__
-ccl_device_inline void triangle_intersect_local(
+ccl_device_inline bool triangle_intersect_local(
KernelGlobals *kg,
LocalIntersection *local_isect,
float3 P,
@@ -92,7 +93,7 @@ ccl_device_inline void triangle_intersect_local(
* already know we are only intersecting the right object. */
if(object == OBJECT_NONE) {
if(kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
- return;
+ return false;
}
}
@@ -115,7 +116,12 @@ ccl_device_inline void triangle_intersect_local(
#endif
&u, &v, &t))
{
- return;
+ return false;
+ }
+
+ /* If no actual hit information is requested, just return here. */
+ if(max_hits == 0) {
+ return true;
}
int hit;
@@ -123,7 +129,7 @@ ccl_device_inline void triangle_intersect_local(
/* Record up to max_hits intersections. */
for(int i = min(max_hits, local_isect->num_hits) - 1; i >= 0; --i) {
if(local_isect->hits[i].t == t) {
- return;
+ return false;
}
}
@@ -138,13 +144,13 @@ ccl_device_inline void triangle_intersect_local(
hit = lcg_step_uint(lcg_state) % local_isect->num_hits;
if(hit >= max_hits)
- return;
+ return false;
}
}
else {
/* Record closest intersection only. */
if(local_isect->num_hits && t > local_isect->hits[0].t) {
- return;
+ return false;
}
hit = 0;
@@ -167,6 +173,8 @@ ccl_device_inline void triangle_intersect_local(
tri_c = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex+2));
#endif
local_isect->Ng[hit] = normalize(cross(tri_b - tri_a, tri_c - tri_a));
+
+ return false;
}
#endif /* __BVH_LOCAL__ */
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index b0f53aef2d5..d79b556c2ce 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -491,7 +491,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
#ifdef __AO__
/* ambient occlusion */
- if(kernel_data.integrator.use_ambient_occlusion || (sd->flag & SD_AO)) {
+ if(kernel_data.integrator.use_ambient_occlusion) {
kernel_path_ao(kg, sd, emission_sd, L, state, throughput, make_float3(0.0f, 0.0f, 0.0f));
}
#endif /* __AO__ */
@@ -661,7 +661,7 @@ ccl_device_forceinline void kernel_path_integrate(
#ifdef __AO__
/* ambient occlusion */
- if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) {
+ if(kernel_data.integrator.use_ambient_occlusion) {
kernel_path_ao(kg, &sd, emission_sd, L, state, throughput, shader_bsdf_alpha(kg, &sd));
}
#endif /* __AO__ */
diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h
index 66f67c3e2c4..80fcf5b0565 100644
--- a/intern/cycles/kernel/kernel_path_branched.h
+++ b/intern/cycles/kernel/kernel_path_branched.h
@@ -526,7 +526,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
#ifdef __AO__
/* ambient occlusion */
- if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) {
+ if(kernel_data.integrator.use_ambient_occlusion) {
kernel_branched_path_ao(kg, &sd, emission_sd, L, &state, throughput);
}
#endif /* __AO__ */
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 937a50cba8b..b83460b3ffb 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -914,10 +914,6 @@ ccl_device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_fac
eval += sc->weight*ao_factor;
N += bsdf->N*fabsf(average(sc->weight));
}
- else if(CLOSURE_IS_AMBIENT_OCCLUSION(sc->type)) {
- eval += sc->weight;
- N += sd->N*fabsf(average(sc->weight));
- }
}
*N_ = (is_zero(N))? sd->N : normalize(N);
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 8df7c369799..c2a65dc9999 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -881,8 +881,6 @@ enum ShaderDataFlag {
SD_EXTINCTION = (1 << 6),
/* Shader has have volume phase (scatter) closure. */
SD_SCATTER = (1 << 7),
- /* Shader has AO closure. */
- SD_AO = (1 << 8),
/* Shader has transparent closure. */
SD_TRANSPARENT = (1 << 9),
/* BSDF requires LCG for evaluation. */
@@ -895,7 +893,6 @@ enum ShaderDataFlag {
SD_HOLDOUT |
SD_EXTINCTION |
SD_SCATTER |
- SD_AO |
SD_BSDF_NEEDS_LCG),
/* Shader flags. */
diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp
index 8fff19407d9..30a9e84c399 100644
--- a/intern/cycles/kernel/osl/background.cpp
+++ b/intern/cycles/kernel/osl/background.cpp
@@ -74,21 +74,6 @@ public:
}
};
-/// ambient occlusion closure
-///
-/// We only have a ambient occlusion closure for the shaders
-/// to return a color in ambient occlusion shaders. No methods,
-/// only the weight is taking into account
-///
-class AmbientOcclusionClosure : public CClosurePrimitive {
-public:
- void setup(ShaderData *sd, int /* path_flag */, float3 weight)
- {
- closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_AMBIENT_OCCLUSION_ID, weight);
- sd->flag |= SD_AO;
- }
-};
-
ClosureParam *closure_background_params()
{
static ClosureParam params[] = {
@@ -110,16 +95,5 @@ ClosureParam *closure_holdout_params()
CCLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure)
-ClosureParam *closure_ambient_occlusion_params()
-{
- static ClosureParam params[] = {
- CLOSURE_STRING_KEYPARAM(AmbientOcclusionClosure, label, "label"),
- CLOSURE_FINISH_PARAM(AmbientOcclusionClosure)
- };
- return params;
-}
-
-CCLOSURE_PREPARE(closure_ambient_occlusion_prepare, AmbientOcclusionClosure)
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index ee16ddaf0fd..6a1e52d7d16 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -310,8 +310,6 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
closure_background_params(), closure_background_prepare);
register_closure(ss, "holdout", id++,
closure_holdout_params(), closure_holdout_prepare);
- register_closure(ss, "ambient_occlusion", id++,
- closure_ambient_occlusion_params(), closure_ambient_occlusion_prepare);
register_closure(ss, "diffuse_ramp", id++,
closure_bsdf_diffuse_ramp_params(), closure_bsdf_diffuse_ramp_prepare);
register_closure(ss, "phong_ramp", id++,
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h
index dca7e74f154..68dfa9a4650 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/osl_closures.h
@@ -45,7 +45,6 @@ CCL_NAMESPACE_BEGIN
OSL::ClosureParam *closure_emission_params();
OSL::ClosureParam *closure_background_params();
OSL::ClosureParam *closure_holdout_params();
-OSL::ClosureParam *closure_ambient_occlusion_params();
OSL::ClosureParam *closure_bsdf_diffuse_ramp_params();
OSL::ClosureParam *closure_bsdf_phong_ramp_params();
OSL::ClosureParam *closure_bsdf_transparent_params();
@@ -65,7 +64,6 @@ OSL::ClosureParam *closure_bsdf_principled_clearcoat_params();
void closure_emission_prepare(OSL::RendererServices *, int id, void *data);
void closure_background_prepare(OSL::RendererServices *, int id, void *data);
void closure_holdout_prepare(OSL::RendererServices *, int id, void *data);
-void closure_ambient_occlusion_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_diffuse_ramp_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_transparent_prepare(OSL::RendererServices *, int id, void *data);
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 1aca54d2ad5..4b7a4cb34b7 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -125,6 +125,7 @@ ustring OSLRenderServices::u_u("u");
ustring OSLRenderServices::u_v("v");
ustring OSLRenderServices::u_empty;
ustring OSLRenderServices::u_at_bevel("@bevel");
+ustring OSLRenderServices::u_at_ao("@ao");
OSLRenderServices::OSLRenderServices()
{
@@ -957,6 +958,25 @@ bool OSLRenderServices::texture(ustring filename,
status = true;
}
}
+ else if(filename == u_at_ao) {
+ /* AO shader hack. */
+ PathState *state = sd->osl_path_state;
+ int num_samples = (int)s;
+ float radius = t;
+ float3 N = make_float3(dsdx, dtdx, dsdy);
+ int flags = 0;
+ if((int)dtdy) {
+ flags |= NODE_AO_INSIDE;
+ }
+ if((int)options.sblur) {
+ flags |= NODE_AO_ONLY_LOCAL;
+ }
+ if((int)options.tblur) {
+ flags |= NODE_AO_GLOBAL_RADIUS;
+ }
+ result[0] = svm_ao(kg, sd, N, state, radius, num_samples, flags);
+ status = true;
+ }
else if(filename[1] == 'l') {
/* IES light. */
int slot = atoi(filename.c_str() + 2);
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h
index d96048e26f2..1a40e2ece2b 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -182,6 +182,7 @@ public:
static ustring u_v;
static ustring u_empty;
static ustring u_at_bevel;
+ static ustring u_at_ao;
private:
KernelGlobals *kernel_globals;
diff --git a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
index 5f056122bbe..d7ffa3c1606 100644
--- a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
+++ b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2013 Blender Foundation
+ * Copyright 2011-2018 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,10 +17,19 @@
#include "stdosl.h"
shader node_ambient_occlusion(
- normal NormalIn = N,
- color Color = 0.8,
- output closure color AO = 0)
+ color ColorIn = color(0.8, 0.8, 0.8),
+ int samples = 8,
+ float Distance = 1.0,
+ normal Normal = N,
+ int inside = 0,
+ int only_local = 1,
+ output color ColorOut = color(0.8, 0.8, 0.8),
+ output float AO = 1.0)
{
- AO = Color * ambient_occlusion();
+ int global_radius = (Distance == 0.0 && !isconnected(Distance));
+
+ /* Abuse texture call with special @ao token. */
+ AO = texture("@ao", samples, Distance, Normal[0], Normal[1], Normal[2], inside, "sblur", only_local, "tblur", global_radius);
+ ColorOut = ColorIn * AO;
}
diff --git a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h
index 88919f47c7a..f14eecec2f2 100644
--- a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h
+++ b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h
@@ -149,7 +149,7 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
#ifdef __AO__
if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
/* ambient occlusion */
- if(kernel_data.integrator.use_ambient_occlusion || (sd->flag & SD_AO)) {
+ if(kernel_data.integrator.use_ambient_occlusion) {
enqueue_flag = 1;
}
}
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index ce2affe96c8..10d5fe0e42b 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -144,6 +144,7 @@ CCL_NAMESPACE_END
#include "kernel/svm/svm_color_util.h"
#include "kernel/svm/svm_math_util.h"
+#include "kernel/svm/svm_ao.h"
#include "kernel/svm/svm_attribute.h"
#include "kernel/svm/svm_gradient.h"
#include "kernel/svm/svm_blackbody.h"
@@ -324,9 +325,6 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a
case NODE_CLOSURE_HOLDOUT:
svm_node_closure_holdout(sd, stack, node);
break;
- case NODE_CLOSURE_AMBIENT_OCCLUSION:
- svm_node_closure_ambient_occlusion(sd, stack, node);
- break;
case NODE_FRESNEL:
svm_node_fresnel(sd, stack, node.y, node.z, node.w);
break;
@@ -480,6 +478,9 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a
case NODE_BEVEL:
svm_node_bevel(kg, sd, state, stack, node);
break;
+ case NODE_AMBIENT_OCCLUSION:
+ svm_node_ao(kg, sd, state, stack, node);
+ break;
# endif /* __SHADER_RAYTRACE__ */
#endif /* NODES_GROUP(NODE_GROUP_LEVEL_3) */
case NODE_END:
diff --git a/intern/cycles/kernel/svm/svm_ao.h b/intern/cycles/kernel/svm/svm_ao.h
new file mode 100644
index 00000000000..3f761627e2c
--- /dev/null
+++ b/intern/cycles/kernel/svm/svm_ao.h
@@ -0,0 +1,111 @@
+/*
+* Copyright 2011-2018 Blender Foundation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+CCL_NAMESPACE_BEGIN
+
+ccl_device_noinline float svm_ao(KernelGlobals *kg,
+ ShaderData *sd,
+ float3 N,
+ ccl_addr_space PathState *state,
+ float max_dist,
+ int num_samples,
+ int flags)
+{
+ if(flags & NODE_AO_GLOBAL_RADIUS) {
+ max_dist = kernel_data.background.ao_distance;
+ }
+
+ /* Early out if no sampling needed. */
+ if(max_dist <= 0.0f || num_samples < 1 || sd->object == OBJECT_NONE) {
+ return 0.0f;
+ }
+
+ if(flags & NODE_AO_INSIDE) {
+ N = -N;
+ }
+
+ float3 T, B;
+ make_orthonormals(N, &T, &B);
+
+ int unoccluded = 0;
+ for(int sample = 0; sample < num_samples; sample++) {
+ float disk_u, disk_v;
+ path_branched_rng_2D(kg, state->rng_hash, state, sample, num_samples,
+ PRNG_BEVEL_U, &disk_u, &disk_v);
+
+ float2 d = concentric_sample_disk(disk_u, disk_v);
+ float3 D = make_float3(d.x, d.y, safe_sqrtf(1.0f - dot(d, d)));
+
+ /* Create ray. */
+ Ray ray;
+ ray.P = ray_offset(sd->P, N);
+ ray.D = D.x*T + D.y*B + D.z*N;
+ ray.t = max_dist;
+ ray.time = sd->time;
+
+ if(flags & NODE_AO_ONLY_LOCAL) {
+ if(!scene_intersect_local(kg,
+ ray,
+ NULL,
+ sd->object,
+ NULL,
+ 0)) {
+ unoccluded++;
+ }
+ }
+ else {
+ Intersection isect;
+ if(!scene_intersect(kg,
+ ray,
+ PATH_RAY_SHADOW_OPAQUE,
+ &isect,
+ NULL,
+ 0.0f, 0.0f)) {
+ unoccluded++;
+ }
+ }
+ }
+
+ return ((float) unoccluded) / num_samples;
+}
+
+ccl_device void svm_node_ao(KernelGlobals *kg,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ float *stack,
+ uint4 node)
+{
+ uint flags, dist_offset, normal_offset, out_ao_offset;
+ decode_node_uchar4(node.y, &flags, &dist_offset, &normal_offset, &out_ao_offset);
+
+ uint color_offset, out_color_offset, samples;
+ decode_node_uchar4(node.z, &color_offset, &out_color_offset, &samples, NULL);
+
+ float dist = stack_load_float_default(stack, dist_offset, node.w);
+ float3 normal = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): sd->N;
+ float ao = svm_ao(kg, sd, normal, state, dist, samples, flags);
+
+ if (stack_valid(out_ao_offset)) {
+ stack_store_float(stack, out_ao_offset, ao);
+ }
+
+ if (stack_valid(out_color_offset)) {
+ float3 color = stack_load_float3(stack, color_offset);
+ stack_store_float3(stack, out_color_offset, ao * color);
+ }
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index 76464e37c66..f5b316c67da 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -996,24 +996,6 @@ ccl_device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 nod
sd->flag |= SD_HOLDOUT;
}
-ccl_device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, uint4 node)
-{
- uint mix_weight_offset = node.y;
-
- if(stack_valid(mix_weight_offset)) {
- float mix_weight = stack_load_float(stack, mix_weight_offset);
-
- if(mix_weight == 0.0f)
- return;
-
- closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_AMBIENT_OCCLUSION_ID, sd->svm_closure_weight * mix_weight);
- }
- else
- closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_AMBIENT_OCCLUSION_ID, sd->svm_closure_weight);
-
- sd->flag |= SD_AO;
-}
-
/* Closure Nodes */
ccl_device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight)
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index ac24d23ecd2..54db18cd7bb 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -124,7 +124,7 @@ typedef enum ShaderNodeType {
NODE_PARTICLE_INFO,
NODE_TEX_BRICK,
NODE_CLOSURE_SET_NORMAL,
- NODE_CLOSURE_AMBIENT_OCCLUSION,
+ NODE_AMBIENT_OCCLUSION,
NODE_TANGENT,
NODE_NORMAL_MAP,
NODE_HAIR_INFO,
@@ -386,6 +386,12 @@ typedef enum NodeTexVoxelSpace {
NODE_TEX_VOXEL_SPACE_WORLD = 1,
} NodeTexVoxelSpace;
+typedef enum NodeAO {
+ NODE_AO_ONLY_LOCAL = (1 << 0),
+ NODE_AO_INSIDE = (1 << 1),
+ NODE_AO_GLOBAL_RADIUS = (1 << 2),
+} NodeAO;
+
typedef enum ShaderType {
SHADER_TYPE_SURFACE,
SHADER_TYPE_VOLUME,
@@ -456,7 +462,6 @@ typedef enum ClosureType {
/* Other */
CLOSURE_HOLDOUT_ID,
- CLOSURE_AMBIENT_OCCLUSION_ID,
/* Volume */
CLOSURE_VOLUME_ID,
@@ -491,7 +496,6 @@ typedef enum ClosureType {
#define CLOSURE_IS_VOLUME_SCATTER(type) (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
#define CLOSURE_IS_VOLUME_ABSORPTION(type) (type == CLOSURE_VOLUME_ABSORPTION_ID)
#define CLOSURE_IS_HOLDOUT(type) (type == CLOSURE_HOLDOUT_ID)
-#define CLOSURE_IS_AMBIENT_OCCLUSION(type) (type == CLOSURE_AMBIENT_OCCLUSION_ID)
#define CLOSURE_IS_PHASE(type) (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
#define CLOSURE_IS_GLASS(type) (type >= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID && type <= CLOSURE_BSDF_SHARP_GLASS_ID)
#define CLOSURE_IS_PRINCIPLED(type) (type == CLOSURE_BSDF_PRINCIPLED_ID)
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 1ddc84848cc..59ac6257499 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -2792,11 +2792,17 @@ NODE_DEFINE(AmbientOcclusionNode)
{
NodeType* type = NodeType::add("ambient_occlusion", create, NodeType::SHADER);
- SOCKET_IN_NORMAL(normal_osl, "NormalIn", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
+ SOCKET_INT(samples, "Samples", 8);
+
SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
+ SOCKET_IN_FLOAT(distance, "Distance", 1.0f);
+ SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
- SOCKET_OUT_CLOSURE(AO, "AO");
+ SOCKET_BOOLEAN(inside, "Inside", false);
+ SOCKET_BOOLEAN(only_local, "Only Local", true);
+
+ SOCKET_OUT_COLOR(color, "Color");
+ SOCKET_OUT_FLOAT(ao, "AO");
return type;
}
@@ -2809,17 +2815,33 @@ AmbientOcclusionNode::AmbientOcclusionNode()
void AmbientOcclusionNode::compile(SVMCompiler& compiler)
{
ShaderInput *color_in = input("Color");
+ ShaderInput *distance_in = input("Distance");
+ ShaderInput *normal_in = input("Normal");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *ao_out = output("AO");
- if(color_in->link)
- compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
- else
- compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
+ int flags = (inside? NODE_AO_INSIDE : 0) | (only_local? NODE_AO_ONLY_LOCAL : 0);
- compiler.add_node(NODE_CLOSURE_AMBIENT_OCCLUSION, compiler.closure_mix_weight_offset());
+ if (!distance_in->link && distance == 0.0f) {
+ flags |= NODE_AO_GLOBAL_RADIUS;
+ }
+
+ compiler.add_node(NODE_AMBIENT_OCCLUSION,
+ compiler.encode_uchar4(flags,
+ compiler.stack_assign_if_linked(distance_in),
+ compiler.stack_assign_if_linked(normal_in),
+ compiler.stack_assign(ao_out)),
+ compiler.encode_uchar4(compiler.stack_assign(color_in),
+ compiler.stack_assign(color_out),
+ samples),
+ __float_as_uint(distance));
}
void AmbientOcclusionNode::compile(OSLCompiler& compiler)
{
+ compiler.parameter(this, "samples");
+ compiler.parameter(this, "inside");
+ compiler.parameter(this, "only_local");
compiler.add(this, "node_ambient_occlusion");
}
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index d1c7c9176e1..996c582d206 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -540,12 +540,16 @@ public:
SHADER_NODE_CLASS(AmbientOcclusionNode)
bool has_spatial_varying() { return true; }
- virtual int get_group() { return NODE_GROUP_LEVEL_1; }
- virtual ClosureType get_closure_type() { return CLOSURE_AMBIENT_OCCLUSION_ID; }
+ virtual int get_group() { return NODE_GROUP_LEVEL_3; }
+ virtual bool has_raytrace() { return true; }
- float3 normal_osl;
float3 color;
- float surface_mix_weight;
+ float distance;
+ float3 normal;
+ int samples;
+
+ bool only_local;
+ bool inside;
};
class VolumeNode : public ShaderNode {
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index d60710db4aa..713dbdafcc5 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -177,6 +177,7 @@ shader_node_categories = [
NodeItem("ShaderNodeNewGeometry"),
NodeItem("ShaderNodeWireframe"),
NodeItem("ShaderNodeBevel"),
+ NodeItem("ShaderNodeAmbientOcclusion"),
NodeItem("ShaderNodeObjectInfo"),
NodeItem("ShaderNodeHairInfo"),
NodeItem("ShaderNodeParticleInfo"),
@@ -209,7 +210,6 @@ shader_node_categories = [
NodeItem("ShaderNodeEmission", poll=object_eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeBsdfHair", poll=object_cycles_shader_nodes_poll),
NodeItem("ShaderNodeBackground", poll=world_shader_nodes_poll),
- NodeItem("ShaderNodeAmbientOcclusion", poll=object_eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeHoldout", poll=object_cycles_shader_nodes_poll),
NodeItem("ShaderNodeVolumeAbsorption", poll=eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeVolumeScatter", poll=eevee_cycles_shader_nodes_poll),
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index c3dbb362206..0dddb8e7b0b 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -28,7 +28,7 @@
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 280
-#define BLENDER_SUBVERSION 17
+#define BLENDER_SUBVERSION 18
/* Several breakages with 280, e.g. collections vs layers */
#define BLENDER_MINVERSION 280
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index ba714405cc0..7f5646eddc2 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -1665,7 +1665,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- {
+ if (!MAIN_VERSION_ATLEAST(bmain, 279, 4)) {
/* Fix for invalid state of screen due to bug in older versions. */
for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) {
for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index e7d4e4f33ae..0324161f6e1 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -1493,7 +1493,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- {
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 18)) {
if (!DNA_struct_elem_find(fd->filesdna, "Material", "float", "roughness")) {
for (Material *mat = bmain->mat.first; mat; mat = mat->id.next) {
if (mat->use_nodes) {
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
index ac1dd071a29..69c96eed3f3 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -479,4 +479,4 @@ void CLOSURE_NAME(
#ifdef CLOSURE_SUBSURFACE
#undef CLOSURE_SUBSURFACE
-#endif \ No newline at end of file
+#endif
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index db718da12ef..a162a863038 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -1080,6 +1080,13 @@ static void node_shader_buts_bevel(uiLayout *layout, bContext *UNUSED(C), Pointe
uiItemR(layout, ptr, "samples", 0, NULL, ICON_NONE);
}
+static void node_shader_buts_ambient_occlusion(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "samples", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "inside", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "only_local", 0, NULL, ICON_NONE);
+}
+
/* only once called */
static void node_shader_set_butfunc(bNodeType *ntype)
{
@@ -1210,6 +1217,9 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_BEVEL:
ntype->draw_buttons = node_shader_buts_bevel;
break;
+ case SH_NODE_AMBIENT_OCCLUSION:
+ ntype->draw_buttons = node_shader_buts_ambient_occlusion;
+ break;
}
}
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 1a07b26ff4d..3affacf5203 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -1203,14 +1203,12 @@ void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Cl
result.ssr_id = REFRACT_CLOSURE_FLAG;
}
-void node_ambient_occlusion(vec4 color, vec3 vN, out Closure result)
+void node_ambient_occlusion(vec4 color, float distance, vec3 normal, out vec4 result_color, out float result_ao)
{
vec3 bent_normal;
vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
- float final_ao = occlusion_compute(normalize(worldNormal), viewPosition, 1.0, rand, bent_normal);
- result = CLOSURE_DEFAULT;
- result.ssr_normal = normal_encode(vN, viewCameraVec);
- result.radiance = final_ao * color.rgb;
+ result_ao = occlusion_compute(normalize(normal), viewPosition, 1.0, rand, bent_normal);
+ result_color = result_ao * color;
}
#endif /* VOLUMETRICS */
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 7d8d1883100..4dd2579883b 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1043,6 +1043,9 @@ typedef struct NodeSunBeams {
#define SHD_SPACE_BLENDER_OBJECT 3
#define SHD_SPACE_BLENDER_WORLD 4
+#define SHD_AO_INSIDE 1
+#define SHD_AO_LOCAL 2
+
/* math node clamp */
#define SHD_MATH_CLAMP 1
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 3790dffec3b..56065df45bb 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -4398,6 +4398,27 @@ static void def_sh_bevel(StructRNA *srna)
RNA_def_property_update(prop, 0, "rna_Node_update");
}
+static void def_sh_ambient_occlusion(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "samples", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "custom1");
+ RNA_def_property_range(prop, 1, 128);
+ RNA_def_property_ui_text(prop, "Samples", "Number of rays to trace per shader evaluation");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "inside", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom2", SHD_AO_INSIDE);
+ RNA_def_property_ui_text(prop, "Inside", "Trace rays towards the inside of the object");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "only_local", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom2", SHD_AO_LOCAL);
+ RNA_def_property_ui_text(prop, "Only Local", "Only consider the object itself when computing AO");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+}
+
static void def_sh_subsurface(StructRNA *srna)
{
static const EnumPropertyItem prop_subsurface_falloff_items[] = {
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 437093a9cb3..ec4e88768de 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -71,7 +71,7 @@ DefNode( ShaderNode, SH_NODE_LAYER_WEIGHT, 0, "LA
DefNode( ShaderNode, SH_NODE_MIX_SHADER, 0, "MIX_SHADER", MixShader, "Mix Shader", "" )
DefNode( ShaderNode, SH_NODE_ADD_SHADER, 0, "ADD_SHADER", AddShader, "Add Shader", "" )
DefNode( ShaderNode, SH_NODE_ATTRIBUTE, def_sh_attribute, "ATTRIBUTE", Attribute, "Attribute", "" )
-DefNode( ShaderNode, SH_NODE_AMBIENT_OCCLUSION, 0, "AMBIENT_OCCLUSION", AmbientOcclusion, "Ambient Occlusion", "" )
+DefNode( ShaderNode, SH_NODE_AMBIENT_OCCLUSION, def_sh_ambient_occlusion,"AMBIENT_OCCLUSION", AmbientOcclusion, "Ambient Occlusion", "" )
DefNode( ShaderNode, SH_NODE_BACKGROUND, 0, "BACKGROUND", Background, "Background", "" )
DefNode( ShaderNode, SH_NODE_HOLDOUT, 0, "HOLDOUT", Holdout, "Holdout", "" )
DefNode( ShaderNode, SH_NODE_BSDF_ANISOTROPIC, def_anisotropic, "BSDF_ANISOTROPIC", BsdfAnisotropic, "Anisotropic BSDF", "" )
diff --git a/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.c b/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.c
index f835822469c..eae35b4cd22 100644
--- a/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.c
+++ b/source/blender/nodes/shader/nodes/node_shader_ambient_occlusion.c
@@ -31,17 +31,29 @@
static bNodeSocketTemplate sh_node_ambient_occlusion_in[] = {
{ SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 0, N_("Distance"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
+ { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
{ -1, 0, "" }
};
static bNodeSocketTemplate sh_node_ambient_occlusion_out[] = {
- { SOCK_SHADER, 0, N_("AO")},
+ { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 0, N_("AO"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
static int node_shader_gpu_ambient_occlusion(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- return GPU_stack_link(mat, node, "node_ambient_occlusion", in, out, GPU_builtin(GPU_VIEW_NORMAL));
+ if (!in[2].link)
+ GPU_link(mat, "world_normals_get", &in[2].link);
+
+ return GPU_stack_link(mat, node, "node_ambient_occlusion", in, out);
+}
+
+static void node_shader_init_ambient_occlusion(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->custom1 = 8; /* samples */
+ node->custom2 = SHD_AO_LOCAL;
}
/* node type definition */
@@ -49,10 +61,10 @@ void register_node_type_sh_ambient_occlusion(void)
{
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_AMBIENT_OCCLUSION, "Ambient Occlusion", NODE_CLASS_SHADER, 0);
+ sh_node_type_base(&ntype, SH_NODE_AMBIENT_OCCLUSION, "Ambient Occlusion", NODE_CLASS_INPUT, 0);
node_type_compatibility(&ntype, NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_ambient_occlusion_in, sh_node_ambient_occlusion_out);
- node_type_init(&ntype, NULL);
+ node_type_init(&ntype, node_shader_init_ambient_occlusion);
node_type_storage(&ntype, "", NULL, NULL);
node_type_gpu(&ntype, node_shader_gpu_ambient_occlusion);