### Author Topic: [SOLVED] Using shader to apply fake 3D rotation effect on a sf::Text  (Read 591 times)

0 Members and 1 Guest are viewing this topic.

#### Esteban

• Newbie
• Posts: 6
##### [SOLVED] Using shader to apply fake 3D rotation effect on a sf::Text
« on: May 12, 2024, 11:17:42 pm »
Hello everyone,
i am working on a game project and i face difficulties understanding how to use shader on sf::Text.
What i wanted to do is in the title and i dont realize if this is possible or not. I wanted to spin a text to have a fake 3D rotation effect. I Found a shader that does the spin effect in shadertoy and adapt it  :
.frag
precision mediump float;

#define Mouse_Rotation ( Max_Rotation - Max_Rotation * 2.0 * (iMouse.xy / iResolution.xy) )
#define RotationCenter vec3(0.000, 0.000, 0.000)
#define Max_Rotation 0.65

/*
A simple rotating effect of a textured plane in 3D space.
I&#39;m basically using a ray for each pixel that intersects the plane
as drawn in a 2D view below.

Created By Jaap Boerhof (Dec. 2017)
Forked by yohjimane (Jul. 2023)

Positioning                             Positioning at a certain angle:
at zero degrees rotation:

|------plane-----|  coords:                              __--|
\                /  (-1.0..1.0, 0.0)                 __--   /
\              /                                __--      /
\            /                             __--         /
\          /                         \ _--            /
\        /                          |\              /
\      /                             \            /
\    /                               \          /
\  /                                 \        /
\/          Camera                   \      /
position                  \    /
at (0.0, -1.0)             \  /
\/
*/

uniform vec2 u_resolution;
uniform float u_time;
uniform sampler2D texture;
vec2 rotate(vec2 v, vec2 o, float a) {
float s = sin(a);
float c = cos(a);
mat2 m = mat2(c, -s, s, c);
return m * (v-o) + o;
}

vec3 rotateZ(vec3 v, vec3 o, float a) {
float s = sin(a);
float c = cos(a);
mat2 m = mat2(c, -s, s, c);
return vec3(m * (v.xy - o.xy) + o.xy, v.z);
}

vec2 TransformPlane(vec2 uv, vec3 center, float XRot, float YRot, float ZRot) {
// First Rotate around Y axis
vec2 RayDirection =  vec2(uv.x, 0.0);
vec2 A1 = vec2(0.0, -1.0);
vec2 B1 = RayDirection - A1;
vec2 C1 = rotate(vec2(-1.0, 0.0), vec2(center.x, 0.0), YRot);
vec2 D1 = rotate(vec2(1.0, 0.0), vec2(center.x, 0.0), YRot) - C1;

// calculate intersection point
float u = ( (C1.y + 1.0) * D1.x - C1.x * D1.y ) / (D1.x*B1.y-D1.y*B1.x);

// position on the XY plane after Y-axis rotation
float sx = u * B1.x;
float sy = u * uv.y;

// Now Rotate around X axis
RayDirection = vec2(sy, 0.0);
vec2 B2 = RayDirection - A1;
vec2 C2 = rotate(vec2(-1.0, 0.0), vec2(center.y, 0.0), XRot);
vec2 D2 = rotate(vec2(1.0, 0.0), vec2(center.y, 0.0), XRot) - C2;

// calculate intersection point
float v = ( (C2.y + 1.0) * D2.x - C2.x * D2.y ) / (D2.x*B2.y-D2.y*B2.x);

// the position after x and y rotations
vec3 pos = vec3(v * sx, v * B2.x, 0.0 );

// Now rotate the position around Z axis
vec3 finalPos = rotateZ(pos, center, ZRot);

// final position on the 3D plane after Z-axis rotation
return finalPos.xy;
}

void main()
{
vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / u_resolution.xy;
float R_X = 0.;
float R_Y =  u_time;
float R_Z = 0.; // Adjust the value for Z-axis rotation
vec3 MyCoords = vec3(TransformPlane(uv, RotationCenter, R_X, R_Y, R_Z), 0.0);
vec2 MyTexCoord = (MyCoords.xy + vec2(1.0)) / 2.0;

//vec4 image1 = texture2D(texture, MyTexCoord);
//vec4 image2 = texture(iChannel1, MyTexCoord);
//fragColor = mix(image1, image2, (sin(iTime * 0.5) + 1.0) / 2.0);
gl_FragColor = texture2D(texture, MyTexCoord);
}

The shader looks fine and seems to work on a sprite but i don't know if i can use it to spin a text.
I tried to use a rendertexture and make a sprite out of it but with this i have a black background on my text
sf::RenderTexture rendertexture;
rendertexture.create(SCREEN_WIDTH,SCREEN_HEIGHT);
rendertexture.clear();
rendertexture.draw(myText);
sf::Sprite sprite(rendertexture.getTexture());
//window.draw(myText,&testRotation); This doesnt work
window.draw(sprite,&testRotation);
This doesnt work, i dont know if i need to use deeper things as vertex and stuff like that.
Thanks for reading this and let me know if you need sample of code or smthing else
« Last Edit: May 13, 2024, 03:20:16 pm by Esteban »

#### kojack

• Sr. Member
• Posts: 335
• C++/C# game dev teacher.
##### Re: Using shader to apply fake 3D rotation effect on a sf::Text
« Reply #1 on: May 12, 2024, 11:29:28 pm »
Render textures need to have display() called on them after drawing on them for them to update correctly.
So after rendertexture.draw(myText); put a rendertexture.display(); and see if that helps.

#### Esteban

• Newbie
• Posts: 6
##### Re: Using shader to apply fake 3D rotation effect on a sf::Text
« Reply #2 on: May 13, 2024, 08:28:21 am »
Render textures need to have display() called on them after drawing on them for them to update correctly.
So after rendertexture.draw(myText); put a rendertexture.display(); and see if that helps.
Thanks for you answer,i did it previously but it dont change the behaviour (which is kinda weird because yes i didnt display anything on the screen yet) but it result on the same black background.

I used this tutorial to help me use my shader on the text but i couldn't figure it out
« Last Edit: May 13, 2024, 08:37:42 am by Esteban »

#### eXpl0it3r

• SFML Team
• Hero Member
• Posts: 10936
##### Re: Using shader to apply fake 3D rotation effect on a sf::Text
« Reply #3 on: May 13, 2024, 08:29:09 am »
Not sure it will give you the wanted effect, but you can pass the shader as render state during the draw call of the text object itself: window.draw(text, shader) (this should implicitly construct a sf::RenderState).

but with this i have a black background on my text
You'll need to clear the RenderTexture with a transparent color (alpha = 0).
You may then want to render the text without any blending (i.e. without alpha blending) to prevent colored outlines.

Alternatively, you can also take a look at Hapax's Spinning card: https://github.com/Hapaxia/SelbaWard/wiki/Spinning-Card
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

#### Esteban

• Newbie
• Posts: 6
##### Re: Using shader to apply fake 3D rotation effect on a sf::Text
« Reply #4 on: May 13, 2024, 08:36:03 am »
that the effect i want to get thanks for your answer ! And thanks for you work on sfml this is huge