Pryme8 Posted October 21, 2017 Share Posted October 21, 2017 ok so I have three textures one is the texture to display one is the locations of the tiles, and the third is a reference sheet for the animations on the sprite sheet. so I am able to get the coordinates of the correct 'sprite' by sampling the tiles texture: vec4 tile = texture2D(tiles, texCoord); if(tile.x == 1.0 && tile.y == 1.0) { discard; } then I check the animation map for an animation refrence vec4 aTile = texture2D(animationMap, tile.xy); if(aTile.a == 1.0 ){ I have the flags on the alpha channel for if this is an animation or not the z or blue channel as the "timing" for the frame and the red green as the x,y of the next frame. What I want to happen is a loop so something like: float _t = sin(time); float aS = aTile.z; while(aS > _t){ aTile = texture2D(animationMap, aTile .xy); aS = aTile.z; } tile.xy = aTile.xy; but when I do something like this it crashes the webGL which I am guessing is do to the loop never exiting or something. If I do something like: vec4 tile = texture2D(tiles, texCoord); if(tile.x == 1.0 && tile.y == 1.0) { discard; } vec4 aTile = texture2D(animationMap, tile.xy); if(aTile.a == 1.0){ float _t = sin(time); float aS = aTile.z; if(aS < _t){ tile.xy = aTile.xy; } } I can toggle between two frames, but I want to support more! Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted October 22, 2017 Author Share Posted October 22, 2017 vec4 tile = texture2D(tiles, texCoord); if(tile.x == 1.0 && tile.y == 1.0) { discard; } vec4 aTile = texture2D(animationMap, tile.xy); if(aTile.a != 0.0) { float aS = aTile.b; float _t = sin(time); while(aS < _t && aTile.a > 0.){ aTile = texture2D(animationMap, aTile.xy); aS = aTile.b; } } which does not crash anything, but effectively does nothing but prove the loop is not making it crash. but the second I add this vec4 tile = texture2D(tiles, texCoord); if(tile.x == 1.0 && tile.y == 1.0) { discard; } vec4 aTile = texture2D(animationMap, tile.xy); if(aTile.a != 0.0) { float aS = aTile.b; float _t = sin(time); while(aS < _t && aTile.a > 0.){ aTile = texture2D(animationMap, aTile.xy); aS = aTile.b; } if(aS > _t){ tile.xy = aTile.xy; } } it crashes after the first "frame" if I do this: vec4 tile = texture2D(tiles, texCoord); if(tile.x == 1.0 && tile.y == 1.0) { discard; } vec4 aTile = texture2D(animationMap, tile.xy); if(aTile.a != 0.0) { float aS = aTile.b; float _t = sin(time); if(aS > _t){ tile.xy = aTile.xy; } } It toggles between the frames but I need to support more then two frames. Quote Link to comment Share on other sites More sharing options...
Nabroski Posted October 22, 2017 Share Posted October 22, 2017 @Pryme8 Interesting observation while loop needs and exit plan https://playground.babylonjs.com/#PYK67E#3 But it sounds more like you need to access the previous rendered frame eg. sampler2D backbuffer in sandbox http://glslsandbox.com/e#207.3 Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted October 22, 2017 Author Share Posted October 22, 2017 Ok so that kicks it out and stops it from freezing, but I still cant get the "animation" to work. Here is the idea: I have 3 textures for the animation test I am using: the atlas which is the art The layer which gives the shader the location of the original sprite placed. In the example I am going to provide it is set to repeat when I make the texture so this 1 by 1 tile covers the whole screen multiple times. ^ hopefully you see the one pxl above its colors are r:0:g:0:b:0:a:1 which represents the number 1 tile on the atlas (r:1:g:0:b:0:a:1 would be 2) r is x and g is y, blue/alpha are unused right now. And lastly where I am trying to make the magic happen is the animation look up texture, this uses the same idea as the layer but holds different information and is a 1x1pxl equivalent to the atlas: Right now I have the bottom blank, I just want to get through the 1234... so the information stored on these are the x:y of the next tile held in the red green, the 'step' of the tile is in the blue. the step I am using in a very rudimentary way right now, it is just a number between 0-1 that says when to go to the next tile dependent on right now a time calculation. Later I will use the alpha as a scaler for that timing, and will pass another global variable to it as well to fine tune timing on each client as well but that's later down the road....https://pryme8.github.io/TileMaster/ani-test.html <- for the nonworking animation example. https://github.com/Pryme8/TileMaster/blob/gh-pages/ani-test.html <- Line 174 If I uncomment line 166 through 170 then it will toggle between tiles... but like I said unless the super duper retro look is what your going for this is not going to work. Quote Link to comment Share on other sites More sharing options...
Nabroski Posted October 22, 2017 Share Posted October 22, 2017 Hello @Pryme8 let my rephrase, for my own understanding, the goal - deserved look is to loop through the nummers 1 -4, - more generally speaking through a specific area and simpel if statment : http://musician-elephant-31700.bitballoon.com/ is not enough, you want to test for a specific color value in an area, and when it's present, then cut out the object, - like in photoshop select area by color ? Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted October 22, 2017 Author Share Posted October 22, 2017 What if I don't know the number of frames I'll take a look at what you got when I get home. Quote Link to comment Share on other sites More sharing options...
Nabroski Posted October 23, 2017 Share Posted October 23, 2017 OK. I understand, this can turn out a time consuming project. But also a very interessting one. I think what you are looking for is kind of text font rendering technique using shaders, some good implementations here: https://www.shadertoy.com/results?query=font Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted October 23, 2017 Author Share Posted October 23, 2017 Ok I finally got to look at your example with: float _t = sin(time); if(0.5<=_t)tile.xy += aTile.xy; // 1 if(0.25<=_t)tile.xy += aTile.xy; // 2 ; if(-0.25<=_t)tile.xy += aTile.xy;// 3 ; if(-0.5<=_t)tile.xy =tile.xy;// 4 ; And that is fine, for hard coding the animations in, but what I want is to sample the blue channel from aTile check if its > then _t and if so stop on that tile. I know this seems weird to do but there is a really good idea behind this that I just don't feel like explaining at this juncture. The proccess that I am looking for would be like: 1) Check the layer texture for what sprite to reference; 2) With the X:Y value of tile, check the value on that sprite on the animation sheet; 3) If the alpha is 0 on the animation sheet do nothing but return the base sprite; 3a) Else if the Alpha is > 0 on the animation sheet get the blue value and test; 4) if its > then _t, set the red and green channels (or the xy) of the aTile to the tile.xy and output that sprite. 5) if its < then _t get the current aTile.xy and re-sample that coordinate off the animation sheet to get the tile data agian on the animation texture; 6) repeat steps 3-5 as necessary until the blue channel meets the requirements or you run into a 0 alpha tile. you need to shift the _t into a range of 0-1 though because the blue channel is in that range. This will make it so any tile can reference any other tile on the sheet for animations and once I put together the editor it will be seamless I am hoping if I can figure this one part out. Quote Link to comment Share on other sites More sharing options...
Nabroski Posted October 23, 2017 Share Posted October 23, 2017 Yes, now its more descriptive! And also sorry i'm out of time. I can give you only suggestions. first littele playground update: check if this works on other platforms like ios, i looks a bit weird to me:https://playground.babylonjs.com/#PYK67E#4 if you are looking for tiles also check how babylon is mapping your texture gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); you could easily run in an error becourse of the "hidden" default behavior Pryme8 1 Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted October 23, 2017 Author Share Posted October 23, 2017 Do I need to do it as secondary functions? Like have one that loops with an if statement that runs another function to sample the animation tile and then keep recalling that function till it tests out? Quote Link to comment Share on other sites More sharing options...
Nabroski Posted October 23, 2017 Share Posted October 23, 2017 function recursion an that is all webgl 2.0 stuff. you need to do and if statement in a while loop becourse in your shader the while loop never exits (has no real logical exit condition) sin(t)<5&& is repetitivehttps://stackoverflow.com/questions/872996/immediate-exit-of-while-loop-in-c Pryme8 1 Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted October 23, 2017 Author Share Posted October 23, 2017 so why does this one not kick out of the while loop then? Figured that is what I was doing with this one. On 10/21/2017 at 6:29 PM, Pryme8 said: vec4 tile = texture2D(tiles, texCoord); if(tile.x == 1.0 && tile.y == 1.0) { discard; } vec4 aTile = texture2D(animationMap, tile.xy); if(aTile.a != 0.0) { float aS = aTile.b; float _t = sin(time); while(aS < _t && aTile.a > 0.){ aTile = texture2D(animationMap, aTile.xy); aS = aTile.b; } if(aS > _t){ tile.xy = aTile.xy; } } Quote Link to comment Share on other sites More sharing options...
Nabroski Posted October 24, 2017 Share Posted October 24, 2017 So i did a little shader, this is not what you are looking for ... so i would do everything in a singel shader test for color and the print the nummbers. i wrote some notes maybe you find something usefull https://playground.babylonjs.com/#PYK67E#5 Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted October 24, 2017 Author Share Posted October 24, 2017 https://pryme8.github.io/TileMaster/ani-test.html Ok so it "works" but the positions are wrong... I just gotta figure out why I'm referencing the wrong tiles when I use the animation map samples... uhh but hopefully this gets me in the right direction *update* vec4 tile = texture2D(tiles, texCoord); if(tile.x == 1.0 && tile.y == 1.0) { discard; } vec4 aTile = texture2D(animationMap, tile.xy); if(aTile.a != 0.0) { float aS = aTile.b; float _t = (tan(time)+1.0)/2.0; if(aS>_t){ for(int i=0; i<maxFrames; i++){ aTile = texture2D(animationMap, aTile.xy); if(aTile.a == 0.0)break; aS = aTile.b; if(aS>_t){ tile.xy = aTile.xy; break; } } } } this is pretty close, but I can not get it to go past the second frame... it just seems to toggle back and forth between the first frame and the second. Im starting to think its really close... I just am to much of a dummy at glsl to figure it out. Quote Link to comment Share on other sites More sharing options...
NasimiAsl Posted October 24, 2017 Share Posted October 24, 2017 hi http://www.babylonjs-playground.com/#2BJAXD#6 why you don't use Mod and floor time = > 0 - 1 - 2 - 3 - 4 - 5 - 6 - ... mod(time,1.) => 0 - 1 - 1 - 1 - 1 - 1 - ... mod(time *10.,1.)/10. => 0 , 0.1 , 0.2 , 0.3 , 0.4 ,0.5 ,0.6 , ... https://playground.babylonjs.com/#PYK67E#6 vec2( mod( (p.x*4. ),1.)/4. /*take one column */ + floor(_t*4.)/4. /*move columns (step by step )*/ ,p.y) Nabroski 1 Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted October 24, 2017 Author Share Posted October 24, 2017 what If the number of frames is dynamic and they have different timings? the whole point of this, is to reference the animation texture file for what tile to go to and "when" to go there. What if the texture animation sheet says the tile goes from number 1 to number 4 to one of the squiggly blue lines back to 1 ect... Maybe the answer is here I just don't understand it? Quote Link to comment Share on other sites More sharing options...
NasimiAsl Posted October 24, 2017 Share Posted October 24, 2017 you can control that https://playground.babylonjs.com/#PYK67E#8 vec2( mod( (p.x*4. ),1.)/4. /*take one column */ + _t * 0.25 /*move columns (t = frame )*/ ,p.y) Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted October 24, 2017 Author Share Posted October 24, 2017 Did you read the above post about what I am trying to do with the 3 different sampler2d uniforms? How could I use your method with that principal? I’m trying to basically make a way to turn any texture atlas into a animated sheet. Thanks so much guys for helping me with ideas on this, it may just be a bad formatted idea but I’m pretty sure if I can explain it well enough it will click, or I will get enough info to figure it out myself. Ive got other ways I could do it that are more traditional but I have a greater goal at mind. Quote Link to comment Share on other sites More sharing options...
Nabroski Posted October 24, 2017 Share Posted October 24, 2017 @Pryme8 "what If the number of frames is dynamic and they have different timings?" Yes, you need to make a grid[row,colums] and then Access the values. - different timings -> then will be calculated based on grid[row,colums] .length frame: 0 1 2 3 texPos: 0.2,.0.4,.0.8. 1.0 or -> firstpos 0.2 +firstpos 0.2 = frame 1// prev.pos PLUS=MOVE TO NEXT POSTIONfloat _t = sin(time);if(0.5<=_t)tile.xy += aTile.xy;if(0.25<=_t)tile.xy += aTile.xy; // NEXT POSTION ? if(aS>_t){ for(int i=0; i<maxFrames; i++){ aTile = texture2D(animationMap, aTile.xy); if(aTile.a == 0.0)break; aS = aTile.b; if(aS>_t){ tile.xy = aTile.xy; break; NasimiAsl vec2( mod( (p.x*4. ),1.)/4. /*take one column */ + _t * 0.25 /*move columns (t = frame )*/ ,p.y) + make a grid on a texture + specify a singel element(char) [width,height] + move the singel element position along the grid to get the next element : Pryme8 1 Quote Link to comment Share on other sites More sharing options...
Nabroski Posted October 25, 2017 Share Posted October 25, 2017 OFFTOPIC@NasimiAsl "why you don't use Mod and floor" Whatever works, -works https://playground.babylonjs.com/#PYK67E#13http://www.wolframalpha.com/input/?i=({x,y}%2F4.)%2Bfract(({0..16,3-0..16%2F4})%2F4.),x%3D0..1.,y%3D0..1. Pryme8 1 Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted October 25, 2017 Author Share Posted October 25, 2017 Ok, now I just gotta figure out what it is yall just told me! I gave not had a chance because work has been so overloaded but maybe today ill get a second. Thanks yall. Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted October 25, 2017 Author Share Posted October 25, 2017 can you do this one https://playground.babylonjs.com/#PYK67E#13 as webgl 1.0 instead of 2.0 please? I tried but am getting some weird errors. Also I dont see how this method is going to work in situations like this: So this sheet has several different animation sequences on it, what I am trying to do is use the Animation Map texture to define where these different 'zones' are. Maybe use your method with a combination of mine? Where the Animation map has the data structure of r -> xCount of tiles, g -> y count of tiles, b -> speed Adjustment, a -> is it animated or not. And then use that data to control the mod method you have demonstrated? I think we are getting closer. The whole point of this, is to be able to animate whole atlas files without passing a bunch of other information to the shader. Quote Link to comment Share on other sites More sharing options...
Nabroski Posted October 25, 2017 Share Posted October 25, 2017 @Pryme8 Yes, i know. I was placing the #version derivative a second time ( it's already done by babylonjs ) becourse gl_FragColor in WebGL2.0 is deprecated and now is is able to have multiple outputs, so you can write directly from shader to shader etc. So my custom shader is compete with babylonjs the default material https://github.com/BabylonJS/Babylon.js/blob/407b2d3f0ffe9d7e80ecc670ebab7fc3f14bae9d/src/Shaders/default.fragment.fx#L420 ( but im not sure about this )Compatibility Mode Solution 1 (quick and dirty)#if __VERSION__ >= 300 https://playground.babylonjs.com/#PYK67E#17 Compatibility Mode Solution 2 Their a function i forgot like scene.StandartMaterial=null, or scene.hasDefaultMaterial(NO); Ok, so this is a webgl1.0 shader - when i done it right, should workhttps://playground.babylonjs.com/#PYK67E#16 Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted October 25, 2017 Author Share Posted October 25, 2017 Awesome, Ok I am going to take what you have and combine my processes and maybe we will have a solution! Thank you. Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted October 25, 2017 Author Share Posted October 25, 2017 Really quick: texture2D(tex, vuv / 4. + fract(vec2(_t, 3 - _t / 4) / 4. )); so its texture2D(texture, cellsize? + please explain the fract part?) Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.