Unity3d 如何仅渲染特定点半径内的对象?

Unity3d 如何仅渲染特定点半径内的对象?,unity3d,mobile,Unity3d,Mobile,我希望我的相机只渲染特定点半径内的对象,该点与相机的位置无关,因此我应该能够在我的世界的这一部分飞行。作为游戏的一部分,该中心点将发生变化 我还希望alpha边缘融合,而不是立即结束(这将是一款手机增强现实游戏) 有没有现成的技术可以做到这一点?可能是一个着色器或什么的?我对这个问题进行了研究,并想出了一些办法。我刚刚注意到这个问题还在这里,所以我想我会分享解决方案 将以下脚本添加到相机中 using UnityEngine; [ExecuteInEditMode] [RequireCompo

我希望我的相机只渲染特定点半径内的对象,该点与相机的位置无关,因此我应该能够在我的世界的这一部分飞行。作为游戏的一部分,该中心点将发生变化

我还希望alpha边缘融合,而不是立即结束(这将是一款手机增强现实游戏)


有没有现成的技术可以做到这一点?可能是一个着色器或什么的?

我对这个问题进行了研究,并想出了一些办法。我刚刚注意到这个问题还在这里,所以我想我会分享解决方案

将以下脚本添加到相机中

using UnityEngine;

[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
public class UniverseSubSection : MonoBehaviour
{
    public Shader shader;
    [Header("Center of the universe")]
    public Vector3 fixedCenterOfUniverse;
    public Transform objectAtCenterOfUniverse;
    [Header("Universe configuration")]
    public float universeRadius = 2f;
    public float featheringRadius = 1f;
    public Color chromaKey = new Color(0, 1, 0, 0.618f);
    public bool clipBelowGround = true;
    [Header("Background")]
    public Texture backgroundTexture;
    public MonoBehaviour backgroundTextureProvider;

    Material material;
    new Camera camera;

    void Update()
    {
        GetComponent<Camera>().depthTextureMode = DepthTextureMode.Depth;
    }

    void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (material == null)
        {
            material = new Material(shader);
            material.hideFlags = HideFlags.DontSave;
            camera = GetComponent<Camera>();
            camera.backgroundColor = chromaKey;
        }

        material.SetFloat("_UniverseRadius", universeRadius);
        material.SetFloat("_FeatheringRadius", featheringRadius);
        material.SetColor("_ChromaKey", chromaKey);
        material.SetInt("_ClipBelowGround", clipBelowGround ? 1 : 0);

        var matrix = camera.cameraToWorldMatrix;
        material.SetMatrix("_InverseView", matrix);

        Vector3 centerPosition = objectAtCenterOfUniverse != null ? objectAtCenterOfUniverse.position : fixedCenterOfUniverse;
        material.SetVector("_CenterOfUniverse", centerPosition);

        Texture background = null;
        if (backgroundTexture != null)
            background = backgroundTexture;
        else if (Application.isPlaying && backgroundTextureProvider != null)
        {
            var provider = backgroundTextureProvider as IBackgroundTextureProvider;
            Debug.Assert(provider != null, "BackgroundTextureProvider needs to be an IBackgroundTextureProvider");
            background = provider.GetBackgroundTexture();
        }
        material.SetTexture("_BackgroundTex", background);

        Graphics.Blit(source, destination, material);
    }

    public interface IBackgroundTextureProvider
    {
        Texture GetBackgroundTexture();
    }
}
如果希望用网络摄像头图像填充背景,也可以添加此组件并在
backgroundTextureProvider
属性中引用它

using UnityEngine;

public class WebCamBackgroundTextureProvider : MonoBehaviour, UniverseSubSection.IBackgroundTextureProvider
{
    WebCamTexture texture;

    public Texture GetBackgroundTexture()
    {
        return texture;
    }

    // Use this for initialization
    void Start()
    {
        if (WebCamTexture.devices.Length > 0)
        {
            texture = new WebCamTexture(WebCamTexture.devices[0].name);
            texture.Play();
        }
    }

    private void OnDestroy()
    {
        if (texture != null)
            texture.Stop();
    }
}

我对这个问题进行了研究,并想出了一些办法。我刚刚注意到这个问题还在这里,所以我想我会分享解决方案

将以下脚本添加到相机中

using UnityEngine;

[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
public class UniverseSubSection : MonoBehaviour
{
    public Shader shader;
    [Header("Center of the universe")]
    public Vector3 fixedCenterOfUniverse;
    public Transform objectAtCenterOfUniverse;
    [Header("Universe configuration")]
    public float universeRadius = 2f;
    public float featheringRadius = 1f;
    public Color chromaKey = new Color(0, 1, 0, 0.618f);
    public bool clipBelowGround = true;
    [Header("Background")]
    public Texture backgroundTexture;
    public MonoBehaviour backgroundTextureProvider;

    Material material;
    new Camera camera;

    void Update()
    {
        GetComponent<Camera>().depthTextureMode = DepthTextureMode.Depth;
    }

    void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (material == null)
        {
            material = new Material(shader);
            material.hideFlags = HideFlags.DontSave;
            camera = GetComponent<Camera>();
            camera.backgroundColor = chromaKey;
        }

        material.SetFloat("_UniverseRadius", universeRadius);
        material.SetFloat("_FeatheringRadius", featheringRadius);
        material.SetColor("_ChromaKey", chromaKey);
        material.SetInt("_ClipBelowGround", clipBelowGround ? 1 : 0);

        var matrix = camera.cameraToWorldMatrix;
        material.SetMatrix("_InverseView", matrix);

        Vector3 centerPosition = objectAtCenterOfUniverse != null ? objectAtCenterOfUniverse.position : fixedCenterOfUniverse;
        material.SetVector("_CenterOfUniverse", centerPosition);

        Texture background = null;
        if (backgroundTexture != null)
            background = backgroundTexture;
        else if (Application.isPlaying && backgroundTextureProvider != null)
        {
            var provider = backgroundTextureProvider as IBackgroundTextureProvider;
            Debug.Assert(provider != null, "BackgroundTextureProvider needs to be an IBackgroundTextureProvider");
            background = provider.GetBackgroundTexture();
        }
        material.SetTexture("_BackgroundTex", background);

        Graphics.Blit(source, destination, material);
    }

    public interface IBackgroundTextureProvider
    {
        Texture GetBackgroundTexture();
    }
}
如果希望用网络摄像头图像填充背景,也可以添加此组件并在
backgroundTextureProvider
属性中引用它

using UnityEngine;

public class WebCamBackgroundTextureProvider : MonoBehaviour, UniverseSubSection.IBackgroundTextureProvider
{
    WebCamTexture texture;

    public Texture GetBackgroundTexture()
    {
        return texture;
    }

    // Use this for initialization
    void Start()
    {
        if (WebCamTexture.devices.Length > 0)
        {
            texture = new WebCamTexture(WebCamTexture.devices[0].name);
            texture.Play();
        }
    }

    private void OnDestroy()
    {
        if (texture != null)
            texture.Stop();
    }
}

统一是无形的,也是可见的。。它只在摄影机看到对象时调用。。。但我认为它需要改进,这不是我想要的。该点与相机无关,我只想渲染世界的一个子集,任意点X半径范围内的所有内容。所以只需获取点周围任何对象中的所有渲染组件。。。。和禁用/启用组件。对吗?统一开始变得不可见,开始变得可见。。它只在摄影机看到对象时调用。。。但我认为它需要改进,这不是我想要的。该点与相机无关,我只想渲染世界的一个子集,任意点X半径范围内的所有内容。所以只需获取点周围任何对象中的所有渲染组件。。。。和禁用/启用组件。正确的??