Emuladores de consoles antigos nos PCs necessitam de processamento em cima dos gráficos, já que os jogos até o Playstation 1 não passavam de 512 x 384, raras as exceções, o que não era percebido na época em razão das baixas resoluções das televisões.
Os arquivos dos shaders são plain text e ao serem importados nos emuladores são compilados e a partir daí interpretados. Podem conter os mais diversos efeitos, desde algo que se aproxime de uma filtragem anti-alising, a efeitos de cartoon e vidros quebrados.
Vou colocar aqui exemplos para o SNES e o Playstation 1:
SNES: shaders no snes9x
Basta selecionar em Display se deseja utilizar Direct3D ou OpenGL. Daí é só importar o arquivo na seção correspondente. Aqui utilizo Direct3D.
Imagem para visualizar a tela:
E aqui o shader 4xSoft-HD em ação:
Esse filtro dá um efeito semelhante a anti-alising, muito bom para jogar em resoluções altas, como dá para ver nas imagens.
Aqui o código:
/*
Copyright (C) 2007 guest(r) - guest.r@gmail.com
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
The 4xSoft shader processes a gfx. surface and redraws it 4x finer.
Note: set scaler to normal2x.
*/
const static half3 dt = half3(1.0, 1.0, 1.0);
struct input
{
half2 video_size;
half2 texture_size;
half2 output_size;
};
struct out_vertex {
half4 position : POSITION;
half4 color : COLOR;
half2 texCoord : TEXCOORD0;
half4 t1 : TEXCOORD1;
half4 t2 : TEXCOORD2;
half4 t3 : TEXCOORD3;
half4 t4 : TEXCOORD4;
half4 t5 : TEXCOORD5;
half4 t6 : TEXCOORD6;
};
/* VERTEX_SHADER */
out_vertex main_vertex
(
half4 position : POSITION,
half4 color : COLOR,
half2 tex : TEXCOORD0,
uniform half4x4 modelViewProj,
uniform input IN
)
{
half2 ps = half2(1.0/1152.0, 1.0/672.0);
half dx = ps.x;
half dy = ps.y;
half sx = ps.x * 0.5;
half sy = ps.y * 0.5;
out_vertex OUT = {
mul(modelViewProj, position),
color,
tex,
half4(tex,tex) + half4(-dx, -dy, dx, -dy), // outer diag. texels
half4(tex,tex) + half4(dx, dy, -dx, dy),
half4(tex,tex) + half4(-sx, -sy, sx, -sy), // inner diag. texels
half4(tex,tex) + half4(sx, sy, -sx, sy),
half4(tex,tex) + half4(-dx, 0, dx, 0), // inner hor/vert texels
half4(tex,tex) + half4(0, -dy, 0, dy)
};
return OUT;
}
half4 main_fragment(in out_vertex VAR, uniform sampler2D s_p : TEXUNIT0, uniform input IN) : COLOR
{
half3 c11 = tex2D(s_p, VAR.texCoord).xyz;
half3 c00 = tex2D(s_p, VAR.t1.xy).xyz;
half3 c20 = tex2D(s_p, VAR.t1.zw).xyz;
half3 c22 = tex2D(s_p, VAR.t2.xy).xyz;
half3 c02 = tex2D(s_p, VAR.t2.zw).xyz;
half3 s00 = tex2D(s_p, VAR.t3.xy).xyz;
half3 s20 = tex2D(s_p, VAR.t3.zw).xyz;
half3 s22 = tex2D(s_p, VAR.t4.xy).xyz;
half3 s02 = tex2D(s_p, VAR.t4.zw).xyz;
half3 c01 = tex2D(s_p, VAR.t5.xy).xyz;
half3 c21 = tex2D(s_p, VAR.t5.zw).xyz;
half3 c10 = tex2D(s_p, VAR.t6.xy).xyz;
half3 c12 = tex2D(s_p, VAR.t6.zw).xyz;
half d1=dot(abs(c00-c22),dt)+0.0001;
half d2=dot(abs(c20-c02),dt)+0.0001;
half hl=dot(abs(c01-c21),dt)+0.0001;
half vl=dot(abs(c10-c12),dt)+0.0001;
half m1=dot(abs(c00-c22),dt)+0.001;
half m2=dot(abs(c02-c20),dt)+0.001;
half3 t1=(hl*(c10+c12)+vl*(c01+c21)+(hl+vl)*c11)/(3.0*(hl+vl));
half3 t2=(d1*(c20+c02)+d2*(c00+c22)+(d1+d2)*c11)/(3.0*(d1+d2));
return half4(0.25*(t1+t2+(m2*(s00+s22)+m1*(s02+s20))/(m1+m2)),0);
}
Playstation: Shaders no EPSXE, utilizando o plugin de vídeo Pete's OpenGL2 2.9Aqui o processo é bem semelhante, cada shader é feito com base em um tipo de efeito em cima do plugin. No caso gosto aqui bastante do Natural Shader, o qual funciona selecionando em Shader Effects a opção número 5 GLSlang Files.
Reparem que está selecionado Internal X Resolution e Internal Y Resolution em 1, pois assim fica com um efeito que ficaria na TV de resolução baixa.
Imagens abaixo do Natural Shader em execução:
Final Fantasy 8 com o Natural Shader, com resolução 1366x768:
Agora na mesma resolução sem shader nenhum:
Aqui um shader que simula efeitos de vidro quebrado e uma screen do Advanced Cartoon Shader e um vídeo (não meu) mostrando os efeitos no Final Fantasy 7:
http://www.dailymotion.com/video/x6odte_ff7-cartoon-shader-epsxe-1-70_videogames
Aqui um pacote com todos os shaders que utilizei no tutorial: http://www.4shared.com/file/GCK2egjs/shaders.html
No Project64, os plugins Glide64 NapalmWX e Mudlord's Rice Video (versão aqui modificada pelo Aristotle) além do 1964 video suportam shaders e pacotes de texturas modificados. Para utilizá-los, basta pegar um pacote de texturas e dentro da pasta plugin, o Rice video cria uma pasta "hires_texture". Basta pegar um pacote, descompactá-lo e colocá-lo ali, com a pasta nomeada conforme aparece no título da janela do Emulador. Exemplo: O Zelda Ocarina of Time tem a informação do seu nome no cabeçalho do jogo como "The Legend of Zelda", daí a pasta com os texture pack deve ser nomeada desta forma.
Aqui um texture-pack que indico para o Ocarina of Time: http://www.n64redux.com/content/ocarina-time-community-retexture-project
Vejam a diferença:
Normal:
Com o Texture-Pack:
Com os textures pack ainda é possível coisas além, como tradução de jogos, como no Sin&Punishment: http://www.romhacking.net/translations/920/
Aqui eu gosto de jogar os jogos antigos mais natural, apenas tentando não deixar pixelado, como ficaria nas TVs CRT jogando.
E era isso, indiquem outros shaders que acham bons que não foram citados aqui. Para outros consoles também.