How can I map a portrait 2D video to a 3D sphere in Unity, but not fully stretched like a 360 video?

66 Views Asked by At

I am trying to map a portrait 2D video to a 3D sphere in Unity. The video is not a 360 video, so it does not need to be stretched to cover the entire sphere(see the attached sketch).

Instead, I would like to map the video to the sphere so that it maintains its aspect ratio and leaves other parts of the sphere transparent. The video has a resolution of 800 x 1920, which is about 20% of the resolution of a typical 4K 360 video (3840 x 1920). I am wondering if there is a way to achieve this effect using texture remapping or a custom shader.

A sketch showing what I try to apply

At this moment, I have tried to create a shader to maintain the aspect ratio of the portrait video while applying to the 3D sphere, but seems not working as expected, the shader is like below:

Shader "Custom/PortraitVideoSphere" { Properties { _MainTex ("Video Texture", 2D) = "white" {} }
    SubShader {
        Tags { "RenderType"="Opaque" }
    
        Pass {
            CGPROGRAM
            #pragma surface surf Standard fullforwardshadows
            #pragma target 3.0
    
            sampler2D _MainTex;
    
            struct Input {
                float2 uv_MainTex;
            };
    
            void surf (Input IN, inout SurfaceOutputStandard o) {
                // Get the width and height of the video texture.
                int width = _MainTex.GetWidth();
                int height = _MainTex.GetHeight();
    
                // Calculate the ratio between the width and height of the video texture.
                float ratio = width / height;
    
                // Set the scale of the sphere so that it maintains its aspect ratio.
                Vector3 scale = new Vector3(ratio, 1.0f, ratio);
                o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
                o.Alpha = 1.0f;
                o.Normal = float3(0.0f, 0.0f, 1.0f);
            }
            ENDCG
        }
    }
}

However that seems now work. Please let me know if I can do this in a texture mapping in a script, or by using a different shader.

0

There are 0 best solutions below