簡體   English   中英

如何從渲染紋理獲取3D世界空間位置

[英]How to get 3D world space position from Render Texture

我正在使用“ 渲染紋理”制作“ 側面貼圖” ,它工作正常,並且已經通過這些步驟完成了工作。

  1. 一台主鏡頭渲染場景。
  2. NGUI Camera渲染GUI。
  3. 該GUI包含Render Texture(渲染貼圖)(微型貼圖),可使用GUI Camera在紋理上渲染場景。

但是,現在我想進一步改善地圖,並使其變得難以處理。 我想從“渲染紋理”點擊點獲得世界空間位置。 有什么方法可以從渲染紋理的特定點擊點獲得世界空間位置?

如果單擊渲染紋理中的某個位置,那么如何獲得3D世界空間中的點。

例如:我在“渲染紋理”上單擊了汽車對象。 現在,如何在3D世界空間中突出顯示或獲取它? 如何將2D渲染紋理單擊位置轉換為世界空間位置!

這假設了一些事情。

首先,我使用EventSystems獲得鼠標點擊。 這不是必需的,可以輕松更改(由^^更改)。 要正確設置它,您的場景中需要一個EventSystem (如果您有UI,則可能已經有一個)。

其次,您需要將PhysicsRaycaster組件連接到主攝像機(播放器可以看到的攝像機)。

最后,在包含渲染紋理渲染器(我使用簡單的四邊形)的GameObject上,應用以下腳本並分配相應的攝像機。

using UnityEngine;
using UnityEngine.EventSystems;

//i chose box collider because its cheap
[RequireComponent(typeof(BoxCollider))]
public class RenderTextureRaycaster : MonoBehaviour, IPointerDownHandler {

    //assign in inspector
    public Camera portalExit;

    BoxCollider portal;
    Vector3 portalExitSize;

    void Start() {
        portal = GetComponent<BoxCollider>();
        //this is the target camera resolution, idk if there is another way to get it.
        portalExitSize = new Vector3(portalExit.targetTexture.width, portalExit.targetTexture.height, 0);
    }

    public void OnPointerDown(PointerEventData eventData) {
        //the click in world space
        Vector3 worldClick = eventData.pointerCurrentRaycast.worldPosition;
        //transformed into local space
        Vector3 localClick = transform.InverseTransformPoint(worldClick);
        //since the origin of the collider is in its center, we need to offset it by half its size to get it realtive to bottom left
        Vector3 textureClick = localClick + portal.size / 2;
        //now we scale it up by the actual texture size which equals to the "camera resoution"
        Vector3 rayOriginInCameraSpace = Vector3.Scale(textureClick, portalExitSize);

        //with this knowledge we can creata a ray.
        Ray portaledRay = portalExit.ScreenPointToRay(rayOriginInCameraSpace );
        RaycastHit raycastHit;

        //and cast it.
        if (Physics.Raycast(portaledRay, out raycastHit)) {
            Debug.DrawLine(portaledRay.origin, raycastHit.point, Color.blue, 4);
        }
        else {
            Debug.DrawRay(portaledRay.origin, portaledRay.direction * 100, Color.red, 4);
        }
    }
}

編輯:上面也許有點冗長,如果您喜歡一個襯板,可以輕松地減少它,它只是為了顯示它是如何工作的。 還請僅將此視為概念證明,未經徹底測試

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM