-
-
Save greenfox1505/208bac0e7bae4ceed0ec9a1f91346af2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
shader_type canvas_item; | |
uniform sampler2D spritesheet; // Should be a slice image as exported from Magica Voxel | |
uniform int slice_count = 1; // The number of slices | |
uniform vec2 camera_vec = vec2( 1., 1. ); // Recomend using (1,1) or (1,1.5) | |
uniform float camera_ang = 0.0; // change this to change the view angle of the object | |
uniform bool flip_stack_order = true; | |
const int MAX_SLICE_COUNT = 1000; | |
const vec2 center = vec2( 0.5 ); | |
bool scale_and_rotate_with_offset( inout vec2 uv, vec2 sxy, float ang, vec2 cent, vec2 offset ) | |
{ | |
mat2 trmat = mat2( vec2( sxy.x * cos( ang ), -sxy.x * sin( ang ) ), vec2( sxy.y * sin( ang ), sxy.y * cos( ang ) ) ); | |
uv = trmat * ( uv - cent ) + cent - ( offset * sxy ) * inverse( trmat ); | |
if( uv.x < 0. || uv.x > 1. || uv.y < 0. || uv.y > 1. ) return false; | |
return true; | |
} | |
vec4 texture_slice( vec2 uv, int sliceno ) | |
{ | |
if( flip_stack_order ) | |
sliceno = slice_count - sliceno; | |
float slice_height_uv = 1. / float( slice_count ); | |
vec2 sliceuv = uv; | |
sliceuv.y *= slice_height_uv; | |
sliceuv.y += float( sliceno ) * slice_height_uv; | |
return textureLod( spritesheet, sliceuv, 0. ); | |
} | |
void vertex() | |
{ | |
VERTEX *= 4.0; | |
} | |
void fragment() | |
{ | |
vec2 uvx = UV;//floor( UV / ( TEXTURE_PIXEL_SIZE / 4.0 ) ) * ( TEXTURE_PIXEL_SIZE / 4.0 ); | |
//uvx.y = floor( uvx.y / ( TEXTURE_PIXEL_SIZE.y / 4.0 ) ) * TEXTURE_PIXEL_SIZE.y / 4.0; | |
vec2 uv = ( uvx - vec2( 0.5 ) ) * 4.0 + vec2( 0.5 ); | |
vec4 c; | |
vec2 py = vec2( 0., 1.*TEXTURE_PIXEL_SIZE.y ); | |
vec2 camera_vec_norm = normalize( camera_vec ); | |
float sliceno = 0.0; | |
for(int i = 0; i < MAX_SLICE_COUNT; i++){ | |
if(sliceno >= float(slice_count)){break;} | |
sliceno = 0.25 * float(i); | |
vec2 uv1 = uv; | |
if( scale_and_rotate_with_offset( uv1, camera_vec, camera_ang, center, -camera_vec.y * float( sliceno ) * py ) ) | |
{ | |
//vec2 pxs = | |
vec4 c1 = texture_slice( uv1, slice_count - int( sliceno ) - 1 ); | |
if( c1.a > 0. ) c = c1; | |
} | |
} | |
COLOR = c; | |
} |
great!
Hey @greenfox1505, @securas. This is awesome, thanks for putting this together. However, I'm having an issue where the result isn't really what I expect? Here's what I see:
This is just a slice export from one of the default MagicaVoxel models. The sprite sheet result is 20x420, with 20 slices (the sprite itself is 20x21, which is the sprite I have in the Sprite Node). As you can see, I'm getting gaps in the helmet and things look a bit skewed.
Any obvious reason why I might be experiencing this?
Thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Godot on GLES2 in WebGL failed at the unbounded for loop. For loops in WebGL must have hard limits (not uniforms). I fixed this with line 46-48.
I also added a stack inverter (
flip_stack_order
). SpriteStack.io exports stacks in the reverse order, so this now is now compatible with that.