示例#1
0
 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;
 }
示例#2
0
        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);
        }
示例#3
0
 public static bool RaycastToRegisteredTargetsFromMousePosition(Camera camera, out GPURaycastDecalsTargetInfo hitInfo)
 {
     return(RaycastToRegisteredTargets(camera, Input.mousePosition.x, Input.mousePosition.y, out hitInfo));
 }
示例#4
0
        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));
        }