Good shader for spritesheets?

edited April 2016 in General discussions
Could someone please grade me

I've finally come up with this for a shader to be applied to only the cropped texture region of an object:
[DemoObject]
Position = (50, 50, -1.0) 
Graphic = DemoGraphic
ShaderList = Shader
Scale = 10
 
[DemoGraphic]
Texture = sprites.png
TextureOrigin = (0,8,0)
TextureSize = (8,8,0)

[Shader]
ParamList = texture 
Code = "

void main() {
 
    vec2 p = gl_TexCoord[0].xy;
    vec4 textureCol = texture2D(texture, p);
 
	vec2 textStartCoord = vec2(texture_left, texture_top);
	vec2 textEndCoord = vec2(texture_right, texture_bottom);
	vec2 cropWidth = textEndCoord - textStartCoord;
	
	gl_FragColor = textureCol;
		
	if (p.x >= textStartCoord.x && p.x <= textEndCoord.x && p.y >= textStartCoord.y && p.y <= textEndCoord.y){
		
		vec2 outerCoord = (p-textStartCoord) / cropWidth;
		gl_FragColor.a = 1.0-outerCoord.y;

	}

}"
sprites.png

Comments

  • edited April 2016
    Looks good to me. Maybe the comparisons could be done with 2D vectors (.xy) instead of separating them by components?
    But that's really minor.

    For references, did you check the two "tutorials" I think I mentioned quite a while ago?
    Resource and SimpleTest

    EDIT: Actually, I don't think your test is necessary at all, you should only get values that are between those boundaries.
  • edited April 2016
    I checked out what you said, removing the check.

    I was thinking the values outside the crop area would calculate outside range of 0.0 and 1.0 and would be ignored, which would be pretty handy.

    But I noticed that without the check, the lower half of the spritesheet ends up with alpha = 0. So I lose the lower half of the sheet.

    When you mentioned doing the check by vectors, was it something like: ?
    if (p.xy >= textStartCoord.xy && p.xy <= textEndCoord.xy){
    }
    

    Using glsl 110, I can't use operands on that type.

    I took a look at the two tutorials, but they're a little beyond me at the moment. Couldn't find anything similar to what I was doing in those. I'll check again though.
  • edited April 2016
    The shaders are in data.ini, the lines you wanted were:
    vec2  vTL     = vec2(texture_left, texture_top);
    vec2  vBR     = vec2(texture_right, texture_bottom);
    vec2  vPos    = -1.0 + 2.0 * (gl_TexCoord[0].xy - vTL) / (vBR - vTL);
    

    Which is very similar to what you do, the only added thing was to map the whole range for vPos to [-1, 1].

    There shouldn't be any value outside [0, 1] in your example as the texture coordinate should always be between boundaries (otherwise it'd display something that isn't your sprite in the spritesheet).
  • edited April 2016
    Right I see, yes that's a good idea. I did note that both routines produce the same effect. I'll drop you a note and see what you think.

    In the meantime, I'll draw up the example with the check.
Sign In or Register to comment.