A simple "Frame" shader

Here I am coming up with an idea to make all graphics entirely (or mostly) shader-generated in my next game. This is my first serious push on writing a bunch of shaders by hand, so after some experiments, I have a question, that can be generalized to: How do I draw a frame for a window with a shader? My aim is to get a frame like this:

a frame example

The question is - how to draw the frame within the exact coordinates and of the exact width. My confusion is caused by the mess in OpenGL deprecations and their support in JME3 and its example shaders. So could please someone give me an example of this simple shader, which is written in its most correct and recommended way? Thanks! :slight_smile:

EDIT: saying “exact coordinates” i mean that i know the required width of the frame and its distance from the windows edge. The window itself is a 2D quad of arbitrary dimensions, so the frame itself is procedurally stretchy.

If you are drawing it on screen-aligned gui quads, then you can probably just refer to screen coordinates in the shader (gl_FragCoord), pass x,y,width,height in pixels as uniforms and do the logic as needed there. But it might be easier to do 3x3 subquads with simple textures/texture atlas and resized them as needed - it will be a lot easier to prepare ‘skins’ for it, many UI toolkits already work in similar way.

@noncom If you’re trying to do this, and your game is set to only run in one aspect ratio (i.e, 4:3 [1280x1024 res] or 16:9 [1920x1080 res]) then you can just make the UI image as the right aspect ratio, and set the image as the texture of a Quad in the GUI Node. In fact you could create 2 versions of the photo for 4:3 and 16:9 and choose the texture according to the aspect ratio you calculate. (You can check that by doing something like this):


if((float)cam.getWidth() / cam.getHeight() == 4.0F / 3.0F) {
     //Set the 4:3 aspect photo to the texture
} else {
     //Set the 16:9 aspect photo
}

Of course, this is using minimal code change, mostly asset changing. If you’re going for code (or just overall applicability), Nifty’s approach to getting bordered images to fit any size is smart - take a look at how Nifty does its buttons.

Thanks for the answers! :slight_smile: Although they give useful advices, they do not answer the initial question. Please consider the initial question to be answered directly, without a workaround. You can say, this is more theoretical than practical - I am interested exactly in learning the things about the glsl and shaders. My solution for a post-processor shader is this: simple frame, but this won’t work on a quad in JME3, since the coordinates are screen absolute. I am interested in how do I get the correct coordinates (same result) for an arbitrarty-sized quad?

@noncom


float xPos = texCoord.x * m_ScreenWidth;
float yPos = texCoord.y * m_ScreenHeight;

Remember that those numbers will not return a correct texture sample. When sampling a texture, the point (0, 0) is bottom left and (1, 1) is top right.

If I’m not mistaken, you can have jME pass in the width and height as GLSL uniforms (similar to how it passes in the world view proj matrices). I’d link you to the jME GLSL uniforms page I have bookmarked but I’m not at home at the moment.

As far as I remember, gl_FragCoord.xy will give you pixel coordinates on the screen. Pass x,y,width,height as shader uniforms and get your quad coordinates as gl_FragCoord.xy - vec(quadx,quady)