introduction to nikola mihaylov, sep 1, 2008. //blogs.msdn.com/nikola

17
WPF PIXEL SHADERS Introduction to Nikola Mihaylov, Sep 1, 2008. http://blogs.msdn.com/nikola

Upload: phillip-lynch

Post on 27-Dec-2015

217 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

WPF PIXEL SHADERS

Introduction to

Nikola Mihaylov, Sep 1, 2008. http://blogs.msdn.com/nikola

Page 2: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

What is Pixel Shader?

a) A fantasy creature: male pixie that likes shades

b) Person who likes to cast shadow on computer screens

c) Any of the above

d) All of the above except this answer

e) Not this answer

Page 3: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

Pixel Shader Is: A set of software instructions Used to calculate colors of individual pixels

on screen Typically executing on the graphics card

(Graphics Processing Unit or GPU) Executed very fast on the GPU Primarily used to compute rendering effects Written in shader language, e.g. HLSL –

similar to C Can be used for any computation

Page 4: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

Demo: Grayscale Effect

Shader Inputs:Bitmap to be processed(u,v) location of pixel to be processed

○ (u,v) is used instead of (x,y) to mean that the range of values is from 0 to 1

○ (u,v) is called “texture coordinates”float DesaturationFactor: specifies how much

the bitmap is to be saturated Shader Output: pixel color at specified

location

Page 5: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

Grayscale Effect Pixel Shader:grayscale.fxsampler2D implicitInput : register(s0);

float factor : register(c0);

float4 main(float2 uv : TEXCOORD) : COLOR

{

float4 color = tex2D(implicitInput, uv);

float gray = color.r * 0.3 + color.g * 0.59 + color.b *0.11;

float4 result;

result.r = (color.r - gray) * factor + gray;

result.g = (color.g - gray) * factor + gray;

result.b = (color.b - gray) * factor + gray;

result.a = color.a;

return result;

}

Input bitmap – sampler register s0Code-behind: ShaderEffect.RegisterPixelShaderSamplerProperty()

Input float in c0 register. Code-behind: PixelShaderConstantCallback(0)

Output: R, G, B, A: float4Color of the pixel at (u,v)

Input: (u,v) coordinates of pixel in the bitmap

Retrieve pixel color at location (u,v) from bitmap

Grayscale code

Shader code from http://bursjootech.blogspot.com/2008/06/grayscale-effect-pixel-shader-effect-in.html

Page 6: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

Using Shaders in WPF: Overview

1. Install DirectX SDK

2. Create new WPF app and add .fx file containing the shader code

3. Compile .fx file to .ps file. Set the Build Action of the .ps file to Resource

• Add this as pre-build event to VS in Project properties: • “c:\Program Files\Microsoft DirectX SDK (June 2008)\Utilities\bin\x86\fxc" /T ps_2_0 /E main /Fo

"$(ProjectDir)MyEffect.ps" "$(ProjectDir)MyEffect.fx“

4. Override ShaderEffect class

5. Link WPF properties to shader input arguments in code-behind

6. Apply shader effect in XAML

Page 7: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

Using Shaders in WPF: The Easy Way Install DirectX SDK Download and open the Shader

template project from Nikola’s site: www.nokola.com/sources/ShaderEffectTemplate.zip

Start coding your effect in MyEffect.fx

Next: connecting WPF and the GPU in C#

Page 8: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

GrayscaleEffect Initialization

public class GrayscaleEffect : ShaderEffect {

private static PixelShader _pixelShader = new PixelShader()

{ UriSource = new Uri(@"pack://application:,,,/GrayscaleEffect;component/GrayscaleEffect.ps") };

public GrayscaleEffect() {

PixelShader = _pixelShader;

UpdateShaderValue(InputProperty);

UpdateShaderValue(DesaturationFactorProperty);

}

Call UpdateShaderValue() to set the default value of the WPF property into the shader registers, since PropertyChangedCallback() is not called when setting default value.

Page 9: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

Register Bitmap Texture Input Propertypublic static readonly DependencyProperty

InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(GrayscaleEffect), 0);

public Brush Input { get { return (Brush)GetValue(InputProperty); } set { SetValue(InputProperty, value); } }

Register the bitmap input property in register s0..fx code: sampler2D implicitInput : register(s0);

<- s0

Page 10: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

Register Other Shader Input Properties public static readonly DependencyProperty

DesaturationFactorProperty =

DependencyProperty.Register("DesaturationFactor", typeof(double), typeof(GrayscaleEffect),

new UIPropertyMetadata(0.0, PixelShaderConstantCallback(0), CoerceDesaturationFactor));

public double DesaturationFactor { get { return

(double)GetValue(DesaturationFactorProperty); } set { SetValue(DesaturationFactorProperty, value); }}

Just another WPF DependencyProperty

Link to c0 register.fx code: float factor : register(c0);

Page 11: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

Use in XAML! <Image Source=“myimage.jpg”>

<Image.Effect>

<effect:GrayscaleEffect x:Name="grayscaleEffect“

DesaturationFactor="0.7"/>

</Image.Effect>

</Image>

Supports Bindings, Animation and everything that typical WPF property supports!

Page 12: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

More Shaders They can scale, twist, rotate, ripple or do anything with the

image Full access to texture Customizable inputs

Can be used for realistic effects Light, Shadows Water, Fire, Rain Human faces Clouds, Terrains Projectile traces Light auras, Magic spell effects Candles and smoke Physics Many, many more MANY more

Page 13: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

Demo: Water Reflection

sampler2D input : register(s0);

float val0 : register(c0);

float4 main(float2 uv : TEXCOORD) : COLOR

{

float4 color;

uv.y = uv.y + sin((uv.y-val0) * 100) * 0.03 * (1-uv.y);

color = tex2D(input , uv.xy);

return color;

}

Shader code from: http://rakeshravuri.blogspot.com/2008/07/wave-reflection-shader-effect-in-wpf.html

Page 14: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

More Demos: Twirled UI, Lights and Novas

Twirl: offsets image a little bit based on cos() and sin(uv+inputValue)

Lights: same as RadialGradientBrush, only quadratic – light gets weaker with distance squared

Novas: zoom motion blur effect. Mixes colors of 2 points on the same radius but different distance from center of image.

Page 15: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

Other Shaders

Geometry shaderCan generate new primitives (geometry), for

example: lines, points, trianglesDirectX 10 and above

Vertex shaderModifies attributes of existing 3D vertices

○ Color○ Texture○ Location○ Other

Page 17: Introduction to Nikola Mihaylov, Sep 1, 2008. //blogs.msdn.com/nikola

End