LoginSignup
13
5

More than 5 years have passed since last update.

Fisheye shader

Last updated at Posted at 2017-10-04

プラネタリウム映像を作成&上映する機会があり、いくつか作って上映してきました。

プラネタリウム映像をUnityで

tmtest_00883.png

IMG_4356.JPG

サンプルムービーをいくつか作って試した結果、cubemapを使った360映像でなくても、FoV90[deg]くらいのカメラでFishEye(魚眼レンズ)化したものでもそこそこいけそうな感じでしたので、Fisheyeシェーダーを用意しました。

FisheyeShader.shader
Shader "Unlit/FisheyeShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Rate ("Distortion Rate", Range(0.55,0.7)) = 0.58
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
//      Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #pragma multi_compile _ IS_SQUARE
            #pragma multi_compile _ USE_MASK

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float rate : RATE;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _Rate;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                #ifndef IS_SQUARE
                    o.rate = 1;
                #else
                    o.rate = _ScreenParams.x/_ScreenParams.y;
                #endif
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float2 coord = (i.uv-0.5);
                float dist = (distance(coord, 0));
                #ifdef USE_MASK
                #ifndef IS_SQUARE
                if(dist>0.5){ return fixed4(0,0,0,0);}
                #else
                float2 ckCoord = (0.5 - i.uv)*float2(i.rate,1);
                float ckDist = (distance(ckCoord, 0));
                if(ckDist>0.5){ return fixed4(0,0,0,0);}
                #endif
                #endif

                float ang = atan2(coord.y,coord.x);
                float r = tan(dist * UNITY_PI/2) / tan(_Rate * UNITY_PI);
                coord.x = cos(ang)*r*2;
                coord.y = sin(ang)*r*2;
                coord = max(min(0.5-coord,1),0);
                fixed4 col = tex2D(_MainTex, coord);
                return col;
            }
            ENDCG
        }
    }
}

カメラへの適用は、カメラにアタッチしたスクリプト内で

void OnRenderImage(RenderTexture src, RenderTexture dest){
  Graphics.Blit(src, dest, material);
}

のようにしています。

元画像
元画像

Fish eye
Fish eye

360画像(dome master)
360画像(dome master)

13
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
5