question

ReginaHenschel-4160 avatar image
0 Votes"
ReginaHenschel-4160 asked TomJebo-9587 commented

What is KeyLightOffset and FillLightOffset?

The current [MS-OI29500] "Office Implementation Information for ISO/IEC 29500 Standards Support" has got a table in 2.1.1319 Part 1 Section 20.1.10.30, ST_LightRigType (Light Rig Type).

This table has the columns "KeyLightOffset" and "FillLightOffset". What is the meaning of these columns? There exists no corresponding attribute in RichTextFormat or MS Binary Format.

Kind regards,
Regina

openspecs-office-fileformats
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@ReginaHenschel-4160

Thank you for contacting Microsoft Open Specifications Support. One of our engineers will get back to you shortly.

0 Votes 0 ·

Hi Regina,

I will look into this and get back to you.

Best regards,
Tom Jebo
Sr Escalation Engineer
Microsoft Open Specifications Support

0 Votes 0 ·
TomJebo-9587 avatar image
0 Votes"
TomJebo-9587 answered TomJebo-9587 commented

@ReginaHenschel-4160,

Here's the revised and expanded explanation from the graphics team:

It is challenging to explain how all the properties of lights and shapes are combined to calculate final per-pixel colors seen on the screen. The light “scale and offset” values only affect the diffuse color component for a pixel. This pseudo-code shows how the diffuse color is calculated given a point, the surface normal at that point, the shape’s diffuse color at that point, and a collection of lights:

 // IN: p is the surface point, n is the normal vector at that point, surfaceDiffuseColor is the color of the surface at that point.
 // OUT: diffuse and specular colors are returned
 Color CalculateGouraudLighting( const Point3D& p, const Vector3D& n, const Color& surfaceDiffuseColor, const LightArray& lights )
 {
    // Init RGBA diffuse color
    Color diff( 0.0f, 0.0f, 0.0f, 1.0f );
    
    for( int i = 0; i < lights.Count(); i++ )
    {
       // Get this light's colors.
       const IModelLight& light = lights[ i ];
       Color lightColor = light.GetColor();
    
       // Get light direction
       Vector3D lightDir = light.DirectionToPoint( p );
    
       // Calc diffuse contribution if needed.
       if( light.AffectsDiffuse() )
       {
          // Calc scalar dot product from surface normal and light direction
          float dot = -( n * lightDir );
    
          // Apply scale and offset to adjust light attenuation
          dot = dot * light.GetWrapScale() + light.GetWrapOffset();
    
          if( dot >= 1.0f )
          {
             // Add in full diffuse contribution
             diff.r += surfaceDiffuseColor.r * lightColor.r;
             diff.g += surfaceDiffuseColor.g * lightColor.g;
             diff.b += surfaceDiffuseColor.b * lightColor.b;
          }
          else if ( dot > 0.0 )
          {
             // Add in diffuse contribution attenuated by the scalar dot product
             diff.r += dot * surfaceDiffuseColor.r * lightColor.r;
             diff.g += dot * surfaceDiffuseColor.g * lightColor.g;
             diff.b += dot * surfaceDiffuseColor.b * lightColor.b;
          }
       }  // end of diffuse calculation
    }  // end of loop over each light
    
    return diff;
 }

Here is where the scale and offset of individual key & fill lights contribute to the diffuse lighting calculation for a given surface point. Scale values < 1, or negative offset values, make the light illuminate the shape less. Scale values > 1, or positive offset values, make the light illuminate the shape more.

There are further factors that can affect the color ultimately shown on screen. We use a non-directional ambient light that provides a dim base lighting for the parts of a shape that aren’t facing the light, so they are never totally dark. Lights also contribute specular highlights, too. And if a shape has a metallic surface, the diffuse and specular colors are further blended.

I hope that is more helpful. Let me know if you have more questions.

Best regards,
Tom Jebo
Sr Escalation Engineer
Microsoft Open Specifications Support



· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you very much for your detailed answer. Now it is much clearer how this 'offset' affects the final color on screen. I am glad you took the time to answer my question satisfactorily.

Kind regards,
Regina

0 Votes 0 ·
TomJebo-9587 avatar image TomJebo-9587 ReginaHenschel-4160 ·

@ReginaHenschel-4160,

Thanks for confirming. I'll let the graphics folks know you appreciate the effort.

Tom

0 Votes 0 ·
TomJebo-9587 avatar image
0 Votes"
TomJebo-9587 answered TomJebo-9587 commented

@ReginaHenschel-4160,

Our graphics team has provided this explanation, please let me know if this is enough information for you:

The scale and offset values are part of our Gouraud shading equation for calculating the color at any point on a polygon; the scale and offset values can modify the contribution of the shape diffuse color to this equation.

This old D3D9 article describes the basic concepts of diffuse lighting, with visual examples: Diffuse Lighting (Direct3D 9) - Win32 apps | Microsoft Docs. It doesn’t mention our Office scale or offset values, but those can be thought as modifiers that are pre-applied to the parameter Cd of that article.

We probably didn’t need to document these Office properties at all, as they always have default values (scale of 1.0, offset of 0.0), so they really have no impact on our lighting equations in practice.

Best regards,
Tom Jebo
Sr Escalation Engineer
Microsoft Open Specifications Support


· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

The D3D9 article is valuable, but it does not answer the question. And the statement "always have default values (scale of 1.0, offset of 0.0)" is wrong. The rows LegacyFlat* and LegacyNormal* have FillLightScale 0.5 and FillLightOffset 0.5.
Unfortunately, the explanation does not answer the question.

0 Votes 0 ·
TomJebo-9587 avatar image TomJebo-9587 ReginaHenschel-4160 ·

@ReginaHenschel-4160,

Thanks for the reply. I'll check back with the graphics team and see if they can add further explanation.

Tom

0 Votes 0 ·