Shader "Hidden/Internal-TiledReflections" { Properties { _LightTexture0 ("", any) = "" {} _ShadowMapTexture ("", any) = "" {} _SrcBlend ("", Float) = 1 _DstBlend ("", Float) = 1 } SubShader { Pass { ZWrite Off ZTest Always Cull Off //Blend Off Blend [_SrcBlend] [_DstBlend] CGPROGRAM #pragma target 5.0 #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "UnityStandardBRDF.cginc" #include "UnityStandardUtils.cginc" #include "UnityPBSLighting.cginc" #include "..\common\ShaderBase.h" #include "LightDefinitions.cs.hlsl" uniform float4x4 g_mViewToWorld; uniform float4x4 g_mWorldToView; uniform float4x4 g_mInvScrProjection; uniform float4x4 g_mScrProjection; Texture2D _CameraDepthTexture; Texture2D _CameraGBufferTexture0; Texture2D _CameraGBufferTexture1; Texture2D _CameraGBufferTexture2; UNITY_DECLARE_TEXCUBEARRAY(_reflCubeTextures); StructuredBuffer g_vLightList; StructuredBuffer g_vLightData; float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far { float3 vP = float3(0.0f,0.0f,zDptBufSpace); float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0)); return v4Pres.z / v4Pres.w; } float3 GetViewPosFromLinDepth(float2 v2ScrPos, float fLinDepth) { float fSx = g_mScrProjection[0].x; //float fCx = g_mScrProjection[2].x; float fCx = g_mScrProjection[0].z; float fSy = g_mScrProjection[1].y; //float fCy = g_mScrProjection[2].y; float fCy = g_mScrProjection[1].z; #ifdef LEFT_HAND_COORDINATES return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 ); #else return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 ); #endif } #ifdef USE_CLUSTERED_LIGHTLIST uniform float g_fClustScale; uniform float g_fClustBase; uniform float g_fNearPlane; uniform float g_fFarPlane; //uniform int g_iLog2NumClusters; // numClusters = (1< g_vLayeredOffsetsBuffer; #ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE Buffer g_logBaseBuffer; #endif #include "ClusteredUtils.h" void GetLightCountAndStart(out uint uStart, out uint uNrLights, uint2 tileIDX, int nrTilesX, int nrTilesY, float linDepth) { g_iLog2NumClusters = (int) (g_fLog2NumClusters+0.5); // ridiculous #ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE float logBase = g_logBaseBuffer[tileIDX.y*nrTilesX + tileIDX.x]; #else float logBase = g_fClustBase; #endif int clustIdx = SnapToClusterIdx(linDepth, logBase); int nrClusters = (1<>27)&31; } uint FetchIndex(const uint tileOffs, const uint l) { return g_vLightList[ tileOffs+l ]; } #else void GetLightCountAndStart(out uint uStart, out uint uNrLights, uint2 tileIDX, int nrTilesX, int nrTilesY, float linDepth) { const int tileOffs = (tileIDX.y+REFLECTION_LIGHT*nrTilesY)*nrTilesX+tileIDX.x; uNrLights = g_vLightList[ 16*tileOffs + 0]&0xffff; uStart = tileOffs; } uint FetchIndex(const uint tileOffs, const uint l) { const uint l1 = l+1; return (g_vLightList[ 16*tileOffs + (l1>>1)]>>((l1&1)*16))&0xffff; } #endif float3 ExecuteReflectionProbes(uint2 pixCoord, uint start, uint numLights, float linDepth); float3 OverlayHeatMap(uint uNumLights, float3 c); struct v2f { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; }; v2f vert (float4 vertex : POSITION, float2 texcoord : TEXCOORD0) { v2f o; o.vertex = UnityObjectToClipPos(vertex); o.texcoord = texcoord.xy; return o; } half4 frag (v2f i) : SV_Target { uint2 pixCoord = ((uint2) i.vertex.xy); uint iWidth; uint iHeight; _CameraDepthTexture.GetDimensions(iWidth, iHeight); uint nrTilesX = (iWidth+15)/16; uint nrTilesY = (iHeight+15)/16; uint2 tileIDX = pixCoord / 16; float zbufDpth = FetchDepth(_CameraDepthTexture, pixCoord.xy).x; float linDepth = GetLinearDepth(zbufDpth); uint numLights=0, start=0; GetLightCountAndStart(start, numLights, tileIDX, nrTilesX, nrTilesY, linDepth); float3 c = ExecuteReflectionProbes(pixCoord, start, numLights, linDepth); //c = OverlayHeatMap(numLights, c); return float4(c,1.0); } struct StandardData { float3 specularColor; float3 diffuseColor; float3 normalWorld; float smoothness; float occlusion; }; StandardData UnityStandardDataFromGbuffer(float4 gbuffer0, float4 gbuffer1, float4 gbuffer2) { StandardData data; data.normalWorld = normalize(2*gbuffer2.xyz-1); data.smoothness = gbuffer1.a; data.diffuseColor = gbuffer0.xyz; data.specularColor = gbuffer1.xyz; data.occlusion = gbuffer0.a; return data; } half3 distanceFromAABB(half3 p, half3 aabbMin, half3 aabbMax) { return max(max(p - aabbMax, aabbMin - p), half3(0.0, 0.0, 0.0)); } half3 Unity_GlossyEnvironment (UNITY_ARGS_TEXCUBEARRAY(tex), int sliceIndex, half4 hdr, Unity_GlossyEnvironmentData glossIn); float3 ExecuteReflectionProbes(uint2 pixCoord, uint start, uint numLights, float linDepth) { float3 vP = GetViewPosFromLinDepth(float2(pixCoord.x+0.5, pixCoord.y+0.5), linDepth); float3 worldPos = mul(g_mViewToWorld, float4(vP.xyz,1.0)).xyz; //unity_CameraToWorld float3 vWSpaceVDir = normalize(mul((float3x3) g_mViewToWorld, -vP).xyz); //unity_CameraToWorld float4 gbuffer0 = _CameraGBufferTexture0.Load( uint3(pixCoord.xy, 0) ); float4 gbuffer1 = _CameraGBufferTexture1.Load( uint3(pixCoord.xy, 0) ); float4 gbuffer2 = _CameraGBufferTexture2.Load( uint3(pixCoord.xy, 0) ); StandardData data = UnityStandardDataFromGbuffer(gbuffer0, gbuffer1, gbuffer2); float oneMinusReflectivity = 1.0 - SpecularStrength(data.specularColor.rgb); float3 worldNormalRefl = reflect(-vWSpaceVDir, data.normalWorld); float3 vspaceRefl = mul((float3x3) g_mWorldToView, worldNormalRefl).xyz; UnityLight light; light.color = 0; light.dir = 0; float3 ints = 0; uint l=0; // we need this outer loop for when we cannot assume a wavefront is 64 wide // since in this case we cannot assume the lights will remain sorted by type // during processing in lightlist_cs.hlsl #if !defined(XBONE) && !defined(PLAYSTATION4) while(l11 ? float4(1.0,1.0,1.0,1.0) : kRadarColors[nColorIndex]; return lerp(c, pow(col.xyz, 2.2), 0.3*col.w); } half3 Unity_GlossyEnvironment (UNITY_ARGS_TEXCUBEARRAY(tex), int sliceIndex, half4 hdr, Unity_GlossyEnvironmentData glossIn) { #if UNITY_GLOSS_MATCHES_MARMOSET_TOOLBAG2 && (SHADER_TARGET >= 30) // TODO: remove pow, store cubemap mips differently half perceptualRoughness = pow(glossIn.roughness, 3.0/4.0); #else half perceptualRoughness = glossIn.roughness; // MM: switched to this #endif //perceptualRoughness = sqrt(sqrt(2/(64.0+2))); // spec power to the square root of real roughness #if 0 float m = perceptualRoughness*perceptualRoughness; // m is the real roughness parameter const float fEps = 1.192092896e-07F; // smallest such that 1.0+FLT_EPSILON != 1.0 (+1e-4h is NOT good here. is visibly very wrong) float n = (2.0/max(fEps, m*m))-2.0; // remap to spec power. See eq. 21 in --> https://dl.dropboxusercontent.com/u/55891920/papers/mm_brdf.pdf n /= 4; // remap from n_dot_h formulatino to n_dot_r. See section "Pre-convolved Cube Maps vs Path Tracers" --> https://s3.amazonaws.com/docs.knaldtech.com/knald/1.0.0/lys_power_drops.html perceptualRoughness = pow( 2/(n+2), 0.25); // remap back to square root of real roughness #else // MM: came up with a surprisingly close approximation to what the #if 0'ed out code above does. perceptualRoughness = perceptualRoughness*(1.7 - 0.7*perceptualRoughness); #endif half mip = perceptualRoughness * UNITY_SPECCUBE_LOD_STEPS; half4 rgbm = UNITY_SAMPLE_TEXCUBEARRAY_LOD(tex, float4(glossIn.reflUVW.xyz, sliceIndex), mip); //return rgbm.xyz; return DecodeHDR_NoLinearSupportInSM2 (rgbm, hdr); } ENDCG } } Fallback Off }