static void SetupHitInfo(out GPURaycastDecalsTargetInfo hitInfo) { hitInfo.position = Vector3.zero; hitInfo.normal = Vector3.zero; hitInfo.hittedRenderer = null; hitInfo.IsHitted = false; hitInfo.hittedTarget = null; hitInfo.VertexIndex = -1; }
public static bool RaycastToRegisteredTargets(Camera camera, Vector2 uv, out GPURaycastDecalsTargetInfo hitInfo) { InitRes(); uv.y = 1f - uv.y; #if UNITY_EDITOR_OSX uv.y -= 0.5f; uv.y *= 2f; uv.x *= 2f; #endif SetupHitInfo(out hitInfo); int cameraPixelWidth = camera.targetTexture == null ? camera.pixelWidth : camera.targetTexture.width; int cameraPixelHeight = camera.targetTexture == null ? camera.pixelHeight : camera.targetTexture.height; float scaleFactor = 0.2f; cameraPixelWidth = (int)(cameraPixelWidth * scaleFactor); cameraPixelHeight = (int)(cameraPixelHeight * scaleFactor); if (lastCamera != camera || gpuRaycastCamera == null) { gpuRaycastCamera = new GameObject("GPURaycastCamera", typeof(Camera)).GetComponent <Camera>(); gpuRaycastCamera.gameObject.SetActive(false); gpuRaycastCamera.enabled = false; gpuRaycastCamera.gameObject.hideFlags = HideFlags.HideAndDontSave; } gpuRaycastCamera.cameraType = CameraType.Game; gpuRaycastCamera.targetTexture = null; gpuRaycastCamera.transform.position = camera.transform.position; gpuRaycastCamera.transform.rotation = camera.transform.rotation; gpuRaycastCamera.clearFlags = CameraClearFlags.Color; gpuRaycastCamera.backgroundColor = Color.clear; gpuRaycastCamera.renderingPath = RenderingPath.Forward; gpuRaycastCamera.rect = camera.rect; lastCamera = camera; cameraPlanes = GeometryUtility.CalculateFrustumPlanes(gpuRaycastCamera); visibleRegisteredRenderers.Clear(); visibleRegisteredRenderers.AddRange(allRegisteredRenderers.FindAll((r) => { return(GeometryUtility.TestPlanesAABB(cameraPlanes, r.bounds)); })); for (int i = 0; i < visibleRegisteredRenderers.Count; i++) { visibleRegisteredRenderers[i].GetPropertyBlock(propertyBlock); propertyBlock.SetInt("ObjectID", i + 1); visibleRegisteredRenderers[i].SetPropertyBlock(propertyBlock); } if (LastPixelWidth != cameraPixelWidth || LastPixelHeight != cameraPixelHeight || worldPosBuffer == null) { if (worldPosBuffer != null) { worldPosBuffer.Release(); GameObject.DestroyImmediate(worldPosBuffer, true); } worldPosBuffer = new RenderTexture(cameraPixelWidth, cameraPixelHeight, 16, RenderTextureFormat.ARGBFloat); worldPosBuffer.Create(); LastPixelWidth = cameraPixelWidth; LastPixelHeight = cameraPixelHeight; } gpuRaycastCamera.targetTexture = worldPosBuffer; gpuRaycastCamera.RenderWithShader(gpuPackedRaycastShader, ""); if (uv.x < 0 || uv.x > 1 || uv.y < 0 || uv.y > 1) { return(false); } int idx = (int)(uv.x * cameraPixelWidth); int idy = (int)(uv.y * cameraPixelHeight); var lastActive = RenderTexture.active; RenderTexture.active = worldPosBuffer; posBufferCopy.ReadPixels(new Rect(idx, idy, 1, 1), 0, 0); RenderTexture.active = lastActive; posBufferCopy.Apply(); Color packedData = posBufferCopy.GetPixel(0, 0); // r - bone index // g - lineareyedepth(uv.z) // b - packed world normal // a - object id + 1 Color spDepth = Color.clear; spDepth.r = uv.x; spDepth.g = 1f - uv.y; spDepth.b = packedData.g; Vector2 screenPos = new Vector2(spDepth.r, spDepth.g); float depth = spDepth.b; Matrix4x4 proj = camera.projectionMatrix; Matrix4x4 cameraToWorld = camera.cameraToWorldMatrix; Vector2 p11_22 = new Vector2(proj.m00, proj.m11); Vector2 p13_31 = new Vector2(proj.m02, proj.m12); Vector2 xy = (screenPos * 2 - Vector2.one - p13_31); xy.x /= p11_22.x; xy.y /= p11_22.y; Vector3 pos_o = new Vector3(xy.x, xy.y, 1) * depth; pos_o.z *= -1; Vector3 wpos = cameraToWorld.MultiplyVector(pos_o) + camera.transform.position; normalRead = UnpackData(packedData.b) * 2 - Color.white; Vector3 normVector = new Vector3(normalRead.r, normalRead.g, normalRead.b); normVector.Normalize(); int objectID = Mathf.RoundToInt(packedData.a) - 1 - 1; hitInfo.position = wpos; hitInfo.normal = normVector; if (objectID >= 0 && objectID < visibleRegisteredRenderers.Count) { hitInfo.hittedRenderer = visibleRegisteredRenderers[objectID]; hitInfo.hittedTarget = targets[hitInfo.hittedRenderer]; } hitInfo.VertexIndex = (int)packedData.r; hitInfo.IsHitted = packedData.a > 1; return(hitInfo.IsHitted); }
public static bool RaycastToRegisteredTargetsFromMousePosition(Camera camera, out GPURaycastDecalsTargetInfo hitInfo) { return(RaycastToRegisteredTargets(camera, Input.mousePosition.x, Input.mousePosition.y, out hitInfo)); }
public static bool RaycastToRegisteredTargets(Camera camera, float pixelX, float pixelY, out GPURaycastDecalsTargetInfo hitInfo) { Vector2 uv = Vector2.zero; uv.x = pixelX / camera.pixelWidth; uv.y = pixelY / camera.pixelHeight; return(RaycastToRegisteredTargets(camera, uv, out hitInfo)); }