Download

Scene capture not working when procedurally generated.

If I create a blue-print actor, give it a scene capture component (2D), give it a mesh with a material that samples from a render target texture, point the capture component to that render target, then everything works hunky dory!! In other words, if I author all of that in the editor, everything works.

That’s great. Fine. But if I try to do all of this at run-time in C++ by dynamically creating the components, the materials, the render target, etc…then I fail miserably, and it just doesn’t work. In my case, I pre-author the material and the render target texture and I’m just loading them when I need them. But the scene capture component is being created by me at run-time.

To be as specific as possible, here are my steps. These steps occur in my actor’s tick function, but not every frame. I have wrapped the following steps in an if-false block so that they only execute inside my tick function if I have a debugger attached and I tell the debugger to step into the block. Here are the steps…

  1. I load the material using an FSoftObjectPath object. This works great and I get my material–the very one I authored in the editor. It’s a 2-sided material with my own shader-logic, etc.

  2. I create an instance of the material as a UMaterialInstanceDynamic object, and then use SetMaterialByName on my actor’s mesh component to apply the material.

  3. I then use GetTextureParameterValue on the material instance to get at its texture that it is sampling from when it renders. I then cast the UTexture to a UTextureRenderTarget2D, and this works great. Life is good.

  4. I create the USceneCaptureComponent2D object, set its render target to the UTextureRenderTarget2D in step 3, setup a bunch of other parameters, tell it to capture every frame, set the capture source to SCS_SceneColorHDR, set it visible, set it non-hidden in game, set the FOV angle to 90 degrees, and finally, I register the component. I also setup the scene capture component’s world location and orientation to something reasonable as a test.

Having done all that(!)…what I find is that the rendering of my actor’s mesh does indeed change where I would expect it to, but the texture being applied is just a checker-board and not texels derived from a scene capture. I’ve tried many variants of the above steps and looked at a lot of examples in the engine. What am I doing wrong?!

The checkerboard texture might be UE4’s “missing” texture or something. What is UE4 trying to tell me?

I’ve verified that the scene capture component is trying to do work in the engine. I’m not sure, however, where to trap the engine to make sure it will actually write something to the texture. The disconnect appears to be that whatever is captured isn’t being written to the texture being used by the material.

Any ideas? Any good examples I should look at?

What I’m doing here isn’t rocket science. A lot of C++ programmers are doing stuff like this all over the place for many different kinds of applications. I just can’t get a super simple case of it to work for me.

As a side note…I used the developer menu to generate C++ code from the BP actor that does everything I’m trying to do, but does it successfully. In that generated code, they’re creating the component in the constructor, but I can’t afford to do that. I need to create the scene capture component later long after the actor has already been created.

I was able to resolve this issue by checking the “Used with Skeletal Mesh” check-box in the details tab for the render target material. I looked at the log output and found a warning indicating why the checkerboard material was being used. My material is now showing what is being captured by the scene capture component.

Yay.