Pregunta interesante, tal vez el muestreo puntual con un filtro de proceso posterior FXAA crudo haría algo similar ... Solo una idea rápida, no lo he probado.
János Turánszki
en.wikipedia.org/wiki/Hqx explica aproximadamente cómo funcionan y tiene algunos enlaces a implementaciones.
Obtuve una versión pirateada mediante el uso del hqxSharpproyecto, pero santa mierda es lenta (lo que advierte). Necesito algo que pueda mantener un framerate decente.
prueba
1
También pensé que CG era compatible con DirectX 9, que es en lo que se basa XNA. Intente compilar uno de los ejemplos en el enlace como si fuera un archivo HLSL. github.com/libretro/common-shaders/tree/master/hqx
ClassicThunder
Respuestas:
6
Puede reducir el recuento de instrucciones utilizando operaciones vectoriales: por ejemplo, en lugar de
Los operadores en HLSL se pueden aplicar a vectores, incluso los lógicos, como &&dos bool3valores. Estos operadores realizarán la operación por componentes.
Ya usé esas optimizaciones en mi respuesta. Así fue como pude superar el error de ranura de instrucciones que estaba viendo.
prueba
Olvidalo entonces. Yo estaba un poco demasiado lento :)
zogi
ir_lv1 = ((e != f) && (e != h));ir_lv2_left = ((e != g) && (d != g));ir_lv2_up = ((e != c) && (b != c)); Esas son buenas optimizaciones que extrañé que encontraste, no terminé necesitándolas para mi problema porque pude reducir el recuento de instrucciones con otras optimizaciones.
prueba
Okay. Buen tema sin embargo. No he oído hablar de estos algoritmos antes de su pregunta. Encontré esta publicación de blog sobre hqx, que me ayudó a entender algo el algoritmo. Lo recomiendo mucho, si está interesado.
zogi
6
Tengo esto funcionando. No usa el filtro hqx, usa el filtro xBR (que prefiero). Para mí, esto no es un problema. Si necesita el filtro hqx, entonces querrá convertir los archivos .cg en su equivalente XNA apropiado.
Por razones completas y de búsqueda, editaré la pregunta para que sea más concisa y luego publicaré toda la información relevante para responder la pregunta aquí.
Paso 1: Configuración del código del juego
En primer lugar, lo más probable es que desee configurar un objetivo de renderizado donde dibuje su juego a escala 1: 1 y luego renderice el 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);}}}
Paso 2: archivo de efectos
El siguiente es el archivo de efectos compatible con XNA para realizar el filtro xBR.
hqxSharpproyecto, pero santa mierda es lenta (lo que advierte). Necesito algo que pueda mantener un framerate decente.Respuestas:
Puede reducir el recuento de instrucciones utilizando operaciones vectoriales: por ejemplo, en lugar de
puedes escribir
Los operadores en HLSL se pueden aplicar a vectores, incluso los lógicos, como
&&dosbool3valores. Estos operadores realizarán la operación por componentes.Código de sombreador
Imágenes
La imagen original de Redshrike se ha ampliado en un factor de 4.
fuente
ir_lv1 = ((e != f) && (e != h));ir_lv2_left = ((e != g) && (d != g));ir_lv2_up = ((e != c) && (b != c));Esas son buenas optimizaciones que extrañé que encontraste, no terminé necesitándolas para mi problema porque pude reducir el recuento de instrucciones con otras optimizaciones.Tengo esto funcionando. No usa el filtro hqx, usa el filtro xBR (que prefiero). Para mí, esto no es un problema. Si necesita el filtro hqx, entonces querrá convertir los archivos .cg en su equivalente XNA apropiado.
Por razones completas y de búsqueda, editaré la pregunta para que sea más concisa y luego publicaré toda la información relevante para responder la pregunta aquí.
Paso 1: Configuración del código del juego
En primer lugar, lo más probable es que desee configurar un objetivo de renderizado donde dibuje su juego a escala 1: 1 y luego renderice el filtro.
Paso 2: archivo de efectos
El siguiente es el archivo de efectos compatible con XNA para realizar el filtro xBR.
Resultados
La textura que utilicé para el render 240x160:
El resultado de ejecutar el juego:
Fuentes
El archivo .cg que convertí en compatible con XNA vino de aquí . Entonces los créditos van a ellos por escribirlo.
fuente