0
\$\begingroup\$

Can someone tell me what is different about the shader implementation in LibGDX that makes it incompatible with the shaders from ShaderToy? It looks like you can use ShaderToy shaders directly with other frameworks so am wondering what the difference is.

People talk about converting shadertoy shaders from GLSL to HLSL for use with Unity or Monogame, but as far as I know LibGDX uses GLSL so I don't see why the code is different?

\$\endgroup\$
14
  • \$\begingroup\$ What specific incompatibility have you observed? Do you have a test case and error message we can examine? \$\endgroup\$
    – DMGregory
    Commented Oct 20, 2020 at 6:12
  • \$\begingroup\$ @DMGregory♦ It just doesn't work at all using the code directly. Check here someone has used a shadertoy shader in libgdx libgdx.info/shaders , the original shadertoy code is shadertoy.com/view/llj3Dz but he had to convert it a huge amount to this github.com/julienvillegas/libgdx.info-Shader-Shockwave/blob/… for it to work. Not sure why since it's supposedly all GLSL, it's not like LibGDX uses HLSL. \$\endgroup\$
    – Hasen
    Commented Oct 20, 2020 at 6:38
  • 1
    \$\begingroup\$ @Hasen all in all, that GLSL code you link is shorter that the ShaderToy script it is based on. The first thing I notice is that the developer was doing some extra work to get the center in ShaderToy, while they could just pass it as an uniform in GLSL. Thus, some of the difference you see is not just for it to work, but efficiencies found in GLSL that are not available in ShaderToy. It also appears to not be exactly the same, I see an extra if in GLSL. I guess the developer took the opportunity to tweak it. \$\endgroup\$
    – Theraot
    Commented Oct 20, 2020 at 6:51
  • \$\begingroup\$ @Theraot It's still very different though. All the names of everything are different and even little things like 1. is 1.0? I guess if you know what everything should be you can convert it but it's still far from the same, I didn't understand why since I thought it was the same language - that was my main point. \$\endgroup\$
    – Hasen
    Commented Oct 20, 2020 at 8:25
  • \$\begingroup\$ @Hasen yes, they are different. Learning ShaderToy helps, but does not replace learning GLSL. By the way, the standard allows 1., it should work. However, I avoid that. I ran into problems with that years ago. I kept the practice. \$\endgroup\$
    – Theraot
    Commented Oct 20, 2020 at 8:59

1 Answer 1

0
\$\begingroup\$

LibGDX support GLSL shaders. GLSL is an standard language… ShaderToy scripts, while based in GLSL are not standard.

It looks like you can use ShaderToy scripts directly with other frameworks so am wondering what the difference is.

What do you mean directly? I have seen plugins for a couple engine that will allow you to paste ShaderToy scripts and use them as materials. Not what I would call "directly", but it works most of the time. People also convert ShaderToy scripts to GLSL by hand.

It is worth noting that ShaderToy scripts closely resemble fragment shaders, and - unless the ShaderToy script uses some other features, such as input or sound - it takes little work to adapt them by hand to GLSL fragment shaders. If the script uses such features… well, though luck, because shaders are programs uploaded to the GPU, and thus are unable to take user input or play sound. Which means that a complete implementation of a ShaderToy script runtime in another engine is not a trivial task.

What work does it take to adapt it? As per the fragment shader, first ShaderToy has some built-in variables that you would have to pass as uniforms. And second you need to write a main function that calls the mainImage function from ShaderToy (or just paste the code from mainImage inside main). If you want an output equal to the one you get in ShaderToy you will also have to setup an scene with a single quad that covers the view, and has the appropriate UV coordinates.

I want to make empahsis on that ShaderToy scripts are not standard. The function mainImage is not standard. On the other hand, main is part of the GLSL standard.

These are the input uniforms according to the ShaderToy documentation:

uniform vec3 iResolution;
uniform float iTime;
uniform float iTimeDelta;
uniform float iFrame;
uniform float iChannelTime[4];
uniform vec4 iMouse;
uniform vec4 iDate;
uniform float iSampleRate;
uniform vec3 iChannelResolution[4];
uniform samplerXX iChanneli;

You can see you will have to pass stuff like the current time and the position of the mouse. That means you also need a script that is updating these uniforms before doing the render call. For LibGDX in particular, you would do that inside render. You can imagine, from there, how to go about making a ShaderToy clone in LibGDX. If you are trying to do this as a shorthand to implement your game, you probably should simply implement your game instead.

However, chances are, you want to use the ShaderToy scripts as a material. That is, you would be rendering a scene, as you would normally do, and the ShaderToy scripts defines how to shade a surface. That means that you would create your GLSL fragment shader based on your ShaderToy script, then when rendering the mesh that uses it, you would set the uniforms and call render on the mesh. And at that point, it makes much more sense to implement only what you need instead of cloning all ShaderToy functionality, and it would be much more efficient.

To reiterate, ShaderToy is based on GLSL. Thus, if you can use ShaderToy, you got a head start in GLSL. However do not let ShaderToy prevent you from learning GLSL.

\$\endgroup\$
9
  • \$\begingroup\$ Ok so they are GLSL but not standard, interesting. I wouldn't say they are easy to convert at all though. Like this github.com/julienvillegas/libgdx.info-Shader-Shockwave/blob/… is an adaption of this shadertoy.com/view/llj3Dz but the code is radically different. I was trying to convert even this short shader shadertoy.com/view/MtlyD2 but was unable to get the long line before last to work - it just keeps throwing an error. \$\endgroup\$
    – Hasen
    Commented Oct 20, 2020 at 6:51
  • \$\begingroup\$ @Hasen would have to see the GLSL version. You could post a question, with your GLSL code and the error you are getting. \$\endgroup\$
    – Theraot
    Commented Oct 20, 2020 at 6:56
  • \$\begingroup\$ Not sure what you mean, I posted both the shadertoy and libGDX versions. You can see clearly the code is very different indeed. The last one is one I'm trying to convert from shadertoy, there is no other version. \$\endgroup\$
    – Hasen
    Commented Oct 20, 2020 at 7:01
  • \$\begingroup\$ @Hasen you say you are trying to covert the last one, and that it throws and errors. From which I infer you have a version that is not working. You could make a question around that. By the way, I just remembered something: what GPU do you have? Nvidia drivers are usually more forgiving with GLSL allowing some not standard notation, while AMD are more strict. \$\endgroup\$
    – Theraot
    Commented Oct 20, 2020 at 7:10
  • \$\begingroup\$ precision highp float; uniform sampler2D tex; uniform float time; uniform vec2 resolution; float circleFast(vec2 st, vec2 pos, float r) { vec2 dist = st-pos; return 1.0-smoothstep(r-(0.09),r+(0.09),dot(dist,dist)*4.0); } void main() { vec2 CC = vec2(0.9, 0.5); float MAX = 1.0; float time = fract(time/2.0); vec2 uv = gl_FragCoord.xy/resolution.y; gl_FragColor = vec4(uv,0.5+0.5*sin(time),1.0); uv += 1.0-(circleFast(uv,CC,time*2.0)-circleFast(uv,CC,(time/1.3)*2.0)) * (1.0-clamp(distance(CC,uv)*1.0/MAX,0.0,1.0)); gl_FragColor = texture2D(tex,uv); } // @Hasen \$\endgroup\$
    – Theraot
    Commented Oct 20, 2020 at 7:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .