Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Text and shaders  (Read 952 times)

0 Members and 1 Guest are viewing this topic.

ThePersonWithAQuestion

  • Newbie
  • *
  • Posts: 5
    • View Profile
Text and shaders
« on: April 26, 2025, 01:06:13 pm »
Hello there, I'm here again with a new question. To make it short, I want to shade text to like like what you see in this picture:

Every text is different, but what they share is that  they have different coloring depending on their pixel position. I wonder what's the best strategy to achieve this. By the way, I'm using ttf fonts.
« Last Edit: April 26, 2025, 01:08:11 pm by ThePersonWithAQuestion »

Me-Myself-And-I

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Re: Text and shaders
« Reply #1 on: April 28, 2025, 06:04:51 am »
I don't think SFML supports this. You might be able to duplicate the effect by drawing a font like this then making something that places each letter along a specified position. You could also make an array ID list to reference the needed image IntRect in relation to the char requested. That is a bit of a hackish method but I think it is basically same to what they did in those example games anyway.

Hapax

  • Hero Member
  • *****
  • Posts: 3422
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Text and shaders
« Reply #2 on: April 29, 2025, 07:26:33 pm »
Presumably, the vertical gradient is to what you refer?

This effect can be done in SFML simply with two very different methods.

The first would be to use a bitmap text instead of a scalable text (like TTF, for example).
One example of this is Selba Ward's Bitmap Text:


The second would be to use a fragment shader. Fragment shaders adjust the pixel dependant on a multitude of things but included is the pixel position so you can, for example, just adjust the colour based on the y position of the fragment (pixel). Note, though, that OpenGL fragment shaders use non-inverted y axis; that is, the opposite to SFML - the y value increase as it goes up instead of down.
These can seem to be a bit complicated at first but once you get used to them, they are very powerful and flexible, and - I expect - would be the ideal approach for your situation.


EDIT:
In addition, there is another rather simple solution but adds additional overhead (cost of the simplicity):
Render the text to a render texture and the draw that render texture with a quad (vertex array). This vertex array can have different colours per vertex so each corner can have a different colour. This allows both the top corners to be the same and both the bottom ones to be the same. However, the top and bottom can be different, causing linear interpolation - vertically - causing a gradient. If you want to try this method, remember to render the text as while (on a transparent render texture) and note that you can only pick two colours (the top and bottom) so you cannot have it go from one colour to another and back again without splitting the quad into pieces (although that is relatively simple to do too!).
« Last Edit: April 29, 2025, 07:55:45 pm by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11193
    • View Profile
    • development blog
    • Email
Re: Text and shaders
« Reply #3 on: April 30, 2025, 08:15:30 am »
A fourth option, although I've never done this and wouldn't know how, is to use stencil testing. So the rendered text becomes a stencil to use with another texture that has the gradient.
Official FAQ: https://www.sfml-dev.org/faq/
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Hapax

  • Hero Member
  • *****
  • Posts: 3422
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Text and shaders
« Reply #4 on: April 30, 2025, 07:04:09 pm »
I realised that gradients in texts are so common that I really should have a shader prepared for that sort of thing already but alas, I did not.

That was then (up to yesterday) and this is now!

I present to you my new shader: multiGradient!

I've added it to be a part of my Lens collection. All shaders are in the "Lens" folder of that directory.
For information on how to use it, you can read the short wiki entry:
https://github.com/Hapaxia/Lens/wiki#multigradient

It allows to provide multiple heights (y positions) and multiple colours to the shader. The shader then interpolates those colours based on the current y position, creating a gradient.
This can be used on textured or non-textured objects and there can be up to 16 different heights and colours!

Here are a couple of quick test examples...

3 steps (3 different colours - yellow, magenta, cyan):


10 steps (10 different colours, yellow, magenta, cyan, white, blue, yellow, magenta, cyan, red, black):

Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*