// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) #ifndef UNITY_SHADER_UTILITIES_INCLUDED #define UNITY_SHADER_UTILITIES_INCLUDED // This file is always included in all unity shaders. #include "UnityShaderVariables.cginc" float3 ODSOffset(float3 worldPos, float ipd) { //based on google's omni-directional stereo rendering thread const float EPSILON = 2.4414e-4; float3 worldUp = float3(0.0, 1.0, 0.0); float3 camOffset = worldPos.xyz - _WorldSpaceCameraPos.xyz; float4 direction = float4(camOffset.xyz, dot(camOffset.xyz, camOffset.xyz)); direction.w = max(EPSILON, direction.w); direction *= rsqrt(direction.w); float3 tangent = cross(direction.xyz, worldUp.xyz); if (dot(tangent, tangent) < EPSILON) return float3(0, 0, 0); tangent = normalize(tangent); float directionMinusIPD = max(EPSILON, direction.w*direction.w - ipd*ipd); float a = ipd * ipd / direction.w; float b = ipd / direction.w * sqrt(directionMinusIPD); float3 offset = -a*direction + b*tangent; return offset; } inline float4 UnityObjectToClipPosODS(float3 inPos) { float4 clipPos; float3 posWorld = mul(unity_ObjectToWorld, float4(inPos, 1.0)).xyz; #if defined(STEREO_CUBEMAP_RENDER_ON) float3 offset = ODSOffset(posWorld, unity_HalfStereoSeparation.x); clipPos = mul(UNITY_MATRIX_VP, float4(posWorld + offset, 1.0)); #else clipPos = mul(UNITY_MATRIX_VP, float4(posWorld, 1.0)); #endif return clipPos; } // Tranforms position from object to homogenous space inline float4 UnityObjectToClipPos(in float3 pos) { #if defined(STEREO_CUBEMAP_RENDER_ON) return UnityObjectToClipPosODS(pos); #else // More efficient than computing M*VP matrix product return mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, float4(pos, 1.0))); #endif } inline float4 UnityObjectToClipPos(float4 pos) // overload for float4; avoids "implicit truncation" warning for existing shaders { return UnityObjectToClipPos(pos.xyz); } #endif