[Patch] Sun Shading

Technical discussion for those interested in Supermodel development and Model 3 reverse engineering. Prospective contributors welcome.
Forum rules
Keep it classy!

  • No ROM requests or links.
  • Do not ask to be a play tester.
  • Do not ask about release dates.
  • No drama!

Re: [Patch] Sun Shading

Postby HarryTuttle » Sat Aug 19, 2017 9:21 am

I already tried to store them as int, however the result is the same.

Emulation-wise I would do the conversion anyway since is what the hw is expecting, also I'd use your INT8toFloat macro for either vertex and polygon normals in addition to fixed shading.

I noticed that polygon normals, stored as 24 bit, are normalized and saturated so they reach the [-1, 1] limits, unlike the vertex INT8 normals.
User avatar
HarryTuttle
 
Posts: 558
Joined: Thu Mar 09, 2017 8:57 am

Re: [Patch] Sun Shading

Postby Ian » Sat Aug 19, 2017 9:23 am

I mean
24bit poly normal -> int8 ?
Ian
 
Posts: 1216
Joined: Tue Feb 23, 2016 9:23 am

Re: [Patch] Sun Shading

Postby HarryTuttle » Sat Aug 19, 2017 9:49 am

Yes, that conversion.
User avatar
HarryTuttle
 
Posts: 558
Joined: Thu Mar 09, 2017 8:57 am

Re: [Patch] Sun Shading

Postby Ian » Sat Aug 19, 2017 10:05 am

oh well, was worth a try :)
I'm currently working on merging your last changes, been quite busy past few days
Ian
 
Posts: 1216
Joined: Tue Feb 23, 2016 9:23 am

Re: [Patch] Sun Shading

Postby HarryTuttle » Sat Aug 19, 2017 10:12 am

Ok :)
Before commit, if you want, we can summarize here the fixed shading math, just to be sure we've understood each other. We still have to finalize how luminous polygons behave in step 1.5 (NdotL & fixed shaded).
User avatar
HarryTuttle
 
Posts: 558
Joined: Thu Mar 09, 2017 8:57 am

Re: [Patch] Sun Shading

Postby Ian » Sat Aug 19, 2017 10:16 am

Code: Select all
      // Compute diffuse factor for sunlight
      if(fixedShading) {
         sunFactor = fsFixedShade;
      }
      else {
         sunFactor = dot(sunVector, fsViewNormal);
      }


For fixed shading + disabled light
Really not 100% sure of the logic at all
But on step 1.5 it's something like colour + vpAmbient
Step 2.0 just colour. As far as I can see it's not effected by vpAmbient or diffuse
Ian
 
Posts: 1216
Joined: Tue Feb 23, 2016 9:23 am

Re: [Patch] Sun Shading

Postby HarryTuttle » Sat Aug 19, 2017 11:01 am

Ok, I'll add something like:
Code: Select all
// Set limits, for models without "modelScale" defined
sunFactor  = clamp(sunFactor, -1.0, 1.0);

// Check if GPU is set to clamp intensity floor to zero
if (intensityLowClamp)
   sunFactor = max(sunFactor, 0.0);

That's all for sunFactor itself.

For the remaining math:
Code: Select all
// Once we fetch viewport lightDiffuse and lightAmbient values...

if (lightEnabled) {
   lightDiffuse *= sunFactor;
}
else {
   if (hardwareStep == 0x15) {
      float offset = fixedShading ? 0.5 : 0.0;
      lightDiffuse += offset;
   }
   else {
      lightAmbient = one;
      lightDiffuse = zero;
   }
}
fragment.rgb *= lightDiffuse + lightAmbient;

That'll take care for both NdotL and Fixed shaded polygons, illuminated or luminous.

In particular: for illuminated polygons in step 2.x the resulting math will be like you've said, for step 1.5 will be equivalent to this:
Code: Select all
if (fixedShading)
   fragment.rgb *= (lightDiffuse + 0.5) + lightAmbient;
else
   fragment.rgb *= lightDiffuse + lightAmbient;
User avatar
HarryTuttle
 
Posts: 558
Joined: Thu Mar 09, 2017 8:57 am

Re: [Patch] Sun Shading

Postby Ian » Sun Aug 20, 2017 8:44 am

Harry,
total long shot here ..
But have you tried doing flat shading by calculating the polygon normal .. instead of using the actual normal provided?
In theory they should always be the same, but in practice they seem to vary for reasons I can't understand

Code: Select all
void CNew3D::CopyVertexData(const R3DPoly& r3dPoly, std::vector<Poly>& polyArray)
{
   //====================
   Poly      p;
   V3::Vec3   normal;
   float      dotProd;
   bool      clockWise;
   //====================

   V3::createNormal(r3dPoly.v[0].pos, r3dPoly.v[1].pos, r3dPoly.v[2].pos, normal);

   dotProd      = V3::dotProduct(normal, r3dPoly.faceNormal);
   clockWise = dotProd >= 0;

   {
      V3::normalise(normal);
      float test = std::abs(normal[0]) - std::abs(r3dPoly.faceNormal[0]);

      if (std::abs(test) > 0.01) {
         int debug = 0;
      }
   }


run that with lemans 24 and stick a break point in there
Ian
 
Posts: 1216
Joined: Tue Feb 23, 2016 9:23 am

Re: [Patch] Sun Shading

Postby HarryTuttle » Sun Aug 20, 2017 10:32 am

You're telepathic :)

I'm currently fiddling with polygon normal not only for that, but because I've had a second chance to do the conversion 24bit -> INT8, and found that sometimes some term, because of lost precision, is inverted. That is: when in 24bit is "1.0", in signed byte becomes -128, so "-1.0" with the consequence you can imagine. Infact it'll affect CopyVertexData computations.

I'll update the post with some dumped values to console, to show better that behavior. Maybe you'll be able to see something I don't see.

UPDATE: This is an extract of the console dump of the "x" component when is either "1" or "-1". Tested with Le Mans 24 intro and with your INT8_TO_FLOAT macro applied when fetched as INT8.
Code: Select all
[...]
INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: -1
INT32.x -> float.x: -1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000

INT32.x: 1
INT32.x -> float.x: 1.000000
INT8.x: -128
INT8.x -> float.x: -1.000000
[...]
User avatar
HarryTuttle
 
Posts: 558
Joined: Thu Mar 09, 2017 8:57 am

Re: [Patch] Sun Shading

Postby HarryTuttle » Sun Aug 20, 2017 10:53 am

Ian wrote:But have you tried doing flat shading by calculating the polygon normal .. instead of using the actual normal provided?


EDIT:
Removed my dumb observation, I've understood the exact opposite of what you wrote... :roll:
Last edited by HarryTuttle on Sun Aug 20, 2017 12:12 pm, edited 1 time in total.
User avatar
HarryTuttle
 
Posts: 558
Joined: Thu Mar 09, 2017 8:57 am

PreviousNext

Return to The Dark Room

Who is online

Users browsing this forum: No registered users and 2 guests