5
$\begingroup$

I wish to create skybox textures for use in Unity3D, by baking environment materials to the textures. How would I go about setting something like this up?

EDIT: I have tried simply putting a camera in the center of the scene and rotating it at 90 degree angles, and rendering to a square texture. However, the texture edges are not aligned, so I think I can assume that the field of view is wrong.

$\endgroup$
7
$\begingroup$

I managed to figure this out on my own, based on what I had noted above.

Prior to beginning, you must have set up an Environment material to render, or have set up a surrounding scene to capture. Once that is done, you set resolution of the render to a square texture, preferably with a power-of-two size (I set it to 1024).

Once the environment or scene is set up and ready to capture, the first step is to open the camera object's properties, and just below the Perspective/Orthographic/Panoramic selectors, you change the Lens Units from Millimeters to Field of View, and then set the field on the left to 90 degrees.

enter image description here

After that, set the camera's position to the center of the grid (0,0,0 coords), and set its rotation so that it is facing straight forward (rotation 90,0,0). Then render, and save it as the Front texture.

Then rotate 90 degrees counterclockwise, and render as the "Right" texture (even though the camera is facing left). Rotate 90 degrees counterclockwise again, and render that as the "Back" texture. Rotate 90 degrees counterclockwise again, and render that as the "Left" texture.

Rotate 90 degrees counterclockwise again, and then you're back at the starting position. Rotate the camera 90 degrees to point upwards (exact rotation should be 180,0,0), and render that as the "Up" texture. Then rotate the camera 180 degrees to point downwards (exact rotation is 0,0,0) and render that as the "Down" texture.

After that, fire up the Unity3D editor. Import each of the textures (which should be named according to direction). Bring up each texture in the inspector, and make sure that Texture Type is set to Texture, and that Wrap Mode is set to Clamp. Then, create a new Material asset, and in the inspector, set the Shader to "Skybox/6 Sided". Then assign each of the textures to the corresponding slots, and you're done.

enter image description here

$\endgroup$
2
$\begingroup$

After visiting this page I made a small python script that creates the camera and renders all 6 images. You can download the script here:

https://github.com/oleg3630/blendertools/blob/main/render_skybox.py

You can set destination folder and image size right in the script.

import bpy
import math
import mathutils
import os


scene = bpy.context.scene

cam_data = bpy.data.cameras.new('SkyBoxCamera')
cam = bpy.data.objects.new('SkyBoxCamera', cam_data)
bpy.context.collection.objects.link(cam)
scene.camera = cam

bpy.context.scene.render.resolution_x = imageSize
bpy.context.scene.render.resolution_y = imageSize
cam.data.lens_unit = 'FOV'
cam.data.angle = 1.5708

#cam.rotation_clear(clear_delta=False)0
scene.render.image_settings.file_format = 'PNG'

cam.rotation_euler = mathutils.Euler((0, 0, 0))
scene.render.filepath = os.path.join(savePath, "SkyBox_Down.png")
bpy.ops.render.render(write_still = 1)

cam.rotation_euler = mathutils.Euler((math.pi/2, 0, 0))
scene.render.filepath = os.path.join(savePath, "SkyBox_Front.png")
bpy.ops.render.render(write_still = 1)

cam.rotation_euler = mathutils.Euler((math.pi, 0, 0))
scene.render.filepath = os.path.join(savePath, "SkyBox_Up.png")
bpy.ops.render.render(write_still = 1)

cam.rotation_euler = mathutils.Euler((math.pi*3/2, math.pi, 0))
scene.render.filepath = os.path.join(savePath, "SkyBox_Back.png")
bpy.ops.render.render(write_still = 1)

cam.rotation_euler = mathutils.Euler((-math.pi/2, math.pi,-math.pi/2))
scene.render.filepath = os.path.join(savePath, "SkyBox_Right.png")
bpy.ops.render.render(write_still = 1)

cam.rotation_euler = mathutils.Euler((math.pi/2,0,-math.pi/2))
scene.render.filepath = os.path.join(savePath, "SkyBox_Left.png")
bpy.ops.render.render(write_still = 1)

objs = bpy.data.objects
objs.remove(cam, do_unlink=True)
$\endgroup$
  • $\begingroup$ Thanks - it worked! But on my Mac I had to launch blender through "Blender.app/Content/MacOS/Blender" first. BTW, for those who might not know how to activate the script: Click on the Scripting tab, click on the folder button on the toolbar on top, select the script file, edit savePath and imageSize, click the Run Script button (Triangle) and wait (took me over 10 minutes on my slow computer). $\endgroup$ – yyy Dec 24 '20 at 20:05
1
$\begingroup$

I'd like to add a few things to the technique detailed by Zauber Paracelsus:

I set up my scene to have 6 frames. Each frame animated the camera to capture a different face of the sky cube. This is what my fcurves looked like, but I'm not 100% certain that I got the up and down cameras perfect (please correct me in the comments if so).

fcurves of animated camera

The result is that I can rerender the skybox simply by rendering the animation.

Actually configuring the skybox for a Unity scene is done in the dialog box accessible through the Window/Lighting menu option.

As of 2016-June it seems like the most detailed skybox supported by unity is 1024x1024 per face. If you need resolution better than that, you might have to instantiate those objects in the Unity scene and leave them out of the skybox.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.