Skip to content

Commit edf2951

Browse files
maiconpintoabreupsxdev
authored andcommitted
[examples] Fix shaders_ascii_rendering (raysan5#5219)
* Add ascii post processing * Fix broken characters and add more comments * Rename example * Refactored as requested
1 parent ae62946 commit edf2951

File tree

5 files changed

+125
-79
lines changed

5 files changed

+125
-79
lines changed

examples/shaders/resources/shaders/glsl100/ascii.fs

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,58 +10,71 @@ varying vec4 finalColor;
1010

1111
uniform sampler2D texture0;
1212
uniform vec2 resolution;
13+
14+
// Fontsize less then 9 may be not complete
1315
uniform float fontSize;
1416

15-
float greyScale(in vec3 col) {
17+
float GreyScale(in vec3 col)
18+
{
1619
return dot(col, vec3(0.2126, 0.7152, 0.0722));
1720
}
1821

19-
float character(float n, vec2 p)
22+
float GetCharacter(float n, vec2 p)
2023
{
21-
p = floor(p * vec2(4.0, -4.0) + 2.5);
22-
23-
// Check if the coordinate is inside the 5x5 grid (0 to 4).
24-
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y) {
25-
26-
if (int(mod(n / exp2(p.x + 5.0 * p.y), 2.0)) == 1) {
27-
return 1.0; // The bit is on, so draw this part of the character.
24+
p = floor(p*vec2(-4.0, 4.0) + 2.5);
25+
26+
// Check if the calculated coordinate is inside the 5x5 grid (from 0.0 to 4.0)
27+
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y)
28+
{
29+
float a = floor(p.x + 0.5) + 5.0*floor(p.y + 0.5);
30+
31+
// This checked if the 'a'-th bit of 'n' was set
32+
float shiftedN = floor(n/pow(2.0, a));
33+
34+
if (mod(shiftedN, 2.0) == 1.0)
35+
{
36+
return 1.0; // The bit is on
2837
}
2938
}
3039

31-
return 0.0; // The bit is off, or we are outside the grid.
40+
return 0.0; // The bit is off, or we are outside the grid
3241
}
3342

3443
// -----------------------------------------------------------------------------
3544
// Main shader logic
3645
// -----------------------------------------------------------------------------
46+
3747
void main()
3848
{
39-
vec2 charPixelSize = vec2(fontSize, fontSize * 1.8);
40-
vec2 uvCellSize = charPixelSize / resolution;
49+
vec2 charPixelSize = vec2(fontSize, fontSize);
50+
vec2 uvCellSize = charPixelSize/resolution;
4151

42-
vec2 cellUV = floor(fragTexCoord / uvCellSize) * uvCellSize;
52+
// The cell size is based on the fontSize set by application
53+
vec2 cellUV = floor(fragTexCoord/uvCellSize)*uvCellSize;
4354

4455
vec3 cellColor = texture2D(texture0, cellUV).rgb;
45-
float gray = greyScale(cellColor);
4656

47-
float n = 4096;
57+
// Gray is used to define what character will be selected to draw
58+
float gray = GreyScale(cellColor);
59+
60+
float n = 4096.0;
4861

49-
// limited character set
62+
// Character set from https://www.shadertoy.com/view/lssGDj
63+
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
5064
if (gray > 0.2) n = 65600.0; // :
51-
if (gray > 0.3) n = 163153.0; // *
65+
if (gray > 0.3) n = 18725316.0; // v
5266
if (gray > 0.4) n = 15255086.0; // o
5367
if (gray > 0.5) n = 13121101.0; // &
5468
if (gray > 0.6) n = 15252014.0; // 8
5569
if (gray > 0.7) n = 13195790.0; // @
5670
if (gray > 0.8) n = 11512810.0; // #
5771

58-
vec2 localUV = (fragTexCoord - cellUV) / uvCellSize; // Range [0.0, 1.0]
59-
60-
vec2 p = localUV * 2.0 - 1.0;
72+
vec2 localUV = (fragTexCoord - cellUV)/uvCellSize; // Range [0.0, 1.0]
6173

62-
float charShape = character(n, p);
74+
vec2 p = localUV*2.0 - 1.0; // Range [-1.0, 1.0]
6375

64-
vec3 final_col = cellColor * charShape;
76+
// cellColor and charShape will define the color of the char
77+
vec3 color = cellColor*GetCharacter(n, p);
6578

66-
gl_FragColor = vec4(final_col, 1.0);
79+
gl_FragColor = vec4(color, 1.0);
6780
}

examples/shaders/resources/shaders/glsl120/ascii.fs

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,58 +8,71 @@ varying vec4 finalColor;
88

99
uniform sampler2D texture0;
1010
uniform vec2 resolution;
11+
12+
// Fontsize less then 9 may be not complete
1113
uniform float fontSize;
1214

13-
float greyScale(in vec3 col) {
15+
float GreyScale(in vec3 col)
16+
{
1417
return dot(col, vec3(0.2126, 0.7152, 0.0722));
1518
}
1619

17-
float character(float n, vec2 p)
20+
float GetCharacter(float n, vec2 p)
1821
{
19-
p = floor(p * vec2(4.0, -4.0) + 2.5);
20-
21-
// Check if the coordinate is inside the 5x5 grid (0 to 4).
22-
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y) {
23-
24-
if (int(mod(n / exp2(p.x + 5.0 * p.y), 2.0)) == 1) {
25-
return 1.0; // The bit is on, so draw this part of the character.
22+
p = floor(p*vec2(-4.0, 4.0) + 2.5);
23+
24+
// Check if the calculated coordinate is inside the 5x5 grid (from 0.0 to 4.0)
25+
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y)
26+
{
27+
float a = floor(p.x + 0.5) + 5.0*floor(p.y + 0.5);
28+
29+
// This checked if the 'a'-th bit of 'n' was set
30+
float shiftedN = floor(n/pow(2.0, a));
31+
32+
if (mod(shiftedN, 2.0) == 1.0)
33+
{
34+
return 1.0; // The bit is on
2635
}
2736
}
2837

29-
return 0.0; // The bit is off, or we are outside the grid.
38+
return 0.0; // The bit is off, or we are outside the grid
3039
}
3140

3241
// -----------------------------------------------------------------------------
3342
// Main shader logic
3443
// -----------------------------------------------------------------------------
44+
3545
void main()
3646
{
37-
vec2 charPixelSize = vec2(fontSize, fontSize * 1.8);
47+
vec2 charPixelSize = vec2(fontSize, fontSize);
3848
vec2 uvCellSize = charPixelSize / resolution;
3949

40-
vec2 cellUV = floor(fragTexCoord / uvCellSize) * uvCellSize;
50+
// The cell size is based on the fontSize set by application
51+
vec2 cellUV = floor(fragTexCoord / uvCellSize)*uvCellSize;
4152

4253
vec3 cellColor = texture2D(texture0, cellUV).rgb;
43-
float gray = greyScale(cellColor);
4454

45-
float n = 4096;
55+
// Gray is used to define what character will be selected to draw
56+
float gray = GreyScale(cellColor);
57+
58+
float n = 4096.0;
4659

47-
// limited character set
60+
// Character set from https://www.shadertoy.com/view/lssGDj
61+
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
4862
if (gray > 0.2) n = 65600.0; // :
49-
if (gray > 0.3) n = 163153.0; // *
63+
if (gray > 0.3) n = 18725316.0; // v
5064
if (gray > 0.4) n = 15255086.0; // o
5165
if (gray > 0.5) n = 13121101.0; // &
5266
if (gray > 0.6) n = 15252014.0; // 8
5367
if (gray > 0.7) n = 13195790.0; // @
5468
if (gray > 0.8) n = 11512810.0; // #
5569

56-
vec2 localUV = (fragTexCoord - cellUV) / uvCellSize; // Range [0.0, 1.0]
57-
58-
vec2 p = localUV * 2.0 - 1.0;
70+
vec2 localUV = (fragTexCoord - cellUV)/uvCellSize; // Range [0.0, 1.0]
5971

60-
float charShape = character(n, p);
72+
vec2 p = localUV*2.0 - 1.0; // Range [-1.0, 1.0]
6173

62-
vec3 final_col = cellColor * charShape;
74+
// cellColor and charShape will define the color of the char
75+
vec3 color = cellColor*GetCharacter(n, p);
6376

64-
gl_FragColor = vec4(final_col, 1.0);
77+
gl_FragColor = vec4(color, 1.0);
6578
}

examples/shaders/resources/shaders/glsl330/ascii.fs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,26 @@ out vec4 finalColor;
88

99
uniform sampler2D texture0;
1010
uniform vec2 resolution;
11+
12+
// Fontsize less then 9 may be not complete
1113
uniform float fontSize;
1214

1315
float GreyScale(in vec3 col)
1416
{
1517
return dot(col, vec3(0.2126, 0.7152, 0.0722));
1618
}
1719

18-
float GetCharacter(float n, vec2 p)
20+
float GetCharacter(int n, vec2 p)
1921
{
20-
p = floor(p*vec2(4.0, -4.0) + 2.5);
22+
p = floor(p*vec2(-4.0, 4.0) + 2.5);
2123

2224
// Check if the coordinate is inside the 5x5 grid (0 to 4)
2325
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y)
2426
{
25-
if (int(mod(n/exp2(p.x + 5.0 * p.y), 2.0)) == 1)
27+
int a = int(round(p.x) + 5.0*round(p.y));
28+
if (((n >> a) & 1) == 1)
2629
{
27-
return 1.0; // The bit is on, so draw this part of the character
30+
return 1.0;
2831
}
2932
}
3033

@@ -34,30 +37,37 @@ float GetCharacter(float n, vec2 p)
3437
// -----------------------------------------------------------------------------
3538
// Main shader logic
3639
// -----------------------------------------------------------------------------
40+
3741
void main()
3842
{
39-
vec2 charPixelSize = vec2(fontSize, fontSize*1.8);
43+
vec2 charPixelSize = vec2(fontSize, fontSize);
4044
vec2 uvCellSize = charPixelSize/resolution;
45+
46+
// The cell size is based on the fontSize set by application
4147
vec2 cellUV = floor(fragTexCoord/uvCellSize)*uvCellSize;
4248

4349
vec3 cellColor = texture(texture0, cellUV).rgb;
50+
51+
// Gray is used to define what character will be selected to draw
4452
float gray = GreyScale(cellColor);
4553

46-
float n = 4096;
54+
int n = 4096;
4755

48-
// Limited character set
49-
if (gray > 0.2) n = 65600.0; // :
50-
if (gray > 0.3) n = 163153.0; // *
51-
if (gray > 0.4) n = 15255086.0; // o
52-
if (gray > 0.5) n = 13121101.0; // &
53-
if (gray > 0.6) n = 15252014.0; // 8
54-
if (gray > 0.7) n = 13195790.0; // @
55-
if (gray > 0.8) n = 11512810.0; // #
56+
// Character set from https://www.shadertoy.com/view/lssGDj
57+
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
58+
if (gray > 0.2) n = 65600; // :
59+
if (gray > 0.3) n = 18725316; // v
60+
if (gray > 0.4) n = 15255086; // o
61+
if (gray > 0.5) n = 13121101; // &
62+
if (gray > 0.6) n = 15252014; // 8
63+
if (gray > 0.7) n = 13195790; // @
64+
if (gray > 0.8) n = 11512810; // #
5665

5766
vec2 localUV = (fragTexCoord - cellUV)/uvCellSize; // Range [0.0, 1.0]
58-
vec2 p = localUV*2.0 - 1.0;
5967

60-
float charShape = GetCharacter(n, p);
68+
vec2 p = localUV*2.0 - 1.0; // Range [-1.0, 1.0]
69+
70+
vec3 color = cellColor*GetCharacter(n, p);
6171

62-
finalColor = vec4(cellColor*charShape, 1.0);
72+
finalColor = vec4(color, 1.0);
6373
}

examples/shaders/shaders_ascii_rendering.c

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ int main(void)
4848
int fontSizeLoc = GetShaderLocation(shader, "fontSize");
4949

5050
// Set the character size for the ASCII effect
51-
float fontSize = 4.0f;
51+
// Fontsize should be 9 or more
52+
float fontSize = 9.0f;
5253

5354
// Send the updated values to the shader
5455
float resolution[2] = { (float)screenWidth, (float)screenHeight };
5556
SetShaderValue(shader, resolutionLoc, resolution, SHADER_UNIFORM_VEC2);
56-
SetShaderValue(shader, fontSizeLoc, &fontSize, SHADER_UNIFORM_FLOAT);
5757

58-
Vector2 circlePos = (Vector2){40.0f, (float)screenHeight * 0.5f};
58+
Vector2 circlePos = (Vector2){40.0f, (float)screenHeight*0.5f};
5959
float circleSpeed = 1.0f;
6060

6161
// RenderTexture to apply the postprocessing later
@@ -67,37 +67,47 @@ int main(void)
6767
// Main game loop
6868
while (!WindowShouldClose()) // Detect window close button or ESC key
6969
{
70+
7071
// Update
7172
//----------------------------------------------------------------------------------
73+
if (IsKeyPressed(KEY_LEFT) && fontSize > 9.0) fontSize -= 1; // Reduce fontSize
74+
75+
if (IsKeyPressed(KEY_RIGHT) && fontSize < 15.0) fontSize += 1; // Increase fontSize
76+
77+
if (circlePos.x > 200.0f || circlePos.x < 40.0f) circleSpeed *= -1; // Revert speed
78+
7279
circlePos.x += circleSpeed;
73-
74-
if ((circlePos.x > 200.0f) || (circlePos.x < 40.0f)) circleSpeed *= -1;
75-
//----------------------------------------------------------------------------------
80+
81+
// Set fontsize for the shader
82+
SetShaderValue(shader, fontSizeLoc, &fontSize, SHADER_UNIFORM_FLOAT);
7683

7784
// Draw
7885
//----------------------------------------------------------------------------------
79-
// Draw our scene to a render texture first
86+
8087
BeginTextureMode(target);
81-
ClearBackground(WHITE);
82-
88+
ClearBackground(WHITE); // The background of the scene itself
89+
90+
// Samples Using custom shader
8391
DrawTexture(fudesumi, 500, -30, WHITE);
8492
DrawTextureV(raysan, circlePos, WHITE);
85-
93+
8694
EndTextureMode();
87-
8895
BeginDrawing();
96+
8997
ClearBackground(RAYWHITE);
9098

9199
BeginShaderMode(shader);
92-
// Draw the render texture containing scene
93-
// The shader will process every pixel on the screen
94-
DrawTextureRec(target.texture,
95-
(Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height },
96-
(Vector2){ 0, 0 }, WHITE);
100+
101+
// Draw the scene texture (that we rendered earlier) to the screen
102+
// The shader will process every pixel of this texture
103+
DrawTextureRec(target.texture,
104+
(Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height },
105+
(Vector2){ 0, 0 },
106+
WHITE);
97107
EndShaderMode();
98108

99109
DrawRectangle(0, 0, screenWidth, 40, BLACK);
100-
DrawText("Ascii effect", 120, 10, 20, LIGHTGRAY);
110+
DrawText(TextFormat("Ascii effect - FontSize:%2.0f - [Left] -1 [Right] +1 ", fontSize), 120, 10, 20, LIGHTGRAY);
101111
DrawFPS(10, 10);
102112

103113
EndDrawing();
-2.08 KB
Loading

0 commit comments

Comments
 (0)