Trouble drawing clean lines

This topic is 4742 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I'm having trouble with getting lines to render cleanly in DirectX8. I'm rendering a cityscape, but my building outlines often look dashed or dotted instead of being nice clean lines. I've tried playing with the near & far view-plane settings but this hasn't solved the problem. I've also tried setting a low z-bias and drawing the building faces (D3DPT_TRIANGLELIST) and then setting a high z-bias for the building outlines (D3DPT_LINELIST), but this just seems to make things worse. Below is a link to a screenshot as well as a couple of hopefully relevent snippets. Cityscape screenshot ' Fill in the type structure used to create the device d3dpp.BackBufferCount = 1 d3dpp.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE d3dpp.EnableAutoDepthStencil = 1 d3dpp.AutoDepthStencilFormat = D3DFMT_D16 'set up the projection matrix (pi/4 = radians) Call D3DXMatrixPerspectiveFovLH(MatProj, PI / 4, 1, 0.001, 3) In closing, many thanks to GameDev.net and it's many contributers - they've been immensively helpful!!

Share on other sites
I haven't found a good solution to this myself. One thing I tried was to map a texture with a white center and a thin border around it. In each mip-level, I keep the thin border the same actual width by growing it for each mip-level smaller.

Share on other sites
I've never had any problems rendering lines. I can't see your screenshot, it says the host is having a massage. Whatever that means.

Here's a snap of my line drawing. Up close, then far, far away:

It's difficult to understand what the problem is without the screenshot. Maybe repost it on image shack?

Share on other sites
I think what you are looking for is somewhat like opengl's polygon offset. Unfortunately, this feature isn't supported by DirectX, so the only way to properly do outline is to tweak the projection matrix : add a little offset to the near plane, it should solve the problem in many cases (but not all). Be sure to take the good offset : a too low value would change nothing, and a too high one would shift the outline compared to the object.

Share on other sites
actually, a more robust solution would be to construct a projection-matrix that add fractions of w into z. this would effectivly work in more or less the same way as polygon offset.

multiply your normal projection-matrix with something like
[ 1 0 0 0
0 1 0 0
0 0 1 x
0 0 0 1 ]

where x is the fraction you want.

the reason this works is that adding a value to z after viewportmapping is the same as adding the value multiplied with w to z prior to perspective division, because:

(x + y * z) / z = x / z + y

so what you end up doing is adding a constant value to z, ie offsetting the zbuffer-values, but not affecting the rasterization of the primitive in any other way. yay!

[Edited by - kusma on May 25, 2005 7:31:04 AM]

Share on other sites
Ahh, now I can see your snap shot. Just a z-buffer problem. This is how I implimented this. You only need to modify two attributes of your projection matrix:

float diff = 0.1f; // this is the modifer. It depends on your unit scale.float off_far = FarDistance + diff;float off_near = NearDistance + diff;Projection._33 = off_far / ( off_far - off_near );Projection._43 = -Projection._33 * off_near;

You need to make sure you re-send the matrix to the API. After you render the lines, if you need to render something normal afterwards, and before Present(), just do the same thing again without adding diff to the far and near values. That should return it to normal.

Share on other sites
I tried modifying my projection matrix as suggested, but this caused the previously hidden building lines on the backside of the building to become visible (see Cityscape2).

Here's the abbreviated code for this:

Const NEAR_DIST = 0.001
Const FAR_DIST = 3
Const OFFSET = 0.00005

Sub InitializeD3D:
Call D3DXMatrixPerspectiveFovLH(MatProj, PI / 4, 1, NEAR_DIST, FAR_DIST)
Call D3DDevice.SetTransform(D3DTS_PROJECTION, MatProj)

Sub RenderScene
draw buildings faces
MatProj.m33 = (FAR_DIST + OFFSET) / (FAR_DIST - NEAR_DIST)
MatProj.m44 = MatProj.m33 * (NEAR_DIST + OFFSET)
Call D3DDevice.SetTransform(D3DTS_PROJECTION, MatProj)
draw buildings edges
restore original MatProj
draw some other stuff

So, I'm trying another approach - manually separating the building edge vertexes from the building face vertexes by a very small distance.
So far I've just done the trivially easy rooflines (see Cityscape3). I still get some dash/dotting on the rooflines, but it is much improved.

It seems like a brute force approach and I'm sure there are much more elegant solutions. Am I missing something on the projection matrix approach?

Share on other sites
One reason that you could be having that problem, is that the line that you are drawing seems to be 1 pixel wide. If that is the case, there isn't much you can do about it. It's basically the problem when you try to draw a diagonal line in Microsoft Paint. Another example is Microsoft Flight Sim 2004. The lines of the buildings are always dotted or dashed.

Anyway, if I were you, I would forget about that problem! With a few textures ans some proper lighting, the program will look great!

Nice work!

Share on other sites
The problem with the lines showing up when you alter the projection matrix is caused by using an offset that is way too large. Your projection range is very flat (0.001 is very low for a near clip plane, even if you're using 3 as a far plane). The offset of 0.00005 is far to great when compared to the near clip plane. That's a 5% change (which results in the Z values changing a similar order of magnitude). Try making the offset something like 5 or 6 orders of magnitude smaller than the near clip plane (for instance: 0.000000005 == 10E-9).

Share on other sites
My 0.1f offset was relative to 1.0 being an inch. My near and far plane distance ranges from 20.0 to 2000.0 [smile]

Try turning the offset to as low as possible, then turning it up by small amounts while checking results. Having it set too high will cause it to render over top of things as the view gets farther away. I started off with the value 1.0, but soon realized it wasn't going to work. After I adjusted to 0.1, it works well enough that there is never a visible flaw from any decent distance. So you should be able to find a value that suits yours.

I've never seen a scale as small as 3.0 for the far plane. Is this because your modeling program scale is really small?

edit:

You know what, I'm not so sure that is the problem. I'm thinking my setup may also have the glitch simular to yours if the lines appeared on a hard corner while viewing it at specific angles. Have you thought about using stencils?

• 10
• 18
• 14
• 18
• 15