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:
-rw-r--r--intern/cycles/blender/blender_mesh.cpp2
-rw-r--r--intern/cycles/kernel/kernel_object.h3
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp28
-rw-r--r--intern/cycles/kernel/shaders/node_geometry.osl24
-rw-r--r--intern/cycles/kernel/shaders/node_ward_bsdf.osl27
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h20
-rw-r--r--intern/cycles/kernel/svm/svm_geometry.h47
-rw-r--r--intern/cycles/render/mesh.cpp3
-rw-r--r--intern/cycles/render/nodes.cpp26
-rw-r--r--intern/cycles/render/nodes.h2
-rw-r--r--intern/cycles/util/util_attribute.cpp2
-rw-r--r--intern/cycles/util/util_math.h23
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c5
14 files changed, 147 insertions, 67 deletions
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index b1b1a638219..a0feec90203 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -141,7 +141,7 @@ static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_la
/* create attribute */
/* todo: create float4 attribute for sign */
- Attribute *attr = mesh->attributes.add(ATTR_STD_TANGENT, ustring("Tangent"));
+ Attribute *attr = mesh->attributes.add(ATTR_STD_TANGENT, ustring("tangent"));
float3 *tangent = attr->data_float3();
for (int i = 0; i < nverts.size(); i++) {
diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h
index 2fa9443766e..112bfbb86b5 100644
--- a/intern/cycles/kernel/kernel_object.h
+++ b/intern/cycles/kernel/kernel_object.h
@@ -84,7 +84,8 @@ __device_inline Transform object_fetch_transform_motion_test(KernelGlobals *kg,
}
else {
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
- *itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ if(itfm)
+ *itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
return tfm;
}
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index ade085c795d..ac26fc1c18d 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -393,25 +393,25 @@ static bool set_attribute_float3_3(float3 P[3], TypeDesc type, bool derivatives,
static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OSLGlobals::Attribute& attr,
const TypeDesc& type, bool derivatives, void *val)
{
- if (attr.type == TypeDesc::TypeFloat) {
- float fval[3];
- fval[0] = triangle_attribute_float(kg, sd, attr.elem, attr.offset,
- (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
- set_attribute_float(fval, type, derivatives, val);
- return true;
- }
- else if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
+ if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
{
- /* todo: this won't work when float3 has w component */
float3 fval[3];
fval[0] = triangle_attribute_float3(kg, sd, attr.elem, attr.offset,
(derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
set_attribute_float3(fval, type, derivatives, val);
return true;
}
- else
+ else if (attr.type == TypeDesc::TypeFloat) {
+ float fval[3];
+ fval[0] = triangle_attribute_float(kg, sd, attr.elem, attr.offset,
+ (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ set_attribute_float(fval, type, derivatives, val);
+ return true;
+ }
+ else {
return false;
+ }
}
static void get_object_attribute(const OSLGlobals::Attribute& attr, bool derivatives, void *val)
@@ -598,7 +598,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
if (it != attribute_map.end()) {
const OSLGlobals::Attribute& attr = it->second;
-
+
if (attr.elem != ATTR_ELEMENT_VALUE) {
/* triangle and vertex attributes */
if (tri != ~0)
@@ -613,11 +613,11 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
else {
/* not found in attribute, check standard object info */
bool is_std_object_attribute = get_object_standard_attribute(kg, sd, name, type, derivatives, val);
+
if (is_std_object_attribute)
return true;
- else {
- return get_background_attribute(kg, sd, name, type, derivatives, val);
- }
+
+ return get_background_attribute(kg, sd, name, type, derivatives, val);
}
return false;
diff --git a/intern/cycles/kernel/shaders/node_geometry.osl b/intern/cycles/kernel/shaders/node_geometry.osl
index a3831cbec9c..953c5d1fa2b 100644
--- a/intern/cycles/kernel/shaders/node_geometry.osl
+++ b/intern/cycles/kernel/shaders/node_geometry.osl
@@ -32,7 +32,6 @@ shader node_geometry(
{
Position = P;
Normal = NormalIn;
- Tangent = normalize(dPdu);
TrueNormal = Ng;
Incoming = I;
Parametric = point(u, v, 0.0);
@@ -46,5 +45,28 @@ shader node_geometry(
Position += Dy(Position);
Parametric += Dy(Parametric);
}
+
+ /* first try to get tangent attribute */
+ vector T;
+
+ if (getattribute("geom:tangent", T)) {
+ /* ensure orthogonal and normalized (interpolation breaks it) */
+ T = transform("object", "world", T);
+ Tangent = cross(Normal, normalize(cross(T, Normal)));
+ }
+ else {
+ point generated;
+
+ /* try to create spherical tangent from generated coordinates */
+ if (getattribute("geom:generated", generated)) {
+ T = vector(-(generated[1] - 0.5), (generated[0] - 0.5), 0.0);
+ T = transform("object", "world", T);
+ Tangent = cross(Normal, normalize(cross(T, Normal)));
+ }
+ else {
+ /* otherwise use surface derivatives */
+ Tangent = normalize(dPdu);
+ }
+ }
}
diff --git a/intern/cycles/kernel/shaders/node_ward_bsdf.osl b/intern/cycles/kernel/shaders/node_ward_bsdf.osl
index e204be123b8..03a0477038e 100644
--- a/intern/cycles/kernel/shaders/node_ward_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_ward_bsdf.osl
@@ -20,11 +20,32 @@
shader node_ward_bsdf(
color Color = color(0.8, 0.8, 0.8),
- float RoughnessU = 0.0,
- float RoughnessV = 0.0,
+ float Roughness = 0.0,
+ float Anisotropy = 0.0,
+ float Rotation = 0.0,
normal Normal = N,
+ normal Tangent = normalize(dPdu),
output closure color BSDF = diffuse(Normal))
{
- BSDF = Color * ward(Normal, normalize(dPdu), RoughnessU, RoughnessV);
+ /* rotate tangent around normal */
+ vector T = Tangent;
+
+ if(Rotation != 0.0)
+ T = rotate(T, Rotation*2.0*M_PI, point(0.0, 0.0, 0.0), Normal);
+
+ /* compute roughness */
+ float RoughnessU, RoughnessV;
+ float aniso = clamp(Anisotropy, -0.99, 0.99);
+
+ if(aniso < 0.0) {
+ RoughnessU = Roughness*(1.0 + aniso);
+ RoughnessV = Roughness/(1.0 + aniso);
+ }
+ else {
+ RoughnessU = Roughness/(1.0 - aniso);
+ RoughnessV = Roughness*(1.0 - aniso);
+ }
+
+ BSDF = Color * ward(Normal, T, RoughnessU, RoughnessV);
}
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index b72fad26a1f..11ce3b7c5d1 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -211,8 +211,24 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
sc->T = stack_load_float3(stack, data_node.z);
svm_node_closure_set_mix_weight(sc, mix_weight);
- sc->data0 = param1;
- sc->data1 = param2;
+ /* rotate tangent */
+ float rotation = stack_load_float(stack, data_node.w);
+
+ if(rotation != 0.0f)
+ sc->T = rotate_around_axis(sc->T, sc->N, rotation * 2.0f * M_PI_F);
+
+ /* compute roughness */
+ float roughness = param1;
+ float anisotropy = clamp(param2, -0.99f, 0.99f);
+
+ if(anisotropy < 0.0f) {
+ sc->data0 = roughness*(1.0f + anisotropy);
+ sc->data1 = roughness/(1.0f + anisotropy);
+ }
+ else {
+ sc->data0 = roughness/(1.0f - anisotropy);
+ sc->data1 = roughness*(1.0f - anisotropy);
+ }
sd->flag |= bsdf_ward_setup(sc);
break;
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h
index 501fed95002..8e772f849c7 100644
--- a/intern/cycles/kernel/svm/svm_geometry.h
+++ b/intern/cycles/kernel/svm/svm_geometry.h
@@ -20,22 +20,6 @@ CCL_NAMESPACE_BEGIN
/* Geometry Node */
-__device_inline float3 svm_tangent_from_generated(float3 P)
-{
- float length = len(P);
-
- if(length == 0.0f)
- return make_float3(0.0f, 0.0f, 0.0f);
-
- float u = 0.0f;
- if(!(P.x == 0.0f && P.y == 0.0f))
- u = (1.0f - atan2f(P.x, P.y))/(2.0f*M_PI_F);
-
- float v = 1.0f - acosf(clamp(P.z/length, -1.0f, 1.0f))/M_PI_F;
-
- return make_float3(u, v, 0.0f);
-}
-
__device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
{
float3 data;
@@ -45,27 +29,30 @@ __device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack,
case NODE_GEOM_N: data = sd->N; break;
#ifdef __DPDU__
case NODE_GEOM_T: {
- if(sd->object != ~0) {
- int attr_offset = find_attribute(kg, sd, ATTR_STD_TANGENT);
+ /* first try to get tangent attribute */
+ int attr_offset = (sd->object != ~0)? find_attribute(kg, sd, ATTR_STD_TANGENT): ATTR_STD_NOT_FOUND;
+
+ if(attr_offset != ATTR_STD_NOT_FOUND) {
+ /* ensure orthogonal and normalized (interpolation breaks it) */
+ data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, attr_offset, NULL, NULL);
+ object_normal_transform(kg, sd, &data);
+ data = cross(sd->N, normalize(cross(data, sd->N)));;
+ }
+ else {
+ /* try to create spherical tangent from generated coordinates */
+ int attr_offset = (sd->object != ~0)? find_attribute(kg, sd, ATTR_STD_GENERATED): ATTR_STD_NOT_FOUND;
if(attr_offset != ATTR_STD_NOT_FOUND) {
- data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, attr_offset, NULL, NULL);
+ data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL);
+ data = make_float3(-(data.y - 0.5), (data.x - 0.5), 0.0f);
object_normal_transform(kg, sd, &data);
+ data = cross(sd->N, normalize(cross(data, sd->N)));;
}
else {
- attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED);
-
- if(attr_offset != ATTR_STD_NOT_FOUND) {
- data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL);
- svm_tangent_from_generated(data);
- object_normal_transform(kg, sd, &data);
- }
- else
- data = normalize(sd->dPdu);
+ /* otherwise use surface derivatives */
+ data = normalize(sd->dPdu);
}
}
- else
- data = normalize(sd->dPdu);
break;
}
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 13c06a922cc..14f23992664 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -355,6 +355,9 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
/* set object attributes */
foreach(AttributeRequest& req, attributes.requests) {
+ if(req.element == ATTR_ELEMENT_NONE)
+ continue;
+
OSLGlobals::Attribute osl_attr;
osl_attr.elem = req.element;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 42ab3fe17aa..d7bf71337f6 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1214,7 +1214,7 @@ BsdfNode::BsdfNode()
add_output("BSDF", SHADER_SOCKET_CLOSURE);
}
-void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2)
+void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3)
{
ShaderInput *color_in = input("Color");
ShaderInput *normal_in = input("Normal");
@@ -1231,6 +1231,14 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *
compiler.stack_assign(param1);
if(param2)
compiler.stack_assign(param2);
+ if(param3)
+ compiler.stack_assign(param3);
+
+ if(normal_in->link)
+ compiler.stack_assign(normal_in);
+
+ if(tangent_in && tangent_in->link)
+ compiler.stack_assign(tangent_in);
compiler.add_node(NODE_CLOSURE_BSDF,
compiler.encode_uchar4(closure,
@@ -1240,14 +1248,9 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *
__float_as_int((param1)? param1->value.x: 0.0f),
__float_as_int((param2)? param2->value.x: 0.0f));
- if(normal_in->link)
- compiler.stack_assign(normal_in);
-
if(tangent_in) {
- if(tangent_in->link)
- compiler.stack_assign(tangent_in);
-
- compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset, tangent_in->stack_offset);
+ compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset, tangent_in->stack_offset,
+ (param3)? param3->stack_offset: SVM_STACK_INVALID);
}
else {
compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset);
@@ -1272,8 +1275,9 @@ WardBsdfNode::WardBsdfNode()
add_input("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT);
- add_input("Roughness U", SHADER_SOCKET_FLOAT, 0.2f);
- add_input("Roughness V", SHADER_SOCKET_FLOAT, 0.2f);
+ add_input("Roughness", SHADER_SOCKET_FLOAT, 0.2f);
+ add_input("Anisotropy", SHADER_SOCKET_FLOAT, 0.5f);
+ add_input("Rotation", SHADER_SOCKET_FLOAT, 0.0f);
}
void WardBsdfNode::attributes(AttributeRequestSet *attributes)
@@ -1290,7 +1294,7 @@ void WardBsdfNode::attributes(AttributeRequestSet *attributes)
void WardBsdfNode::compile(SVMCompiler& compiler)
{
- BsdfNode::compile(compiler, input("Roughness U"), input("Roughness V"));
+ BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation"));
}
void WardBsdfNode::compile(OSLCompiler& compiler)
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 0508bf6b266..d90cae5f668 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -193,7 +193,7 @@ class BsdfNode : public ShaderNode {
public:
SHADER_NODE_CLASS(BsdfNode)
- void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2);
+ void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3 = NULL);
ClosureType closure;
};
diff --git a/intern/cycles/util/util_attribute.cpp b/intern/cycles/util/util_attribute.cpp
index 3a1c2b6f332..163a92902f3 100644
--- a/intern/cycles/util/util_attribute.cpp
+++ b/intern/cycles/util/util_attribute.cpp
@@ -30,6 +30,8 @@ const char *attribute_standard_name(AttributeStandard std)
return "uv";
else if(std == ATTR_STD_GENERATED)
return "generated";
+ else if(std == ATTR_STD_TANGENT)
+ return "tangent";
else if(std == ATTR_STD_POSITION_UNDEFORMED)
return "undeformed";
else if(std == ATTR_STD_POSITION_UNDISPLACED)
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 0b6f020ade5..70adee4385b 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -1069,6 +1069,29 @@ __device_inline float3 safe_divide_color(float3 a, float3 b)
return make_float3(x, y, z);
}
+/* Rotation of point around axis and angle */
+
+__device_inline float3 rotate_around_axis(float3 p, float3 axis, float angle)
+{
+ float costheta = cosf(angle);
+ float sintheta = sinf(angle);
+ float3 r;
+
+ r.x = ((costheta + (1 - costheta) * axis.x * axis.x) * p.x) +
+ (((1 - costheta) * axis.x * axis.y - axis.z * sintheta) * p.y) +
+ (((1 - costheta) * axis.x * axis.z + axis.y * sintheta) * p.z);
+
+ r.y = (((1 - costheta) * axis.x * axis.y + axis.z * sintheta) * p.x) +
+ ((costheta + (1 - costheta) * axis.y * axis.y) * p.y) +
+ (((1 - costheta) * axis.y * axis.z - axis.x * sintheta) * p.z);
+
+ r.z = (((1 - costheta) * axis.x * axis.z - axis.y * sintheta) * p.x) +
+ (((1 - costheta) * axis.y * axis.z + axis.x * sintheta) * p.y) +
+ ((costheta + (1 - costheta) * axis.z * axis.z) * p.z);
+
+ return r;
+}
+
CCL_NAMESPACE_END
#endif /* __UTIL_MATH_H__ */
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 5713c5e88a2..b930058864c 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -2013,7 +2013,7 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result)
result = vec4(L*color.rgb, 1.0);
}
-void node_bsdf_anisotropic(vec4 color, float roughnessU, float roughnessV, vec3 N, vec3 T, out vec4 result)
+void node_bsdf_anisotropic(vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T, out vec4 result)
{
node_bsdf_diffuse(color, 0.0, N, result);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c
index 7e023ff8547..71780e9316e 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c
@@ -31,8 +31,9 @@
static bNodeSocketTemplate sh_node_bsdf_anisotropic_in[] = {
{ SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 1, N_("Roughness U"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 1, N_("Roughness V"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Roughness"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Anisotropy"), 0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Rotation"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
{ SOCK_VECTOR, 1, N_("Tangent"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
{ -1, 0, "" }