Skip to content

Take a faded alpha from the material, as the DirectX driver does - #15

Merged
nsgomez merged 1 commit into
nsgomez:mainfrom
aspctt:alpha-multiplier-fade
Oct 25, 2026
Merged

nsgomez merged 1 commit into
nsgomez:mainfrom
aspctt:alpha-multiplier-fade

Conversation

@aspctt

@aspctt aspctt commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #7.

AlphaMultiplier writes the faded alpha into the diffuse material, but while glColorMaterial tracks GL_DIFFUSE, the vertex colour replaces the diffuse material, alpha included, so the fade never shows. It also skips the write entirely when neither vertex colour flag is set.

What the DirectX driver does, from SimCity 4 version 641:

  • AlphaMultiplier (0x883310) sets the material's diffuse alpha, then sets D3DRS_DIFFUSEMATERIALSOURCE to D3DMCS_MATERIAL when the alpha is below 1.0, or back to D3DMCS_COLOR1 at 1.0 if the diffuse flag of EnableVertexColors is set.
  • EnableVertexColors (0x8833e0) sets D3DRS_AMBIENTMATERIALSOURCE and D3DRS_DIFFUSEMATERIALSOURCE from its two flags, whatever the alpha was.

Changes:

  • Below 1.0, colour material stops tracking the diffuse material, so the lit alpha is the material's.
  • At 1.0, it tracks the vertex colour again if EnableVertexColors asked for that. EnableVertexColors sets the source outright, as on DirectX.
  • The diffuse material is written back whenever tracking stops, since OpenGL leaves the last vertex colour in a material it stops tracking.

This is what kept cars from fading in and out right.

#13 also targets #7, by always writing the alpha to the material. That covers the case where neither vertex colour flag is set, but while colour material tracks GL_DIFFUSE the material's alpha is still replaced, by the vertex colour or by the glColor4f(1, 1, 1, 1) that InterleavedArrays sets for formats without one. Switching the source as DirectX does covers both cases.

One side effect: while something fades, the directional light no longer adds the vertex colour, so it can look a little darker during the fade. DirectX never adds it: its driver gives Direct3D no normals (the FVF is built from XYZ, DIFFUSE and TEX only, 0x8891c0), so the light contributes nothing. With OpenGL's default normal of (0,0,1) it adds part of the vertex colour in two of the four camera rotations.

Tested in game on version 641 with an NVIDIA RTX 3070, against upstream main: cars fade in and out.

- Below one, AlphaMultiplier stops the vertex colour feeding the diffuse material, so the fade wins over the vertex alpha
- At one, the vertex colour feeds it again if EnableVertexColors asked for that
- The diffuse material is written back whenever the vertex colour stops feeding it, since OpenGL leaves the last vertex colour there
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Alpha blending for cars on streets is broken

2 participants