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

<p>The <a href="http://renderman.pixar.com/resources/current/RenderMan/rslGuidelines97.html#part-2-coordinate-spaces">Renderman Shading Guidelines</a> have this to say about it:</p>

<blockquote>
  <p>At the start of shader execution, all point, vector, normal, and matrix variables are expressed in the "current" coordinate system. Exactly which coordinate system is "current" is implementation-dependent. It just so happens to be that "current" is "camera" for PRMan*, but you should never count on this behavior - it is entirely possible that other RenderMan compliant renderers (including future renderers from Pixar) may use some other space (like "world") as "current" space.</p>
</blockquote>

<p>It goes on to give a case like this as an example. Most lighting calculations should be done in camera space, but evaluating a noise function should be in the object's co-ordinate system, because you want the noise to stay the same as the object moves through world space.</p>

<p>In your C# implementation, you'll also need to transform the point being shaded from camera space to the object's co-ordinate system. Maybe you've done this already before computing the texture co-ordinates. If not, you'll need to multiply by the object's transformation matrix. Remember that the only use of this transformed point is as an input (like a seed) to the Perlin noise generator. It sets the domain that the noise varies over: world space co-ordinates.</p>

<p>In RSL, the <code>noise()</code> function can return any type you like: a <code>float</code>, a <code>color</code>, a <code>point</code>, or a <code>vector</code>. As you're adding it to another <code>float</code> (<code>u</code> or <code>v</code>), you'll get a <code>float</code> in this code. Really, the two <code>noise()</code> calls, added to <code>s</code> and <code>t</code>, 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.</p>

<hr>

<p>If you're interested in making a nice noise generator, <a href="https://www.shadertoy.com/results?query=noise">Shadertoy</a> has a lot of noise shaders featuring different variants of Perlin noise with different properties (isotropic or not, configurable smoothness and bandwidth) and is worth looking at for inspiration as well as implementation hints.</p>

CC BY-SA 3.0
2015-11-12T13:40:36.583Z
2015-11-12T13:40:36.583Z
Dan Hulme
<p>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</p>

<p><code>Ct = texture("example.tx", s, t);</code></p>

<p>is replaced by</p>

<pre><code>point Psh;
float ss, tt;
Psh = transform("shader", P);
ss = s + 0.2 * snoise(Psh);
tt = t + 0.2 * snoise(Psh+(l.5,6.7,3.4));
Ct = texture("example.tx", ss, tt);</code></pre>

<p>transforming the image on the left to that on the right.
<a href="https://i.sstatic.net/vxxJX.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/vxxJX.png" alt="enter image description here"></a></p>

<p>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.</p>

<p>$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).
(<a href="http://renderman.pixar.com/resources/current/RenderMan/noiseFunctions.html" rel="nofollow noreferrer">http://renderman.pixar.com/resources/current/RenderMan/noiseFunctions.html</a>)</p>

<p>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.</p>

<texture><algorithm><noise>
Perturbed image texture implementation from renderman language
simog
# Perturbed image texture implementation from renderman language

(Asked by: username_0 on 2015-11-10)

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;
Psh = transform("shader", P);
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.
[![enter image description here](https://i.sstatic.net/vxxJX.png)](https://i.sstatic.net/vxxJX.png)

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.

**Tags:** texture, algorithm, noise


---

## 1 answers

### Answer by username_1 on 2015-11-12. Score: 6

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.

The [Renderman Shading Guidelines](http://renderman.pixar.com/resources/current/RenderMan/rslGuidelines97.html#part-2-coordinate-spaces) have this to say about it:

> At the start of shader execution, all point, vector, normal, and matrix variables are expressed in the "current" coordinate system. Exactly which coordinate system is "current" is implementation-dependent. It just so happens to be that "current" is "camera" for PRMan\*, but you should never count on this behavior - it is entirely possible that other RenderMan compliant renderers (including future renderers from Pixar) may use some other space (like "world") as "current" space.

It goes on to give a case like this as an example. Most lighting calculations should be done in camera space, but evaluating a noise function should be in the object's co-ordinate system, because you want the noise to stay the same as the object moves through world space.

In your C# implementation, you'll also need to transform the point being shaded from camera space to the object's co-ordinate system. Maybe you've done this already before computing the texture co-ordinates. If not, you'll need to multiply by the object's transformation matrix. Remember that the only use of this transformed point is as an input (like a seed) to the Perlin noise generator. It sets the domain that the noise varies over: world space co-ordinates.

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.

---

If you're interested in making a nice noise generator, [Shadertoy](https://www.shadertoy.com/results?query=noise) has a lot of noise shaders featuring different variants of Perlin noise with different properties (isotropic or not, configurable smoothness and bandwidth) and is worth looking at for inspiration as well as implementation hints.


---

