I am attempting to write a cubemap shader that can be applied to any geometry, with the goal to create a Holodeck-like effect. This shader would be applied to the walls/floor/ceiling of a room, and give the appearance that the room is much bigger than it is. I am using Unity 2022 with the built-in pipeline.
After much trial and error, I was able to recreate the simple parallax cubemap effect, however, only certain aspects of geometry behind it will still be rendered. Perhaps fog, ambient occlusion, global illumination, my "computer vision" shader which relies on the Z-buffer seem to be particularly capable of rendering "through" the parallax cubemap surface shader.
Left side shows normal geometry that is not occluded by the parallax cubemap surface. This is a normal ol' Standard shader material using yellow as the albedo color; nothing special.
Right side shows the same object, occluded by the parallax cubemap surface. I am using a simple starfield as my cubemap. The parallax cubemap surface shader doing its job by rendering the stars... except for not blocking SOME aspects of the geometry behind it.
This is one screenshot by the way, I just positioned a parallax cubemap surface to partially obstruct the yellow geometry.
I have proven that this strange "partial blocking" applies to any surfaces that are behind the parallax cubemap surface, regardless of shader, and render order.
Here is the complete parallax cubemap shader:
Shader "Custom/ParallaxCubemap"
{
Properties
{
_FrontTex ("FrontTex", 2D) = "white" {}
_BackTex ("BackTex", 2D) = "white" {}
_LeftTex ("LeftTex", 2D) = "white" {}
_RightTex ("RightTex", 2D) = "white" {}
_UpTex ("UpTex", 2D) = "white" {}
_DownTex ("DownTex", 2D) = "white" {}
}
SubShader
{
Tags {"Queue"="Geometry" "RenderType"="Opaque" "LightMode"="Always"}
ZWrite On
Lighting Off
LOD 100
CGPROGRAM
#pragma surface surf Unlit noambient noshadow novertexlights nolightmap nodynlightmap nodirlightmap nofog nometa nolppv noshadowmask noforwardadd
#pragma target 3.0
sampler2D _FrontTex;
sampler2D _BackTex;
sampler2D _LeftTex;
sampler2D _RightTex;
sampler2D _UpTex;
sampler2D _DownTex;
struct Input
{
float3 worldPos;
float3 worldNormal;
float3 viewDir;
};
void surf (Input IN, inout SurfaceOutput o)
{
float3 dir = normalize(IN.viewDir);
float2 uv;
fixed4 texcolor;
float3 absDir = abs(dir);
if (absDir.x >= absDir.y && absDir.x >= absDir.z)
{
uv = dir.yz / absDir.x;
if (dir.x < 0)
{
uv.y *= -1;
texcolor = tex2D(_RightTex, uv * 0.5f + 0.5f);
}
else
{
texcolor = tex2D(_LeftTex, uv * 0.5f + 0.5f);
}
}
else if (absDir.y >= absDir.x && absDir.y >= absDir.z)
{
uv = dir.xz / absDir.y;
if (dir.y < 0)
{
texcolor = tex2D(_UpTex, uv * 0.5f + 0.5f);
}
else
{
texcolor = tex2D(_DownTex, uv * 0.5f + 0.5f);
}
}
else
{
uv = dir.xy / absDir.z;
if (dir.z < 0)
{
texcolor = tex2D(_FrontTex, uv * -0.5f + 0.5f);
}
else
{
uv.x *= -1;
texcolor = tex2D(_BackTex, uv * -0.5f + 0.5f);
}
}
o.Albedo = texcolor.rgb;
o.Normal = IN.worldNormal;
o.Emission = fixed3(0,0,0);
o.Specular = 0;
o.Gloss = 0;
o.Alpha = 1.0f;
}
half4 LightingUnlit(SurfaceOutput s, half3 lightDir, half atten)
{
return half4(s.Albedo, 1.0f);
}
ENDCG
}
}
EDIT: Switching to Lambert lighting model does fix the "partial obstruction" issues, but then fog impacts the ParallaxCubemap surfaces, which is not ideal, but much better than seeing through walls!
Any ideas would be deeply appreciated!