forked from bartvdbraak/blender
Cycles: improve Anisotropic BSDF node, changing the Roughness U/V inputs to
Roughness, Anisotropy and Rotation. Also a fix for automatic tangents and OSL attribute handling. Meaning of new sockets explained in the documentation: http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/Shaders#Anisotropic
This commit is contained in:
parent
110a36a8ab
commit
2ba840652d
@ -141,7 +141,7 @@ static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_la
|
|||||||
|
|
||||||
/* create attribute */
|
/* create attribute */
|
||||||
/* todo: create float4 attribute for sign */
|
/* 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();
|
float3 *tangent = attr->data_float3();
|
||||||
|
|
||||||
for (int i = 0; i < nverts.size(); i++) {
|
for (int i = 0; i < nverts.size(); i++) {
|
||||||
|
@ -84,7 +84,8 @@ __device_inline Transform object_fetch_transform_motion_test(KernelGlobals *kg,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
|
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;
|
return tfm;
|
||||||
}
|
}
|
||||||
|
@ -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,
|
static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OSLGlobals::Attribute& attr,
|
||||||
const TypeDesc& type, bool derivatives, void *val)
|
const TypeDesc& type, bool derivatives, void *val)
|
||||||
{
|
{
|
||||||
if (attr.type == TypeDesc::TypeFloat) {
|
if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
|
||||||
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 ||
|
|
||||||
attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
|
attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
|
||||||
{
|
{
|
||||||
/* todo: this won't work when float3 has w component */
|
|
||||||
float3 fval[3];
|
float3 fval[3];
|
||||||
fval[0] = triangle_attribute_float3(kg, sd, attr.elem, attr.offset,
|
fval[0] = triangle_attribute_float3(kg, sd, attr.elem, attr.offset,
|
||||||
(derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
(derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||||
set_attribute_float3(fval, type, derivatives, val);
|
set_attribute_float3(fval, type, derivatives, val);
|
||||||
return true;
|
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;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_object_attribute(const OSLGlobals::Attribute& attr, bool derivatives, void *val)
|
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()) {
|
if (it != attribute_map.end()) {
|
||||||
const OSLGlobals::Attribute& attr = it->second;
|
const OSLGlobals::Attribute& attr = it->second;
|
||||||
|
|
||||||
if (attr.elem != ATTR_ELEMENT_VALUE) {
|
if (attr.elem != ATTR_ELEMENT_VALUE) {
|
||||||
/* triangle and vertex attributes */
|
/* triangle and vertex attributes */
|
||||||
if (tri != ~0)
|
if (tri != ~0)
|
||||||
@ -613,11 +613,11 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
|
|||||||
else {
|
else {
|
||||||
/* not found in attribute, check standard object info */
|
/* not found in attribute, check standard object info */
|
||||||
bool is_std_object_attribute = get_object_standard_attribute(kg, sd, name, type, derivatives, val);
|
bool is_std_object_attribute = get_object_standard_attribute(kg, sd, name, type, derivatives, val);
|
||||||
|
|
||||||
if (is_std_object_attribute)
|
if (is_std_object_attribute)
|
||||||
return true;
|
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;
|
return false;
|
||||||
|
@ -32,7 +32,6 @@ shader node_geometry(
|
|||||||
{
|
{
|
||||||
Position = P;
|
Position = P;
|
||||||
Normal = NormalIn;
|
Normal = NormalIn;
|
||||||
Tangent = normalize(dPdu);
|
|
||||||
TrueNormal = Ng;
|
TrueNormal = Ng;
|
||||||
Incoming = I;
|
Incoming = I;
|
||||||
Parametric = point(u, v, 0.0);
|
Parametric = point(u, v, 0.0);
|
||||||
@ -46,5 +45,28 @@ shader node_geometry(
|
|||||||
Position += Dy(Position);
|
Position += Dy(Position);
|
||||||
Parametric += Dy(Parametric);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,11 +20,32 @@
|
|||||||
|
|
||||||
shader node_ward_bsdf(
|
shader node_ward_bsdf(
|
||||||
color Color = color(0.8, 0.8, 0.8),
|
color Color = color(0.8, 0.8, 0.8),
|
||||||
float RoughnessU = 0.0,
|
float Roughness = 0.0,
|
||||||
float RoughnessV = 0.0,
|
float Anisotropy = 0.0,
|
||||||
|
float Rotation = 0.0,
|
||||||
normal Normal = N,
|
normal Normal = N,
|
||||||
|
normal Tangent = normalize(dPdu),
|
||||||
output closure color BSDF = diffuse(Normal))
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
sc->T = stack_load_float3(stack, data_node.z);
|
||||||
svm_node_closure_set_mix_weight(sc, mix_weight);
|
svm_node_closure_set_mix_weight(sc, mix_weight);
|
||||||
|
|
||||||
sc->data0 = param1;
|
/* rotate tangent */
|
||||||
sc->data1 = param2;
|
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);
|
sd->flag |= bsdf_ward_setup(sc);
|
||||||
break;
|
break;
|
||||||
|
@ -20,22 +20,6 @@ CCL_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
/* Geometry Node */
|
/* 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)
|
__device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
|
||||||
{
|
{
|
||||||
float3 data;
|
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;
|
case NODE_GEOM_N: data = sd->N; break;
|
||||||
#ifdef __DPDU__
|
#ifdef __DPDU__
|
||||||
case NODE_GEOM_T: {
|
case NODE_GEOM_T: {
|
||||||
if(sd->object != ~0) {
|
/* first try to get tangent attribute */
|
||||||
int attr_offset = find_attribute(kg, sd, ATTR_STD_TANGENT);
|
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) {
|
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);
|
object_normal_transform(kg, sd, &data);
|
||||||
|
data = cross(sd->N, normalize(cross(data, sd->N)));;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED);
|
/* otherwise use surface derivatives */
|
||||||
|
data = normalize(sd->dPdu);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
data = normalize(sd->dPdu);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -355,6 +355,9 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
|
|||||||
|
|
||||||
/* set object attributes */
|
/* set object attributes */
|
||||||
foreach(AttributeRequest& req, attributes.requests) {
|
foreach(AttributeRequest& req, attributes.requests) {
|
||||||
|
if(req.element == ATTR_ELEMENT_NONE)
|
||||||
|
continue;
|
||||||
|
|
||||||
OSLGlobals::Attribute osl_attr;
|
OSLGlobals::Attribute osl_attr;
|
||||||
|
|
||||||
osl_attr.elem = req.element;
|
osl_attr.elem = req.element;
|
||||||
|
@ -1214,7 +1214,7 @@ BsdfNode::BsdfNode()
|
|||||||
add_output("BSDF", SHADER_SOCKET_CLOSURE);
|
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 *color_in = input("Color");
|
||||||
ShaderInput *normal_in = input("Normal");
|
ShaderInput *normal_in = input("Normal");
|
||||||
@ -1231,6 +1231,14 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *
|
|||||||
compiler.stack_assign(param1);
|
compiler.stack_assign(param1);
|
||||||
if(param2)
|
if(param2)
|
||||||
compiler.stack_assign(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.add_node(NODE_CLOSURE_BSDF,
|
||||||
compiler.encode_uchar4(closure,
|
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((param1)? param1->value.x: 0.0f),
|
||||||
__float_as_int((param2)? param2->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) {
|
||||||
if(tangent_in->link)
|
compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset, tangent_in->stack_offset,
|
||||||
compiler.stack_assign(tangent_in);
|
(param3)? param3->stack_offset: SVM_STACK_INVALID);
|
||||||
|
|
||||||
compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset, tangent_in->stack_offset);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset);
|
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("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT);
|
||||||
|
|
||||||
add_input("Roughness U", SHADER_SOCKET_FLOAT, 0.2f);
|
add_input("Roughness", SHADER_SOCKET_FLOAT, 0.2f);
|
||||||
add_input("Roughness V", 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)
|
void WardBsdfNode::attributes(AttributeRequestSet *attributes)
|
||||||
@ -1290,7 +1294,7 @@ void WardBsdfNode::attributes(AttributeRequestSet *attributes)
|
|||||||
|
|
||||||
void WardBsdfNode::compile(SVMCompiler& compiler)
|
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)
|
void WardBsdfNode::compile(OSLCompiler& compiler)
|
||||||
|
@ -193,7 +193,7 @@ class BsdfNode : public ShaderNode {
|
|||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(BsdfNode)
|
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;
|
ClosureType closure;
|
||||||
};
|
};
|
||||||
|
@ -30,6 +30,8 @@ const char *attribute_standard_name(AttributeStandard std)
|
|||||||
return "uv";
|
return "uv";
|
||||||
else if(std == ATTR_STD_GENERATED)
|
else if(std == ATTR_STD_GENERATED)
|
||||||
return "generated";
|
return "generated";
|
||||||
|
else if(std == ATTR_STD_TANGENT)
|
||||||
|
return "tangent";
|
||||||
else if(std == ATTR_STD_POSITION_UNDEFORMED)
|
else if(std == ATTR_STD_POSITION_UNDEFORMED)
|
||||||
return "undeformed";
|
return "undeformed";
|
||||||
else if(std == ATTR_STD_POSITION_UNDISPLACED)
|
else if(std == ATTR_STD_POSITION_UNDISPLACED)
|
||||||
|
@ -1069,6 +1069,29 @@ __device_inline float3 safe_divide_color(float3 a, float3 b)
|
|||||||
return make_float3(x, y, z);
|
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
|
CCL_NAMESPACE_END
|
||||||
|
|
||||||
#endif /* __UTIL_MATH_H__ */
|
#endif /* __UTIL_MATH_H__ */
|
||||||
|
@ -2013,7 +2013,7 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result)
|
|||||||
result = vec4(L*color.rgb, 1.0);
|
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);
|
node_bsdf_diffuse(color, 0.0, N, result);
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,9 @@
|
|||||||
|
|
||||||
static bNodeSocketTemplate sh_node_bsdf_anisotropic_in[] = {
|
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_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"), 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_("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_("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},
|
{ SOCK_VECTOR, 1, N_("Tangent"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
|
||||||
{ -1, 0, "" }
|
{ -1, 0, "" }
|
||||||
|
Loading…
Reference in New Issue
Block a user