angelwire
Member
EDIT: After some tests, it turns out that the speed of buffer_get_surface for an 8x8 surface is pretty much the same speed as what it would be for a 256x256 surface. So not only will this not make my game faster, but it would slow it down. Never figured out why the shader didn't work but it's not even necessary any more.(hence the unsolved but useless)
I'm using GMS 1.4.1763
Apologies for the confusing title. Here's a slightly better explanation of what I'm trying to do:
What I need is a shader that will take a sprite and convert the alpha values to either 1(visible) or 0 (invisible).
Then the shader should store the values in the color information that it's drawing (the gl_FragColor's rgba). The color of the each pixel would be based on 32 of the 1 or 0 values. Basically, the first 8 pixels' visibility would be stored as binary information in the Red channel of a color, the second 8 would be stored in the Blue etc..
The idea is to draw a sprite to a surface and use buffer_get_surface, but I only need to know whether or not a pixel is visible or invisible. (I don't need to know the rgb or even how visible it is) So if I can use buffer_get_surface on a surface that's a quarter of the width and height I can save quite a bit of time.
So for example if I drew a 32x32 sprite the shader would compress it down to 1024 bits (whether or not each pixel is visible or invisible) which could fit into an 8x8 texture which would be 1/16th of the number of pixels that would need to be converted with buffer_get_surface.
Hopefully you can understand what I'm trying to do.
Here's what I have for the fragment shader, you may notice that I'm very good with shaders and not even use what I have: (but at least you might be able to understand what I'm trying to do)
When the shader is compiled it throws this error
I've also tried passing in a sampler2D and using it instead of the gm_BaseTexture but that didn't work.
I was really hoping this would be simple but nothing I've tried seems to work. I either get an error thrown at me, nothing is drawn, or a blank white square is drawn.
Hopefully what I'm trying to accomplish is understandable, if not I'd be happy to explain anything that I haven't made clear. I would try to go into more detail but I feel like that could make things more confusing. I've worked out the math several times so I'm pretty confident it's right, but I could show my work if that would help.
Alternatively, if there's any way I can get buffer_get_surface to run faster or just collect the alpha values I would welcome that.
Thanks in advance for your help.
Edit: I updated parts of my code to reflect some changes that are being made
I'm using GMS 1.4.1763
Apologies for the confusing title. Here's a slightly better explanation of what I'm trying to do:
What I need is a shader that will take a sprite and convert the alpha values to either 1(visible) or 0 (invisible).
Then the shader should store the values in the color information that it's drawing (the gl_FragColor's rgba). The color of the each pixel would be based on 32 of the 1 or 0 values. Basically, the first 8 pixels' visibility would be stored as binary information in the Red channel of a color, the second 8 would be stored in the Blue etc..
The idea is to draw a sprite to a surface and use buffer_get_surface, but I only need to know whether or not a pixel is visible or invisible. (I don't need to know the rgb or even how visible it is) So if I can use buffer_get_surface on a surface that's a quarter of the width and height I can save quite a bit of time.
So for example if I drew a 32x32 sprite the shader would compress it down to 1024 bits (whether or not each pixel is visible or invisible) which could fit into an 8x8 texture which would be 1/16th of the number of pixels that would need to be converted with buffer_get_surface.
Hopefully you can understand what I'm trying to do.
Here's what I have for the fragment shader, you may notice that I'm very good with shaders and not even use what I have: (but at least you might be able to understand what I'm trying to do)
Code:
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform float one_pixel; //This is being set to 1/sprite_width
float look_x = 0.0;
float cc[32]; //whether or not a pixel is visible or invisilble
float binary(float n1,float n2, float n3, float n4, float n5, float n6, float n7, float n8); //Returns an 8 bit number from the 8 given numbers
int ii = 0; //this is for the loop
void main()
{
look_x = (v_vTexcoord.x * 32.0) + v_vTexcoord.y; //This keeps me from counting the same pixel multiple times
while (ii < 31)
{
look_x += one_pixel; //Look for the next pixel over
cc[ii] = sign(texture2D( gm_BaseTexture, vec2(look_x,(floor(look_x))*one_pixel)).a);
//Find the pixel alpha and move the position down if it has gone too far to the right
//I use sign() to take any value greater than 0 and turn it into a 1, but all the values of 0 stay as 0.
ii+=1; //increment counter
}
gl_FragColor = vec4(binary(cc[0],cc[1],cc[2],cc[3],cc[4],cc[5],cc[6],cc[7]),
binary(cc[8],cc[9],cc[10],cc[11],cc[12],cc[13],cc[14],cc[15]),
binary(cc[16],cc[17],cc[18],cc[19],cc[20],cc[21],cc[22],cc[23]),
binary(cc[24],cc[25],cc[26],cc[27],cc[28],cc[29],cc[30],cc[31]));
//Take all 32 of the values and convert them into 8-bit numbers for each part of the gl_FragColor
}
float binary(float n1,float n2, float n3, float n4, float n5, float n6, float n7, float n8) //This is the binary function
{
return n8 + n7*2.0 + n6*4.0 + n5*8.0 + n4*16.0 + n3*32.0 + n2*64.0 + n1*128.0;
}
I have typed the loop out (by copying and pasting it 32 times) and the error was gone but nothing was drawn.array reference cannot be used as an l-value; not natively addressable, forcing loop to unroll
I've also tried passing in a sampler2D and using it instead of the gm_BaseTexture but that didn't work.
I was really hoping this would be simple but nothing I've tried seems to work. I either get an error thrown at me, nothing is drawn, or a blank white square is drawn.
Hopefully what I'm trying to accomplish is understandable, if not I'd be happy to explain anything that I haven't made clear. I would try to go into more detail but I feel like that could make things more confusing. I've worked out the math several times so I'm pretty confident it's right, but I could show my work if that would help.
Alternatively, if there's any way I can get buffer_get_surface to run faster or just collect the alpha values I would welcome that.
Thanks in advance for your help.
Edit: I updated parts of my code to reflect some changes that are being made
Last edited: