现在的位置: 首页 > 综合 > 正文

Sobel Edge Detection 的shader实现

2013年12月08日 ⁄ 综合 ⁄ 共 4592字 ⁄ 字号 评论关闭
//-----------------------------------------------------------------------------
//           Name: Sobel.fx
//         
//           Description: 
//                 
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Effect File Variables
//-----------------------------------------------------------------------------

float4x4 worldViewProj : WorldViewProjection; 
// This matrix will be loaded by the application

texture testTexture; 
// This texture will be loaded by the application
const float Brightness = 1.0f;

sampler Sampler 
= sampler_state
{
    Texture   
= (testTexture);
    MipFilter 
= LINEAR;
    MinFilter 
= LINEAR;
    MagFilter 
= LINEAR;
}
;

//-----------------------------------------------------------------------------
// Vertex Definitions
//-----------------------------------------------------------------------------

// Our sample application will send vertices 
// down the pipeline laid-out like this...

struct VS_INPUT
{
    float3 position    : POSITION;
    float2 texture0 : TEXCOORD0;
}
;

// Once the vertex shader is finished, it will 
// pass the vertices on to the pixel shader like this...

struct VS_OUTPUT
{
    float4 hposition : POSITION;
    float2 texture0  : TEXCOORD0;
    float4 color     : COLOR0;
}
;

// And finally, the pixel shader will send a single 
// color value to the frame buffer like this...

struct PS_OUTPUT
{
    float4 color : COLOR;
}
;

//-----------------------------------------------------------------------------
// Simple Vertex Shader
//-----------------------------------------------------------------------------

VS_OUTPUT myvs( VS_INPUT IN )
{
    VS_OUTPUT OUT;

    OUT.hposition 
= mul( worldViewProj, float4(IN.position, 1) );

    OUT.color 
= float4( 1.01.01.01.0 ); // Pass white as a default color
    
//OUT.color = float4( 0.0, 1.0, 0.0, 1.0 ); // Pass green to test vertex shader

    OUT.texture0 
= IN.texture0;

    
return OUT;
}


//-----------------------------------------------------------------------------
// Simple Pixel Shader
//-----------------------------------------------------------------------------

PS_OUTPUT myps( VS_OUTPUT IN )
{
    PS_OUTPUT OUT;

//    OUT.color = tex2D( Sampler, IN.texture0 ) * IN.color;

    
// If you uncomment the next line, the color passed to us by our
    
// vertex shader and the selected texture sampler will be ignored 
    
// completely and all output to the frame buffer will be blue regardless.

    
//OUT.color = float4( 0.0, 0.0, 1.0, 1.0);
    
    
    
const int NUM = 9;
    
const float threshold = 0.09;
    
const float texW = 140.f;
    
const float texH = 140.f;

//round texels
    const float2 c[NUM] ={
            float2( 
-1/texW,1/texH),
            float2( 
0.00,   1/texH),
            float2( 
1/texW, 1/texH),
            float2( 
-1/texW,0.00),
            float2( 
0.00,   0.00),
            float2( 
1/texW, 1/texH ),
            float2(
-1/texW, -1/texH),
            float2( 
0.00 ,  -1/texH),
            float2( 
1/texW, -1/texH),
    }
;
    
    float3 col[NUM];    
    
int i;

//it stores the samples of texture to col array.

    
for (i=0; i < NUM; i++{
      col[i] 
= tex2D(Sampler, IN.texture0 + c[i]);
    }


//now we start to compute the luminance with dot product and store them in lum array.
//lum = 0.30r + 0.59g + 0.11b;
    float3 rgb2lum = float3( 0.300.590.11);
    
    
float lum[NUM];
    
for (i = 0; i < NUM; i++{
        lum[i] 
=  dot(col[i].xyz, rgb2lum);
        
    }


//Sobel filter computes new value at the central position by sum the weighted neighbors.

    
float x = lum[2]+  lum[8]+2*lum[5]-lum[0]-2*lum[3]-lum[6];
    
float y = lum[6]+2*lum[7]+  lum[8]-lum[0]-2*lum[1]-lum[2];

//show the points which values are over the threshold and hide others. Final result is the 
//product of col[5] and edge detector value. Brightness adjusts the brightness of the image.

    
float edge =(x*+ y*< threshold)? 1.0:0.0;

//final output

    OUT.color.xyz 
= Brightness * col[5].xyz * edge;
    OUT.color.w 
= 1.0;

    
return OUT;
}


//-----------------------------------------------------------------------------
// Simple Effect (1 technique with 1 pass)
//-----------------------------------------------------------------------------

technique Technique0
{
    pass Pass0
    
{
        Lighting 
= FALSE;

        Sampler[
0= (Sampler); // Needed by pixel shader

        VertexShader 
= compile vs_2_0 myvs();
        PixelShader  
= compile ps_2_0 myps();
    }

}


效果图:

 

参考文档:

 http://homepages.inf.ed.ac.uk/rbf/HIPR2/sobel.htm

http://www.pages.drexel.edu/~weg22/edge.html

http://www.neatware.com/lbstudio/web/hlsl.html

抱歉!评论已关闭.