diff --git a/Assets/measuregeneric/shaders/InteriorImposterShader.shader b/Assets/measuregeneric/shaders/InteriorImposterShader.shader index 96dcd42..53d3171 100644 --- a/Assets/measuregeneric/shaders/InteriorImposterShader.shader +++ b/Assets/measuregeneric/shaders/InteriorImposterShader.shader @@ -13,6 +13,11 @@ Shader "Custom/InteriorImposterShader" #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" + #include "Lighting.cginc" + #include "AutoLight.cginc" + #include "UnityShadowLibrary.cginc" + #include "UnityLightingCommon.cginc" + #include "UnityStandardBRDF.cginc" struct appdata { @@ -36,29 +41,44 @@ Shader "Custom/InteriorImposterShader" return o; } - // ChatGPT snippet - float3 BoxProjectReflectionDir(float3 worldPos, float3 worldRefl) + // Snippet from https://github.com/frostbone25/Unity-Improved-Box-Projected-Reflections/blob/main/ImprovedBoxProjectedReflections/Assets/Shaders/ImprovedBoxProjectedReflections.shader#L80 + float3 BoxProjectReflectionDir(float3 worldPos, float3 worldRefl, out float distanceToHitPoint) { - // Calculate relative position within the box - float3 boxMin = unity_SpecCube0_BoxMin.xyz; - float3 boxMax = unity_SpecCube0_BoxMax.xyz; - float3 boxCenter = 0.5 * (boxMin + boxMax); - float3 boxSize = boxMax - boxMin; + float4 probePos = unity_SpecCube0_ProbePosition; + float4 boxMin = unity_SpecCube0_BoxMin; + float4 boxMax = unity_SpecCube0_BoxMax; - float3 localPos = worldPos - boxCenter; - float3 absLocalRefl = abs(worldRefl); + // Do we have a valid reflection probe? + if (probePos.w > 0.0) + { + float3 nrdir = normalize(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; + float3 rbmax = (boxMax.xyz - worldPos) / nrdir; + float3 rbmin = (boxMin.xyz - worldPos) / nrdir; + + float3 rbminmax = (nrdir > 0.0f) ? rbmax : rbmin; + + distanceToHitPoint = min(min(rbminmax.x, rbminmax.y), rbminmax.z); + + worldPos -= probePos.xyz; + worldRefl = worldPos + nrdir * distanceToHitPoint; + } + + return worldRefl; } fixed4 frag (v2f i) : SV_Target { + float mipLevel = 0.0; + half3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); // Direction of ray from the camera towards the object surface - half4 skyData = UNITY_SAMPLE_TEXCUBE(unity_SpecCube0, BoxProjectReflectionDir(i.worldPos, -worldViewDir)); + float3 boxProjection = BoxProjectReflectionDir(i.worldPos, -worldViewDir, mipLevel); + + mipLevel = (mipLevel / UNITY_SPECCUBE_LOD_STEPS) * perceptualRoughnessToMipmapLevel(0.0); // Fixing incorrect mipmap level of cubemap texture + + half4 skyData = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, boxProjection, mipLevel); half3 skyColor = DecodeHDR(skyData, unity_SpecCube0_HDR); // This is done becasue the cubemap is stored HDR + return half4(skyColor, 1.0); } ENDCG