I’ve created a Surface shader in Unity that involves sampling from a cubemap. I am working on the Oculus Go with Single-Pass Multi-View rendering enabled. But in-game the cubemap looks as if it was just a completely flat texture applied to the surface with no stereo-depth to it(With generally “correct” cube-map samples but applied to the surface as if it was just a “_MainTex”). But when I apply a “Standard” shader on one of the meshes to the scene, the cubemap reflections appear to work where the view-direction of each eye is being accounted for during the reflection vector calculation and the reflection has proper “depth”. I’ve downloaded the built-in shaders from the unity download page to see if i can dissect if I am doing anything wrong and followed the standard shaders setup but nothing stood out to me.
The reflections appear to work fine when ran on the desktop using an Oculus rift, when Multi-Pass is enabled on the Oculus Go, or when I use one of the unity “Standard” shaders but not when I use my surface shader. Is there a flag or variable or variant flag or something I’m missing?
Here’s some key parts of my shader with some attempts to get it to retrieve stereo per-eye vectors.
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 250
Cull Back
CGPROGRAM
#pragma target 4.0
#pragma surface surf BlinnPhong vertex:vert noforwardadd nodynlightmap nofog noshadow
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_MULTIVIEW_ON STEREO_CUBEMAP_RENDER_ON STEREO_INSTANCING_ON
#pragma multi_compile_instancing
#pragma multi_compile_fwdbase
#include "UnityCG.cginc"
...
struct Input
{
float2 uv_MainTex;
float2 uv_BumpMap;
float2 uv_Glossiness;
float3 worldPos;
float worldNormal;
float3 worldRefl;
INTERNAL_DATA
float3 viewDir;
UNITY_VERTEX_OUTPUT_STEREO
};
void vert (inout appdata_full v, out Input o) {
UNITY_INITIALIZE_OUTPUT(Input,o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
}
...
void surf (Input IN, inout SurfaceOutput o)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN)
fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
fixed4 glossTex = tex2D(_Glossiness, IN.uv_Glossiness);
o.Albedo = tex.rgb;
o.Gloss = glossTex * _GlossinessPower;
o.Alpha = tex.a;
o.Specular = _Specularity;
o.Normal = UnpackScaleNormal(
tex2D(_BumpMap, IN.uv_BumpMap),
_BumpPower
);
const float3 ReflectionDirection = BoxProjectedCubemapDirection(
WorldReflectionVector(IN, o.Normal).xyz,
IN.worldPos,
unity_SpecCube0_ProbePosition,
unity_SpecCube0_BoxMin,
unity_SpecCube0_BoxMax
);
const float4 ProbeColor = UNITY_SAMPLE_TEXCUBE_LOD(
unity_SpecCube0,
ReflectionDirection,
UNITY_SPECCUBE_LOD_STEPS * (o.Gloss + _ReflectionBlurBoost)
);
o.Emission = ProbeColor * _ReflectionPower;
}
I also notice that in the compiled shader in the “STEREO_MULTIVIEW_ON” variant, it seems to always use matrices from the left eye(0). Is this possibly a unity bug?
...
-- Hardware tier variant: Tier 3
-- Fragment shader for "gles3":
Shader Disassembly:
// All GLSL source is contained within the vertex program
//////////////////////////////////////////////////////
Keywords set in this variant: DIRECTIONAL STEREO_MULTIVIEW_ON
-- Hardware tier variant: Tier 1
-- Vertex shader for "gles3":
Shader Disassembly:
#ifdef VERTEX
#version 300 es
...
u_xlat0.y = vs_TEXCOORD3.w;
u_xlat0.z = vs_TEXCOORD4.w;
u_xlat1.xyz = (-u_xlat0.xyz) + unity_StereoWorldSpaceCameraPos[0].xyz; // <<< It's always sampling the left eye???
u_xlat30 = dot(u_xlat1.xyz, u_xlat1.xyz);
u_xlat30 = inversesqrt(u_xlat30);
...