1
\$\begingroup\$

I've been trying to learn shader coding, specifically procedural skyboxes. I've been using this guide here which is a shader graph tutorial and try to write out the steps in code. However, I'm stuck at the first part about fixing the texture UV's to wrap around a sphere as the current texture is warped:

Warped texture

Here is my current shader:

Shader "Unlit/TestSky"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
                float3 normal :NORMAL;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
          


            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = normalize(UnityObjectToClipPos(v.vertex));
                o.normal = v.normal;
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }
             #define PI 3.141592653589793
            fixed4 frag (v2f i) : SV_Target
            {
                float3 pos = i.vertex;
                float2 newUV;
                newUV.x = 0.5 + atan2(pos.z,pos.x)/PI*2;
                newUV.y = 0.5 - asin(pos.y)/PI;
                
                fixed4 col = tex2D(_MainTex, i.uv);
                
               
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

I also used wikipedias formula on wrapping uvs to a sphere:

formula for wrapping uv's to a sphere

However, when I go back to the Unity Editor all I see is this:

picture of unity editor

I tried using this solution:

Shader "Unlit/TestSky"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

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

            struct v2f
            {
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
                float3 normal :NORMAL;
                float3 direction : TEXCOORD0;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
          


            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = (UnityObjectToClipPos(v.vertex));
                o.direction = mul(unity_ObjectToWorld, v.vertex).xyz - _WorldSpaceCameraPos;
                return o;
            }
             #define PI 3.141592653589793
            fixed4 frag (v2f i) : SV_Target
            {
                float3 pos = normalize(i.direction);
                float2 newUV;
                newUV.x = 0.5 + atan2(pos.z,pos.x)/PI*2;
                newUV.y = 0.5 - asin(pos.y)/PI;
                
                float2 dx = ddx(newUV);
                float2 dy = ddy(newUV);
                float2 du = float2(dx.x, dy.x);
                du -= (abs(du) > 0.5f) * sign(du);
                dx.x = du.x;
                dy.x = du.y;

                // In case you want to rotate your view using the texture x-offset.
                newUV.x += _MainTex_ST.z;     

                // Sample the texture with our calculated UV & seam fixup.
                fixed4 col = tex2Dgrad(_MainTex, newUV, dx, dy);
                return col;
            }
            ENDCG
        }
    }
}

But ended up getting this image:

Updated image of unity editor

\$\endgroup\$
8
  • 1
    \$\begingroup\$ Does this answer your question? \$\endgroup\$ – DMGregory Feb 22 at 14:24
  • \$\begingroup\$ I tried it and still got that green image above ^. I don't quite understand the solution so maybe I did something wrong... \$\endgroup\$ – Jamie Hyland Feb 22 at 14:29
  • \$\begingroup\$ Likely. Can you share the exact code you used when trying to follow that answer? Also, what shape of mesh are you drawing here? \$\endgroup\$ – DMGregory Feb 22 at 14:41
  • \$\begingroup\$ I'll update my answer now, Its supposed to be a sphere? But I just applied it to the skybox settings in unity by going to window -> rendering and then setting the skybox \$\endgroup\$ – Jamie Hyland Feb 22 at 14:45
  • 1
    \$\begingroup\$ Does atan2(pos.z,pos.x)/PI*2 -> atan2(pos.z,pos.x)/(PI*2) resolve the remaining issue? \$\endgroup\$ – Tyyppi_77 Feb 22 at 16:19
2
\$\begingroup\$

You have mistranslated the formulas you found into code. You need to add parenthesis around the denominator in atan2(pos.z,pos.x)/PI*2, so change it to atan2(pos.z,pos.x)/(PI*2).

\$\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.