#Surfaces + Shaders for 3D Card flip effect (with Scribble)

1 messages · Page 1 of 1 (latest)

turbid yoke
#

So I have a card object that is drawn from multiple parts, and the text on the card is rendered using Scribble. I now want to apply a vertex shader for 3D rotation (with some matrix multiplications) on the whole card, and since you can't apply 2 shaders at once and Scribble itself already uses a shader, I figured the solution would be to first bake the card on a separate surface, then drawing that surface with my shader applied.

BUT it turns out when drawing the exact same elements to a separate surface instead of directly onto application_surface, it loses resolution and creates more jittering in the subpixels since the original view port to camera is scaled 2:1 but the surface is 1:1

So now I'm left wondering, what would be the best approach to this problem? (I don't really want to apply a 3D camera to the whole scene/room, since that would mean fundamentally changing the entire game's UI)

TLDR: I want to apply a shader (matrix transformation) to a composite card that uses Scribble

turbid yoke
visual nebula
#

you dont really need a shader for this. make a 2:1 surface and put the card on it, then make a 1:1 vertex buffer with two sides, one for front one for back

#

then just matrix-transform the vertex buffer

half aspen
#

isn't this flip effect just animating the x scale?

#

doesn't seem like that needs to be a shader or even a transform matrix

visual nebula
#

yeah if the card doesnt have a back (and really i guess, even if it did) you can lerp the x scale back and forth

turbid yoke
#

but I wanted to try a 3D rotation effect

turbid yoke
#

I've implemented the shader in a separate test project and I wonder if it would look better

half aspen
#

ok so this is an experiment in 3D rendering?

#

i'm not sure what your goals are tbh

turbid yoke
#

I've been playing a lot of Balatro lately and it inspired me to learn vertex shaders and add a bunch of cool shader effects to my card game

visual nebula
#

i say go for it; even use a surface with a 3d camera to spin the card

eager nest
turbid yoke
eager nest
#

its just a curve, similar to the one you showed.
the thing with perspective is, to make it mathematically correct, you need a "horizon" and a depth/view distance, how far away the horizon is.
As we are in 2D I recommend, that you just try to move the back corners "a bit" closer, and the two front corners "a bit" more distant.

What is "a bit" -> so much, that it "looks good in your environment". Experiment a bit. 3-5% i suggest

#

the flip-center is the center of x of the card. the two back like 3-5% closer, the two front like 3-5% more distant (in y only of course), then you get a nice perspective effect.

visual nebula
#

draw sprite pos will introduce texture warping at a certain point due to the lack of perspective correction. definitely suggest just using some basic 3d camera here and you can skip all the hard stuff. its just a simple matrix transform

turbid yoke
#

yeah exactly at this point I think it's just easier to do a matrix transformation (with or without a vertex shader)

modern crown
#

sorry i missed all the comments above V:

turbid yoke
eager nest
#

would you mind to share the code how you did it with matrix?

visual nebula
#

to "flip" a card, a matrix transform is done around the y axis:

var transform = matrix_build(x, y, 0, 0, rotation, 0, 1, 1, 1);
matrix_set(matrix_world, transform);
draw_surface(card, 0, 0);
matrix_set(matrix_world, matrix_build_identity());```
#

that would rotate it hot dog style

little goblet
#

I just drew an animation of the cards flipping over and scaled the image_xscale of the face sprite to look about right. That might be a quicker solution.

turbid yoke
visual nebula
#

you can just do this yes

turbid yoke
turbid yoke
# eager nest would you mind to share the code how you did it with matrix?

This is the vertex shader I made for matrix rotation

attribute vec3 in_Position;                  // (x,y,z)
//attribute vec3 in_Normal;                  // (x,y,z)     unused in this shader.
attribute vec4 in_Colour;                    // (r,g,b,a)
attribute vec2 in_TextureCoord;              // (u,v)

varying vec2 v_vTexcoord;
varying vec4 v_vColour;

uniform vec2 u_Rotation;
uniform vec2 u_Middle;

uniform mat4 u_ViewMatrix;
uniform mat4 u_ProjMatrix;

uniform float u_Angle;

void main()
{
    // this is 3D because we need Z rotation
    vec3 pos = vec3(in_Position.x, in_Position.y, in_Position.z);
    
    // move the origin to (0; 0)
    vec3 middle = vec3(u_Middle.x, u_Middle.y, in_Position.z);
    pos -= middle;
    
    // apply the rotation matrices
    float sinx = sin(u_Rotation.x), cosx = cos(u_Rotation.x);
    float siny = sin(u_Rotation.y), cosy = cos(u_Rotation.y);
    float sinz = sin(u_Angle), cosz = cos(u_Angle);
    float sinzi = sin(-u_Angle), coszi = cos(-u_Angle);
    
    // prerotate
    mat3 rot_mat_z = mat3(cosz, sinz, 0, -sinz, cosz, 0, 0, 0, 1);
    // ???????
    // im a natural, it's not random luck 
    mat3 rot_mat_z_inv = mat3(-coszi, -sinzi, 0, -sinzi, coszi, 0, 0, 0, 1);
    //mat3 rot_mat_z_inv = mat3(coszi, sinzi, 0, -sinzi, coszi, 0, 0, 0, 1);
    
    mat3 rot_mat_x = mat3(cosx, 0, -sinx, 0, 1, 0, sinx, 0, cosx);
    mat3 rot_mat_y = mat3(1, 0, 0, 0, cosy, siny, 0, -siny, cosy);
    
    pos = rot_mat_z_inv * pos;
    pos = rot_mat_x * rot_mat_y * pos;
    pos = rot_mat_z * pos;
    
    // move back from (0; 0) to original coords
    pos += middle;
    
    
    vec4 object_space_pos = vec4( pos.x, pos.y, pos.z, 1.0);
    
    gl_Position = u_ProjMatrix * u_ViewMatrix * object_space_pos;
    
    v_vColour = in_Colour;
    v_vTexcoord = in_TextureCoord;
}
visual nebula
#

congrats homie u rewrote the render pipe haha