I am trying to make a ASCII art (text art) shader with edge detection based upon this video: https://youtu.be/gg40RWiaHRY (most relevant part starts at about 8:00) I have recreated the base ASCII shader.
I have a Sobel filter, but I cannot figure how to make the edge detection place texture or have at the right spacing.
Sobel filter:
(the colors represent different angles)
the code in the custom nodes:
float2 sobelMatrix[9] = { float2(-1,-1), float2(0,-2), float2(1,-1),
float2(-1, 0), float2(0, 0), float2(1, 0),
float2(-1 ,1), float2(0, 2), float2(1, 1) };
float intensity = 1.0;
float2 gradients = 0.0;
for (int i = 0; i < 9; i++)
{
int row = i / 3;
int col = i % 3;
float offsetX = (col - 1) /res.x;
float offsetY = (row - 1) /res.y;
float2 offsetUV = float2(uv.x + offsetX, uv.y + offsetY);
float2 sampledintensity = SceneTextureLookup(offsetUV, 14, false);
gradients += sobelMatrix[i] * sampledintensity;
}
gradients *= intensity;
// Calculate gradient magnitude
float gradientMagnitude = length(gradients);
// Threshold to detect edges
float threshold = 0.5; // Adjust this threshold as needed
if (gradientMagnitude < threshold)
{
// If gradient magnitude is below threshold, output black (or another color of your choice)
return float4(0.0, 0.0, 0.0, 1.0); // Black
}
else
{
// Calculate gradient angle
float angle = atan2(gradients.y, gradients.x);
angle = degrees(angle); // Convert radians to degrees
// Map angle to 0, 45, 90, or 135 degrees
float mappedAngle = fmod(angle + 22.5, 180.0); // HLSL uses fmod for modulus operation
if (mappedAngle < 0.0)
mappedAngle += 180.0;
int sector = int(floor(mappedAngle / 45.0)) % 4;
// Output color based on sector
float4 color;
switch (sector)
{
case 0: // 0-45 degrees
color = float4(1.0, 0.0, 0.0, 1.0); // Red
break;
case 1: // 45-90 degrees
color = float4(0.0, 1.0, 0.0, 1.0); // Green
break;
case 2: // 90-135 degrees
color = float4(0.0, 0.0, 1.0, 1.0); // Blue
break;
case 3: // 135-180 degrees
color = float4(1.0, 1.0, 0.0, 1.0); // Yellow
break;
default:
color = float4(0.0, 0.0, 0.0, 1.0); // Black (shouldnt happen)
break;
}
return color;
}
and the node for the UV:
return GetSceneTextureUV(Parameters);
I was wondering if it was possible to to have the screen split into 8x8 pixel quadrants.
and averaging the color in the quadrant and depending on how close that color is to red, green, blue or yellow
it chooses witch texture to place there. But i don’t know how to do that or even if its the best option
well there it is if you need the base ASCII shader or anything just tell me
P.S. I am very new to coding and unreal in general all the code I got from watching tutorials