Drill & Jetpack

Export and import of assets.
Post Reply
User avatar
Viech
Project Head
Posts: 2139
Joined: Fri Aug 03, 2012 11:50 pm UTC
Location: Berlin

Drill & Jetpack

Post by Viech »

The ingame shading on the Drill and Jetpack is incorrect and we will need to figure out the source of the problem before Warvinc or lhdc do what all modelers do eventually (get sucked into their modeling applications and fall down along the Z axis for all eternity), since we cannot yet know for sure that their exported material works for us.

The issue, visually

How the drill is supposed to look:

Image

How the drill looks without normal mapping (the shading is already incorrect):

Image

How the drill looks with normal and specular mapping (the shading is still incorrect):

Image

Considering that the light is mostly coming from above, the shading doesn't look right in a lot of places but there is one spot where it gets obvious that it's actually wrong, which is the area I marked in the followig shot of an older version of the drill (the "Check smoothing here." note was directed at Warvinc at that time):

Image

The issue is also visible on the flat sides of the drill's feet, which have a strong shadow gradient were none should be, given that they are entirely flat and small compared to the distance to the dominant light source (so a difference in radiance along the surface can be neglected).

The problem is even more apparent on the jetpack. Can you spot where?

Without normal mapping:

Image

With normal mapping:

Image

Right, there is more-than-bad shading around the hinges above the jets, regardless of the presence of normal mapping. Note that the hinges were supposed to be animated to have the jets extend outwards, so there are opposing surfaces hidden inside the jetpack body. Consequently this time the gradients of wrongness aren't conflicting – they repeat. So while the surface around the gap (which might even have a width of exactly zero) is entirely flat it is shaded like the jetpack is powered by a small reverse sun from a parallel universe. This is so wrong that there are literally no technically accurate terms to describe what's happening.

It's worth noting that the jetpack's normal map actually adds a hard edge in the middle. By now it should also be apparent how much these anomalies reduce the visual quality of our assets. So let's move on and try to explain what's going on.

The issue, technically

