scud fog and los position

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!

scud fog and los position

Postby Ian » Wed Jan 10, 2018 3:14 pm

One for Harry,
you still alive Harry ? :) Thought this one might interest you since you wrote most of the fog code. Some people had noticed in the attract mode for scud in the first level, fog shows up where it doesn't on the real hardware.

ie here
Image

and the real hardware
Image

It's like that for the entire section

Anyway in the viewport there are some values we aren't passing out

Code: Select all
    0x1c:   xxxxxxxx xxxxxxxx -------- -------- "lj"
            -------- -------- xxxxxxxx xxxxxxxx "li"


These values are almost always zero, except for this section of scud. As soon as the fog shows where it shouldn't suddenly these values spring to life.

In the SDK I think it's this

Code: Select all
      void        SetLOSPosition   ( float los_position_i
                                   , float los_position_j ) ;


In the decompiled lib comes out as

Code: Select all
void __thiscall PRO_Viewport::SetLOSPosition(PRO_Viewport *this, float los_position_i, float los_position_j)
{
  int v3; // eax@1

  *((float *)this + 53) = los_position_i;
  *((float *)this + 54) = los_position_j;
  *((_DWORD *)this + 13) = (*((_DWORD *)g_API_Data + 343))++;
  v3 = *((_DWORD *)this + 14) | 1;
  *((_DWORD *)this + 14) = v3;
  *((_DWORD *)this + 14) = v3 | 0x80;
  PRO_Pingpong_Data_Block::NotifyUpdate(this);
}


And

Code: Select all
void __thiscall PRO_Viewport::updateLOSPosition(PRO_Viewport *this)
{
  if ( *((_DWORD *)this + 4) == 1 )
  {
    *(_DWORD *)(*((_DWORD *)this + 7) + 112) = *(_DWORD *)(*((_DWORD *)this + 7) + 112) & 0xFFFF | ((signed __int16)(signed __int64)(*((float *)this + 53) * *((float *)this + 47) * 8.0) << 16);
    *(_DWORD *)(*((_DWORD *)this + 7) + 112) = *(_DWORD *)(*((_DWORD *)this + 7) + 112) & 0xFFFF0000 | (unsigned __int16)(signed __int64)(*((float *)this + 48) * *((float *)this + 54) * 8.0);
  }
}


The updateLosPosition tells us the values are multiplied by 8
(float *)this + 47) * 8.0) << 16
and
(float *)this + 54) * 8.0

So we can read out this los position ?? with this code
Code: Select all
      float li = (vpnode[0x1c] & 0xFFFF) / 8.0f;
      float lj = (vpnode[0x1c] >> 16) / 8.0f;


Any idea what the hell a los position is? I guess it's related to lighting or the lens flair somehow.
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: scud fog and los position

Postby HarryTuttle » Thu Jan 11, 2018 5:37 am

That one puzzled me for some time. LOS is Line-Of-Sight and some scarce infos are here. Here's a snippet:
LINE OF SIGHT RANGING:

The system can be directed to report the depth (Z) to any point as
defined by its pixel location. This feature can accurately detect
when a portion of a polygon has been declared translucent by virtue
of its texturing, and instead report the range to the closest opaque
polygon beyond. This method relies on locating the LOS within the
field of view of a display channel. Range is reported with 22-bit
floating point accuracy (six bits exponent, 16 bits mantissa).

I think has to do with stencil/depth buffering and polygon hiding or sorting. There is a dedicated test in the hidden menu of Scud, there're values at the bottom that should supposedly change as the green plane goes away from camera and intersects the red sphere, but currently are stuck maybe by missing emulation.
los_01.png
los_01.png (19.93 KiB) Viewed 6923 times

But aside from this I wasn't able to go further.
Last edited by HarryTuttle on Thu Jan 11, 2018 9:53 am, edited 2 times in total.
User avatar
HarryTuttle
 
Posts: 646
Joined: Thu Mar 09, 2017 8:57 am

Re: scud fog and los position

Postby Ian » Thu Jan 11, 2018 7:27 am

That sounds like it's it.

The devguide has this
Line of Sight (LOS) . . . Viewray from the viewpoint through a pixel on the screen.


So the x/y paramaters must be a position in the viewport. Not sure how the coordinates work though. How do the coordinates work for the head light? I know they are capped at 2048
But what would the coordinates by for 0,0 and 496x384 ?
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: scud fog and los position

