banner



Unity How To Create A Skybox

View from a skyscraper. As long as the background is static and sufficiently far away, it is a good candidate for a skybox.

This tutorial covers the rendering of environment maps as backgrounds with the help of cube maps.

It is based on Section "Reflecting Surfaces". If you haven't read that tutorial, this would be a very good time to read it.

Rendering a Skybox in the Background [edit | edit source]

As explained in Section "Reflecting Surfaces", a skybox can be thought of as an infinitely large, textured box that surrounds a scene. Sometimes, skyboxes (or skydomes) are implemented by sufficiently large textured models, which approximate an infinitely large box (or dome). However, Section "Reflecting Surfaces" introduced the concept of a cube map, which actually represents an infinitely large box; thus, we don't need the approximation of a box or a dome of limited size. Instead, we can render any screen-filling model (it doesn't matter whether it is a box, a dome, or an apple tree as long as it covers the whole background), compute the view vector from the camera to the rasterized surface point in the vertex shader (as we did in Section "Reflecting Surfaces") and then perform a lookup in the cube map with this view vector (instead of the reflected view vector in Section "Reflecting Surfaces") in the fragment shader:

                                                float4                                    frag            (            vertexOutput                                    input            )                                    :                                    COLOR                                                {                                                return                                    texCUBE            (            _Cube            ,                                    input            .            viewDir            );                                                }                      

For best performance we should, of course, render a model with only a few vertices and each pixel should be rasterized only once. Thus, rendering the inside of a cube that surrounds the camera (or the whole scene) is fine.

Complete Shader Code [edit | edit source]

The shader should be attached to a material, which should be attached to a cube that surrounds the camera. In the shader code, we deactivate writing to the depth buffer with ZWrite Off such that no objects are occluded by the skybox. (See the description of the depth test in Section "Per-Fragment Operations".) Front-face culling is activated with Cull Front such that only the "inside" of the cube is rasterized. (See Section "Cutaways".) The line Tags { "Queue" = "Background" } instructs Unity to render this pass before other objects are rendered.

                        Shader                                    "Cg shader for skybox"                                    {                                                Properties                                    {                                                _Cube                                    (            "Environment Map"            ,                                    Cube            )                                    =                                    ""                                    {}                                                }                                                SubShader                                    {                                                Tags                                    {                                    "Queue"                                    =                                    "Background"                                    }                                                                        Pass                                    {                                                            ZWrite                                    Off                                                Cull                                    Front                                                CGPROGRAM                                                                        #pragma vertex vert                                                #pragma fragment frag                                                                        #include                                    "UnityCG.cginc"                                                // User-specified uniforms                                    uniform                                    samplerCUBE                                    _Cube            ;                                                                                    struct            vertexInput                                    {                                                float4                                    vertex            :                                    POSITION            ;                                                };                                                struct            vertexOutput                                    {                                                float4                                    pos            :                                    SV_POSITION            ;                                                float3                                    viewDir            :                                    TEXCOORD1            ;                                                };                                                                        vertexOutput                                    vert            (            vertexInput                                    input            )                                                            {                                                vertexOutput                                    output            ;                                                                        float4x4                                    modelMatrix                                    =                                    unity_ObjectToWorld            ;                                                output            .            viewDir                                    =                                    mul            (            modelMatrix            ,                                    input            .            vertex            ).            xyz                                                            -                                    _WorldSpaceCameraPos            ;                                                output            .            pos                                    =                                    UnityObjectToClipPos            (            input            .            vertex            );                                                return                                    output            ;                                                }                                                                        float4                                    frag            (            vertexOutput                                    input            )                                    :                                    COLOR                                                {                                                return                                    texCUBE            (            _Cube            ,                                    input            .            viewDir            );                                                }                                                                        ENDCG                                                }                                                }                        }                      

Shader Code for Unity's Skybox System [edit | edit source]

The shader above illustrates how to render a skybox by rendering a cube around the camera with a specific shader. This is a very general approach. Unity, however, has its own skybox system that doesn't require any game object: you just specify the material with the skybox shader in the main menu Window > Rendering > Lighting Settings > Scene > Skybox Material and Unity takes care of the rest. Unfortunately, we cannot use our shader for this system since we have to do the lookup in the cube texture at the position that is specified by the vertex texture coordinates. This is actually easier than computing the view direction. Here is the code:

                        Shader                                    "Cg shader for Unity-specific skybox"                                    {                                                Properties                                    {                                                _Cube                                    (            "Environment Map"            ,                                    Cube            )                                    =                                    "white"                                    {}                                                }                                                SubShader                                    {                                                Tags                                    {                                    "Queue"            =            "Background"                                    }                                                Pass                                    {                                                ZWrite                                    Off                                                            Cull                                    Off                                                CGPROGRAM                                                #pragma vertex vert                                    #pragma fragment frag                                    // User-specified uniforms                                    samplerCUBE                                    _Cube            ;                                                struct            vertexInput                                    {                                                float4                                    vertex            :                                    POSITION            ;                                                float3                                    texcoord            :                                    TEXCOORD0            ;                                                };                                                struct            vertexOutput                                    {                                                float4                                    vertex            :                                    SV_POSITION            ;                                                float3                                    texcoord            :                                    TEXCOORD0            ;                                                };                                                vertexOutput                                    vert            (            vertexInput                                    input            )                                                {                                                vertexOutput                                    output            ;                                                output            .            vertex                                    =                                    UnityObjectToClipPos            (            input            .            vertex            );                                                output            .            texcoord                                    =                                    input            .            texcoord            ;                                                return                                    output            ;                                                }                                                fixed4                                    frag                                    (            vertexOutput                                    input            )                                    :                                    COLOR                                                {                                                return                                    texCUBE                                    (            _Cube            ,                                    input            .            texcoord            );                                                }                                                ENDCG                                                            }                                                }                                    }                      

As mentioned above, you should create a material with this shader and drag the material to Window > Rendering > Lighting Settings > Scene > Skybox Material. There is no need to attach the material to any game object.

Summary [edit | edit source]

Congratulations, you have reached the end of another tutorial! We have seen:

  • How to render skyboxes in general.
  • How to render skyboxes in Unity without a game object.

Further reading [edit | edit source]

If you still want to know more

  • about cube maps and reflections of skyboxes in objects, you should read Section "Reflecting Surfaces".
  • about lighting that is consistent with a skybox, you should read Section "Many Light Sources".

< Cg Programming/Unity

Unless stated otherwise, all example source code on this page is granted to the public domain.

Unity How To Create A Skybox

Source: https://en.wikibooks.org/wiki/Cg_Programming/Unity/Skyboxes

Posted by: kingparrived.blogspot.com

0 Response to "Unity How To Create A Skybox"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel