Hello! I have been working on a shader to turn this
into this
To do so I know I have identified that I need the following things:
- The ability to recolor the image
- The ability to scale the screen to add a background border
- Per-pixel LCD grid lines
- Some way to create slightly darker foreground area
- filtering to blur the border between pixels, but not go over the grid or outside the pixel grid area
- shadow to define the boundry between the “foreground” and “background” layer
All while keeping the pixels perfectly square, with no warping. So far I’ve been able to achieve this:
With this Shader (some variables aren’t in use yet)
Shader "Custom/GameboyScreen"
{
Properties
{
_MainTex("Gameboy Screen Render Texture", 2D) = "white" {}
_ScaleFactor("Amount to reduce by", Range(0.0, 1.0)) = 0.25
_ScreenResolutionH("Horizontal Screen Resolution", float) = 160
_ScreenResolutionV("Vertical Screen Resolution", float) = 144
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_TexelSize;
float4 _MainTex_ST;
float _ScaleFactor;
float _ScreenResolutionH;
float _ScreenResolutionV;
half4x4 _ColorMatrix;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
//Screen Scaling
float2 scaleCenter = float2(0.5f, 0.5f);
i.uv = (i.uv - scaleCenter) * (1 + _ScaleFactor) + scaleCenter;
//Colorize
fixed red = tex2D(_MainTex, i.uv).r;
float4 colorized = _ColorMatrix[red * 3];
// Pixel Border
int x = _MainTex_TexelSize.z * i.uv.x;
int y = _MainTex_TexelSize.w * i.uv.y;
int xmod = x % 8;
int ymod = y % 8;
if (xmod == 0 || ymod == 0)
{
colorized += float4(.02, .02, .02, 0);
}
return colorized;
}
ENDCG
}
}
}
I’ve also attached all my assets so you can see the setup. I was able to recolor the screen pretty easily. I can resize the texture, but I get artifacts around the border, and I don’t know if the way I’m doing it can reliably create pixel-perfect output. For the pixel grid, I was able to figure out how to create the lines at 8x8 tiles, but I’m not sure how to create the sub-pixel borders with my current setup.
The way I have it set up currently takes a render texture at the native resolution of the Gameboy, then applies that texture to a plane with the shader effects added. I think I’d have to do something to upscale the texture, but I’m not sure how to do that.
Does anyone have any tips for how I can proceed with this? I’m not sure where to go from here.
Thank you!
4996190–488051–GB Screen Test Project.unitypackage (24.1 KB)