Getting a GLSL shader to display - anything at all

I found some nice shaders online. So I thought I'd create a sample project in orx and play a bit. However, no matter which shader I pick, I always end up with an empty black screen.Tried different shader versions... Surely I must be doing something wrong. Please help!

1) Create a sample project with "init" command.
2) Assign a shader to "Object". E.g. This one: http://glslsandbox.com/e#58544.0
3) Run it. Screen is black :(

I have tried setting the texture to "pixel" and a size etc. Nothing helps. Ideas?

Comments

  • edited November 2019

    Have you gone through the shader examples on the wiki?
    There are other shader tutorials there as well.

    In any case, you need to adapt the shader you found on glslandbox (I also recommend checking shadertoy.com as a source of inspiration):

    • you need to provide the parameters separately
    • if you want your shader to run on an object, you cannot use gl_FragCoord, which uses screen space coordinates (even on a viewport, where it would work, you could still stick with gl_TexCoord[0] instead)
    • you need to make sure there's no compiling errors on your shader, you'll get the error messages by running orx in debug

    In your case, that would give us something like:

    [MyShader]
    Code = "
    vec2 rotz(vec2 p, float ang)
    {
      return vec2(p.x * cos(ang) - p.y * sin(ang), p.x * sin(ang) + p.y * cos(ang));
    }
    
    void main(void)
    {
      vec2 p = gl_TexCoord[0].xy * vec2(2.0) - vec2(1.0);
      float d = 2.0 * length(p);
      vec3 col = vec3(0.0);
      p = rotz(p, time * 0.5 + atan(p.x, p.y) * 8.0);
    
      for(int i = 0; i < 18; i++)
      {
        float dist = abs(p.y + sin(float(i) + time * 0.3 + 3.0 * p.x)) - 0.2;
        if(dist < 1.0)
        {
          col += (1.0 - pow(abs(dist), 0.28)) * vec3(0.8 + 0.2 * sin(time), 0.9 + 0.1 * sin(time * 1.1), 1.2);
        }
        p *= 0.99 / d;
        p = rotz(p, 30.0);
      }
      col *= 0.49;
      gl_FragColor = vec4(col - d - 0.4, 1.0);
    }
    "
    UseCustomParam  = true
    ParamList       = time
    time            = time ; using time as value instruct orx to set this parameter as a float and to use the object's age (or the global elapsed time in the case of a viewport)
    

    You can now attach this shader to an object or a viewport.

  • Thanks! The use of gl_TexCoord[0] certainly fixed some of my headache :) I got it working for a viewport, now trying to get my "pixel" object to render this.

    This "resolution" parameter is found in most samples online. It's not available out-of-the-box in orx? I see you hard-coded it to (1.0, 1.0). Should I derive this from the frustum width/height or object size?

    These tricks should indeed be part of the orx documentation. E.g. "If you encounter gl_Fragcoord in some shader..."

  • edited November 2019

    @znakeeye said:
    Thanks! The use of gl_TexCoord[0] certainly fixed some of my headache :) I got it working for a viewport, now trying to get my "pixel" object to render this.

    My pleasure. It should be working as-is in both cases.

    This "resolution" parameter is found in most samples online. It's not available out-of-the-box in orx? I see you hard-coded it to (1.0, 1.0). Should I derive this from the frustum width/height or object size?

    You're looking at very specific setups, such as glslsandbox, whose goal is to use fullscreen shaders and nothing else and have thus hardcoded a few parameters like time, mouse and resolution. Those are not standard GLSL. If you look at shadertoy, for example, the available hardcoded options will be slightly different but still relevant in the case of fullscreen shaders.

    Now if you're going to use shaders in a different context, like in a game engine such as orx, those hardcoded parameters will never exist, as they are not relevant anymore (they only apply to the case of a fullscreen single quad rendering), and it will be your responsibility to add whichever parameters your situation requires.

    Actually most game engines will only accept HLSL shaders, not GLSL ones, and some will even use their own intermediate representation, like godot.

    These tricks should indeed be part of the orx documentation. E.g. "If you encounter gl_Fragcoord in some shader..."

    Those are not tricks nor are they specific to orx: they're standard GLSL built-in variables. We assume users know how to use GLSL and the difference between gl_FragCoord and gl_TexCoord, for example, as this knowledge isn't specific to orx itself.

    The only differences between regular GLSL shaders and orx ones are how the uniform variables are declared, through the config system, and a couple of extra built-in variables in the case of textures. Those parts should all be covered in the wiki. Everything else is plain standard GLSL.

    To go back to gl_FragCoord and gl_TexCoord, those are standard GLSL built-ins. You can learn about them in any GLSL documentation or tutorials but here's a quick breakdown:

    • gl_FragCoord is the coordinates of your fragment, in screen space, in pixels. That's why you need to know the resolution in order to normalize it and know in which part of the screen you are.
    • gl_TexCoord[0] is your primary texture coordinate coming out of the fixed vertex shader used by orx, for both viewports and objects. Texture coordinates, often called UVs, are always normalized, so you don't need to know about the resolution to use it, even for a quad covering the full screen.
  • The info above has been used in the following tutorial series to help new users get something simple going: https://wiki.orx-project.org/en/tutorials/shaders/getting_started_with_shaders

Sign In or Register to comment.