SceneCaptureComponent Post Process

Running 4.10.2, I’m getting a bug that was (purportedly) fixed way back in 4.6

If you have a SceneCaptureComponent on an actor (note, I’m not using a separate SceneCapture ACTOR for this), changing its PostProcess settings does absolutely nothing. Note that this applies to both HDR and LDR mode (though it would only really matter for the former for me)

Repro steps:

  1. Create a new actor
  2. Add a SceneCapture2D component.
  3. Add a Plane static mesh or something with a material that can receive what the previous capture component is outputting, to test
  4. Apply any sort of really obvious postprocess setting to this (I was using a stylized rendering blendable, but it’s equally broken just doing something like setting the scene color to neon blue or adding a really intense white vignette or something)
  5. Play (in editor is where I tested), note that the SceneCapture2D is outputting the correct image(s), but they’re not getting any of the postprocess that you’ve applied.

Hi RhythmScript -

I am not experiencing the same behavior you are describing above. Can you take a look at my setup in the attached Test Project and let me know what you might be setting up differently?

Thank You

Eric Ketchum

Test Project 4.10.2

Ah, I see… you’re using the LDR-with-Postprocess setting.

Now, here’s the issue I have: I have a global postprocess. I ALSO want this postprocess to be applied to the output of the captured scene.

If I use HDR, the global postprocess is not applied AT ALL… if I use LDR, as you do, the global postprocess gets applied TWICE (first to the captured scene, then again to the output when it’s seen by the in-game camera)

I don’t suppose there’s actually a way around this, I’ll probably have to hack something together with Custom Depth channels to flag the output of scene captures to be skipped by the global postprocess.

AH! I now see the problem. It’s not the postprocess being applied, it’s the fact that the postprocess sees the SceneCapture as a texture. Which, you know, is exactly what you’d expect in the abstract, but it’s a bit tricky to realize that it’s NOT showing, for example, basecolor or normal or depth information.

So the challenge is, how do I make the output of a scenecapture look like it’s “part of the scene” when I don’t have access to all the gbuffer data usually present in a render pass… but that’s not a bug, it’s just a programming challenge.

We can mark this as solved.

Okay, a related bug/I’m-too-stupid-to-understand-this: when set to LDR capture, the SceneCapture seems to be completely ignoring all light sources and their effect on the scene…?

I think what I’m really looking for here is a way to set the SceneCapture component to capture “HDR + Postprocessing”, or else apply the postprocessing to the HDR image.

The PostProcess blendable I’m trying to use here on the SceneCap is designed to be Before The Tonemapper, so I’m getting screwy results with the lighting if I try to use the LDR output since the tonemapper is being applied to the final color twice, thus darkening it fairly substantially (making it look like the lights aren’t being rendered).

The HDR capture ignores postprocess settings, and the LDR capture applies the tonemapper, causing it to be applied twice… this is the crux of my issue.

Hi -

So I am attempting to setup an example project and determine if this is a bug, a feature request, or something I can help you develop. If you can would you mind sharing a screenshot of your Blendable setup? You can link it here or if you want to keep it private link it to me via the Engine Forums Direct Messages.

Thank You

Eric Ketchum

Showing the blendable won’t really help as it’s extremely complex… Lemme tell you what I’m trying to do and you’ll see exactly where the issue is. It’s not a bug, but so far I’ve been unable to work around it.

I’m using SceneCaptureComponents (HDR) as part of a seamless portal actor in my game. This is working fairly well, but there’s a coloration problem, as you can see from this image.

Note how in the first half, the background is much darker, especially in places that the emissive pink is not present .

I know why this is happening, and it’s my PostProcess blendable, which is a cel shader. I’ll save you the hassle of deciphering a massive screenshot and say that the reason is twofold:

  1. My postprocess needs to read the SceneDepth gbuffer to draw outlines, and
  2. It needs to read the BaseColor gbuffer to calculate the lighting intensity (dividing PostProcessInput0 by BaseColor, then banding this output)

You can see what the problem is: since there’s no SceneDepth or BaseColor information present in the captured result of the SceneCapture2D (which is expected, it’s writing a single texture file, not an entire series of render passes), the math being performed by the PostProcess on the portal’s visuals is incorrect. It treats it as a flat surface for its depth calculations, and it has no BaseColor since it’s an unlit (emissive) surface.

Now, it would be possible to work around this issue by applying the postprocess directly to the SceneCapture2D’s output that it’s writing to the surface. Since the portal is translucent it won’t write to SceneDepth, and since it’s unlit it won’t get processed by the cel shader.

BUT that leads to the second problem (which I believe is beyond my capacity to fix)

Since a SceneCapture2D can only be configured to apply postprocess blendables IF it’s set to LDR mode, the Tonemapper hits it twice.

