I won’t make this tutorial in one go. I will keep updating this post.
I will start by briefly describing the overall procedure.
The goal is to
- Render a scene somewhere off-screen to a texture.
- Cut out the portion of the scene I am interested in based on the objects distance from the camera.
- Feed the rendered image and the depths mask into a material where the flickering/screen effect is created.
- Create an UMG widget with a Border widget that uses the material as its brush.
- Do some line tracing to translate the screen position back to the scene that is still some place off-screen.
The first two points of this tutorial will be very closely based on the wonderful tutorial by RATSGAME.
The third part is actually based on the official post processing documentation example.
Starting point is the Flying blueprint template. There is no need to write anything in C++.
Step 1: Create a new Actor Blueprint. I named mine ‘SceneCaptureActor’.
Add a static mesh component and make it the root component. The static mesh component should be whatever mesh you want to create the hologram of. I use the UFO from the template here.
Add a scene capture component 2D. And place it in a way that the model component is somewhere in front of it.
Next we need to create a render target. Basically a texture-like object that stores whatever the scene capture component is ‘seeing’. Just right click in the content browser and create on ‘Materials&Textures’->‘RenderTarget’. I named mine ‘SceneCaptureTarget’.
We also need a new Material which creates the depths mask. I named mine ‘DepthMaskMaterial’. I will explain how to setup this material later. For now it only needs to exist in order to complete the setup of the ‘SceneCaptureActor’.
Now we need to get back to the ‘SceneCaptureActor’ to finish setting up the scene capture component.
First select the created render target in the Details panel and change the Capture source to ‘Final Color (LDR) in RGB’:
Next we have to tell the component to feed the captured scene to the post process material before storing it in the render target. Somewhere way down in the Details panel in the ‘Post Process Volume’ section is the point ‘Blendables’. Just search for ‘Blendables’ in the search bar to find it quickly.
Under ‘Blendables’ add an element to the array by clicking the + icon. Select ‘Asset Reference’ in the newly appeared drop down menu.
Then chose the ‘DepthMaskMaterial’ as the asset reference.
Now we are done with the Actor’s setup.
Setting up the depths mask:
Open the DepthMaskMaterial. Right-click somewhere and add the SceneTexture node.
We are insterested in the depth of the scene, not the color. Select the Node and select Scene Depth in the node details panel’s dropdown menu.
Now the color output pin will output the distance of each pixel from the camera from 0 (close) to some big number. If you would display the output without modifying it, it would most likely be a purely white image. Not very useful.
Next we need to scale the depth to some reasonable value. This can be done by dividing the output by a value that is approximately the distance of the model object from the scene capture component.
Now the image would look something like this:
Its almost a mask now but it could use a little more contrast. Since the part we are interested in has some value between 1 and 0, we can simply multiply the whole image with itself for a few times like this:
Resulting in an image like this:
Almost done with the mask. Just add the OneMinus node to get a simple multipliable mask:
As a last step we need to combine the actual image with the mask like this:
The red node is again the SceneTexture node but this time the ‘PostProcessInput0’ is selected in the details panel. This input contains the actual color information.
The nodes after that convert the color image into a gray scale image. Maybe there is a better way to do this but this works. I then combine the gray scale image with the mask by using them as different channels in the RGB output.
It is unfortunate that I have to throw away the color information (luckily I don’t need it here) but I found no other way to have access to the mask in its own channel and the image itself in the other channels. If someone knows if I can output an alpha channel in a post process material, please let me know.
The image would now look like this:
Very pretty…
Now to the material setup:
This is obviously pretty messy and impossible to see clearly. I will therefore split it up into 4 parts.
TopLeft:
BottomLeft:
BottomRight:
Right:
I tried to make appropriate comments to make it easier to understand what is happening in each part. Most of this setup is very close on the official post processing tutorial and the noise and distortion textures are also copied from there.
This is the texture I added for the projector beam. Feel free to use it for whatever you like.
Now, all that is left to do is to create a UMG Widget Blueprint and add a Border Widget. I used Border instead of Image to easily get access to the ‘OnMouseMovement’… etc events.
Add the HUD to the viewport in the PlayerController’s BeginPlay event and enjoy the hologram effect.
If you want to rotate the hologram, the SceneCaptureActor need to modified a little bit:
And that’s it. I hope you find this useful.
If you are interested in knowing how I implemented deprojection from HUD space to Hologram space, please let me know.
#######Here starts the original post#########
While I was playing around following a few tutorials, I put together a small asset. Its nothing too fancy and basically just recycling and mixing together of already available tutorials.
Nevertheless, I learned a lot doing this and it has the appropriate complexity for writing a short tutorial about it so I decided to share it.
But before I start I would like to check if there is any interest.
You could use this method to create a nice futuristic HUD, put it on an ingame computer screen, project it somewhere in your game world.
I made this as an interactive space ship equipment widget which allows you to drag and drop equipment onto sockets of the ship’s mesh.
Please let me know if you are interested in a tutorial.