Skip to content

RTSS: support emissive colour on unlit passes - #3785

Open
Chex4ever wants to merge 1 commit into
OGRECave:masterfrom
Chex4ever:fix/rtss-unlit-emissive
Open

Chex4ever wants to merge 1 commit into
OGRECave:masterfrom
Chex4ever:fix/rtss-unlit-emissive

Conversation

@Chex4ever

Copy link
Copy Markdown
Contributor

Motivation & Use Cases

In games and real-time visualization, many self-illuminating objects must be rendered without being affected by scene lighting or shadows:

  1. In-game screens, digital displays, and 3D UI: Terminal displays and monitors must remain completely readable and emit their intended colours regardless of whether the surrounding room is dark or illuminated by flickering dynamic lights.
  2. Dynamic status indicators (LEDs, buttons, warning lights): Changing a status indicator colour from green to red at runtime is simply done via pass->setEmissive(colour) without needing to swap textures or rebuild vertex buffers.
  3. Textureless glow / neon / laser geometry: Creating 1x1 dummy textures simply to give an unlit surface a solid color is wasteful for texture memory and GPU texture sampler units.
  4. Consistent flat shading: Avoids the overhead and visual distortion of Lambertian/Phong lighting calculations on objects that are purely emissive.

Problem

When lighting is disabled on a pass (!srcPass->getLightingEnabled()) and the mesh does not provide vertex colours, FFPColour::addFunctionInvocations unconditionally assigns Vector4(1.0) (white) as the diffuse colour.

Because FFPLighting is bypassed for unlit passes, unlit materials with non-black emissive colours render as constant white. In RTSS there was previously no way to specify a flat unlit surface colour via pass properties without binding a texture or providing vertex colours.

Solution

In FFPColour::preAddToRenderState, check if the pass is unlit and has a non-black emissive colour:

  • Resolve GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR directly in the fragment shader when !mPSInputDiffuse (or in vertex shader only if output diffuse is required by another stage).
  • Assign the emissive colour uniform to diffuse colour instead of hardcoded Vector4(1.0).
  • Avoids allocating redundant varying interpolators between VS and PS, preserving GPU bandwidth and registers.

Lit passes and unlit passes with black emissive colour remain completely unaffected.

Tests

  • Added TEST_F(RTShaderSystem, UnlitEmissive) in Tests/Components/RTShaderSystemTests.cpp verifying shader generation for unlit emissive passes.

When lighting is disabled on a pass (!srcPass->getLightingEnabled()) and the mesh does not provide vertex colours, FFPColour unconditionally assigned Vector4(1.0) (white) as the diffuse colour. Because FFPLighting is bypassed for unlit passes, unlit materials with non-black emissive colours rendered as constant white.

Resolve ACT_SURFACE_EMISSIVE_COLOUR for unlit passes with non-black emissive colour and assign it directly in the fragment shader so unlit materials can specify flat emissive colours without requiring textures, vertex colours, or varying interpolators.

Also add a unit test in RTShaderSystemTests verifying shader generation.

This branch has not been deployed

No deployments
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.

1 participant