As suggested in the text on the shot of the drill above, the models appear like the normals of one surface "leak" over to the next. This seems consistent with the fact that (correct me if I'm wrong) IQM stores normals per vertex (as opposed to per surface), which means that all surfaces that share a vertex also share its vertex normal, which is then interpolated over the surface along with the other "shared" vertex normals, creating a smooth shading over edges (which is good for edges that only exist because of the limited poly count but bad for all intentional edges).

I can imagine two ways how IQM's representation of normals can be used to create an effect of "hard" (correct) shading in the relevant locations instead:

  1. Surfaces are partitioned into different meshes so that they selectively don't share vertex normals with certain neighbours (which is what I would understand as "smoothing groups"). I heard rumors that this is how it was done with md5. This can happen manually, on export/import or heuristically on model load.

  2. Normal maps are used to "correct" the interpolated normals. I consider this a rather hackish solution as it only works when normal maps are enabled. This can only be done when baking the normal map and needs to be supported by the modeling application.

Just to be clear

The shading is wrong. I spent a lot of time convincing people of the existence of problems like this and I don't want a meta-discussion to slow down our progress on fixing it, so if you really think the shading is correct talk to me in private and explain your breakthrough in quantum theory that allows light to do what it does for us. :tongue:

If you think the issue is neglible wait until you see how gorgeous the models will look once it is resolved.

All hail teamwork!

A lot of people were involved bringing the models ingame, also involving entirely different responsibilities and areas of expertise, which means we have quite a few pieces of the debug cake to distribute. (Mine was spotting the issue. Your turn! :grin: )

Piece #1: Modeling, Baking, Export

Given that the models are made by two different artists we should ask them a few questions first. Warvinc and lhdc,

  1. What modeling application do you use?

  2. What plugin/subsystem do you use to bake the normal map?

  3. What plugin/subsystem do you use to export the model?

  4. Do you use a feature called "smoothing groups" or something similiar? How are smoothing groups considered on export?

Also, just for Warvinc, since his Telenode appears to have no such issue (I cannot judge it for the Spiker or Booster since they don't have hard edges):

  • Please name all methodical differences between the creation of the Telenode and the Drill, especially related to smoothing groups, baking and exporting.

I think that's it for now for you two. Lean back and refresh this thread once in a while!

Piece #2: IQM, Import

First of all, I would like Ishq and gavlig to

  • Find out which of the hard surface models currently use iqm and which use md5.

  • Find out by whom the latest versions of the relevant models were imported.

  • Analyze if there are import options that could make a difference with regards to normals.

  • Import either the Drill or the Jetpack as a MD5 model and see if this makes a difference. If yes, try to explain why.

Then, I need gimhael to add debug draw functionality that visualizes …

  • the vertex normals on iqm models.

  • just the normal map.

  • the combined normals of interpolated vertex normals and normal map.

  • the shading on top of a white diffuse with no specularity.

This will also help us spot future problems early. Using these debug draws should be mandatory when putting a new model ingame.

Also, I'd like gimhael to give a short technical explaination how normals are handled in the iqm format (or link to one that skips the implementational details).

So this is phase one. kharnov and I will keep track of the progress and I specifically will do my best to help with any of the tasks above if you're stuck.

Responsible for: Arch Linux package & torrent distribution, Parpax (map), Chameleon (map texture editor), Sloth (material file generator), gameplay design & programming, artistic direction

User avatar
enneract
Programmer
Posts: 28
Joined: Sun Jun 01, 2014 9:21 pm UTC

Re: Drill & Jetpack

Post by enneract »

(Writing just in case, not sure if it was already covered.)

Blender has an "Edge Split" modifier which splits all sharp edges in two so that faces are no longer connected and normals aren't interpolated between them. Interesingly enough, I couldn't find anything related to smoothing groups in Blender, so it seems like Edge Split is how it's supposed to be done.

Quick demo:
Image

  1. A cylinder without smooth shading at all.
  2. A cylinder with smooth shading enabled (the normals are so fucked up even a raytracer can't render this correctly).
  3. A cylinder with smooth shading enabled and sharp edges split - the cylinder's top and sides are shaded separately.
User avatar
Viech
Project Head
Posts: 2139
Joined: Fri Aug 03, 2012 11:50 pm UTC
Location: Berlin

Re: Drill & Jetpack

Post by Viech »

I consider smoothing groups to be exactly that – a set of disjunct submeshes which are smoothed independently. So blender has this feature, too, regardless of the fact that the smoothing groups are autogenerated here. I was thinking that MD5 did the same (automatic smoothing group generation at either export or loading time) but having had another look at the reactor (which I assume is a MD5?), it looks a bit like the ingame model is smoothed and the normal map is undoing the smoothing where appropriate. However, until we have a set of graphical debug features this is just a theory of mine.

Either way, it seems we will need to decide on one approach eventually – do an edge split at some point in the pipeline or bake the normal maps in a way that they make a completely smoothed model appear appropriate.

Responsible for: Arch Linux package & torrent distribution, Parpax (map), Chameleon (map texture editor), Sloth (material file generator), gameplay design & programming, artistic direction

User avatar
Viech
Project Head
Posts: 2139
Joined: Fri Aug 03, 2012 11:50 pm UTC
Location: Berlin

Re: Drill & Jetpack

Post by Viech »

Here's a condensed log of an IRC discussion on the topic. Please read it if you weren't present and your name shows up anywhere in the first post. Note that the images show color coded world space normals. See this commit for more.

#unvanquished-dev wrote:

<Viech> every hard edge you see on the reactor is a cut in the mesh: http://i.imgur.com/9003KWn.png
<Viech> this is the version with no normal mapping
<Viech> so even without normals, these edges are rendered properly
<Viech> others aren't.
<Ishq> ie, reactor is done properly
<Viech> wait, that's step one
<Viech> (but yes)
<Viech> now we put normalmapping on top, and more edges show up as they are unsmoothed by the normal map: http://i.imgur.com/mXjUqum.jpg
<Viech> so, what we learn from this is 1) the modeling application already knows which edges should be split, because it uses the normal map only to unsmooth all the other edges
[Questions were asked, so I explain the same again:]
<Viech> […] look at those two pictures very closely. the first shows just the interpolated world space normals
<Viech> some edges already have proper normals! no "leaking" of normals over the edges!
<Viech> → smoothing groups (however created) have found their way into the engine
<Viech> the second picture shows what happens when the normal map is applied on top
<Viech> it's important to understand that the engine only knows smoothing and that two methods are used (correctly by the md5 reactor!) to unsmooth the result
<Viech> the first method is splitting of the mesh into multiple meshes (I call these smoothing groups, because those meshes are internally still 100% smoothed but they are not smoothed "against each other")
<Viech> the second method corrects all the other edges that are supposed to be sharp instead of smooth
<Viech> the second method is the normal map
<Viech> so, what we learn from this is 1) there is a set of edges that needs to be "unsmoothed", because the engine would smooth them otherwise and we don't want that (as trivial as that might sound)
<Viech> 2) for the md5 reactor, this set, let's call it U for unsmooth, is split into two disjunct sets Us and Un
<Viech> Us is the set of edges that will be sharpened by splitting the mesh into multiple meshes, thus the engine's smoothing won't kick in at all
<Viech> this implies duplicating the vertices
<Viech> Un is the set of edges that will be smoothed by the engine but, as we don't want that since Un is subset of U, will be sharpened using the normal map
<gimhael> but the blender export should duplicate the vertices where needed
<kangz> I'd say it is the exporter's job to split the edges that need to be unsmoothed
<Viech> yeah, that's how it worked for the md5 reactor and it worked properly there
<Viech> this is part one of my analysis, now for part two
<Viech> I learned that the same double-method is supposed to be used for the iqm drill
<Viech> I know that because the normal map sharpenes some edges correctly
<Viech> those in Un.
<Viech> the others are smoothed by the engine while they should apparently be made sharp by splitting (as part of Us)
<Viech> here is the drill with no normalmapping. it is entirely smooth, as opposed to the reactor where some edges where already super sharp (due to being part of the Us set)
<Viech> http://i.imgur.com/ezLUfbV.jpg
<Viech> now, if we add the normal map, some of the edges are restored/sharepened: http://i.imgur.com/sfq8rAx.jpg
<Viech> (those in Un)
<Viech> so the stand appears correctly shaded now
<Viech> (the big one in the middle)
<Viech> the feets are still borked and show shading artifacts.
<Viech> the normal map doesn't even try to correct these edges – it assumes they are split
<Viech> so, for the md5 reactor, both Un and Us are used and work. for the iqm drill, both Un and Us are supposed to be used but only Un is actually used
<Viech> used as in unsmoothed accordingly
<
Ishq> Viech: Ok
<Ishq> So basically, there are to parts to making your model look correct: the duplicated verts on the geometry and the normalmap
<
Ishq> ANd these two are supposed to work together for the end result
<Ishq> THe reactor does it properly
<
Ishq> The drill does not
<Ishq> Drill has the verts wrong, but the normlamap correct
<Viech>
Ishq, yes. Ideally, Un and Us are disjunct and their union is U.
<Ishq> And the drill is wrong because all geometry normals are smoothed when some shouldn't be smoothed.
<
Ishq> Ok, this makes sense.
<Viech> if Un and Us are not disjunct or their union is not U, but they are both present, you would still get artifacts but less visible ones
<Viech> this could easily happen if the exporter that does the edge splits splits U differently than the normal map baker
<Viech> so if both is done by the same application → ideal results
<`Ishq> I see. Nice work toughing this one out. However, what's our next step?
<Viech> I need to figure that out. I think lhdc and warvinc should read a shortened log of this
<Viech> I'll cut this and post it on the forums if no one objects

Responsible for: Arch Linux package & torrent distribution, Parpax (map), Chameleon (map texture editor), Sloth (material file generator), gameplay design & programming, artistic direction

User avatar
enneract
Programmer
Posts: 28
Joined: Sun Jun 01, 2014 9:21 pm UTC

Re: Drill & Jetpack

Post by enneract »

Drill's shading is wrong because it's being exported without sharp edges split (turns out Blender doesn't do it automatically).

Here's a properly exported Drill model:
Image

User avatar
Viech
Project Head
Posts: 2139
Joined: Fri Aug 03, 2012 11:50 pm UTC
Location: Berlin

Re: Drill & Jetpack

Post by Viech »

After Redman's proper export, it became apparent that the normal map also needed its green channel (vertical component) to be inverted.

Redman's export, no normalmapping:

Image

(Some areas are left smooth where sharp edges were intended. It's the normal map's job to adjust these.)

With the old normalmap:

Image

(You can see that horizontal details are added correctly but vertically the normalmap makes matters worse, for example on the spacers around the core.)

After inverting the green channel on the normal map:

Image

And this is the end result:

Image

Good job so far! Now we only need to correctly export the jetpack.

Responsible for: Arch Linux package & torrent distribution, Parpax (map), Chameleon (map texture editor), Sloth (material file generator), gameplay design & programming, artistic direction

User avatar
enneract
Programmer
Posts: 28
Joined: Sun Jun 01, 2014 9:21 pm UTC

Re: Drill & Jetpack

Post by enneract »

Jetpack had the exact same problem as Drill. It is now fixed.
Image

User avatar
gavlig
Animator
Posts: 518
Joined: Wed Mar 14, 2012 1:20 pm UTC

Re: Drill & Jetpack

Post by gavlig »

You're the man!

User avatar
Viech
Project Head
Posts: 2139
Joined: Fri Aug 03, 2012 11:50 pm UTC
Location: Berlin

Re: Drill & Jetpack

Post by Viech »

And just like the drill, it needed its normal map green channel inverted in addition to the proper export.

Image

However, there are little artifacts in the inverted normal map that I need to look at after the release. Without normal map, for comparison:

Image

The added normal map shows some artifacts (visible as black spots and slightly jagged edges):

Image

Good job so far! I'll mark this issue as completed as soon as I figured out the normal map.

Responsible for: Arch Linux package & torrent distribution, Parpax (map), Chameleon (map texture editor), Sloth (material file generator), gameplay design & programming, artistic direction

Post Reply