(left = arcade, right = Supermodel)
(left = arcade, middle = Supermodel (bad), right = Supermodel (good))
This one has always been under my nose and I never noticed (the mechanics' red suits)

(left = arcade, right = Supermodel)
In fragment shader we've always wrongly clamped the dot product between sun vector and vertex direction normal like this:
- Code: Select all
// Compute diffuse factor for sunlight
sunFactor = max(dot(sunVector, fsViewNormal), 0.0);
instead it should be (so to have a negative shade):
- Code: Select all
// Compute diffuse factor for sunlight
sunFactor = dot(sunVector, fsViewNormal);
In this regard I believe that ambient light could well be above 0.5, even 1.0, because that value will eventually be subtracted by the "sunFactor" value multiplied by sun intensity. Similarly to what happens in fixed-shading with signed values. In the end it seems there's no second sun light merged in.
The results are more consistent with the original Model3 screenshots. Obviously there're still the usual bits of corner cases / weirdness we're accustomed to when dealing with the Real3D.
Also I think there's a missing piece from the puzzle: the (in)famous model scale value that should be multiplied by the vertex direction normal ("fsViewNormal" component), so when it's 0.0 there's no shading; 1.0, vice versa, it's full scale shade. Without that value, as of now, we have some wrongly darkened object.
We should clamp *only* the specular highlight itself, like it's currently done, because you cannot have an absolute black spot on shining surfaces. If you are going to test it, please remove the 0.75 clamping of ambient light.