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
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-10-20 19:09:36 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-10-20 19:09:36 +0400
commit73b79a6763f762ff2999622edd7c70aee69c18e9 (patch)
treec5dfc838e0f61db9c22bddb5e6c3f171953d2453 /intern
parente287c97fea74debb88b73de695b155fb172fa7c6 (diff)
Cycles OSL: light path, texture coordinate, bump and blended box mapping now up
to date and working.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/kernel_types.h4
-rw-r--r--intern/cycles/kernel/osl/nodes/CMakeLists.txt1
-rw-r--r--intern/cycles/kernel/osl/nodes/node_bump.osl19
-rw-r--r--intern/cycles/kernel/osl/nodes/node_image_texture.osl92
-rw-r--r--intern/cycles/kernel/osl/nodes/node_set_normal.osl28
-rw-r--r--intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl31
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp49
-rw-r--r--intern/cycles/kernel/svm/svm_image.h2
-rw-r--r--intern/cycles/render/nodes.cpp10
-rw-r--r--intern/cycles/render/osl.cpp20
10 files changed, 222 insertions, 34 deletions
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 94a55738f2b..c80adba1795 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -152,9 +152,7 @@ enum PathTraceDimension {
PRNG_BOUNCE_NUM = 8
};
-/* these flag values correspond exactly to OSL defaults, so be careful not to
- * change this, or if you do, set the "raytypes" shading system attribute with
- * your own new ray types and bitflag values.
+/* these flags values correspond to raytypes in osl.cpp, so keep them in sync!
*
* for ray visibility tests in BVH traversal, the upper 20 bits are used for
* layer visibility tests. */
diff --git a/intern/cycles/kernel/osl/nodes/CMakeLists.txt b/intern/cycles/kernel/osl/nodes/CMakeLists.txt
index 2c459fd714b..da5441f11e0 100644
--- a/intern/cycles/kernel/osl/nodes/CMakeLists.txt
+++ b/intern/cycles/kernel/osl/nodes/CMakeLists.txt
@@ -48,6 +48,7 @@ set(SRC_OSL
node_particle_info.osl
node_rgb_ramp.osl
node_separate_rgb.osl
+ node_set_normal.osl
node_sky_texture.osl
node_texture_coordinate.osl
node_translucent_bsdf.osl
diff --git a/intern/cycles/kernel/osl/nodes/node_bump.osl b/intern/cycles/kernel/osl/nodes/node_bump.osl
index dbc554e0a72..24db1b24458 100644
--- a/intern/cycles/kernel/osl/nodes/node_bump.osl
+++ b/intern/cycles/kernel/osl/nodes/node_bump.osl
@@ -22,25 +22,28 @@
* Morten S. Mikkelsen, 2010 */
surface node_bump(
+ normal NormalIn = N,
+ float Strength = 0.0,
float SampleCenter = 0.0,
float SampleX = 0.0,
float SampleY = 0.0,
output normal Normal = N)
{
- float dx = SampleX - SampleCenter;
- float dy = SampleY - SampleCenter;
-
+ /* get surface tangents from normal */
vector dPdx = Dx(P);
vector dPdy = Dy(P);
- vector Rx = cross(dPdy, N);
- vector Ry = cross(N, dPdx);
+ vector Rx = cross(dPdy, NormalIn);
+ vector Ry = cross(NormalIn, dPdx);
+ /* compute surface gradient and determinant */
float det = dot(dPdx, Rx);
- vector surfgrad = dx * Rx + dy * Ry;
+ vector surfgrad = (SampleX - SampleCenter) * Rx + (SampleY - SampleCenter) * Ry;
- surfgrad *= 0.1; /* todo: remove this factor */
+ surfgrad *= Strength;
+ float absdet = fabs(det);
- Normal = normalize(abs(det) * N - sign(det) * surfgrad);
+ /* compute and output perturbed normal */
+ Normal = normalize(absdet * NormalIn - sign(det) * surfgrad);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_image_texture.osl b/intern/cycles/kernel/osl/nodes/node_image_texture.osl
index e005f1f4245..2ca7e682a35 100644
--- a/intern/cycles/kernel/osl/nodes/node_image_texture.osl
+++ b/intern/cycles/kernel/osl/nodes/node_image_texture.osl
@@ -19,16 +19,102 @@
#include "stdosl.h"
#include "node_color.h"
+color image_texture_lookup(string filename, string color_space, float u, float v, output float Alpha)
+{
+ color rgb = (color)texture(filename, u, 1.0 - v, "wrap", "periodic", "alpha", Alpha);
+
+ if(color_space == "sRGB")
+ rgb = color_srgb_to_scene_linear(rgb);
+
+ return rgb;
+}
+
shader node_image_texture(
point Vector = P,
string filename = "",
string color_space = "sRGB",
+ string projection = "Flat",
+ float projection_blend = 0.0,
output color Color = color(0.0, 0.0, 0.0),
output float Alpha = 1.0)
{
- Color = (color)texture(filename, Vector[0], 1.0 - Vector[1], "wrap", "periodic", "alpha", Alpha);
+ if(projection == "Flat") {
+ Color = image_texture_lookup(filename, color_space, Vector[0], Vector[1], Alpha);
+ }
+ else if(projection == "Box") {
+ /* object space normal */
+ vector Nob = transform("world", "object", N);
+
+ /* project from direction vector to barycentric coordinates in triangles */
+ Nob = vector(fabs(Nob[0]), fabs(Nob[1]), fabs(Nob[2]));
+ Nob /= (Nob[0] + Nob[1] + Nob[2]);
+
+ /* basic idea is to think of this as a triangle, each corner representing
+ * one of the 3 faces of the cube. in the corners we have single textures,
+ * in between we blend between two textures, and in the middle we a blend
+ * between three textures.
+ *
+ * the Nxyz values are the barycentric coordinates in an equilateral
+ * triangle, which in case of blending, in the middle has a smaller
+ * equilateral triangle where 3 textures blend. this divides things into
+ * 7 zones, with an if() test for each zone */
+
+ vector weight = vector(0.0, 0.0, 0.0);
+ float blend = projection_blend;
+ float limit = 0.5*(1.0 + blend);
+
+ /* first test for corners with single texture */
+ if(Nob[0] > limit*(Nob[0] + Nob[1]) && Nob[0] > limit*(Nob[0] + Nob[2])) {
+ weight[0] = 1.0;
+ }
+ else if(Nob[1] > limit*(Nob[0] + Nob[1]) && Nob[1] > limit*(Nob[1] + Nob[2])) {
+ weight[1] = 1.0;
+ }
+ else if(Nob[2] > limit*(Nob[0] + Nob[2]) && Nob[2] > limit*(Nob[1] + Nob[2])) {
+ weight[2] = 1.0;
+ }
+ else if(blend > 0.0) {
+ /* in case of blending, test for mixes between two textures */
+ if(Nob[2] < (1.0 - limit)*(Nob[1] + Nob[0])) {
+ weight[0] = Nob[0]/(Nob[0] + Nob[1]);
+ weight[0] = clamp((weight[0] - 0.5*(1.0 - blend))/blend, 0.0, 1.0);
+ weight[1] = 1.0 - weight[0];
+ }
+ else if(Nob[0] < (1.0 - limit)*(Nob[1] + Nob[2])) {
+ weight[1] = Nob[1]/(Nob[1] + Nob[2]);
+ weight[1] = clamp((weight[1] - 0.5*(1.0 - blend))/blend, 0.0, 1.0);
+ weight[2] = 1.0 - weight[1];
+ }
+ else if(Nob[1] < (1.0 - limit)*(Nob[0] + Nob[2])) {
+ weight[0] = Nob[0]/(Nob[0] + Nob[2]);
+ weight[0] = clamp((weight[0] - 0.5*(1.0 - blend))/blend, 0.0, 1.0);
+ weight[2] = 1.0 - weight[0];
+ }
+ else {
+ /* last case, we have a mix between three */
+ weight[0] = ((2.0 - limit)*Nob[0] + (limit - 1.0))/(2.0*limit - 1.0);
+ weight[1] = ((2.0 - limit)*Nob[1] + (limit - 1.0))/(2.0*limit - 1.0);
+ weight[2] = ((2.0 - limit)*Nob[2] + (limit - 1.0))/(2.0*limit - 1.0);
+ }
+ }
+
+ Color = color(0.0, 0.0, 0.0);
+ Alpha = 0.0;
+
+ float tmp_alpha;
- if (color_space == "sRGB")
- Color = color_srgb_to_scene_linear(Color);
+ if(weight[0] > 0.0) {
+ Color += weight[0]*image_texture_lookup(filename, color_space, Vector[1], Vector[2], tmp_alpha);
+ Alpha += weight[0]*tmp_alpha;
+ }
+ if(weight[1] > 0.0) {
+ Color += weight[1]*image_texture_lookup(filename, color_space, Vector[0], Vector[2], tmp_alpha);
+ Alpha += weight[1]*tmp_alpha;
+ }
+ if(weight[2] > 0.0) {
+ Color += weight[2]*image_texture_lookup(filename, color_space, Vector[1], Vector[0], tmp_alpha);
+ Alpha += weight[2]*tmp_alpha;
+ }
+ }
}
diff --git a/intern/cycles/kernel/osl/nodes/node_set_normal.osl b/intern/cycles/kernel/osl/nodes/node_set_normal.osl
new file mode 100644
index 00000000000..27a4b2f5b8b
--- /dev/null
+++ b/intern/cycles/kernel/osl/nodes/node_set_normal.osl
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "stdosl.h"
+
+surface node_set_normal(
+ normal Direction = N,
+ output normal Normal = N)
+{
+ N = Direction;
+ Normal = Direction;
+}
+
diff --git a/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl b/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl
index 883135d2a43..405ed118c2b 100644
--- a/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl
+++ b/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl
@@ -19,8 +19,9 @@
#include "stdosl.h"
shader node_texture_coordinate(
- normal Normal = N,
+ normal NormalIn = N,
int is_background = 0,
+ int from_dupli = 0,
string bump_offset = "center",
output point Generated = point(0.0, 0.0, 0.0),
@@ -28,6 +29,7 @@ shader node_texture_coordinate(
output point Object = point(0.0, 0.0, 0.0),
output point Camera = point(0.0, 0.0, 0.0),
output point Window = point(0.0, 0.0, 0.0),
+ output normal Normal = normal(0.0, 0.0, 0.0),
output point Reflection = point(0.0, 0.0, 0.0))
{
if (is_background) {
@@ -37,27 +39,40 @@ shader node_texture_coordinate(
point Pcam = transform("camera", "world", point(0, 0, 0));
Camera = transform("camera", P + Pcam);
Window = transform("NDC", P + Pcam);
+ Normal = NormalIn;
Reflection = I;
}
else {
- getattribute("std::generated", Generated);
- getattribute("std::uv", UV);
+ if (from_dupli) {
+ getattribute("std::dupli_generated", Generated);
+ getattribute("std::dupli_uv", UV);
+ }
+ else {
+ getattribute("std::generated", Generated);
+ getattribute("std::uv", UV);
+ }
+
Object = transform("object", P);
Camera = transform("camera", P);
Window = transform("NDC", P);
- Reflection = reflect(I, Normal);
+ Normal = transform("world", "object", NormalIn);
+ Reflection = reflect(I, NormalIn);
}
if (bump_offset == "dx") {
- Generated += Dx(Generated);
- UV += Dx(UV);
+ if (!from_dupli) {
+ Generated += Dx(Generated);
+ UV += Dx(UV);
+ }
Object += Dx(Object);
Camera += Dx(Camera);
Window += Dx(Window);
}
else if (bump_offset == "dy") {
- Generated += Dy(Generated);
- UV += Dy(UV);
+ if (!from_dupli) {
+ Generated += Dy(Generated);
+ UV += Dy(UV);
+ }
Object += Dy(Object);
Camera += Dy(Camera);
Window += Dy(Window);
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 83574c91d31..7c415e22012 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -287,16 +287,26 @@ static void set_attribute_float3(float3 f[3], TypeDesc type, bool derivatives, v
if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor)
{
- float3 *fval = (float3 *)val;
- fval[0] = f[0];
+ float *fval = (float *)val;
+
+ fval[0] = f[0].x;
+ fval[1] = f[0].y;
+ fval[2] = f[0].z;
+
if (derivatives) {
- fval[1] = f[1];
- fval[2] = f[2];
+ fval[3] = f[1].x;
+ fval[4] = f[1].y;
+ fval[5] = f[1].z;
+
+ fval[6] = f[2].x;
+ fval[7] = f[2].y;
+ fval[8] = f[2].z;
}
}
else {
float *fval = (float *)val;
fval[0] = average(f[0]);
+
if (derivatives) {
fval[1] = average(f[1]);
fval[2] = average(f[2]);
@@ -309,16 +319,25 @@ static void set_attribute_float(float f[3], TypeDesc type, bool derivatives, voi
if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor)
{
- float3 *fval = (float3 *)val;
- fval[0] = make_float3(f[0], f[0], f[0]);
+ float *fval = (float *)val;
+ fval[0] = f[0];
+ fval[1] = f[1];
+ fval[2] = f[2];
+
if (derivatives) {
- fval[1] = make_float3(f[1], f[2], f[1]);
- fval[2] = make_float3(f[2], f[2], f[2]);
+ fval[3] = f[1];
+ fval[4] = f[1];
+ fval[5] = f[1];
+
+ fval[6] = f[2];
+ fval[7] = f[2];
+ fval[8] = f[2];
}
}
else {
float *fval = (float *)val;
fval[0] = f[0];
+
if (derivatives) {
fval[1] = f[1];
fval[2] = f[2];
@@ -377,6 +396,20 @@ static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ust
set_attribute_float(fval, type, derivatives, val);
return true;
}
+ else if (name == "std::dupli_generated") {
+ float3 fval[3];
+ fval[0] = object_dupli_generated(kg, sd->object);
+ fval[1] = fval[2] = make_float3(0.0, 0.0, 0.0); /* derivates set to 0 */
+ set_attribute_float3(fval, type, derivatives, val);
+ return true;
+ }
+ else if (name == "std::dupli_uv") {
+ float3 fval[3];
+ fval[0] = object_dupli_uv(kg, sd->object);
+ fval[1] = fval[2] = make_float3(0.0, 0.0, 0.0); /* derivates set to 0 */
+ set_attribute_float3(fval, type, derivatives, val);
+ return true;
+ }
else if (name == "std::material_index") {
float fval[3];
fval[0] = shader_pass_id(kg, sd);
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index 662419418e3..9877856fec2 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -265,7 +265,7 @@ __device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float *s
* between three textures.
*
* the Nxyz values are the barycentric coordinates in an equilateral
- * triangle, which in case of blending in the middle has a smaller
+ * triangle, which in case of blending, in the middle has a smaller
* equilateral triangle where 3 textures blend. this divides things into
* 7 zones, with an if() test for each zone */
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 76267e9d014..da0dbc12740 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -225,6 +225,8 @@ void ImageTextureNode::compile(OSLCompiler& compiler)
compiler.parameter("color_space", "Linear");
else
compiler.parameter("color_space", "sRGB");
+ compiler.parameter("projection", projection);
+ compiler.parameter("projection_blend", projection_blend);
compiler.add(this, "node_image_texture");
}
@@ -1701,7 +1703,7 @@ void GeometryNode::compile(OSLCompiler& compiler)
TextureCoordinateNode::TextureCoordinateNode()
: ShaderNode("texture_coordinate")
{
- add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
+ add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
add_output("Generated", SHADER_SOCKET_POINT);
add_output("Normal", SHADER_SOCKET_NORMAL);
add_output("UV", SHADER_SOCKET_POINT);
@@ -1823,6 +1825,8 @@ void TextureCoordinateNode::compile(OSLCompiler& compiler)
if(compiler.background)
compiler.parameter("is_background", true);
+
+ compiler.parameter("from_dupli", from_dupli);
compiler.add(this, "node_texture_coordinate");
}
@@ -2770,7 +2774,7 @@ BumpNode::BumpNode()
{
/* this input is used by the user, but after graph transform it is no longer
* used and moved to sampler center/x/y instead */
- add_input("Height", SHADER_SOCKET_NORMAL);
+ add_input("Height", SHADER_SOCKET_FLOAT);
add_input("SampleCenter", SHADER_SOCKET_FLOAT);
add_input("SampleX", SHADER_SOCKET_FLOAT);
@@ -2909,7 +2913,7 @@ void SetNormalNode::compile(SVMCompiler& compiler)
void SetNormalNode::compile(OSLCompiler& compiler)
{
- compiler.add(this, "set_normal");
+ compiler.add(this, "node_set_normal");
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index 21e6c7749b8..638bfa8634e 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -59,6 +59,22 @@ OSLShaderManager::OSLShaderManager()
//ss->attribute("statistics:level", 1);
ss->attribute("searchpath:shader", path_get("shader").c_str());
+ /* our own ray types */
+ static const char *raytypes[] = {
+ "camera", /* PATH_RAY_CAMERA */
+ "reflection", /* PATH_RAY_REFLECT */
+ "refraction", /* PATH_RAY_TRANSMIT */
+ "diffuse", /* PATH_RAY_DIFFUSE */
+ "glossy", /* PATH_RAY_GLOSSY */
+ "singular", /* PATH_RAY_SINGULAR */
+ "transparent", /* PATH_RAY_TRANSPARENT */
+ "shadow", /* PATH_RAY_SHADOW_OPAQUE */
+ "shadow", /* PATH_RAY_SHADOW_TRANSPARENT */
+ };
+
+ const int nraytypes = sizeof(raytypes)/sizeof(raytypes[0]);
+ ss->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes);
+
OSLShader::register_closures(ss);
}
@@ -209,6 +225,10 @@ bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input)
if(strcmp(input->name, "Normal") == 0)
return true;
}
+ else if(node->name == ustring("bump")) {
+ if(strcmp(input->name, "Height") == 0)
+ return true;
+ }
else if(current_type == SHADER_TYPE_DISPLACEMENT && input->link && input->link->parent->name == ustring("bump"))
return true;