# From Shadertoy to OPENRNDR

**URL:** <https://openrndr.discourse.group/t/from-shadertoy-to-openrndr/85>\
**Category:** Tutorials\
**Created:** [April 13, 2020, 2:35pm UTC](https://openrndr.discourse.group/t/from-shadertoy-to-openrndr/85 "2020-04-13T14:35:42Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![abe](https://yyz2.discourse-cdn.com/free1/user_avatar/openrndr.discourse.group/abe/32/700_2.png) [@abe](https://openrndr.discourse.group/u/abe)\
**Post date:** [April 13, 2020, 2:35pm UTC](https://openrndr.discourse.group/t/from-shadertoy-to-openrndr/85/1 "2020-04-13T14:35:43Z")

</div>

This is a simple example porting one program from Shadertoy. Keep in mind that it’s not a generic tutorial for porting every possible program from Shadertoy.

### Shadertoy

[https://www.shadertoy.com/view/wdjcDw](https://www.shadertoy.com/view/wdjcDw)

```auto
vec2 shuffle(vec2 xy, vec2 p) {
    vec2 i = floor(fract(xy) * p) / p;
    vec2 f = fract(xy * p) / p;   
    i.x += step(1.-i.x, .5) / (p.x * 2.);    
    i.y += step(1.-i.y, .5) / (p.y * 2.);    
    return fract(i * 2. + f);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {   
    vec2 uv = fragCoord/iResolution.xy;   
    uv *= .5; // scaling
    uv = shuffle(uv, vec2(30., 1.));
    uv = shuffle(uv, vec2(1., 16.));
    fragColor = texture(iChannel0, uv);
}

```

It is a shader inspired by [this video](https://www.youtube.com/watch?v=f1fXCRtSUWU) posted by @rein in Slack. I wrote it quickly and it’s not specially good 🙈 (as it doesn’t deal with aspect ratio nor it’s easily configurable). But I hope it can still serve as an example of porting a shader to OPENRNDR.

### OPENRNDR

> **Imports**
>
> ```auto
> import org.openrndr.application
> import org.openrndr.draw.loadImage
> import org.openrndr.draw.shadeStyle
> import org.openrndr.extensions.Screenshots
> 
> ```

```auto
fun main() = application {
    configure {
        width = 1024
        height = 1024
    }

    program {
        // https://upload.wikimedia.org/wikipedia/commons/thumb/a/a9/Kissing_Prairie_dog_edit_3.jpg/1024px-Kissing_Prairie_dog_edit_3.jpg
        val img = loadImage("data/images/1024px-Kissing_Prairie_dog_edit_3.jpg")

        extend {
            drawer.stroke = null
            drawer.shadeStyle = shadeStyle {
                fragmentPreamble = """
                    vec2 shuffle(vec2 xy, vec2 p) {
                        vec2 i = floor(fract(xy) * p) / p;
                        vec2 f = fract(xy * p) / p;   
                        i.x += step(1.-i.x, .5) / (p.x * 2.);    
                        i.y += step(1.-i.y, .5) / (p.y * 2.);    
                        return fract(i * 2. + f);
                    }
                """.trimIndent()
                fragmentTransform = """
                    vec2 uv = c_boundsPosition.xy;
                    uv.y = 1.-uv.y; // vert flip
                    uv = shuffle(uv, vec2(30., 1.));
                    uv = shuffle(uv, vec2(1., 30.));
                    x_fill = texture(p_img, uv);
                """.trimIndent()
                parameter("img", img)
            }
            drawer.rectangle(drawer.bounds)
        }
    }
}

```

It’s a very simple program that loads an image, defines a shade style and draws a full screen rectangle using that style.

The `.trimIndent()` is optional but added automatically by the IDE. It removes indentation white space from strings.

The `fragmentTransform` part is what you need to create a typical `shadeStyle`. That parts ends up inside the `main()` function in the GLSL shader. In this case I also want to define my own functions (the one called `shuffle`) therefore I use the `fragmentPreamble` to inject them above the `main()` function.

| concept | shadertoy | OPENRNDR |
| --- | --- | --- |
| normalized position | `fragCoord/iResolution.xy` | `c_boundsPosition.xy` |
| image uniform | `iChannel_0` .. `3` | we name it. in this case we choose `img` and it becomes uniform `p_img` inside shader code |
| uv vertical flip | not needed | `uv.y = 1.-uv.y` |
| uv scaling | `uv *= 0.5` | I was happy with the scale |
| output variable | `fragColor` | `x_fill`. This is something special in OPENRNDR, because by default it contains the requested fill color. I overwrite it by using `texture()` to sample pixels from the provided image. But instead of overwriting I could do `x_fill.rgb *= 1.2;` to make the requested color brighter for all pixels, `x_fill.rgb *= 0.8;` to make them darker or `x_fill.rgb *= 1.0 + 0.1 * sin(c_boundsPosition.x);` to create a horizontal wavy gradient based on the requested fill color. |

Don’t worry if you don’t understand shaders yet, my goal here was only to show similarities and differences between shadertoy code and a similar program written in OPENRNDR.

You can [read more about shader uniforms and attributes in the OPENRNDR Guide](https://guide.openrndr.org/advancedDrawing/shadeStyles.html#the-shade-style-language).

---

<div class="post-metadata">

**Author:** ![Yann](https://avatars.discourse-cdn.com/v4/letter/y/bc79bd/32.png) [@Yann](https://openrndr.discourse.group/u/Yann)\
**Post date:** [April 21, 2020, 4:33pm UTC](https://openrndr.discourse.group/t/from-shadertoy-to-openrndr/85/2 "2020-04-21T16:33:43Z")

</div>

This is a great example! I think the shader section of the guide could be improved with more details. For example, c\_boundsPosition is not mentioned in the table of constants (only the examples).

---

<div class="post-metadata">

**Author:** ![abe](https://yyz2.discourse-cdn.com/free1/user_avatar/openrndr.discourse.group/abe/32/700_2.png) [@abe](https://openrndr.discourse.group/u/abe)\
**Post date:** [April 21, 2020, 6:24pm UTC](https://openrndr.discourse.group/t/from-shadertoy-to-openrndr/85/3 "2020-04-21T18:24:13Z")

</div>

🙂

You are right about the guide, there’s an [issue open for that](https://github.com/openrndr/openrndr-guide/issues/37).

---

<div class="post-metadata">

**Author:** ![andremichelle](https://yyz2.discourse-cdn.com/free1/user_avatar/openrndr.discourse.group/andremichelle/32/145_2.png) [@andremichelle](https://openrndr.discourse.group/u/andremichelle)\
**Post date:** [June 26, 2020, 4:36am UTC](https://openrndr.discourse.group/t/from-shadertoy-to-openrndr/85/4 "2020-06-26T04:36:06Z")

</div>

I use shadertoy to quickly sketch some shader-code and move to openrndr for compositing. Following code accepts one-file shadertoy shaders using _iTime_ and _iResolution_. However there is an option to pass any additional required uniforms like _iMouse_ at render time.

> <https://gist.github.com/andremichelle/e9394e6830e65e8d3b04f62c0b84f67d>

---

<div class="post-metadata">

**Author:** ![abe](https://yyz2.discourse-cdn.com/free1/user_avatar/openrndr.discourse.group/abe/32/700_2.png) [@abe](https://openrndr.discourse.group/u/abe)\
**Post date:** [June 26, 2020, 7:23am UTC](https://openrndr.discourse.group/t/from-shadertoy-to-openrndr/85/5 "2020-06-26T07:23:18Z")

</div>

Nice! Thanks for sharing the code 🙂
