forked from bartvdbraak/blender
Cycles OSL: light path, texture coordinate, bump and blended box mapping now up
to date and working.
This commit is contained in:
parent
e287c97fea
commit
73b79a6763
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
if (color_space == "sRGB")
|
||||
Color = color_srgb_to_scene_linear(Color);
|
||||
/* 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(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
28
intern/cycles/kernel/osl/nodes/node_set_normal.osl
Normal file
28
intern/cycles/kernel/osl/nodes/node_set_normal.osl
Normal file
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user