Earlier last month I had come up with the shader rusty_metal.sl, then within the last week or so I realized that there would be a TON of other surfaces that could use some rust aside from just metal. Such as railings, pipes and the like. What if those materials had a paint surface instead of bare metal, that was my thought. So I went into the shaderman file and did some changes and now I have rusty_surface.sl, this can be used for ALL types of materials that require rust, bare metal or painted.

Now the question I have in regards to this shader - how would one take the parameters associated with the amount of rust applied to a given object and use that to displace, instead of building a displacement shader that is nearly duplicate of the surface, thus requiring us to make duplicate changes, ideally we would want to use shader to shader messaging right? I have read up on that topic on the Fuzda site (Cutter author) however he uses the displacement shader first to declare what gets changed for the surface shader. In this instance I would want to reverse that order and use the surface shader to determine what gets displaced.

The parameters in question would be :

**float Rusty_Octaves=5;**

**float Rusty_Freq=5;**

**float Rust_Amount=0.30;**

```
/*** ----- Mix with step ----- ***/
#define MIXSTEP(a,b,x,f) mix(a,b,step(x,f))
surface rusty_surface (
float Ambience=0.5;
float Diffuse=0.75;
float Specularity=0.80;
float Roughness=0.04;
color AmbientColor=color(0.02,0.02,0.02);
color Surface_Color_01=color(0.95,0.85,0.00);
color Surface_Color_02=color(0.82,0.55,0.11);
point ShaderSpace=point(1.0,1.0,1.0);
float Surface_Octaves=5;
float Surface_Freq=10;
color SpecularColor=color(1.00,1.00,1.00);
color Rust_color1=color(0.15,0.03,0.03);
color Rust_color2=color(1.00,0.62,0.29);
float Rust_octaves=5;
float Rust_freq=10;
float stucco_power3=3;
float stucco_freq3=6;
float Granite_freq18=3;
float roughness=0.04;
float Rust_Amount=0.30;
float Rusty_Octaves=5;
float Rusty_Freq=5;
color OpacityColor=color(1.0,1.0,1.0); )
{
/** Surface main-code start **/
/** Turbulence_Brick_20 **/
point temp_PP20=0;
if (ShaderSpace==point(0.0,0.0,0.0)) temp_PP20=P;
temp_PP20=transform("shader",P);
uniform float i20;
float size20,sum20;
sum20 = 0;
size20 = 1;
for (i20=0;i20<Surface_Octaves;i20+=1)
{
sum20 += noise(temp_PP20*Surface_Freq*size20)/size20;
size20 *= 2;
}
float temt_f20=clamp(sum20-0.4,0,1);
normal Nf8 = faceforward(normalize(N), I);
vector V8 = -normalize(I);
/** Turbulence_Brick_10 **/
point temp_Rust_Space=0;
if (ShaderSpace==point(0.0,0.0,0.0)) temp_Rust_Space=P;
temp_Rust_Space=transform("shader",P);
uniform float i10;
float size10,sum10;
sum10 = 0;
size10 = 1;
for (i10=0;i10<Rust_octaves;i10+=1)
{
sum10 += noise(temp_Rust_Space*Rust_freq*size10)/size10;
size10 *= 2;
}
float temt_f10=clamp(sum10-0.4,0,1);
/*** stucco pattern code ***/
float magnitude3;
point PP3;
PP3 = transform ("shader", P);
magnitude3 = pow (noise(PP3 * stucco_freq3), stucco_power3);
/*** Granite pattern code ***/
point PP18;
float sum18 = 0;
float i18, freq18 = 1;
PP18 = transform("shader", P) * Granite_freq18;
for(i18 = 0; i18 < 6; i18 = i18 + 1) {
#pragma nolint
sum18 = sum18 + abs(.5 - noise(PP18+4*freq18*I))/freq18;
freq18 *= Granite_freq18 * 2;
}
color
LocIllumOrenNayar (normal N; vector V; float roughness;)
{
/* Surface roughness coefficients for Oren/Nayar's formula */
float sigma2 = roughness * roughness;
float A = 1 - 0.5 * sigma2 / (sigma2 + 0.33);
float B = 0.45 * sigma2 / (sigma2 + 0.09);
/* Useful precomputed quantities */
float theta_r = acos (V . N); /* Angle between V and N */
vector V_perp_N = normalize(V-N*(V.N)); /* Part of V perpendicular to N */
/* Accumulate incoming radiance from lights in C */
color C = 0;
extern point P;
illuminance (P, N, PI/2) {
/* Must declare extern L & Cl because we're in a function */
extern vector L; extern color Cl;
float nondiff = 0;
lightsource ("__nondiffuse", nondiff);
if (nondiff < 1) {
vector LN = normalize(L);
float cos_theta_i = LN . N;
float cos_phi_diff = V_perp_N . normalize(LN - N*cos_theta_i);
float theta_i = acos (cos_theta_i);
float alpha = max (theta_i, theta_r);
float beta = min (theta_i, theta_r);
C += (1-nondiff) * Cl * cos_theta_i *
(A + B * max(0,cos_phi_diff) * sin(alpha) * tan(beta));
}
}
return C;
}
normal Nf = faceforward (normalize(N), I);
/** Turbulence_Brick_14 **/
point temp_PP14=0;
if (ShaderSpace==point(0.0,0.0,0.0)) temp_PP14=P;
temp_PP14=transform("shader",P);
uniform float i14;
float size14,sum14;
sum14 = 0;
size14 = 1;
for (i14=0;i14<Rusty_Octaves;i14+=1)
{
sum14 += noise(temp_PP14*Rusty_Freq*size14)/size14;
size14 *= 2;
}
float temt_f14=clamp(sum14-0.4,0,1);
/** Surface main-code end **/
Ci = color(MIXSTEP(color(mix(Surface_Color_01,Surface_Color_02,temt_f20)) * (AmbientColor * Ambience * ambient() + Diffuse * diffuse(Nf8)) +
SpecularColor * Specularity * phong(Nf8, V8, 1/Roughness),color(mix(mix(Rust_color1,Rust_color2,temt_f10),(Rust_color2+((magnitude3+sum18)/2)),temt_f10)) * (Ambience*ambient() + Diffuse*LocIllumOrenNayar(Nf,-normalize(I),roughness)),float((1-(Rust_Amount))),temt_f14));
Oi = OpacityColor;
}
```