Hi All,
One of the immediate set backs to switching from Blender Internal to 3Delight or any Renderman based exporter is the immediate lack of the basics. All of a sudden it becomes a chore to get an image map to work…or to make specularity appear on a surface. All these things we take for granite are really just small pieces of code used to calculate the surface.
So I thought having a Renderman Shader that emulates Blender Internal would be nice thing for noobs or anyone who just wants to get a quick render out of 3Delight and not necessarily dig into shader writing.
This what I have so far…
/*
Blender Surface Shader.
Version 1.0
By Atom 09-12-2011
An attempt at emulating the Blender material as a Renderman shader.
The goal is to offer up at least one image slot
for each main aspect of shading that we take for granted as Blender users.
Option Supported:
DIFFUSE color.
SPECULAR color.
SPECULAR ROUGHNESS.
DIFFUSE IMAGE MAP.
ALPHA IMAGE MAP.
SPECULAR IMAGE MAP.
BUMP MAP.
REFLECTION MAP.
ROTATE TEXTURE BY 90 degree increments. (90,180,270,0)
*/
surface blender_surface (
uniform float flip_S=0;
uniform float flip_T=0;
uniform float swap_ST=0;
string diffuse_map_name = "";
string alpha_map_name = "";
uniform float diffuse_use_alpha = 1.0;
uniform float diffuse_intensity = 0.81;
string bump_map_name = "";
uniform float bump_scale = 1;
string reflection_ENV_map_name = "";
uniform float reflection_intensity = 0.311;
uniform float Ka = 0.5;
uniform float Kd = 0.85;
uniform float Ks = 1;
uniform float roughness = 0.2;
string specularity_map_name = "";
color specular_color = color(1,1,1);
uniform float specular_intensity = 0.311;
)
{
// Offer up a simple way to roate image by 90 degrees via flipping s and t.
float ss = s, tt = t;
if (swap_ST == 1) {
ss = t;
tt = s;
}
if (flip_S == 1)
ss = 1-ss;
if (flip_T == 1)
tt = 1-tt;
// DIFFUSE.
Ci = Oi * Cs; // Default the diffuse color.
Oi = Os; // Default alpha.
// Begin analysis of what maps need to be included in our surface calculation.
float result_type = 0;
if (diffuse_map_name != "") {
if (diffuse_use_alpha == 1)
// Use the alpha from the diffuse map.
result_type = 2;
else
result_type = 1;
}
if (alpha_map_name != "") {
if (diffuse_map_name == "")
result_type = 3;
else
result_type = 4;
}
// Generate the surface color and opacity based upon our result_type.
color diffuse_color = color(0,0,0);
color alpha_color = color(0,0,0);
color specular_color = color(0,0,0);
color reflection_color = color(0,0,0);
if (result_type == 1) {
// Diffuse map only, no Alpha implied.
diffuse_color = diffuse_intensity * color texture(diffuse_map_name, ss, tt);
}
if (result_type == 2) {
// Diffuse map with an alpha channel from the same diffuse map.
color Ct = diffuse_intensity * color texture(diffuse_map_name,ss,tt);
float a = float texture(diffuse_map_name[3],ss,tt);
//Ci = Oi * (Cs + a*(Ct-Cs));
diffuse_color = Cs + a * (Ct-Cs);
}
if (result_type == 3) {
// Alpha map with no diffuse map supplied, just use diffuse color.
// Deterimine if alpha map is 3 or 4 channels?
// i.e. Do I nned to convert RGB intensity to Alpha or is the 4th channel available?
float a = float texture(alpha_map_name[3],ss,tt);
//Ci = Oi * (Cs + a);
diffuse_color = Cs + a;
}
if (result_type ==4) {
// Use the diffuse map for color and alpha map for alpha.
color Ct = diffuse_intensity * color texture(diffuse_map_name,ss,tt);
float a = float texture(alpha_map_name[3],ss,tt);
//Ci = Oi * (Cs + a*(Ct-Cs));
diffuse_color = Cs + a * (Ct-Cs);
}
// SPECULAR.
if(specularity_map_name != "") {
specular_color = specular_intensity * color texture(specularity_map_name, ss, tt);
}
// BUMP.
normal Nf;
vector V, D;
point PP;
float bmp;
if( bump_map_name != "" ) {
bmp = bump_scale * float texture( bump_map_name, ss, tt);
PP = transform("shader", P);
Nf = normalize( ntransform("shader", N) );
PP += bmp * Nf;
PP = transform("shader", "current", PP);
Nf = calculatenormal(PP);
/*
if (abUseNormals == 1) {
normal deltaN = normalize(N) - normalize(Ng);
Nf = normalize(Nf) + deltaN;
}
if( abDoDisplacement == 1.0 )
P = PP;
*/
} else {
Nf = N;
}
Nf = faceforward( normalize(Nf), I );
V = -normalize(I);
// REFLECTION.
if( reflection_ENV_map_name != "" )
{
D = reflect(-V, Nf);
D = vtransform("worldspace", D);
/*
if( abReflectionUp != 0 )
{
D = vector(-zcomp(D), xcomp(D), ycomp(D));
}
*/
reflection_color = reflection_intensity * color environment(reflection_ENV_map_name, D);
}
else
reflection_color = color(0);
// Final calculation.
Ci = diffuse_color * (ambient() + diffuse(Nf)) + (specular_color * (specular(Nf, V, roughness) + reflection_color));
}
Here is the command I used to compile the above shader on Windows.
shaderdl.exe "blender_surface.sl"