# Perturbed image texture implementation from renderman language

I am trying to implement (in C#) an image perturbation algorithm presented in the book "Texturing and modeling - K. Perlin et al" (page 91 if anyone has it), which distorts an image. The following code is in Renderman language: The texture access

Ct = texture("example.tx", s, t);

is replaced by

point Psh;
float ss, tt;
ss = s + 0.2 * snoise(Psh);
tt = t + 0.2 * snoise(Psh+(l.5,6.7,3.4));
Ct = texture("example.tx", ss, tt);

transforming the image on the left to that on the right.

From what I undestood, instead of accessing coordinate $(s,t)\in[0,1]$ we access slighty perturbed coordinates $(ss,tt)$ and display them at place $(s,t)$, thus creating an image that looks slightly perturbed.

$snoise(x)$ is defined as $(noise(x)*2)-1$, mapping noise from $[0,1]$ to $[-1,1]$, and in the RenderMan documentation $noise(P)$ where P is a point, returns a value based on some noise (most likely perlin or lattice). (http://renderman.pixar.com/resources/current/RenderMan/noiseFunctions.html)

What I don't understand is what the transform function does, which is supposed to map the 3d point P into the "shader" space, and how can it be implemented. Also, I'm not sure whether noise(x) returns a 3d point, a float (would make more sense) and if I can use a simple 2d implementation of Perlin's noise to reach the same desired effect.

As you've surmised, the transform() function transforms points from one co-ordinate space to another. (There are also vtransform() and ntransform() for transforming direction vectors and normal vectors, respectively.) The string argument names the co-ordinate space to transform into.

In RSL, the noise() function can return any type you like: a float, a color, a point, or a vector. As you're adding it to another float (u or v), you'll get a float in this code. Really, the two noise() calls, added to s and t, are acting to generate a single 2D noise vector. In your own code, if you are using a 2D vector to store your texture co-ordinates, you can use a single noise function that returns a 2D vector, to get the same effect in one line of code.