Repository navigation
Conversation
OneSidePerFrame renders one cube face and re-runs the full pre-filter, mip generation and main filter on every frame. On a CPU-bound client the reflection pass measured about 0.37 ms of main-thread time per frame. OneSideEveryOtherFrame does the same work on even frames only (by Tr2Renderer::GetCurrentFrameCounter parity, so it gives one answer per frame however often it is asked). On odd frames the render driver prepares no reflection faces, so no face is rendered or filtered and the last filtered reflection stays bound. A full cube update takes 12 frames instead of 6. The first pass after creation still renders all six faces. The new enum value is appended, so existing values and saved settings keep their meaning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a fourth reflection probe update rate,
ReflectionProbeRenderFrequency.OneSideEveryOtherFrame. It does whatOneSidePerFramedoes (render one cube face, then pre-filter, generate mips and run the main filter over the whole cube), but only on even frames. On odd frames the render driver prepares no reflection faces, so nothing is rendered or filtered and the last filtered reflection stays bound.Tr2Renderer::GetCurrentFrameCounter()parity, not from a toggle, so the answer is the same however many times a frame asks.OneSidePerFrame(0) andAllSidesPerFrame(1) keep their values.Why
On a CPU-bound EVE Frontier client (about 5.4 ms CPU against about 3.1 ms GPU per frame), Tracy showed the reflection pass at about 0.37 ms of main-thread time per frame with
OneSidePerFrame. That was one of the larger single costs left after other camera-movement fixes. Reflections on ships and structures change slowly, so updating them at half the rate isn't noticeable in normal play.Changes
trinity/Tr2ReflectionProbe.hONE_SIDE_EVERY_OTHER_FRAME; newShouldRenderThisFrame() const.trinity/Tr2ReflectionProbe.cppShouldRenderThisFrame(): true unless the mode is every-other-frame, the first full pass is done and the frame counter is odd.trinity/Tr2ReflectionProbe_Blue.cppOneSideEveryOtherFramein the chooser.trinity/Eve/EveSpaceSceneRenderDriver.cppPrepareReflectionFacesreturns no faces when the probe says to skip this frame, soRenderReflectionFacesdoes nothing.GetStartFace/GetEndFaceandFinishFacesdon't change: on the frames that do render, the new mode behaves exactly likeOneSidePerFrame.Measurements
Measured in a live EVE Frontier client. It was a local
trinitydevDX12 build of this change (written against the pre-#137 code, where the gate sat inEveSpaceScene::RenderReflectionPass). Reflections were on High, the ship was in space, and there was no input. The mode was switched at runtime throughscene.reflectionProbe.renderFrequency, alternating five 4-second windows of each:OneSidePerFrameOneSideEveryOtherFrameThat saves 0.33 ms a frame (+5% fps). It's more than half of the 0.37 ms main-thread zone, presumably because the filter's GPU work and submission go away on those frames too. The face count was read from
probe.currentFrameonce per frame, which confirms exactly every other frame renders. The screenshots looked normal.After #137 landed I rebased onto it and moved the gate to
EveSpaceSceneRenderDriver::PrepareReflectionFaces, because #137 removedEveSpaceScene::RenderReflectionPassand the driver now owns the faces. The rebased version builds locally (trinitydev, DX12). It hasn't been measured in the client: the client's Perforce stream doesn't have #137 yet.How it's used
The game picks the mode from Python (
packages/trinity/sceneRenderJobSpace.pyin the EVE Frontier stream, Perforce CL 3685716). It usesOneSideEveryOtherFramefor Low, Medium and High reflection quality and keepsAllSidesPerFramefor Ultra. That code falls back toOneSidePerFramewhen the running Trinity doesn't have the new value, so the two changes can land in either order.Testing
x64-windows-trinitydev, DX12 (pre- and post-rebase)🤖 Generated with Claude Code