Render 3D Scene with Panorama Mode in Depth

Render 3D Scene with Panorama Mode in Depth

In this article, we create a Camera and two Light objects to capture the scene, the ShaderSet class helps to create depth shader.

Programming Sample

This code example renders 3D scene with Panorama mode in depth.


 public static void Run()


    // The path to the documents directory.

    string dataDir = RunExamples.GetDataDir();

    //load the scene

    Scene scene = new Scene(dataDir + "skybox.obj");

    //create a camera for capturing the cube map

    Camera cam = new Camera(ProjectionType.Perspective);

    cam.NearPlane = 0.1;

    cam.FarPlane = 200;

    scene.RootNode.CreateChildNode(cam).Transform.Translation = new Vector3(5, 6, 0);

    cam.RotationMode = RotationMode.FixedDirection;

    //create two lights to illuminate the scene

    scene.RootNode.CreateChildNode(new Light() { LightType = LightType.Point }).Transform.Translation = new Vector3(-10, 7, -10);

    scene.RootNode.CreateChildNode(new Light()


        LightType = LightType.Point,

        ConstantAttenuation = 0.1,

        Color = new Vector3(Color.CadetBlue)

    }).Transform.Translation = new Vector3(49, 0, 49);

    //create a render target

    using (var renderer = Renderer.CreateRenderer())


        //Create a cube map render target with depth texture, depth is required when rendering a scene.

        IRenderTexture rt = renderer.RenderFactory.CreateCubeRenderTexture(new RenderParameters(false), 512, 512);

        //create a 2D texture render target with no depth texture used for image processing

        IRenderTexture final = renderer.RenderFactory.CreateRenderTexture(new RenderParameters(false, 32, 0, 0), 1024 * 3, 1024);

        //a viewport is required on the render target

        rt.CreateViewport(cam, RelativeRectangle.FromScale(0, 0, 1, 1));

        renderer.ShaderSet = CreateDepthShader(renderer);


        //execute the equirectangular projection post-processing with the previous rendered cube map as input

        PostProcessing equirectangular = renderer.GetPostProcessing("equirectangular");

        equirectangular.Input = rt.Targets[0];

        renderer.Execute(equirectangular, final);

        //save the texture into disk

        ((ITexture2D)final.Targets[0]).Save(dataDir + "RenderSceneWithPanoramaInDepth_Out.png", ImageFormat.Png);



private static ShaderSet CreateDepthShader(Renderer renderer)


    GLSLSource src = new GLSLSource();

    src.VertexShader = @"#version 330 core

    layout (location = 0) in vec3 position;

    uniform mat4 matWorldViewProj;

    out float depth;

    void main()


        gl_Position = matWorldViewProj * vec4(position, 1.0f);

        float zfar = 200.0;

        float znear = 0.5;

        //visualize the depth by linearize it so we don't get a blank screen

        depth = (2.0 * znear) / (zfar + znear - gl_Position.z /gl_Position.w  * (zfar - znear));


    src.FragmentShader = @"#version 330 core

    in float depth;

    out vec4 color;

    void main()


        color = vec4(depth, depth, depth, 1);


    //we only need the position to render the depth map

    VertexDeclaration fd = new VertexDeclaration();

    fd.AddField(VertexFieldDataType.FVector3, VertexFieldSemantic.Position);

    //compile shader from GLSL source code and specify the vertex input format

    var shader = renderer.RenderFactory.CreateShaderProgram(src, fd);

    //connect GLSL uniform to renderer's internal variable

    shader.Variables = new ShaderVariable[]


        new ShaderVariable("matWorldViewProj", VariableSemantic.MatrixWorldViewProj)


    //create a shader set

    ShaderSet ret = new ShaderSet();

    //we only use the fallback, and left other shaders unassigned, so all materials will be rendered by this shader

    ret.Fallback = shader;

    return ret;