MULTIMEDIA

# Programming with DirectX : Additional Texture Mapping - Image Filters

2/5/2011 5:01:28 PM
##### An image filter is an algorithm that is executed to convert a picture from its original input to some type of output, which is dependent on the algorithm itself. Examples of some image filters are color inversion filters, black-and-white (luminance) filters, sepia filters, edge detection filters, blur filters, and so forth. In this section we will look at a few simple image filters and apply them to textures being rendered on square surfaces to keep the code short and simple. #### Color Inversion Color inversion is a simple effect to create when it comes to image filters. To perform this effect we only have to use 1 minus the color in the pixel shader. This makes colors that are 1 equal to 0 and colors that are 0 equal to 1. In other words, it flips the colors around, so dark becomes light and light becomes dark. The effect shader file from the demo is shown in Listing 1. Figure 1 shows a screenshot of the effect. Listing 1. Color Inversion Demo’s Effect Shader File `/* Color Inversion Filter Demo's HLSL Shader Ultimate Game Programming with DirectX 2nd Edition Created by Allen Sherrod*/Texture2D decal;SamplerState DecalSampler{ Filter = MIN_MAG_MIP_LINEAR; AddressU = Wrap; AddressV = Wrap;};cbuffer cbChangesEveryFrame{ matrix World; matrix View;};cbuffer cbChangeOnResize{ matrix Projection;};struct VS_INPUT{ float4 Pos : POSITION; float2 Tex : TEXCOORD;};struct PS_INPUT{ float4 Pos : SV_POSITION; float2 Tex : TEXCOORD0;};PS_INPUT VS(VS_INPUT input){ PS_INPUT output = (PS_INPUT)0; output.Pos = mul(input.Pos, World); output.Pos = mul(output.Pos, View); output.Pos = mul(output.Pos, Projection); output.Tex = input.Tex; return output;}float4 PS(PS_INPUT input) : SV_Target{ return 1 - decal.Sample(DecalSampler, input.Tex);}technique10 ColorInversion{ pass P0 { SetVertexShader(CompileShader(vs_4_0, VS())); SetGeometryShader(NULL); SetPixelShader(CompileShader(ps_4_0, PS())); }} ` Figure 1. Screenshot from the Color Inversion demo. #### Luminance Filter The algorithm for the luminance filter works by taking each color in the pixel shader and multiplying each component by the luminance constant. You then add the result of each multiplied component together to get the value that will act as the grayscale pixel output. The luminance constant is 0.30 for the red, 0.59 for the green, and 0.11 for the blue components. Multiplying the color’s red, green, and blue components by this luminance constant and then adding the results of all components will create a result that appears black and white for all pixels. The operations are shown as follows, where color is the original pixel color and lum is the luminance constant (0.30, 0.59, 0.11). Luminance = color.red * lum.red + color.green * lum.green + color.blue * lum.blue This operation is essentially the dot product of two vectors, or in this case two colors. You can use the HLSL dot() function to perform this operation, which will be discussed in more detail in the next chapter for vectors. For now, know that the dot() function takes each component from the two vectors (color and the luminance constant in this example) and multiplies them together and adds up the results. The resulting value is used for the output color. The Luminance demo’s effect shader file is shown in Listing 2. Figure 2 shows a screenshot of the demo in action. Listing 2. The Luminance Demo’s Effect Shader File `/* Luminance Filter Ultimate Game Programming with DirectX 2nd Edition Created by Allen Sherrod*/Texture2D decal;SamplerState DecalSampler{ Filter = MIN_MAG_MIP_LINEAR; AddressU = Wrap; AddressV = Wrap;};cbuffer cbChangesEveryFrame{ matrix World; matrix View;};cbuffer cbChangeOnResize{ matrix Projection;};struct VS_INPUT{ float4 Pos : POSITION; float2 Tex : TEXCOORD;};struct PS_INPUT{ float4 Pos : SV_POSITION; float2 Tex : TEXCOORD0;};PS_INPUT VS(VS_INPUT input){ PS_INPUT output = (PS_INPUT)0; output.Pos = mul(input.Pos, World); output.Pos = mul(output.Pos, View); output.Pos = mul(output.Pos, Projection); output.Tex = input.Tex; return output;}float4 PS(PS_INPUT input) : SV_Target{ float3 lumConst = float3(0.30, 0.59, 0.11); float3 color = decal.Sample(DecalSampler, input.Tex); float dp = dot(color, lumConst); return float4(dp, dp, dp, 1);}technique10 LuminanceFilter{ pass P0 { SetVertexShader(CompileShader(vs_4_0, VS())); SetGeometryShader(NULL); SetPixelShader(CompileShader(ps_4_0, PS())); }} ` The luminance filter is also known as the black-and-white transfer function. Figure 2. A screenshot from the Luminance demo. #### Sepia Tone Filter The sepia tone effect is used to color a black-and-white image with a brownish tone to give it the appearance of and old photograph. It does this by taking the original color and a brown tone, and using the two to color a black-and-white version of the image to create the effect. As the description implies, the sepia tone builds off of the luminance filter. The sepia tone filter works in the following steps. 1. Convert the image to black and white.2. Use the luminance (black-and-white) value as a percent between a light and dark set of colors to create the sepia constant, where 0% (0.0) means we use the dark color, 100% (1.0) means we use the light color, and any percentage between 0% and 100% will be a color value between the light and dark colors.3. Take the original color and the luminance color and find a color that is halfway between the two. Let’s call this the half color.4. Use the half color and the sepia constant and find a color that is halfway between those two. This will be the output color. In HLSL you can find a color that is between two colors by using the lerp() function. The lerp() function takes as parameters the first vector (or color in this demo, which is represented by a vector; i.e., they’re the same thing from a structure point of view), the second vector, and a percentage to interpolate between the two. Finding a color between two colors is another way of mixing colors because the result will be a blend of the two colors. When you find a color that is halfway between two other colors, it is like you are equally mixing the colors together. The term lerp stands for linear interpolation. For a simple example, let’s say we are interpolating between the values 0 and 100. The percentage is used to find a value between these two, where a percentage of 0.0 will return 0, and a percent of 1.0 will return 100. So if the percentage is 0.65, then 65 will be returned since 65% into the range of 0 and 100 is 65. The lerp() function does this operation, but on two vectors to obtain a vector that is some percentage between the two parameters. Therefore, to find a color between two colors using lerp(), you just specify the two colors and a percentage between the two for which you want to look. Since we are using colors, the result will be a blend between the two. The sepia tone effect is shown in Listing 3 in the demo’s shader file. This demo builds off of the Luminance demo and adds a few extra lines of code to the pixel shader. Figure 3 shows a screenshot of the demo. We recommend that you run the demo applications to see the results in color to be able to fully appreciate the differences between each image filter. Listing 3. The Sepia Demo’s HLSL Effect Shader File `/* Sepia Filter Demo's HLSL Shader Ultimate Game Programming with DirectX 2nd Edition Created by Allen Sherrod*/Texture2D decal;SamplerState DecalSampler{ Filter = MIN_MAG_MIP_LINEAR; AddressU = Wrap; AddressV = Wrap;};cbuffer cbChangesEveryFrame{ matrix World; matrix View;};cbuffer cbChangeOnResize{ matrix Projection;};struct VS_INPUT{ float4 Pos : POSITION; float2 Tex : TEXCOORD;};struct PS_INPUT{ float4 Pos : SV_POSITION; float2 Tex : TEXCOORD0;};PS_INPUT VS(VS_INPUT input){ PS_INPUT output = (PS_INPUT)0; output.Pos = mul(input.Pos, World); output.Pos = mul(output.Pos, View); output.Pos = mul(output.Pos, Projection); output.Tex = input.Tex; return output;}float4 PS(PS_INPUT input) : SV_Target{ float3 lumConst = float3(0.30, 0.59, 0.11); float3 light = float3(1, 0.9, 0.5); float3 dark = float3(0.2, 0.05, 0); float3 color = decal.Sample(DecalSampler, input.Tex); float luminance = dot(color, lumConst); float3 sepia = lerp(dark, light, luminance); float3 halfColor = lerp(color, luminance, 0.5); float3 final = lerp(halfColor, sepia, 0.5); return float4(final, 1);}technique10 SepiaFilter{ pass P0 { SetVertexShader(CompileShader(vs_4_0, VS())); SetGeometryShader(NULL); SetPixelShader(CompileShader(ps_4_0, PS())); }} ` Figure 3. A screenshot from the Sepia demo.
 Other

 Top 10
 -  Nikon 1 J2 With Stylish Design And Dependable Image And Video Quality
 -  Canon Powershot D20 - Super-Durable Waterproof Camera
 -  Fujifilm Finepix F800EXR – Another Excellent EXR
 -  Sony NEX-6 – The Best Compact Camera
 -  Teufel Cubycon 2 – An Excellent All-In-One For Films
 -  Dell S2740L - A Beautifully Crafted 27-inch IPS Monitor
 -  Philips 55PFL6007T With Fantastic Picture Quality
 -  Philips Gioco 278G4 – An Excellent 27-inch Screen
 -  Sony VPL-HW50ES – Sony’s Best Home Cinema Projector
 -  Windows Vista : Installing and Running Applications - Launching Applications
 Most View
 -  Bamboo Splash - Powerful Specs And Friendly Interface
 -  Powered By Windows (Part 2) - Toshiba Satellite U840 Series, Philips E248C3 MODA Lightframe Monitor & HP Envy Spectre 14
 -  MSI X79A-GD65 8D - Power without the Cost
 -  Canon EOS M With Wonderful Touchscreen Interface (Part 1)
 -  Windows Server 2003 : Building an Active Directory Structure (part 1) - The First Domain
 -  Speed ​​up browsing with a faster DNS
 -  Using and Configuring Public Folder Sharing
 -  Extending the Real-Time Communications Functionality of Exchange Server 2007 : Installing OCS 2007 (part 1)
 -  Google, privacy & you (Part 1)
 -  iPhone Application Development : Making Multivalue Choices with Pickers - Understanding Pickers
 -  Microsoft Surface With Windows RT - Truly A Unique Tablet
 -  Network Configuration & Troubleshooting (Part 1)
 -  Panasonic Lumix GH3 – The Fastest Touchscreen-Camera (Part 2)
 -  Programming Microsoft SQL Server 2005 : FOR XML Commands (part 3) - OPENXML Enhancements in SQL Server 2005
 -  Exchange Server 2010 : Track Exchange Performance (part 2) - Test the Performance Limitations in a Lab
 -  Extra Network Hardware Round-Up (Part 2) - NAS Drives, Media Center Extenders & Games Consoles
 -  Windows Server 2003 : Planning a Host Name Resolution Strategy - Understanding Name Resolution Requirements
 -  Google’s Data Liberation Front (Part 2)
 -  Datacolor SpyderLensCal (Part 1)