// Original code from https://gist.github.com/josephbk117/a43f5335cea9b3e12a44f196dc81f30f Shader "Custom/InteriorReflectionShader" { Properties { _Glossiness ("Smoothness", Range(0,1)) = 0.8 _ReflectionProbePosition ("Reflection Probe Position", Vector) = (0,0,0,0) _ReflectionProbeBoxMin ("Box Min", Vector) = (0,0,0,0) _ReflectionProbeBoxMax ("Box Max", Vector) = (0,0,0,0) } SubShader { Tags { "RenderType"="Opaque" } LOD 200 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "UnityStandardUtils.cginc" struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; }; struct v2f { float4 pos : SV_POSITION; float3 worldNormal : TEXCOORD0; float3 worldPos : TEXCOORD1; }; float4 _ReflectionProbePosition; float4 _ReflectionProbeBoxMin; float4 _ReflectionProbeBoxMax; half _Glossiness; v2f vert (appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; return o; } float3 BoxProjectReflectionDir(float3 worldPos, float3 worldRefl) { // Calculate relative position within the box float3 boxMin = _ReflectionProbeBoxMin.xyz; float3 boxMax = _ReflectionProbeBoxMax.xyz; float3 boxCenter = 0.5 * (boxMin + boxMax); float3 boxSize = boxMax - boxMin; float3 localPos = worldPos - boxCenter; float3 absLocalRefl = abs(worldRefl); // Scale the reflection vector based on which side of the box it hits float3 scale = boxSize / absLocalRefl; float scaleMin = min(min(scale.x, scale.y), scale.z); return localPos + worldRefl * scaleMin; } fixed4 frag (v2f i) : SV_Target { // Get reflection vector float3 worldViewDir = normalize(_WorldSpaceCameraPos - i.worldPos); float3 worldRefl = reflect(worldViewDir, i.worldNormal); // Apply box projection to the reflection vector float3 projectedReflDir = BoxProjectReflectionDir(i.worldPos, worldRefl); fixed4 reflectionColor = UNITY_SAMPLE_TEXCUBE(unity_SpecCube0, projectedReflDir); return reflectionColor; } ENDCG } } FallBack "Diffuse" }