How do I standardize the pixel density my shader outputs?

X

XYZero

Guest
I posted on reddit too about this: https://www.reddit.com/r/gamemaker/comments/e12mnn/how_do_i_standardize_the_pixel_density_my_shader/



My goal is trying to get all the pixel stair stepping to be a standard pixel density / pixel size as say my character so that the game has a consistent pixel size across the board.

My lighting shader system is pulled straight from the YOYO Games blog:

Not really sure how to approach this change. Anyone got any ideas? Is it in the vertex shader? fragment shader? or the object draw event?
 

Binsk

Member
EDIT: This post is assuming that you are trying to make your lighting match the pixelated look of your character.

Let me trying explaining shaders a bit but first:
Everything in your game is drawn out of textured triangles. When you draw a sprite or surface GameMaker is making a rectangle out of two triangles and texturing them with your sprite image.
Triangles are made from 3 vertices; one at each corner of the triangle.

GameMaker gives us access to two shader stages: vertex and fragment (the second is also known as 'pixel'). The vertex shader is responsible for calculating where your vertices need to be on the current surface (even if it's just the application surface) given some location in the world. The GLSL/ES variable gl_Position or, in HLSL, SV_POSITION is set to that final value in the vertex shader. That is the vertex shader's purpose. The fragment shader is responsible for calculating the color of a pixel. The fragment shader will be called for every single pixel resting between the final locations calculated by the vertex shader. That is just how shaders work and cannot be modified in the shader.

As you might now be able to see, you can't change 'pixel density' via the shader. It makes no sense. There are several things that can be done, but as you seem to be extremely new to shaders I am thinking that the simplest would be the best.

You can draw the light with a scale smaller than your game's native resolution; preferably one that closely resembles your main character. Because you would be shrinking the distance between your vertices there would be fewer pixels and thus, once finished, you could blow the image back up and it would look pixelated like your character. You would obviously have to render this all to a surface that is smaller than your window and then stretch it over the scene.

This leaves one small problem: How do you scale the light positions to render at a smaller scale but keep their real-world positions? The simplest method I can think of is this: Pass in an x and y scaling value to your vertex shader to match the scale of the surface. For example, if your surface is half the size of your screen then you would pass in 0.5 for x/y in your vertex shader. You can then multiply the final gl_Position.xy values by these scales so, in this case, they would draw at half the distance and thus half the number of pixels.

This should, in theory, successfully draw a shrunk version of your lighting system on the smaller surface which, when stretched back up over the screen, should give you the desired effect.

NOTE: I'm saying all this out of theory. I haven't read the 'realtime 2d lighting' article above so I am not sure on specifics of that exact system, but the concept should be the same.
 
Last edited:
R

robproctor83

Guest
Yea, it's a pain. I had this same issue, it's a real pain in the butt and ultimately I'm not able to solve some issues related to this. For example, when drawing any shapes, lines, circles and even these lights, you have to either sacrifice the pixel aspect ratio or sub pixel rendering, you can't have both. So, if your trying to match the pixel density of the lights edges with that of your sprites then your going to have to draw it to a surface at 1/scale and then draw the surface blown back up to 1*scale. The problem there is that by doing this you will lose sub pixel rendering because when you draw it at 1/scale you won't get any half pixels and so when the light moves around it may appear to stutter. It's not always noticeable though, it just depends on what your doing exactly.
 
Top