private static float _GetZDist(Color c, float FN, float F, float NsF) { float bufVal = RTUtil.DecodeFloatRGBA(c); float zdist = FN / (F + bufVal * NsF); return(zdist); }
/// <summary> /// given the depth-buffer texture and a screen-pos, return the sampled z-dist /// F: camera farClipPlane /// N: camera nearClipPlane /// FN : F*N /// NsF: N-F /// </summary> public static float GetZDistFromDepthBuffer(Texture2D zbuffer, Vector2 screenPos, float FN, float F, float NsF) { float norX = screenPos.x / zbuffer.width; float norY = screenPos.y / zbuffer.height; Color zBufColor = zbuffer.GetPixel(Mathf.RoundToInt(norX * Screen.width), Mathf.RoundToInt(norY * Screen.height)); float zBufVal = RTUtil.DecodeFloatRGBA(zBufColor); float zBufDist = FN / (F + zBufVal * NsF);//IMPORTANT!!! z-depth is linearized based on reciprocal // ------------------------------ // refer: https://en.wikipedia.org/wiki/Bilinear_filtering // DEPRECATED: not useful, the 4 points all far from right //float u = norX * Screen.width - 0.5f; //float v = norY * Screen.height - 0.5f; //int _x = Mathf.FloorToInt(u); //int x0 = Mathf.Max(0, _x); //int x1 = Mathf.Min(_x + 1, Screen.width - 1); //int _y = Mathf.FloorToInt(v); //int y0 = Mathf.Max(0, _y); //int y1 = Mathf.Min(_y + 1, Screen.height - 1); //float u_ratio = u - _x; //float v_ratio = v - _y; //float u_opposite = 1 - u_ratio; //float v_opposite = 1 - v_ratio; //float v00 = _GetZDist(zbuffer.GetPixel(x0, y0), FN, F, NsF); //float v01 = _GetZDist(zbuffer.GetPixel(x0, y1), FN, F, NsF); //float v10 = _GetZDist(zbuffer.GetPixel(x1, y0), FN, F, NsF); //float v11 = _GetZDist(zbuffer.GetPixel(x1, y1), FN, F, NsF); //Dbg.Log("v00: {0}, v01: {1}, v10: {2}, v11: {3}", v00, v01, v10, v11); //float zBufDist = (v00 * u_opposite + v10 * u_ratio) * v_opposite + // (v01 * u_opposite + v11 * u_ratio) * v_ratio; //------------------------------------------ return(zBufDist); }