RinCity Train Station Unreal 4 upgrade :)

Impressive work!!!

I’m really curious about the modification on the camera actor…I mean, the actual focus is always done in keyframes or the modification on the class improve some aspects?

Inspiring work! I really love the feel of the camera shots!

The internet is a wonderful thing for that :wink:

Impressive work! I would personally add a little bit wind to your trees :wink:

Beautiful work, only thing I see is that in the last pic you might want to bring in the camera a bit since you can see some areas where there are fewer details(trim, rubble seams, etc.). Every other picture looks excellent!

Technical breakdown of RinCity Train Station.

RinCity Technical breakdown:

A. Unreal 3 to Unreal 4 asset conversion.
B. Physical Based material cheat/shortcut (Master Material).
C. HDR lighting n Lightmass.
D. True focus Camera BluePrint.
E. Output.
F. Summary for the conversion.

A. Unreal 3 to Unreal 4 conversion:
Things that I did for the conversion:

  1. There’s no longer ASE support (which is what I typically use for simple static meshes)

  2. There’s no longer VERTEX Lighting bake support.
    (this took me 5 days every night to complete LM for all the assets).

  3. There’s no spline actor to mesh conversion export from UE3.

  4. There’s no BSP UE3 to UE4 export.

  5. Location and rotation from the original scene.

  6. Vertex re-paint.

  7. Scale in UE4 finally do 1 unit 1 cm.

  8. Having all my MAX source files, makes this a non issue.
    Make profile for FBX generic static mesh export in MAX to speed things up in export.
    (important one to check: Smoothing groups, Tangents and Binormals, and Preserve edge orientation.)

  9. No vertext lighting, means lightmaps (spelling this gave me a headache already lol).
    I decided to use lightmap for my indirect lighting for quality and performance test reasoning. (UE3 scene was using indirect lighting bake too.)
    The technique I use is to break the geometry, do UV unwrap in planar as much as possible, then copy it back to the original mesh as UV2 (or whatever desired).

  1. Spline is used for the UE3 hanging rail. Spline actor export from UE3 only shows the spline point, and doesn’t show anything other than that.
    The way I solve this is to export part of the scene to obj and recreate the spline object as best as I can and export it as a single static mesh for UE4 (and lightmapped it too off course XD).

  1. Was thinking to re-create BSP, but ended up thinking it’ll take too much time. Ended up with pretty much an obj Export from UE3,
    cleaned the triangle, set proper Material IDs and finally lightmapped it XD.

  2. Since I’m trying to do an almost 1:1 setup, I would like to use the original rotation and location of the meshes in UE3 to be in UE4. To achieve this:

  • I copy a single type of static mesh placed in my UE3 scene to a notepad++
  • Extract the Location and rotation coordinates.
  • Convert the rotation from integer to degree (in this case UE3 Rotation/65536*360), depending on how many object I was converting from I might sometimes use excel to to batch number conversion.
  • Then duplicate the same number of that particular static mesh in UE4, paste it in notepad and replace the Absolute Location and Absolute Rotation with the one I’ve prepped from UE3 extraction.
    It’s a lot of manual work unfortunately and I’m not proud of it XD (It took 3 days, wish I can make a conversion application for this lol)
  1. Vertex painting for the object for material blend is A LOT OF INFO to copy.
    It gets to the point that it’ll chug your Notepad scroll. Because of this I decided to just do vertex repaint in the UE4 scene.
    Plus its a lot of fun to do material blend paint using vertex (Vertex Paint addict here :P)

  2. Ok so now all my mesh are half the size than the intended scale, but considering the amount of time it took to bake the lighting, I dediced not to do 2x scaling as I’m not planning to walk around in this demo.
    I did found a way to scale it to proper 2x by using attach to function. (basically select all object, then attached it to a box that has 0,0,0 coordinates, then scale the box to x2 and then voila).

B. Physical Based material cheat/shortcut (Master Material).

Material obviously don’t translate from UE3 and UE4 and to begin with, PBS is the reason to go to Unreal 4 :slight_smile:
In my scene I create a basic master material that I use for 90% of the scene assets.

