Pergunta interessante, talvez a amostragem pontual com um filtro pós-processo FXAA bruto faça algo semelhante ... Apenas uma idéia rápida, eu não testei.
János Turánszki
en.wikipedia.org/wiki/Hqx explica basicamente como eles funcionam e tem alguns links para implementações.
Eu tenho uma versão hack trabalhando usando o hqxSharpprojeto, mas, caramba, é lento (o que avisa). Preciso de algo que possa manter uma taxa de quadros decente.
test
1
Também pensei que o CG fosse compatível com o DirectX 9, no qual o iirc é baseado no XNA. Tente compilar um dos exemplos no link como se fosse um arquivo HLSL. github.com/libretro/common-shaders/tree/master/hqx
ClassicThunder
Respostas:
6
Você pode reduzir a contagem de instruções usando operações vetoriais: por exemplo, em vez de
Os operadores no HLSL podem ser aplicados a vetores, mesmo os lógicos, como &&dois bool3valores. Esses operadores executarão a operação componente a componente.
Eu já usei essas otimizações na minha resposta. Foi assim que consegui superar o erro no slot de instruções que estava vendo.
test
Deixa pra lá então. Eu estava um pouco lento demais :)
zogi
ir_lv1 = ((e != f) && (e != h));ir_lv2_left = ((e != g) && (d != g));ir_lv2_up = ((e != c) && (b != c)); Essas são boas otimizações que eu perdi e que você encontrou; não acabei precisando delas para o meu problema, porque reduzi a contagem de instruções com outras otimizações.
test
Está bem. Bom tópico embora. Eu nunca ouvi falar sobre esses algoritmos antes da sua pergunta. Encontrei este post sobre hqx, o que me ajudou a entender um pouco o algoritmo. Eu recomendo, se você estiver interessado.
zogi
6
Eu consegui isso funcionando. Ele não usa o filtro hqx, usa o filtro xBR (que eu prefiro). Para mim, isso não é um problema. Se você precisar do filtro hqx, convém converter os arquivos .cg no equivalente XNA apropriado.
Por motivos de integridade e pesquisa, editarei a pergunta para ser mais concisa e depois publicarei todas as informações relevantes para responder à pergunta aqui.
Etapa 1: Configuração do código do jogo
Primeiro, você provavelmente desejará configurar um destino de renderização no qual desenha seu jogo em uma escala de 1: 1 e depois renderiza o filtro.
usingMicrosoft.Xna.Framework;usingMicrosoft.Xna.Framework.Graphics;namespace xbr
{/// <summary>/// This is the main type for your game/// </summary>publicclassGame1:Microsoft.Xna.Framework.Game{GraphicsDeviceManager graphics;SpriteBatch spriteBatch;RenderTarget2D renderTarget;Effect xbrEffect;Matrix projection;Matrix halfPixelOffset =Matrix.CreateTranslation(-0.5f,-0.5f,0);Texture2D pretend240x160Scene;// the bounds of your 1:1 sceneRectangle renderBounds =newRectangle(0,0,240,160);// the bounds of your output scene (same w:h ratio)Rectangle outputBounds =newRectangle(0,0,720,480);publicGame1(){base.Content.RootDirectory="Content";this.graphics =newGraphicsDeviceManager(this);this.graphics.PreferredBackBufferWidth= outputBounds.Width;this.graphics.PreferredBackBufferHeight= outputBounds.Height;}/// <summary>/// Allows the game to perform any initialization it needs to before starting to run./// This is where it can query for any required services and load any non-graphic/// related content. Calling base.Initialize will enumerate through any components/// and initialize them as well./// </summary>protectedoverridevoidInitialize(){// TODO: Add your initialization logic herebase.Initialize();}/// <summary>/// LoadContent will be called once per game and is the place to load/// all of your content./// </summary>protectedoverridevoidLoadContent(){// Create a new SpriteBatch, which can be used to draw textures.this.spriteBatch =newSpriteBatch(base.GraphicsDevice);this.xbrEffect =Content.Load<Effect>("xbr");// a fake scene that is a 240x160 imagethis.pretend240x160Scene =base.Content.Load<Texture2D>("240x160Scene");this.renderTarget =newRenderTarget2D(base.GraphicsDevice,this.renderBounds.Width,this.renderBounds.Height);// default vertex matrix for the vertex methodthis.projection =Matrix.CreateOrthographicOffCenter(0,this.outputBounds.Width,this.outputBounds.Height,0,0,1);// set the values of this effect, should only have to do this oncethis.xbrEffect.Parameters["matrixTransform"].SetValue(halfPixelOffset * projection);this.xbrEffect.Parameters["textureSize"].SetValue(newfloat[]{ renderBounds.Width, renderBounds.Height});}/// <summary>/// UnloadContent will be called once per game and is the place to unload/// all content./// </summary>protectedoverridevoidUnloadContent(){}/// <summary>/// Allows the game to run logic such as updating the world,/// checking for collisions, gathering input, and playing audio./// </summary>/// <param name="gameTime">Provides a snapshot of timing values.</param>protectedoverridevoidUpdate(GameTime gameTime){base.Update(gameTime);}/// <summary>/// This is called when the game should draw itself./// </summary>/// <param name="gameTime">Provides a snapshot of timing values.</param>protectedoverridevoidDraw(GameTime gameTime){base.GraphicsDevice.Clear(Color.CornflowerBlue);base.GraphicsDevice.SetRenderTarget(this.renderTarget);// draw your scene here scaled 1:1. for now I'll just draw// my fake 240x160 texture
spriteBatch.Begin(SpriteSortMode.Deferred,BlendState.NonPremultiplied,SamplerState.PointClamp,null,null);
spriteBatch.Draw(this.pretend240x160Scene,this.renderBounds,this.renderBounds,Color.White);
spriteBatch.End();// now we'll draw to the back bufferbase.GraphicsDevice.SetRenderTarget(null);// this renders the effect
spriteBatch.Begin(SpriteSortMode.Immediate,BlendState.NonPremultiplied,SamplerState.PointClamp,null,null,this.xbrEffect);
spriteBatch.Draw(this.renderTarget,this.outputBounds,this.renderBounds,Color.White);
spriteBatch.End();base.Draw(gameTime);}}}
Etapa 2: arquivo de efeito
A seguir está o arquivo de efeito compatível com XNA para executar o filtro xBR.
hqxSharp
projeto, mas, caramba, é lento (o que avisa). Preciso de algo que possa manter uma taxa de quadros decente.Respostas:
Você pode reduzir a contagem de instruções usando operações vetoriais: por exemplo, em vez de
você pode escrever
Os operadores no HLSL podem ser aplicados a vetores, mesmo os lógicos, como
&&
doisbool3
valores. Esses operadores executarão a operação componente a componente.Código de sombreador
As fotos
A imagem original de Redshrike foi ampliada por um fator de 4.
fonte
ir_lv1 = ((e != f) && (e != h));
ir_lv2_left = ((e != g) && (d != g));
ir_lv2_up = ((e != c) && (b != c));
Essas são boas otimizações que eu perdi e que você encontrou; não acabei precisando delas para o meu problema, porque reduzi a contagem de instruções com outras otimizações.Eu consegui isso funcionando. Ele não usa o filtro hqx, usa o filtro xBR (que eu prefiro). Para mim, isso não é um problema. Se você precisar do filtro hqx, convém converter os arquivos .cg no equivalente XNA apropriado.
Por motivos de integridade e pesquisa, editarei a pergunta para ser mais concisa e depois publicarei todas as informações relevantes para responder à pergunta aqui.
Etapa 1: Configuração do código do jogo
Primeiro, você provavelmente desejará configurar um destino de renderização no qual desenha seu jogo em uma escala de 1: 1 e depois renderiza o filtro.
Etapa 2: arquivo de efeito
A seguir está o arquivo de efeito compatível com XNA para executar o filtro xBR.
Resultados
A textura que eu usei para a renderização de 240x160:
A saída da execução do jogo:
Fontes
O arquivo .cg que converti para compatível com XNA veio daqui . Então os créditos vão até eles por escrevê-lo.
fonte