Directional lighting gives sharp edges

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
ison
Posts: 42
Joined: Sun Mar 24, 2013 9:09 pm

Directional lighting gives sharp edges

Post by ison »

Hello.

I added directional light like this (OpenGL driver):

Code: Select all

irr::scene::ILightSceneNode*  pLight = sceneManager->addLightSceneNode();
irr::video::SLight & l = pLight->getLightData();
l.Type = irr::video::ELT_DIRECTIONAL;
l.AmbientColor = {0.3f, 0.3f, 0.3f};
This is how my model looks from 1 side (OK, smooth transition):
Image

And this is how it looks from another (sharp edge):
Image

In Blender model looks good from all sides. There are no sharp edges anywhere.

1) What causes this? (I tried normalizing normals and recalculating them)
2) Is it better nowadays to write custom forward-rendering shader with directional and point lights support? (or maybe even deferred rendering?)
3) Would it be noticeably slower than using regular rendering without custom shaders?

Thanks
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Directional lighting gives sharp edges

Post by mongoose7 »

1. Maybe look at the code for creating normals. I think it may have a smoothing angle as a parameter (although the angle in both cases appears to be the same, 135 deg). If it is an OBJ file, make sure there is only one group and one material. On the other hand, it might just be the angle of the light. Try rotating the model. (Fixed-function lighting is calculated per vertex not per pixel.)
2. Yes. The fixed function cannot give you per-pixel lighting, so you really have to use shaders if you want your pictures to look good.
3. I don't think there is much speed difference if the shader is similar to the fixed function. But you really have to use shaders so forget about the speed of the fixed-function pipeline.
ison
Posts: 42
Joined: Sun Mar 24, 2013 9:09 pm

Re: Directional lighting gives sharp edges

Post by ison »

Thanks. Changing light direction indeed solved the problem. But it's still worying that there are some angles at which sharp edges occur - I'm not using flat shading so it should never occur, should it?

Is it better (or faster) to write custom per-pixel shader for directional lighting?
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Directional lighting gives sharp edges

Post by mongoose7 »

Yes it should! You are using per-vertex lighting. If you want per-pixel lighting, you will have to write a shader.

I should note that Irrlicht has a per-pixel shader which supports two lights and normal/parallax mapping. You should get it automatically if you load an OBJ file with a normal map.
ison
Posts: 42
Joined: Sun Mar 24, 2013 9:09 pm

Re: Directional lighting gives sharp edges

Post by ison »

Nice, thanks alot.
I have another problem but I'm not sure if I should start a new thread.

I'm using shadow volumes, and I add volume nodes like this: node->addShadowVolumeSceneNode(mesh);

Usually everything looks OK:
Image
But at some camera angles, if I move camera a little bit, shadows disappear:
Image

Why does it happen?
I tried: shadowVolumeNode->setAutomaticCulling(irr::scene::EAC_OFF);
but it doesn't help.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Directional lighting gives sharp edges

Post by mongoose7 »

You turned off Irrlicht's culling, but the GPU also culls. I don't know how the shadow volume is capped at the near plane so try moving the near plane closer to the camera.
ison
Posts: 42
Joined: Sun Mar 24, 2013 9:09 pm

Re: Directional lighting gives sharp edges

Post by ison »

Thanks.

I tried setting lower 'infinite' value passed to createShadowVolumeSceneNode() and it fixed the problem.

These shadow volumes are extremely slow though, I use 16 vertices shadow mesh and for like 10 meshes the framerate drops significantly, so I guess shadow volumes aren't very useful unless they are optimized.
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Directional lighting gives sharp edges

Post by Mel »

The shadow volumes are quite expensive to calculate. It would be better to use another type of shadowing like soft stencil shadows or shadow buffers that don't need to recreate a (complex) mesh per frame and object.

The shadows are sharp because irrlicht uses stencil shadows, which are binary, so a surface is shaded or not.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
ison
Posts: 42
Joined: Sun Mar 24, 2013 9:09 pm

Re: Directional lighting gives sharp edges

Post by ison »

Thanks for your answer.

So I disabled shadow volumes, but unfortunately the problem is still there.

I set GouraudShading to true for all model's materials.
I replaced directional light with point light, to make sure it's not caused by bugged OpenGL directional light.
I tried recalculating normals using meshManip->recalculateNormals(buffer, true, true);
I tried using NormalizeNormals.
I tried removing doubles in Blender (I had to set high threshold before any vertices were removed).
I tried using different models: .obj trees and .x animated model

But I still get this effect (sharp edges):
Image

Any ideas?
(For trees it sometimes works, sometimes doesn't. There are some trees that have sharp edges, and some that have smooth - even if they share the same mesh)

// edit:
Ok, problem solved.
For animated meshes, setting GouraudShading to true for all materials in Irrlicht doesn't seem to affect shading at all. The problem was that in Blender, I had to disable 'Shadeless' for all materials and apply smooth shading.
For static models I had to remove doubles and check 'Export normals' in Blender.
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Directional lighting gives sharp edges

Post by Mel »

That is what i was going to suggest, that you checked if your normals were properly exported, and that you chose the right format. The 3DS loader, for instance, doesn't read smoothing groups, and thus, can't produce the apropriate normals.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
Post Reply