Edge Detection By Pixel Shader HLSL

自打为XPEC-BeiJing做事职务开发的缘故,这自己做些玩意儿的机会可少多了。
最近为年轻人准备了一些HLSL Shader的讲义,于是作了个lena的edge detection.
这技术很简单,不过在NPR方面还是有些用处。


































图如上,还是比较清楚地把线段都弄出来了的。道理很简单,就是观察任意像素与周围八个像素是否有比较大的差异,如果比较大
那么就认为是边缘。常用的边缘检测算子有Laplace,Sobel,Canny等等,我这种是Roberts的一种"蛮力"推广.

完毕.下面该写Vertex Shader的讲义了,挑个简单的,来个Ocean Water Simulation吧.主要为了破除新同事对Shader和Graphics
的神秘感以及'科学文章'的神秘感.揭露一下那些用所谓的FFT和其他古怪的数学记法的本质就是个加号和逼近而已.

说实话,与那些连sin(x)都要写成复数形式的所谓科学家,我们专业的游戏程序员没有二话,推倒,打到死!哈哈

HLSL Pixel Shader:

//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
float4 g_MaterialAmbientColor;      // Material's ambient color
float4 g_MaterialDiffuseColor;      // Material's diffuse color
float3 g_LightDir;                  // Light's direction in world space
float4 g_LightDiffuse;              // Light's diffuse color
texture g_MeshTexture;              // Color texture for mesh

float    g_fTime;                   // App's time in seconds
float4x4 g_mWorld;                  // World matrix for object
float4x4 g_mWorldViewProjection;    // World * View * Projection matrix

//--------------------------------------------------------------------------------------
// Texture samplers
//--------------------------------------------------------------------------------------
sampler MeshTextureSampler =
sampler_state
{
    Texture = <g_MeshTexture>;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};


//--------------------------------------------------------------------------------------
// Vertex shader output structure
//--------------------------------------------------------------------------------------
struct VS_OUTPUT
{
    float4 Position   : POSITION;   // vertex position
    float4 Diffuse    : COLOR0;     // vertex diffuse color (note that COLOR0 is clamped from 0..1)
    float2 TextureUV  : TEXCOORD0;  // vertex texture coords
};


//--------------------------------------------------------------------------------------
// This shader computes standard transform and lighting
//--------------------------------------------------------------------------------------
VS_OUTPUT RenderSceneVS( float4 vPos : POSITION,
                         float3 vNormal : NORMAL,
                         float2 vTexCoord0 : TEXCOORD0 )
{
    VS_OUTPUT Output;
    float3 vNormalWorldSpace;
   
    // Transform the position from object space to homogeneous projection space
    Output.Position = mul(vPos, g_mWorldViewProjection);
   
    // Transform the normal from object space to world space   
    vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorld)); // normal (world space)

    // Calc diffuse color   
    Output.Diffuse.rgb = g_MaterialDiffuseColor * g_LightDiffuse * max(0,dot(vNormalWorldSpace, g_LightDir)) +
                         g_MaterialAmbientColor;  
    Output.Diffuse.a = 1.0f;
   
    // Just copy the texture coordinate through
    Output.TextureUV = vTexCoord0;
   
    return Output;   
}


//--------------------------------------------------------------------------------------
// Pixel shader output structure
//--------------------------------------------------------------------------------------
struct PS_OUTPUT
{
    float4 RGBColor : COLOR0;  // Pixel color   
};

float2 PixelKernel2[9] =
{
        float2(-1, -1),float2( 0, -1),float2( 1, -1),
        float2(-1,  0),float2( 0,  0),float2( 1,  0),
        float2(-1,  1),float2( 0,  1),float2( 1,  1),
};

float2 TexelKernel2[9]
<
    string ConvertPixelsToTexels = "PixelKernel";
>;

float3 LuminanceConv = { 0.2125f, 0.7154f, 0.0721f };

//--------------------------------------------------------------------------------------
// This shader outputs the pixel's color by modulating the texture's
// color with diffuse material color
//--------------------------------------------------------------------------------------
PS_OUTPUT RenderScenePS( VS_OUTPUT In )
{
    PS_OUTPUT Output;
   
    //原始值
    float4 Orig = tex2D( MeshTextureSampler, In.TextureUV );

    float4 Sum = 0;
    //看看和周围差多少
    for( int i = 0; i < 9; i++ )
    //这0.4,1.2,0.5都是可调参数 其中0.4是一个Threshold
        Sum += ( abs(Orig - tex2D(MeshTextureSampler, In.TextureUV + TexelKernel2[i]))-0.4 ) * 1.2 + 0.5f;

    Output.RGBColor = saturate(dot(LuminanceConv,Sum));;
    return Output;
}


posted on 2007-10-03 17:42 asashina 阅读(1283) 评论(2)  编辑 收藏

导航

统计

公告