Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions examples/shaders/resources/shaders/glsl100/ascii.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#version 100

precision mediump float;

// Input from the vertex shader
varying vec2 fragTexCoord;

// Output color for the screen
varying vec4 finalColor;

uniform sampler2D texture0;
uniform vec2 resolution;
uniform float fontSize;

float greyScale(in vec3 col) {
return dot(col, vec3(0.2126, 0.7152, 0.0722));
}

float character(float n, vec2 p)
{
p = floor(p * vec2(4.0, -4.0) + 2.5);

// Check if the coordinate is inside the 5x5 grid (0 to 4).
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y) {

if (int(mod(n / exp2(p.x + 5.0 * p.y), 2.0)) == 1) {
return 1.0; // The bit is on, so draw this part of the character.
}
}

return 0.0; // The bit is off, or we are outside the grid.
}

// -----------------------------------------------------------------------------
// Main shader logic
// -----------------------------------------------------------------------------
void main()
{
vec2 charPixelSize = vec2(fontSize, fontSize * 1.8);
vec2 uvCellSize = charPixelSize / resolution;

vec2 cellUV = floor(fragTexCoord / uvCellSize) * uvCellSize;

vec3 cellColor = texture2D(texture0, cellUV).rgb;
float gray = greyScale(cellColor);

float n = 4096;

// limited character set
if (gray > 0.2) n = 65600.0; // :
if (gray > 0.3) n = 163153.0; // *
if (gray > 0.4) n = 15255086.0; // o
if (gray > 0.5) n = 13121101.0; // &
if (gray > 0.6) n = 15252014.0; // 8
if (gray > 0.7) n = 13195790.0; // @
if (gray > 0.8) n = 11512810.0; // #

vec2 localUV = (fragTexCoord - cellUV) / uvCellSize; // Range [0.0, 1.0]

vec2 p = localUV * 2.0 - 1.0;

float charShape = character(n, p);

vec3 final_col = cellColor * charShape;

gl_FragColor = vec4(final_col, 1.0);
}
65 changes: 65 additions & 0 deletions examples/shaders/resources/shaders/glsl120/ascii.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#version 120

// Input from the vertex shader
varying vec2 fragTexCoord;

// Output color for the screen
varying vec4 finalColor;

uniform sampler2D texture0;
uniform vec2 resolution;
uniform float fontSize;

float greyScale(in vec3 col) {
return dot(col, vec3(0.2126, 0.7152, 0.0722));
}

float character(float n, vec2 p)
{
p = floor(p * vec2(4.0, -4.0) + 2.5);

// Check if the coordinate is inside the 5x5 grid (0 to 4).
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y) {

if (int(mod(n / exp2(p.x + 5.0 * p.y), 2.0)) == 1) {
return 1.0; // The bit is on, so draw this part of the character.
}
}

return 0.0; // The bit is off, or we are outside the grid.
}

// -----------------------------------------------------------------------------
// Main shader logic
// -----------------------------------------------------------------------------
void main()
{
vec2 charPixelSize = vec2(fontSize, fontSize * 1.8);
vec2 uvCellSize = charPixelSize / resolution;

vec2 cellUV = floor(fragTexCoord / uvCellSize) * uvCellSize;

vec3 cellColor = texture2D(texture0, cellUV).rgb;
float gray = greyScale(cellColor);

float n = 4096;

// limited character set
if (gray > 0.2) n = 65600.0; // :
if (gray > 0.3) n = 163153.0; // *
if (gray > 0.4) n = 15255086.0; // o
if (gray > 0.5) n = 13121101.0; // &
if (gray > 0.6) n = 15252014.0; // 8
if (gray > 0.7) n = 13195790.0; // @
if (gray > 0.8) n = 11512810.0; // #

vec2 localUV = (fragTexCoord - cellUV) / uvCellSize; // Range [0.0, 1.0]

vec2 p = localUV * 2.0 - 1.0;

float charShape = character(n, p);

vec3 final_col = cellColor * charShape;

gl_FragColor = vec4(final_col, 1.0);
}
66 changes: 66 additions & 0 deletions examples/shaders/resources/shaders/glsl330/ascii.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#version 330

// Input from the vertex shader
in vec2 fragTexCoord;

// Output color for the screen
out vec4 finalColor;

uniform sampler2D texture0;
uniform vec2 resolution;
uniform float fontSize;

float greyScale(in vec3 col) {
return dot(col, vec3(0.2126, 0.7152, 0.0722));
}

