How do I draw edge lines using the z-buffer?

Started by
1 comment, last by Danny02 12 years, 9 months ago
Hi! I want to draw edge lines around edges over which the z-coordinate makes a sudden jump, how can I accomplish this? I want to implement it as follows

After the image has been rendered, I look at the z-buffer value for each pixel. I loop though all of the eight neighboring pixels and look at their z-buffer values too, and if they differ by more than, say, 1 % or so of the z-buffer value in the middle (this value is multiplied by the square root of two for the diagonal pixels on the diagonal), then I add one to a counter. For the counter value 0 the pixel should be left unchanged, for 1 it should 1/3 darkened, for 2 it should be 2/3 darkened and for 3 or higher it should be completely black.

How do I implement this? I know that I first have to render the entire scene to get the z-buffer I want to use, but then how can I process all the pixels again? And how do I access the z-buffer?
Advertisement

Hi! I want to draw edge lines around edges over which the z-coordinate makes a sudden jump, how can I accomplish this? I want to implement it as follows

After the image has been rendered, I look at the z-buffer value for each pixel. I loop though all of the eight neighboring pixels and look at their z-buffer values too, and if they differ by more than, say, 1 % or so of the z-buffer value in the middle (this value is multiplied by the square root of two for the diagonal pixels on the diagonal), then I add one to a counter. For the counter value 0 the pixel should be left unchanged, for 1 it should 1/3 darkened, for 2 it should be 2/3 darkened and for 3 or higher it should be completely black.

How do I implement this? I know that I first have to render the entire scene to get the z-buffer I want to use, but then how can I process all the pixels again? And how do I access the z-buffer?


You have to render the depth buffer to a texture first in order to access it in the shader for the 2nd render pass (which can draw both the image and the darkened lines)
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
did exactly this kind of effect a while back as a tiny crysis mod.
And there are some part of this effect which make it a bit more complicated as it seem in the beginning.
My code is probably far from perfect, also i probably would have done it differently if I had the freedom which u have when writing your own renderer but here it comes:

directly from the mod with some simplifications

//tweakables
const float pow = 0.5f;
const float strength = 5.f;
const float delta= 4.f;
const float width = 2.f.;//I choosed 2 pixel wide border

half sceneDepth = tex2D(zMap, IN.baseTC.xy).r; //depth from texture;

half scDepth = pow(sceneDepth, pow);

half2 edgeOffset = width / ScreenSize.xy;

half4 sampels;
sampels.x = tex2D(zMap, IN.baseTC.xy - edgeOffset).r;
sampels.y = tex2D(zMap, IN.baseTC.xy + edgeOffset).r;
sampels.z = tex2D(zMap, IN.baseTC.xy + half2(1. , -1.) * edgeOffset).r;
sampels.w = tex2D(zMap, IN.baseTC.xy + half2(-1. , 1.) * edgeOffset).r;
sampels = pow(sampels, pow);

half dDelta = dot(sampels, 1) - scDepth * delta.; // not so good in hlsl but should be the same as "sampels.x + sampels.y + sampels.z + sampels.w"

dDelta *= 1.0 - PS_NearFarClipDist.x; //sorry don't remember exactly anymore what this var was about

half edgeAmount = dDelta / sceneDepth * strength;
Color.rgb *= saturate(1.0-edgeAmount);



ps: the crymod link seems to be down cause of some site restructuring or so, u can download it at moddb

This topic is closed to new replies.

Advertisement