How to implement a standard cubemapped skybox?

I’m trying to replace the default sky with a space texture that I have in the form of 6 separate texture .png files (top, bottom, left, right, front, back). I feel like I’m close but that maybe there’s something obvious I’m missing.

I created a cubemapped .dds following the guide in the docs (https://docs.unrealengine.com/latest/INT/Engine/Content/Types/Textures/Cubemaps/index.html). Once I have the cubemap, though, I’m not sure what to do with it in order to replace the sky. The docs only seem to cover using the cubemap for ambient lighting, but I’d like to actually see the entire thing. The doc mentions “Two popular uses are via ambient cubemaps and cubemaps within materials” but then they only go into details for the ambient cubemaps.

Directly creating a material from the cubemap doesn’t seem to work correctly (I can’t actually see the texture on the material, it doesn’t seem to realize that this is a cubemap?), or else I’d just make a material from the texture and apply it to a really large sphere. I’ve tried looking at the default skybox for guidance but it appears to me that the default skybox isn’t actually using any cubemaps, or possibly is too complex for me to see where they are being used.

Can anyone offer some guidance? I feel like this should be much more simple than it’s turning out to be.

Hi, we don’t use the 6 faces style cubemaps any longer. Now they have to be long-lat like HDR maps. The camera vector input automatically works with these formats without you needing to do anything.

I also found a free photoshop plugin that converts between cube based cubemaps and longlat maps. It is called flexify2, check it out. I have used it many times to make an image from 6 static screenshots of a level.

you can download flexify2 [COLOR="#B22222"]here[/COLOR] and some other great Photoshop plugins :slight_smile:

This still works in U4: https://www.youtube.com/watch?v=uWYpyNkF26o
That setup is for reflection, but has many common things with what you want. It shows how to use cubemaps in materials.

Now creating skybox may be fun. First you need static mesh that displays your skybox (make material unlit). Mesh can be box, or sphere.
You can also make your material use mesh UVs or create some uv math nodes inside materials so it uses world coordinates.

Then there is also “ancient” way of skyboxes that was done in ut2004, you make “tiny” box put your actors and effects there, then you create cubemap capture camera there and project on your actual huge sky.
It eliminates movement from player pawn, and adds that feeling of huge sky. Rest is just like making sky on big mesh (see above).

But it think best would be if you disassembled current blueprint for sky and modified it to your liking.

ps. did not noticed those screen capture renders are no more cubemaps.

Thanks so much I’ll give this a try! I wonder if you could elaborate a bit on what I should be doing with the HDR map once I’ve made it? Should it be easy to then turn it into a texture and just apply that texture to… I’m assuming to the sky sphere static mesh?

And thanks for the suggestions everyone else, I’ll give everything a try and report back.

Alright I’m almost there! I’ve made the latlong equirectangular map from a horizontal cross cubemap, made a material out of it and applied that material to the sky sphere mesh. The only problem I have left is that the texture seems to be mirrored on the top and bottom of the inside of the sphere instead of wrapping the one texture all the way around:

Capture.jpg

Thumbnail of texture: Capture2.jpg

I’ve tried applying a TextureCoordinate node to the UV input of the texture but giving it .5 for V, which seems like it should fix the problem, just stretches the texture but leaves it mirrored. “Un-mirroring” either axis just throws everything out of whack. Can anyone help get me the last of the way there?

Alright I’ve got something close enough to work, though there’s a bit of aberration at the top and bottom of the sphere where the texture comes together, but not very noticeable unless you’re looking for it. To anyone who stumbles across this thread here’s what I got to work:

  1. Download the flexify2 plugin for Photoshop from the link posted by LexLuthor1.

  2. Arrange the 6 faces of the cube into the “horizontal cross” arrangement as per the flexify manual.

  3. Apply flexify to that image with the input as “horizontal cross” and the output as “equirectangular” (this is the latlong/HDR format referred to by Ryan B) and save as a png.

  4. Import this png into Unreal as a texture.

  5. Get Blender if you don’t have it.

  6. In blender make a primitive sphere, then invert the normals and export as .fbx

  7. Import the fbx into Unreal as a static mesh.

  8. Make a material out of the equirectangular texture and reroute the output from the texture node into the “emissive” input instead of the “base color” input. Set the lighting on this material to “unlit”.

  9. Drag the inverted sphere into the scene, scale it until it’s enormous, and apply the texture.

Should be good enough to work with. Also it’ll give you an error about UV wrapping when you build lighting . Still works for me so at the moment I’m just ignoring the error.

That UV mapping error is coming from one of the static meshes in your scene and has nothing to do with how the cubemap is set up. It just means one of the meshes has the light map UVs overlapping. Or it could be any mesh that has the wrong light map coordinate indx etc…

As far as mapping, I am pretty sure you need to set the UVs to CameraVector and make sure you import the texture as an HDR image. It should only with with a vector3 input in the UVs. It should be a texture cube not a regular texture sample.

Ryan, can you walk through this in a bit more detail? Your last paragraph isn’t making sense to me. The only ‘texture cube’ node I could find is TextureSampleParameterCube. I couldn’t hook the output (ParamCube) to Emissive Color.

I’m in a similar situation to GitRHero. I have an equirectangular panoramic I rendered in Blender of the inside of an icosphere. Can be viewed below:
http://i.imgur.com/0GpwHMS.png

What is the intended way to get this texture into my skybox? Can you show us what the material graph would look like? Does it matter what kind of mesh we use? I had been using SM_SkySphere but it had the UV strangeness that GitRHero described above.

Sorry the exact name in the material editor is “TextureSampleParameterCube”

sky.jpg

Just CameraVector into Cubemap into Emissive. The compression type for cubemaps is TC_HDR.

The mesh just needs to be an inverted sphere that encapsulates the whole possible view space. The UV’s should not matter since we are projecting the camera vector for each pixel.

There is also already a mesh you guys can use in the engine content folders.

  1. Open the content browser.
  2. In the lower right “View Options” select “Show Engine Content”
  3. Find the folder “EditorMeshes”
  4. There should be a mesh called EditorSkySphere that will work for skies.

Thanks for the help ! My problem is that I was importing the texture as a .png which comes in as a Texture2D, while TextureSampleParameterCube wants a TextureCube. I was able to export as a .hdr file through Blender and it imported and displays (somewhat) correctly.

I’m having a different problem now. I can’t figure out why the texture seems to import with a max in-game size of 512x512. The source is 2048x1024 which Unreal Engine seems to identify.
Screenshot: http://i.imgur.com/vTBAJrW.png

The HDR image in question: equi.hdr

I don’t understand why I’m being limited to 512x512. It definitely makes the image and resulting skybox fuzzy. I’ll do some source diving tomorrow to see if it is some oddity in the Radiance HDR import code. Have you run into anything like this before?

To clarify, my goal here is to have a high resolution skybox (current image is 2048x1024). I’m doing so by exporting an equirectangular Radiance HDR image from Blender. The texture seems to import fine but is capped at 512x512. It’s worth noting that the engine assets at \Engine\MapTemplates\Sky including SunsetAmbientCubemap, Desert_Outer_HDR, and DaylightAmbientCubemap all exhibit this behavior of having greater than 512x512 dimensions but being capped.

Hmmm must be something about the compression settings or something. My wife is reading manga on my computer at the moment. In a few hours I will take a look at your HDR file. There’s also a way to save them out of photoshop ill try and figure that out too. Thanks for including the file that will make it easier.

This is caused due to some ini settings that limit the size of hdr Files to 512. I found this out just today. There is some code you need to change which I can post as soon as I am at home :wink:

Daedalus is right. This is because code now assumes a cubemap is going to be used for AmbientCubemap lighting, not as an actual skybox.

If you find a workaround for the .hdr format I am very curious to know what it is also. The coder I spoke to said the engine is clamping these to 512 during the import process. Either way, this is a code issue and I have entered a ticket into our bug tracking database.

You can also import a cubemap through DDS format by laying out the 6-cubemap faces in a straight line. So the aspect ratio would be 6x1. I am not certain of the layout the dds exporter expects. I was able to get a 6144x1024 cubemap imported that way and it seemed a bit sharper. I also tried a 12288x2048 but gave up after waiting 15 minutes for it to import.

Sorry this is probably not the ideal solution. Hopefully we find another workaround soon and get this fixed properly.

Okay…so I am at home now and I will try to describe it best as I can :smiley:

So first of all…it needs to be done in a *.cpp file, and since a friend at work just showed me some things, I dont completely know, but still think those can only be accessed via source code DL (because searching the install folders didnt give me anything).
That means I can not tell you where the file can be found right now, since I am trying to figure that out by myself^^

However…this is what you need to do:

-find “texturecompressionmodule.ccp”

  • search for:

static int32 ComputeLongLatCubemapExtents(const FImage SrcImage)

return FMath::Clamp(1 << FMath::FloorLog2(SrcImage SizeX / 2), 32, 512);

-change the 512 to 1024 or 2048. I wouldnt recommend going any higher because it is used then for all HDRs which you would most likely also use for the reflection environment and that gets pretty **** expensive with huge sizes :wink:

Cheers

Thanks for the info. Will give your changes a shot when I get home Daedalus!

I’m more curious why this hasn’t come up before. How is everyone else doing skyboxes? Surely I am not the first to try the suggested method of “cubemap as skybox.”

I totally understand why these are capped to 512x512 if you assume they are only used for reflections and lighting.

I mean…you could just convert them to a TGA with photoshop to map them on the skydome :wink: So actually there is no need to push it that much. However…I am trying some car rendering stuff at home atm and I really need high quality. So I will push it to 2048 and also increase the quality of SSRs to get the max out (you can also touch the lightmass code if you really need to go for ultra precision for example but then building takes extremely long^^)

Hi sinoth,

“I’m more curious why this hasn’t come up before. How is everyone else doing skyboxes?”

I would say it is because we started making all of our sky domes procedurally. Look at the StarterContent project for an example of a procedural sky material. It uses things like the light vector to create a sun, and uses things like the sky sphere UVs to control the horizon and zenith etc. Clouds are seprate layers. Generally you have more control with a procedural sky, although it is easier to get photo realism with a static captured real image. We only really use the .HDR files for ambient cubemaps these days.

That said, it is still a bug, one that hopefully gets fixed soon.

Thanks again Daedalus, your change did the trick! I did quite a bit of experimenting last night and have a few observations.

Even though I was able to extend the maximum size of cubemaps, they are currently restricted to being square. I made some changes to allow non-square cubemaps but kept having problems… I imagine other parts of the code are assuming square dimensions. Ideally a cubemap used as skybox would have an aspect ratio of 2:1.

I was unable to get anything higher than 2048x2048 to import. The editor silently crashes after a long time.

Makes sense, though in this situation I am porting a game that uses a skybox that would be difficult to generate procedurally. The game uses six 1024x1024 images to form the skybox, giving it effectively 4096 horizontal resolution. The ideal cubemap resolution would be 4096x2048 which isn’t possible at the moment. Due to these limitations, for now I think I will just hack up a traditional six-sided skybox.