float character(float n, vec2 p)
{
p = floor(p * vec2(4.0, -4.0) + 2.5);

// Check if the coordinate is inside the 5x5 grid (0 to 4).
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y) {

if (int(mod(n / exp2(p.x + 5.0 * p.y), 2.0)) == 1) {
return 1.0; // The bit is on, so draw this part of the character.
}
}

return 0.0; // The bit is off, or we are outside the grid.
}

// -----------------------------------------------------------------------------
// Main shader logic
// -----------------------------------------------------------------------------

void main()
{
vec2 charPixelSize = vec2(fontSize, fontSize * 1.8);
vec2 uvCellSize = charPixelSize / resolution;

vec2 cellUV = floor(fragTexCoord / uvCellSize) * uvCellSize;

vec3 cellColor = texture(texture0, cellUV).rgb;
float gray = greyScale(cellColor);

float n = 4096;

// limited character set
if (gray > 0.2) n = 65600.0; // :
if (gray > 0.3) n = 163153.0; // *
if (gray > 0.4) n = 15255086.0; // o
if (gray > 0.5) n = 13121101.0; // &
if (gray > 0.6) n = 15252014.0; // 8
if (gray > 0.7) n = 13195790.0; // @
if (gray > 0.8) n = 11512810.0; // #

vec2 localUV = (fragTexCoord - cellUV) / uvCellSize; // Range [0.0, 1.0]

vec2 p = localUV * 2.0 - 1.0;

float charShape = character(n, p);

vec3 final_col = cellColor * charShape;

finalColor = vec4(final_col, 1.0);
}
119 changes: 119 additions & 0 deletions examples/shaders/shaders_ascii_effect.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*******************************************************************************************
*
* raylib [shaders] example - ascii effect
*
* Example complexity rating: [★☆☆☆] 1/4
*
* Example originally created with raylib 5.5, last time updated with raylib 5.6
*
* Example contributed by Maicon Santana (@maiconpintoabreu) and reviewed by Ramon Santamaria (@raysan5)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2025-2025 Maicon Santana (@maiconpintoabreu)
*
********************************************************************************************/

#include "raylib.h"

#if defined(PLATFORM_DESKTOP)
#define GLSL_VERSION 330
#else // PLATFORM_ANDROID, PLATFORM_WEB
#define GLSL_VERSION 100
#endif

//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;

InitWindow(screenWidth, screenHeight, "raylib [shaders] example - ascii effect");

// Texture to test static drawing
Texture2D fudesumi = LoadTexture("resources/fudesumi.png");
// Texture to test moving drawing
Texture2D raysan = LoadTexture("resources/raysan.png");

// Load shader to be used on postprocessing
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/ascii.fs", GLSL_VERSION));

// These locations are used to send data to the GPU.
int resolutionLoc = GetShaderLocation(shader, "resolution");
int fontSizeLoc = GetShaderLocation(shader, "fontSize");

// Set the character size for the ASCII effect
float fontSize = 4.0f;

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

Vector2 circlePos = (Vector2){40.0f, (float)screenHeight * 0.5f};
float circleSpeed = 1.0f;

// RenderTexture to apply the postprocessing later
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);

SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------

// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (circlePos.x > 200.0f || circlePos.x < 40.0f) {
circleSpeed *= -1;
}
circlePos.x += circleSpeed;

// Draw
//----------------------------------------------------------------------------------

BeginTextureMode(target);
ClearBackground(WHITE); // The background of the scene itself

DrawTexture(fudesumi, 500, -30, WHITE); // Using custom shader
DrawTextureV(raysan, circlePos, WHITE);

EndTextureMode();
BeginDrawing();

ClearBackground(RAYWHITE);

BeginShaderMode(shader);

// Draw the scene texture (that we rendered earlier) to the screen.
// The shader will process every pixel of this texture.
DrawTextureRec(target.texture,
(Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height },
(Vector2){ 0, 0 },
WHITE);
EndShaderMode();

DrawRectangle(0, 0, screenWidth, 40, BLACK);
DrawText("Ascii effect", 120, 10, 20, LIGHTGRAY);
DrawFPS(10, 10);

EndDrawing();
//----------------------------------------------------------------------------------
}

// De-Initialization
//--------------------------------------------------------------------------------------
UnloadShader(shader); // Unload shader
UnloadTexture(fudesumi); // Unload texture
UnloadTexture(raysan); // Unload texture

CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

return 0;
}
Binary file added examples/shaders/shaders_ascii_effect.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading