Last active
February 1, 2023 08:16
-
-
Save tolotratlt/70e8a3790cfb1839a21587d70dd2fda2 to your computer and use it in GitHub Desktop.
Unity Equirectangular unlit shader for inverted (normal) sphere. Only valid for inverted sphere (made under 3d modeling program or procedurally). Does'nt work for classical sphere
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' | |
Shader "Unlit/Equirectangular" | |
{ | |
Properties{ | |
_Color("Main Color", Color) = (1,1,1,1) | |
_MainTex("Diffuse (RGB) Alpha (A)", 2D) = "gray" {} | |
} | |
SubShader | |
{ | |
Pass | |
{ | |
Tags{ "LightMode" = "Always" } | |
//Cull Front //activate if shere normal is not inverted | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#pragma fragmentoption ARB_precision_hint_fastest | |
#pragma glsl | |
#pragma target 3.0 | |
#include "UnityCG.cginc" | |
struct appdata | |
{ | |
float4 vertex : POSITION; | |
float3 normal : NORMAL; | |
}; | |
struct v2f | |
{ | |
float4 pos : SV_POSITION; | |
float3 normal : TEXCOORD0; | |
}; | |
v2f vert(appdata v) | |
{ | |
v2f o; | |
o.pos = UnityObjectToClipPos(v.vertex); | |
o.normal = v.normal; | |
return o; | |
} | |
sampler2D _MainTex; | |
#define PI 3.141592653589793 | |
inline float2 RadialCoords(float3 a_coords) | |
{ | |
float3 a_coords_n = normalize(a_coords); | |
float lon = atan2(a_coords_n.z, a_coords_n.x); | |
float lat = acos(a_coords_n.y); | |
float2 sphereCoords = float2(lon, lat) * (1.0 / PI); | |
return float2(1- (sphereCoords.x * 0.5 - 0.5), 1-sphereCoords.y); | |
} | |
float4 frag(v2f IN) : COLOR | |
{ | |
float2 equiUV = RadialCoords(-IN.normal); | |
return tex2D(_MainTex, equiUV); | |
} | |
ENDCG | |
} | |
} | |
FallBack "VertexLit" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEditor; | |
//NOTE | |
//put in /Assets/Editor folder | |
public class InvertedSphere : EditorWindow | |
{ | |
private string st = "1.0"; | |
[MenuItem("GameObject/Create Other/Inverted Sphere...")] | |
public static void ShowWindow() | |
{ | |
EditorWindow.GetWindow(typeof(InvertedSphere)); | |
} | |
public void OnGUI() | |
{ | |
GUILayout.Label("Enter sphere size:"); | |
st = GUILayout.TextField(st); | |
float f; | |
if (!float.TryParse(st, out f)) | |
f = 1.0f; | |
if (GUILayout.Button("Create Inverted Sphere")) | |
{ | |
CreateInvertedSphere(f); | |
} | |
} | |
private void CreateInvertedSphere(float size) | |
{ | |
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Sphere); | |
MeshFilter mf = go.GetComponent<MeshFilter>(); | |
Mesh mesh = mf.sharedMesh; | |
GameObject goNew = new GameObject(); | |
goNew.name = "Inverted Sphere"; | |
MeshFilter mfNew = goNew.AddComponent<MeshFilter>(); | |
mfNew.sharedMesh = new Mesh(); | |
//Scale the vertices; | |
Vector3[] vertices = mesh.vertices; | |
for (int i = 0; i < vertices.Length; i++) | |
vertices[i] = vertices[i] * size; | |
mfNew.sharedMesh.vertices = vertices; | |
// Reverse the triangles | |
int[] triangles = mesh.triangles; | |
for (int i = 0; i < triangles.Length; i += 3) | |
{ | |
int t = triangles[i]; | |
triangles[i] = triangles[i + 2]; | |
triangles[i + 2] = t; | |
} | |
mfNew.sharedMesh.triangles = triangles; | |
// Reverse the normals; | |
Vector3[] normals = mesh.normals; | |
for (int i = 0; i < normals.Length; i++) | |
normals[i] = -normals[i]; | |
mfNew.sharedMesh.normals = normals; | |
mfNew.sharedMesh.uv = mesh.uv; | |
mfNew.sharedMesh.uv2 = mesh.uv2; | |
mfNew.sharedMesh.RecalculateBounds(); | |
// Add the same material that the original sphere used | |
MeshRenderer mr = goNew.AddComponent<MeshRenderer>(); | |
Renderer gorenderer = go.GetComponent<Renderer>(); | |
//mr.sharedMaterial = go.renderer.sharedMaterial; | |
mr.sharedMaterial = gorenderer.sharedMaterial; | |
DestroyImmediate(go); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment