Кратко, быстро о том как написать шейдер для 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();
}
}













Комментарии
Отправить комментарий