Page 1 of 1

Edge detection with XEffects

Posted: Sun Mar 08, 2009 11:54 am
by B@z
hi

i found an edge detection shader in the dx sdk (didnt have to go far eh xD), but i dunno how to get it work with irrlicht.

Code: Select all

sampler2D g_samSrcNormal;

float2 PixelKernel[4] =
{
    { 0,  1},
    { 1,  0},
    { 0, -1},
    {-1,  0}
};

float2 TexelKernel[4]
<
	string ConvertPixelsToTexels = "PixelKernel";
>;

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

float4 pixelMain( float2 Tex : TEXCOORD0 ) : COLOR0
{
    float4 Orig = tex2D( g_samSrcNormal, Tex );

    float4 Sum = 0;

    for( int i = 0; i < 4; i++ )
        Sum += saturate( 1 - dot( Orig.xyz, tex2D( g_samSrcNormal, Tex + TexelKernel[i] ).xyz ) );

    return Sum;
}

but i dunno how should i pass the g_samSrcNormal from xeffects :|
can somebody get this work for me?

Posted: Sun Mar 08, 2009 12:54 pm
by BlindSide
Try something like this instead:

Code: Select all

sampler2D ScreenMapSampler : register(s1);
sampler2D DepthMapSampler : register(s2);

float unpackFloat(const float4 value)
{
	float extractedDistance = (value.r + (value.g / 256.0));
	return extractedDistance;
}

float calcSample(float depth, float2 texCoords)
{
	float4 tempDepth = tex2D(DepthMapSampler, texCoords);
	float otherDepth = unpackFloat(tempDepth);
	return min(abs(otherDepth - depth) * 20.0, 1.0);
}

float4 pixelMain (
float2 Texcoords 	: TEXCOORD0	
) : COLOR0
{
	const float2 offsetArray[4] = 
	{
		float2( 1.5 / SCREENX,0),
		float2( -1.5 / SCREENX,0),
		float2(0, 1.5 / SCREENY),
		float2(0, -1.5 / SCREENY)
	};

	float depth = unpackFloat(tex2D(DepthMapSampler, Texcoords.xy));
	float outline = float4(0.0, 0.0, 0.0, 0.0);

	for(int i = 0;i < 4;i++)
		outline += calcSample(depth, Texcoords + offsetArray[i]);

	return tex2D(ScreenMapSampler, Texcoords.xy) * min(1.0 - outline, 1.0);
}
Add it in addPostProcessingEffectFromFile() and make sure to add all scene nodes to depth pass and enable depth pass.

Cheers

Posted: Sun Mar 08, 2009 2:52 pm
by B@z
thanks for your answer.
but its funny, but it works on the first frame (the really first frame whats been rendered), and disappears... xD idea?

Code: Select all

	effect->enableDepthPass(true);

	// Load the dwarf mesh.
	IAnimatedMesh* dwarfmesh = smgr->getMesh("media/dwarf.x");
	
	// We create 9 dwarves arranged in a grid in a nested loop.
	for(int g = 0;g < 3;g++)
	{
		for(int v = 0;v < 3;v++)
		{
			// Add a dwarf animated mesh scene node.
			IAnimatedMeshSceneNode* dwarf = smgr->addAnimatedMeshSceneNode(dwarfmesh);
			dwarf->setAnimationSpeed(25);
			dwarf->setScale(vector3df(0.05f, 0.05f, 0.05f));
			dwarf->setPosition(vector3df(g * 4.5f, 0.5f, v * 3.5f + 1.0f));

			// Disable the lighting here too, XEffects overlay will handle it.
			dwarf->getMaterial(0).Lighting = false;
			dwarf->getMaterial(1).Lighting = false;

			// If its the first row add some effects.
			if(g == 0)
			{
				dwarf->setMaterialTexture(0,driver->getTexture("media/red.bmp"));
				effect->addEffectToNode(dwarf, (E_EFFECT_TYPE)(v + 1));
			}

			effect->addNodeToDepthPass(dwarf);
			// Apply a shadow to the dwarf, notice we are applying it to all of them
			// including the ones that have effects applied.
			//effect->addShadowToNode(dwarf, filterType);
		}
	}

	// Set the background clear color to orange.
	effect->setClearColour(SColor(255, 250, 100, 0));

	// Add some post processing effects, a very subtle bloom here.
	core::stringc shaderExt = (driver->getDriverType() == EDT_DIRECT3D9) ? ".hlsl" : ".glsl";
	
effect->addPostProcessingEffectFromFile(core::stringc("shaders/EdgeDetect") + shaderExt);[quote][/quote]

Posted: Mon Mar 09, 2009 2:20 am
by BlindSide
Oh sorry there is a bug in XEffects and depth buffer.

Put the line:

Code: Select all

driver->setRenderTarget(0, false, false);
Right after "effect->update()".

That should hopefully fix it.

Posted: Mon Mar 09, 2009 9:07 am
by B@z
yeah thanks, that did the job ;)

but still have problems :(

Image

first thing, you see that gray lines in the model?
i guess its with the depth map...

and the other thing, the outline is "faster" than the render. so if i move the camera left, the outline goes left, and then the model... so its moving...[/img]

Posted: Thu Mar 12, 2009 7:02 am
by Vandrick

Code: Select all

uniform sampler2D ScreenMapSampler;
uniform sampler2D DepthMapSampler;

float unpackFloat(vec4 value)
{
   float extractedDistance = (value.r + value.g / 256.0);
   return extractedDistance;
}

float calcSample(float depth, vec2 texCoords)
{
   vec4 tempDepth = texture2D(DepthMapSampler, texCoords);
   float otherDepth = unpackFloat(tempDepth);
   return min(abs(otherDepth - depth) * 20.0, 1.0);
}

vec2 offsetArray[4];

//vec4 pixelMain ( vec2 Texcoords)
void main() 
{
   offsetArray[0] = vec2( 1.5 / float(SCREENX),0);
   offsetArray[1] = vec2( -1.5 / float(SCREENX),0);
   offsetArray[2] = vec2(0, 1.5 / float(SCREENY));
   offsetArray[3] = vec2(0, -1.5 / float(SCREENY));


   float depth = unpackFloat(texture2D(DepthMapSampler, gl_TexCoord[0].xy));
   float outline = vec4(0.0, 0.0, 0.0, 0.0);

   for(int i = 0;i < 4;i++)
      outline += calcSample(depth, gl_TexCoord[0] + offsetArray[i]);

   gl_FragColor = texture2D(ScreenMapSampler, gl_TexCoord[0].xy) * min(1.0 - outline, 1.0);
} 

GLSL version of this code.

I did it by trial and error and comparing all of Blindsides differences in his glsl / hlsl code.

Posted: Thu Mar 12, 2009 8:41 am
by BlindSide
The lines do not show up for me, are you using ATI? I think it has to do with having correct ScreenRTT resolution, if it does not match the screen resolution you can get these artifacts. The demo uses 512x512 if it is an ATI card for compatibility in OpenGL, but you can comment this out. Hopefully it will fix the problem. For the camera update, It will be fixed in the next release.

Posted: Thu Mar 12, 2009 10:30 am
by B@z
yeah i have ati card...
but it is dx isnt it? :D
so i have to change the screenRTT resolution? ok i'll try later (cant try at the moment :( )
thanks.