Postby HarryTuttle » Thu Jan 11, 2018 10:01 am

Headlight coordinates work like that because they are supposed to go way off screen if necessary (and limited to -8192/+8191, if I recall). Check the intro of ECA, not the first rolling one, but the second more "dramatic", after the fist highscore display.

This is an example (lower/left corner):
eca01.png
eca01.png (77.9 KiB) Viewed 6886 times
User avatar
HarryTuttle
 
Posts: 646
Joined: Thu Mar 09, 2017 8:57 am

Re: scud fog and los position

Postby HarryTuttle » Thu Jan 11, 2018 10:56 am

Ian, a little quiz for you: where did the red houses on the background go?

Model3:
sr2_01a.jpg
sr2_01a.jpg (237.11 KiB) Viewed 6878 times

Supermodel:
sr2_01b.png
sr2_01b.png (227.8 KiB) Viewed 6878 times

I'm currently investigating, without success.
User avatar
HarryTuttle
 
Posts: 646
Joined: Thu Mar 09, 2017 8:57 am

Re: scud fog and los position

Postby Ian » Thu Jan 11, 2018 11:45 am

Not sure :)
2 things to try, disable fog?
Try disabling culling too. Just stub the relevant method and return inside, so it will draw everything

Edit:
Was having a brain fail. I read those as the other way around, showing up on the model3 and not appearing on supermodel.

Remember the actual hardware is doing some automatic LOD selection. Quite often the lower LODs are sometimes just a single flat poly representing the fence or whatever. So I think there's 2 possible things that could be happening. Lowered LOD removes the house entirely?? Possible maybe. Or the simpler LOD has a different Z value, and thus different fog values.

Example
LOD 0 (highest detail)
Image

LOD 3 (lowest detail)
Image

Maybe try force rendering the lowest level of detail? And see what happens. I would love to implement proper LOD selection but so far haven't been able to figure out how it works.
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: scud fog and los position

Postby HarryTuttle » Fri Jan 12, 2018 5:54 am

Thanks for the hint, I'll see if I can do something by this w.e.

I was thinking one could choose, through some GPU configuration register, the fog density algorithm. For example from linear to, say, exponential.
User avatar
HarryTuttle
 
Posts: 646
Joined: Thu Mar 09, 2017 8:57 am

Re: scud fog and los position

Postby Ian » Fri Jan 12, 2018 12:13 pm

Well I figured out what the LOS numbers are.

Code: Select all
      float li = (vpnode[0x1c] & 0xFFFF) / 16.0f;      // los position
      float lj = (vpnode[0x1c] >> 16) / 16.0f;


Actually values are / 16
It's simply the viewport x/y position.

Can test like this

Code: Select all
   glDisableVertexAttribArray(0);
   glDisableVertexAttribArray(1);
   glDisableVertexAttribArray(2);
   glDisableVertexAttribArray(3);
   glDisableVertexAttribArray(4);
   glDisableVertexAttribArray(5);

   {
      glDisable(GL_TEXTURE_2D);
      glDisable(GL_LIGHTING);
      glPointSize(10);

      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      glViewport(0, 0, 496, 384);
      glOrtho(0, 496, 0, 384, -1, 1);
      glColor3f(1, 0, 0);
      glBegin(GL_POINTS);
      glVertex2f(testI, 384-testJ);
      glEnd();

   }


Now to work out how this effects rendering ..

Image
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: scud fog and los position

Postby HarryTuttle » Sat Jan 13, 2018 12:58 pm

Looking at those screenshots, by association, for a moment I thought about the missing Lost Word red pointer...
User avatar
HarryTuttle
 
Posts: 646
Joined: Thu Mar 09, 2017 8:57 am

Re: scud fog and los position

Postby Ian » Sat Jan 13, 2018 1:20 pm

Na i drew it so I could see what it was doing :)
From the description you found, and looking at where it draws.

At a guess I think it probably reads the depth value at that x/y location, then works out whether to turn on fogging. Fogging definitely happens on the original hardware with those x/y values set, but seems dependent on angle. It also only seems to work if fog is set to white or (1,1,1).

Either there is a 1 frame lag between reading values and working out the depth value, or the hardware does a pre depth pass of all the geometry.
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Next

Return to The Dark Room

Who is online

Users browsing this forum: No registered users and 1 guest