BennyQBD / 3DEngineCpp

It's like the 3D Game Engine, except in C++
Apache License 2.0
301 stars 84 forks source link

Smooth shading / vertex normals #39

Closed zpl-zak closed 8 years ago

zpl-zak commented 8 years ago

Hi, I'd like to ask how to implement vertex normals into this engine properly. No matter what I do, I either get broken or face normals as the result.

So I'd like to know if someone had a success implementing vertex normals in here.

The reason for smooth shading is my terrain generated from heightmap. My terrain feels blocky due to flat normals. See: http://prntscr.com/9xqiqb

citruslee commented 8 years ago

I assume you are using a 3d modelling software like blender to achieve such models. If yes, maybe you need to export the mesh with smooth faces. Also, the second problem should be, that you are not interpolating the vertice normals during computing, or you are directly transforming it. Or maybe you don't normalize them. A simple phong shader should do the trick, which can be found anywhere on the internet, so if that doesn't work okay, maybe you are handling normals wrong

zeyorama commented 8 years ago

Before we are guessing want's going on, lets first ask some question, so we can better argue.

Are you using the default normal map? If so, all normals are perpendicular to the face.

Are you correctly calculating the normals while generating the terrain mesh? Here is a example from Lighthouse3D (http://www.lighthouse3d.com/opengl/terrain/index.php3?normals (Accessed 02. Feb 2016 12:45)).

Are you using Bennys shader model?

zpl-zak commented 8 years ago

I'm using Benny's shader model. Well, this terrain has to be generated programmatically (the terrain is actually 2D heightmap), Well I use Benny's code for normal generation, but these are face normals (resulting in flat shading look). What I need to do, is to generate normals per vertex. I already looked at lighthouse3d link provided and also implemented such algorithm. Only problem is, it takes too long for vertex normals to be computed. That is due to number of vertices involved in terrain (2048x2048 heightmap). While it is true I could just create terrain inside of Blender and just export it, I prefer to use heightmaps directly inside engine for such purposes. If I'm not mistaken, I need face normals (flat shading) to be able to generate vertex normals from them (I could be wrong).

zeyorama commented 8 years ago

Yes 2048x2048 is big indeed, but you only calculate it once on program startup. For your per Vertex normal, you need all face normals of face, where this vertex is contributed to, sum them up and normilize the result. If your generation needs to much time, consider some optimization. Store the face normals per face, so you calculate them only once. If you want, you can calculate the normals using the compute shader or OpenCL to improve perfomance drastically.

zpl-zak commented 8 years ago

Okay, thanks. I'll look into it again. I'm just confused about these things.