Кратко, быстро о том как написать шейдер для 2d в XNA.
Меня научили статьи и исходные коды:http://creators.xna.com/sample/spriteeffects
http://www.facewound.com/tutorials/shader1/
Один из результатов:
Используемое ПО:
Microsoft Visual C# 2008 Express,
XNA 3.1
Исходная картинка:
Создаем новый проект игры для Windows, создаем в контенте файл типа Effect File, я назвал
ShaderEf.fx, пишем:
sampler TextureSampler : register(s0); float4 PixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { float4 tex = tex2D(TextureSampler, texCoord); tex.r = tex.r*sin(texCoord.y*100)*2; tex.g = tex.g*cos(texCoord.y*200)*2; tex.b = tex.b*sin(texCoord.y*300)*2; return tex; } technique Desaturate { pass Pass1 { PixelShader = compile ps_2_0 PixelShader(); } }
Код основной программы:
using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; using Microsoft.Xna.Framework.Net; using Microsoft.Xna.Framework.Storage; namespace test { public class Game1 : Microsoft.Xna.Framework.Game { /// <summary> /// Менеджер графических устройств /// </summary> GraphicsDeviceManager graphics; /// <summary> /// /// </summary> SpriteBatch spriteBatch; /// <summary> /// Шейдер эфект /// </summary> Effect spriteEffect; /// <summary> /// Текстура для отображения /// </summary> Texture2D tex; /// <summary> /// Конструктор /// </summary> public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; graphics.PreferredBackBufferWidth = 1280; graphics.PreferredBackBufferHeight = 720; graphics.PreferMultiSampling = true; } /// <summary> /// Инициализация /// </summary> protected override void Initialize() { base.Initialize(); } /// <summary> /// Загрузка данных /// </summary> protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); //Загружаем текстуру tex = Content.Load<Texture2D>("menuBack"); //Загружаем шейдер spriteEffect = Content.Load<Effect>("ShaderEf"); } /// <summary> /// Выгрузка данных /// </summary> protected override void UnloadContent() { } /// <summary> /// Обновление данных /// </summary> /// <param name="gameTime">Игрове время</param> protected override void Update(GameTime gameTime) { if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); base.Update(gameTime); } /// <summary> /// Отображение данных /// </summary> /// <param name="gameTime">Игровое время</param> protected override void Draw(GameTime gameTime) { //Очищаем экран GraphicsDevice.Clear(Color.Black); //Начинаем рисовать spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None); //Начинаем обрабатывать шейдер spriteEffect.Begin(); //Начинаеться текущая техника, 0-й проход шейдера spriteEffect.CurrentTechnique.Passes[0].Begin(); //Рисуем текстуру spriteBatch.Draw(tex, new Vector2(0, 0), Color.White); //Заканчиваем рисовать spriteBatch.End(); //Заканчиваем текущую технику, 0-й проход шейдера spriteEffect.CurrentTechnique.Passes[0].End(); //Заканчиваем обрабатываеть шейдер spriteEffect.End(); } } }Результат:
Теперь я представляю разные вариации кода шейдера
И результат – картинку:
Осветляем.
sampler TextureSampler : register(s0); float4 PixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { float4 tex = tex2D(TextureSampler, texCoord)*3; return tex; } technique Desaturate { pass Pass1 { PixelShader = compile ps_2_0 PixelShader(); } }
Затемняем.
sampler TextureSampler : register(s0); float4 PixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { float4 tex = tex2D(TextureSampler, texCoord)*texCoord.y; return tex; } technique Desaturate { pass Pass1 { PixelShader = compile ps_2_0 PixelShader(); } }
Меняем цвета.
sampler TextureSampler : register(s0); float4 PixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { float4 tex = tex2D(TextureSampler, texCoord); tex.r = tex.r*2; return tex; } technique Desaturate { pass Pass1 { PixelShader = compile ps_2_0 PixelShader(); } }
Манипулируем координатами: растягиваем
sampler TextureSampler : register(s0); float4 PixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { texCoord.y=texCoord.y*0.5; float4 tex = tex2D(TextureSampler, texCoord); return tex; } technique Desaturate { pass Pass1 { PixelShader = compile ps_2_0 PixelShader(); } }
Манипулируем координатами: волна
sampler TextureSampler : register(s0); float4 PixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { texCoord.y=texCoord.y+(sin(texCoord.x*200)*0.01); float4 tex = tex2D(TextureSampler, texCoord); return tex; } technique Desaturate { pass Pass1 { PixelShader = compile ps_2_0 PixelShader(); } }
Слолжение семплов
sampler TextureSampler : register(s0); float4 PixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { float4 tex = tex2D( TextureSampler, texCoord.xy); tex += tex2D( TextureSampler, texCoord.xy+0.001); tex += tex2D( TextureSampler, texCoord.xy+0.002); tex += tex2D( TextureSampler, texCoord.xy+0.003); return tex; } technique Desaturate { pass Pass1 { PixelShader = compile ps_2_0 PixelShader(); } }
Размытие
sampler TextureSampler : register(s0); float4 PixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { float4 tex = tex2D( TextureSampler, texCoord.xy); tex += tex2D( TextureSampler, texCoord.xy+0.001); tex += tex2D( TextureSampler, texCoord.xy+0.002); tex += tex2D( TextureSampler, texCoord.xy+0.003); return tex/4; } technique Desaturate { pass Pass1 { PixelShader = compile ps_2_0 PixelShader(); } }
Четкость.
sampler TextureSampler : register(s0); float4 PixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { float4 tex = tex2D( TextureSampler, texCoord.xy); tex -= tex2D( TextureSampler, texCoord.xy+0.0001)*10.0f; tex += tex2D( TextureSampler, texCoord.xy+0.0001)*10.0f; return tex; } technique Desaturate { pass Pass1 { PixelShader = compile ps_2_0 PixelShader(); } }
Embossed
sampler TextureSampler : register(s0); float4 PixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { float4 tex; tex.a=1.0f; tex.rgb = 0.5f; tex = tex2D( TextureSampler, texCoord.xy); tex -= tex2D( TextureSampler, texCoord.xy-0.001)*2.0f; tex += tex2D( TextureSampler, texCoord.xy+0.001)*2.0f; tex.rgb = (tex.r+tex.g+tex.b)/3.0f; return tex; } technique Desaturate { pass Pass1 { PixelShader = compile ps_2_0 PixelShader(); } }
Черное и белое
sampler TextureSampler : register(s0); float4 PixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { float4 tex; tex.a=1.0f; tex = tex2D( TextureSampler, texCoord.xy); tex.rgb = (tex.r+tex.g+tex.b)/3.0f; if (tex.r<0.2 || tex.r>0.8) tex.r = 0.0f; else tex.r = 1.0f; if (tex.g<0.2 || tex.g>0.8) tex.g = 0.0f; else tex.g = 1.0f; if (tex.b<0.2 || tex.b>0.8) tex.b = 0.0f; else tex.b = 1.0f; return tex; } technique Desaturate { pass Pass1 { PixelShader = compile ps_2_0 PixelShader(); } }
Негатив.
sampler TextureSampler : register(s0); float4 PixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { float4 tex; tex = 1-tex2D( TextureSampler, texCoord.xy); tex.a = 1.0f; return tex; } technique Desaturate { pass Pass1 { PixelShader = compile ps_2_0 PixelShader(); } }
Комментарии
Отправить комментарий