Hi RhythmScript -

I did a little bit more research and was able to get a successful portal like effect that you are after even with an additional post process. I have attached the test project for you to take a look at, but here is the overview:

I created an Outline Effect Blendable which was applied via a Global Post Process Volume. This was primarily meant to match sure that the results would work with a blendable like the one you describe above.

Next I lined up my Scene Render camera and the world rendered object, so that the lines of the grid pattern in the world would match up correct.

I set the Scene Render Camera to LDR(with Final Post Process)

I created a Blendable which was simply the SceneTexture:PostProcess0 plugged into Emissive Color and Assigned it to the Scene Render Camera.

This step eliminates the double post processing. You will still have to deal with Texture compression and mip generation, but that was going to happen no mater what.

Here is the final Result:

Thank You

Eric Ketchum

[Test Project 4.10.2][2]

Wait wait wait.

How are you getting your PostProcess to be applied to the scene BEFORE the PostProcess on the SceneCapture2D grabs the LDR capture?

If I duplicate your setup in my project, the SceneCapture2D’s PostProcessInput0 shows the unmodified scene (as if no global postprocess was enabled), rather than capturing the scene as modified by the global postprocess…

Are you applying the M_Blendable_PRIME (Just the SceneTexture_PostProcess0 plugged into Post Process Material) to the Scene Capture Actor set to Final Color(LDR with Post Process)?

Yes…

Actually, I realized what the issue is, and it’s partly that I’m thinking about it the wrong way and partly that your postprocess doesn’t really solve the problem fully.

The issue is: your global postprocess only works because it doesn’t do anything to the portal object itself. It uses Custom Stencil to filter the objects it modifies, meaning that when it sees the object the SceneCapture is rendered TO, it does nothing but pass it forward.

My cel shader and outline renderer, unlike yours, aren’t limited by the Custom Stencil flag. They process everything. This means that the portal captures the modified world, then gets modified AGAIN because the portal is also a mesh-with-a-material IN the world. So what I was doing was trying to mask out the portal so that it only passed PostProcess0 through, thinking it would then pass the captured scene, but that doesn’t work because of how the blendables are arranged relative to the tonemapper

I think, really, that the issue is I’m thinking about this backwards. Really, everything is working as it should, it’s just not what I want it to do. I think the proper solution is to forego projecting the SceneCapture ONTO a world object… instead, what I need is for the portal to somehow flag itself in a way that lets a PostProcess isolate it. Then, I can simply render the SceneCapture2D’s texture directly in the PostProcess, rather than into the world, bypassing the double-processing issue entirely.

Custom Stencil was made for this, but because my portal object itself is a translucent surface (so I can use depth fade to mask the seams when objects clip into it) I can’t render it with Custom Stencil/Depth.

So what I really need to do is find a clever way to configure the portal material so that a separate postprocess blendable can get “black, but white where the portal is visible”, then just use that mask to display the RenderTexture directly (which works since my portals already use ScreenSpace UVs)

Oh, and as an addendum, that masking solution needs to be able to discriminate between multiple portals, since each side of the portal has its own rendertexture asset to use. So, again, what CustomStencil was MADE for, but not usable in this case.

Hi RhythmScript -

I think you are on the right track and all you will need to do to get your portal object selectable via CustomDepth or CustomStencil is follow these steps:

  1. Create a BlueprintActor
  2. Add the Portal Static Mesh as a Component
  3. Add another copy of your Portal Static Mesh as a new Component (Total of 2 copies of the same mesh right on top of one another.)
  4. Assign one of the Portals to use your Translucent Material
  5. Assign the other Portal a generic opaque material (you can use the world grid material as well)
  6. In the Details panel of the Opaque Mesh under rendering Uncheck Main Pass and check Render in Custom Depth (assign a Stencil if you are using that stencil)

The opaque mesh will not render in the main pass but will render in the Custom Depth pass which the Translucent Material cannot render in. This way you get your mask and keep the translucent object.

Thank You -

Eric Ketchum

1 Like

That’s clever as heck.

Of course the problem with it is that removes the actual depth fade effect that the translucency is meant to enable… But I SUSPECT (will try it shortly) that I can use the Alpha channel of separate translucency as a secondary mask (i.e. CustomStencil of the unrendered opaque plane, multiplied by the opacity of the translucent plane in the separate translucency pass).

Actually using the translucency mask at all still produces the minor problem of translucent objects in front of the portal being rendered AS the portal texture, though I may be able to cleverly get around that somewhat by making the translucent portal pure white and doing a hue check (R=G=B) to prevent the texture from being rendered over top of any translucent object that isn’t white. Still not perfect (a translucent object in front of the portal will not show the portal behind it). But that can maybe be solved with judicious use of level design.

At any rate it feels like a major step in the right direction.