I would like to save time as much as possible, hence I didn’t do much with the diffuse texture and normal map. I did some metal parameters textures and use as much as specular mask from my old scene as my roughness base as possible.
I use a simple lerp function and 2 constants to control my roughness that’s derived from specular mask.

The rest of 10% materials I create are for:

  1. Skybox and Emissive.
  2. SubSurface for plants.
  3. Paralax shaders and water movement for the underground surface.
  4. Light functions for the clouds.
  5. Car shaders that comes color changing parameters.

C. HDR Lighting and lightmass.
Lightmass took forever to build lighting, to mitigate this, I did a quick simple evnrionment with box (that built less than 30 second) to estimate the light color and value for the scene.
*It took 23 hours on the build where I didn’t know the previous light build busted my cpu radiator coolant, my poor i7 building lightmass under fire lol. In properly cooled machine it’ll roughly render around 5 hours.

As you all have known, HDR if you’re not careful can be a double edge sword.
People get confused on what value they need to put in the light intensity.
If you were to make a scene with proper light bulb and sunlight and time of day cycle, you need to make sure you know what’s your light bulb ratio towards the sun and moon and what type of light you’re using.
I think it’s best to measure light in Exposure value range considering we’re dealing with HDR.

Here’s some technical value that I found out that might help some people figuring out their lighting.

  • In the case of Spotlight/PointLight w/ inverse sq. falloff it’ll be measured in Lumens.
    (if I have to guess that Unreal 4 lumens is based on lux/1m² surface area of a sphere intensity, roughly 0.282m radius).
    Sphere area= 4pir² (
  • If you didn’t activate the inv. Sq fall-off, your intensity value is the origin point of your light and fall-off according to radius and exponent.
  • Based on my test. On Unreal 4.1 The light Intensity internal value for non inv. sq lights is a multiplication of 2.5x
  • For Lights with inv. sq, the intensity at 28.2cm of the lux base is a multiplication of 20x.
  • For people who are interested in setting base exposure checkout table 3 on this wiki link: (see the lx) where 20lux = 3EV [CORRECTION]
  • To test it, point a pure white directional light with 2.5 intensity down to a surface and checkout the HDR logarithmic histogram, it’ll show a value of 1/1 (EV 3) [CORRECTION]
  • With Exposure value, Each time you want your lighting to go to the next EV brightness, you need to double the value of your light. (eg. base light 1, to make the second light 3 EV brighter, you need to put value of 8 [3 power of 2].

Why are the real internal value important?
It’s because you have to know what value to put for anything that will be affected by the Tone mapper (e.g emissive) :stuck_out_tongue:
People who do real world lighting and photography exposure will understand UE4 lighting easier than others. In the end, it’s all about light Ratio.

Since I’m not trying to match proper light bulb value with my sun, I didn’t use the real sun value (which if you were to go with sun typical EV 14-16 = 40,960 - 163,840.
I want my sun and hemisphere ratio to be 1 to 4 EV (3 EVs brighter) so in my case I just use the value of
Directional light 768 and lightmass Environment scale 96 rather than dealing with extreme numbers value.
At the end of the day as long as your light ratio is proper and you set the eye adaptation limit properly, it’ll be the same regardless the EV level you use.
Also don’t forget that FOG will also require to use the HDR value to match :smiley:
Multiply the value of your fog in the color picker (in my case I set mine to be value 32 and 20)
My Skybox emissive multiplier is 35.

D. True focus Camera BluePrint.
The idea is to animate the camera using real world variable input and capture some of the proper camera characteristic.

The closer you focus, the narrower the FOV supposed to be and vice versa.

The input variable I placed in BP are as following:

The one I animate in Matinee:
lens_focallength (mm), aperture (f/stop), Focus Distance(mm), AutoExposureBias(mm)

This blueprint is created based on Camera Actor (which is very prone to crash during compile on 4.02 to 4.1.1 XD)
The stuff I override are these:

Now for the calculation:
For the effective focal length I use thin lens formula to keep things simple.
1/f = 1/s1 + 1/s2
(where f = focal length of the lens, s1 = focus distance, s2 = effective focal length)

Once you got the effective focal length, then to convert it to Horizontal FOV I use this formula:
FOV = 2ATAN(x/(2s2))
(where x = the size of the film horizontal, s2 = effective focal length)
For some reason unreal FOV description said it’s Vertical FOV, but after testing I figure it is a Horizontal FOV, so you can hooked this final value directly to the Field of View of the camera.
(Horizontal size of the film of a full frame 35mm sensor is 36mm)

In case people wondering how to make that ATAN calculation in BP:

So those pretty much handle the effective focal length based on Focus distance and Lens focal length.
Things gets complex when trying to control the DOF and I believe I might get things wrong here (I’m looking for discussion on these for UE4 implementation).
I started by trying to understand the variable I’m overriding from the docs: Depth of Field | Unreal Engine Documentation
Since I’m trying to imitate true focus, then I override these with constant:
DOF Focal Region = 0
DOF Scale = 1

Now then we’re left with the need to figure out:
Near transition region, Far transition region, and Max Bokeh size

To figure Near focus and Far Focus limit you need to figure out hyperfocal of the camera configuration:
HyperFocal = (f^2/N*c) + f
(where f = focal length, N is Aperture, c is Virtual Circle of Confusion)


Once Hyperfocal result is achieved, now here’s the calculation of the Near focus distance and far focus distance:
Dn= s1*(H-f)/(H+ s1 - 2f)
(where Dn = Distance Near focus, s1 = focus distance, H = hyperfocal, f = focal length of lens)
Df= s1
(where Df = Distance Far focus, s1 = focus distance, H = hyperfocal, f = focal length of lens)

Once you figure that out you just substract the focus point with Dn for Near focus range
and focus point with the Df for Far Focus range and feed it to unreal DOF parameters.

Finally we got the Maximum Bokeh size: (need input for people who understood this in Unreal4)
This confused me as I think there should be FAR max bokeh size and NEAR max bokeh size.
In this case I just do a calculation for Infinity Bokeh size.
This will be OK for most cases where your subject is in focus on the foreground without any foreground out of focus element (this makes the near blur wrong after certain focus distance because Near blur becomes larger than far blur, hence why I hacked in a force near bokeh size to 2.0 for certain scene)

In any case,
To calculate infinity bokeh size, you need to figure out magnification ratio
(check the FOV calculation 2 pic above, there’s small stub in the picture that shows the Magnification ratio)
magnification ratio = s2 / s1
(where s2 = final focal length , s1= focus distance,

Once I got the magnification ratio:
I use this formula to calculate Far end largest bokeh
Cfar = f*M/N
(where Cfar = Bokeh size at infinity, f = focal length, M = Magnification ratio, N = Aperture

(check the result is multiplied by 100, because Unreal wants the max bokeh size in Percent)

And that’s it for the calculation. Congratulation for reading up to down here.
Now here comes the problem of the entire setup XD

  1. The BP camera actor “constructscript” DOF effect can only be previewed when you preview the camera actor from Matinee actor.
  2. Well construct script don’t run in runtime lOl so you need to duplicate all those stuff into event graph and make it run.
    Unfortunately you can’t TICK Blueprint based on camera Actor.
    Making this entire thing from Actor based BP and add camera to the component doesn’t allow you to adjust post process, a.k.a useless camera BP.
    I solve this by doing a custom event that I called from Level blueprint. In level blueprint I run a ticker that called that camera custom event.
  3. The BP camera actor keyed variable does NOT reflect in the viewport during playback/scrubbing in Matinee. To preview the whole scene, you need to close matinee, run simulate, then open matinee and playback (it’ll play for 2x speed for some reason) to see the result of all your key.

For the above reason, making the scene focus animate the way I want it becomes very tedious, I hope the community or Epic developer team can help me out on this :slight_smile:

That’s it for the True Focus Camera blueprint (took me quite a while to complete the BP because of the shenanigans or probably lack of knowledge on my end lOl)

Some final tips for the Camera: make sure to cap Maximum Bokeh size to not be larger than 20 or else it’ll kill your GPU :stuck_out_tongue: (like CRASH your GPU kind of kills)
These settings for real size bokeh is typically only used for Cinematic and not in game as it can be very heavy in perf.
I didn’t post my original BP because it’s kind of hairy and it has some extra info for personal test so I post only the important nuggets in this breakdown, but should allow people to re-create the camera if needed.

E. Output.
This is straight forward After Effects editing from all the BMP frame outputted in matinee. (for some reason JPG output didn’t work for me)
But incase anybody wondering it’s outputted to:
MainConcept H.264 1080P 30FPS @CBR 20Mbps Profile: High, Level 5.1
Then Vimeo and Youtube does additional encoding on top of it after the upload XD

F. Summary for the conversion.
At the end of the day this small project turns out to be quite a task to complete.
It’s not as simple as I’ve planned to begin with but the end result didn’t disappoint me and I get more familiar with UE4 :slight_smile:
Unreal 4 Physical based shaders, HDR lighting, Tone Mapper curve, Temporal AA and blueprint blows me away.
It made my 3 weeks effort worth the while :smiley: UE4TW
The only thing I wish UE4 had in the future is either GPU Based Lighting baked (like Octane render) or realtime precalculate radiosity that’s stable and light in performance like Enlighten.

I’ll post some screen comparison between UDK and UE4 version at some point in the future.
Please don’t hesitate to ask question, flame me if I made stupid mistake for any of the camera calculation above and/or help me out in figuring out the proper way to do DOF control in UE4 :slight_smile:
Thanks for looking at my video post and reading the breakdown.

A work of beauty, well done! :slight_smile:

Thanks for this very informative technical breakdown :slight_smile:

Yeah I’ve been doing my best by following tutorials… but it’s difficult when you get stuck, maybe I just need a clearer view of what I want to make.

Lovely work. The end result is really great :smiley:

Awesome job (even if I don’t remember seeing the UDK version) !

Glad you guys liked the videos, hope you guys find the breakdown useful :slight_smile:

Looks fantastic, well done!

Beautiful scene, great work! =)

This is fantastic work.

But that’s not nearly all I want to say.


The technical breakdown of what you’ve done is amazingly detailed and generous of you and your time, knowledge, effort and wisdom.

I owe you!

Hey appreciate the acknowledgement and glad if my breakdown can help people.
The idea is for people to get inspired and make cool stuff that in return inspired me to make better things and jump start this virtuous circle :slight_smile:

Great work. Can we have a download link?

Stunning work and a ton of thanks for the technical breakdown! Very good read :slight_smile:

Thanks for the interest.
Currently it’s just an empty scene with nothing interactive so I’m not sure releasing the realtime version of this scene is a good idea.
I might change my mind in the future when I got time, but I’m currently busy working on another Unreal 4 mini project :slight_smile:

@Daerst Glad that you found the breakdown useful.

Great work, The breakdown was kind but the images are too small to realy help. Anychance you could just strip out the main scene assets and just provide a basic empty scene with your sun lighting/HDR and world light settings etc all left at what they were for the scene, also the camera within the scene would be helpfull and all blueprints including the focal tricks. Basicly just empty scene with sun setup/camera/post pro etc. That would be super handy. Cheers KB

@KingBadger3D Thanks for the compliment.
The light ratio is only proper for my particular setup only, you can still use it if you want.
I specify this in the breakdown:
Directional light 768 and lightmass Environment scale 96 …
Also don’t forget that FOG will also require to use the HDR value to match
Multiply the value of your fog in the color picker (in my case I set mine to be value 32 and 20)
My Skybox emissive multiplier is 35.

If you were to follow that number by the text and have light bulb on your scene, you’ll be setting it’s lumens down to value of single digits. Hence why I wrote the extensive information about unreal HDR Lighting system numbering in the breakdown to suite people needs in their lighting.

As for the camera breakdown, the image I post is 100% image size, I didn’t resize it.
My original camera BP it’s a lot more confusing as I put many test instructions, not to mentioned the final result is imperfect hence why I didn’t release it. I hope people re-create it in order to understand it then improve upon it.

Tbh, the system is effective when the user understood how it works fundamentally.
There’s a classic saying Give a man a fish; you have fed him for today.
Teach a man to fish; and you have fed him for a lifetime, hence the extensive breakdown :wink:

I sincerely apologize if the breakdown is confusing and not helping :slight_smile: