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