Skip to content

Instantly share code, notes, and snippets.

@partybusiness
Last active May 26, 2020 04:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save partybusiness/3dc0a6c3f6314de11dc8c15d5532f098 to your computer and use it in GitHub Desktop.
Save partybusiness/3dc0a6c3f6314de11dc8c15d5532f098 to your computer and use it in GitHub Desktop.
Stereoscopic shaders in Unity
Shader "Stereoscopic/Stereo180Panorama_SideBySide"
{
Properties{
[NoScaleOffset] _MainTex("Texture", 2D) = "white" {}
}
SubShader{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
struct vertexInput {
float4 vertex : POSITION;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float3 viewDir : TEXCOORD0;
};
inline float2 ToRadialCoords(float3 coords)
{
float3 normalizedCoords = normalize(coords);
float latitude = acos(normalizedCoords.y);
float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
float2 sphereCoords = float2(longitude, latitude) * float2(0.5 / UNITY_PI, 1.0 / UNITY_PI);
//show two 180s instead of one 360
sphereCoords.x = fmod(sphereCoords.x*2.0+1.0, 1.0)-0.5;
return float2(0.5, 1.0) - sphereCoords;
}
vertexOutput vert(vertexInput input)
{
vertexOutput output;
float4x4 modelMatrix = unity_ObjectToWorld;
float4x4 modelMatrixInverse = unity_WorldToObject;
output.viewDir = mul(modelMatrix, input.vertex).xyz
- _WorldSpaceCameraPos;
output.pos = UnityObjectToClipPos(input.vertex);
return output;
}
float4 frag(vertexOutput i) : COLOR
{
float2 uv = ToRadialCoords(i.viewDir);
uv = (uv * fixed2(0.5, 1) + fixed2(unity_StereoEyeIndex * 0.5, 0));
return tex2D(_MainTex, uv, ddx(0), ddy(0));
}
ENDCG
}
}
}
Shader "Stereoscopic/Stereo360Panorama_VerticalStack"
{
Properties{
[NoScaleOffset] _MainTex("Texture", 2D) = "white" {}
}
SubShader{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
struct vertexInput {
float4 vertex : POSITION;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float3 viewDir : TEXCOORD0;
};
inline float2 ToRadialCoords(float3 coords)
{
float3 normalizedCoords = normalize(coords);
float latitude = acos(normalizedCoords.y);
float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
float2 sphereCoords = float2(longitude, latitude) * float2(0.5 / UNITY_PI, 1.0 / UNITY_PI);
//Use this if you want 180 instead of 360
//sphereCoords.x = fmod(sphereCoords.x*2.0+1.0, 1.0)-0.5;
return float2(0.5, 1.0) - sphereCoords;
}
vertexOutput vert(vertexInput input)
{
vertexOutput output;
float4x4 modelMatrix = unity_ObjectToWorld;
float4x4 modelMatrixInverse = unity_WorldToObject;
output.viewDir = mul(modelMatrix, input.vertex).xyz
- _WorldSpaceCameraPos;
output.pos = UnityObjectToClipPos(input.vertex);
return output;
}
float4 frag(vertexOutput i) : COLOR
{
float2 uv = ToRadialCoords(i.viewDir);
uv = (uv * fixed2(1, 0.5) + fixed2(0, unity_StereoEyeIndex * 0.5));
//This is the version for if the left eye is on top
//uv = (uv * fixed2(1, 0.5) + fixed2(0, 0.5 - unity_StereoEyeIndex * 0.5));
return tex2D(_MainTex, uv, ddx(0), ddy(0));
}
ENDCG
}
}
}
Shader "Stereoscopic/StereoImage_SideBySide"
{
//reference this:
// https://docs.unity3d.com/Manual/SinglePassStereoRendering.html
// this assumes left eye is on left of texture
Properties
{
[NoScaleOffset] _MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float4 uv : TEXCOORD0;
};
sampler2D _MainTex;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = float4(v.uv * fixed2(0.5,1) + fixed2(unity_StereoEyeIndex * 0.5, 0), v.uv);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv.xy, ddx(i.uv.zw), ddy(i.uv.zw));
return col;
}
ENDCG
}
}
}
Shader "Stereoscopic/StereoImage_VerticalStack"
{
//reference this:
// https://docs.unity3d.com/Manual/SinglePassStereoRendering.html
//this assumes left eye is on bottom of texture, change if this is wrong
Properties
{
[NoScaleOffset] _MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float4 uv : TEXCOORD0;
};
sampler2D _MainTex;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = float4(v.uv * fixed2(1,0.5) + fixed2(0, unity_StereoEyeIndex * 0.5), v.uv);
//This is the version for if the left eye is on top
//o.uv = float4(v.uv * fixed2(1, 0.5) + fixed2(0, 0.5-unity_StereoEyeIndex * 0.5), v.uv);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv.xy, ddx(i.uv.zw), ddy(i.uv.zw));
return col;
}
ENDCG
}
}
}
Shader "Stereoscopic/VertexEyeOffset"
{
//This one might be a dumb gimmick but it offsets the vertices based on the camera and could make things seem nearer or further
// Yeah, in VR this can be disorienting since it makes the stereopsis contradict the depth cues from head movement.
// if you want to do this on purpose for some reason, there you go
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Offset("Offset", float) = 0.1
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Offset;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex) + float4(lerp(-1,1,unity_StereoEyeIndex)*_Offset,0,0,0);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDCG
}
}
}
@partybusiness
Copy link
Author

This is some shaders that use unity_StereoEyeIndex to show steroscopic images in VR in Unity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment