c# - 关于 Unity 上多个渲染目标的渲染行为的问题。还是Shader的问题?
问题描述
我尝试在 Unity 中使用多个渲染目标来获取通用渲染图像、深度图像和 Id(为每种材质预先分配)图像。
首先,看这张图。
RenderTexture
多个渲染目标的输出分配在三个垂直堆叠的框中。从下方,分配了渲染图像、深度图像和 Id 图像。
我希望深度和 id 图像只在盒子所在的地方着色。但是,我遇到了前一帧的颜色仍然存在的问题。我认为这是 z 缓冲区的问题,但我无法解决。
这是github 上的示例存储库。
着色器代码
Shader "Custom/MRT"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Id ("Id", float) = 0.5
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float depth : TEXCOORD1;
};
struct buffer {
float4 buf1 : SV_Target0;
float4 buf2 : SV_Target1;
float4 buf3 : SV_Target2;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Id;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
COMPUTE_EYEDEPTH(o.depth.x);
o.depth *= _ProjectionParams.w;
//for debug visualizing
o.depth *= -1;
o.depth += 1;
//end debug
return o;
}
buffer frag (v2f i)
{
buffer o;
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
o.buf1 = col;
o.buf2 = float4(i.depth.x, 0, 0, 1);
o.buf3 = float4(0, _Id, 0, 1);
return o;
}
ENDCG
}
}
}
C# 代码
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class MRTCamera : MonoBehaviour
{
public GameObject Template;
public Material StandardMaterial;
public Shader MrtShader;
private Camera _camera;
private RenderTexture[] _renderTextureArray;
private RenderBuffer[] _colorBuffers;
private RenderTexture _depthBuffer;
void Start()
{
_camera = GetComponent<Camera>();
_camera.enabled = false;
_renderTextureArray = new RenderTexture[3]
{
new RenderTexture(640,480, 0, RenderTextureFormat.Default),
new RenderTexture(640,480, 0, RenderTextureFormat.Default),
new RenderTexture(640,480, 0, RenderTextureFormat.Default),
};
_renderTextureArray[0].Create();
_renderTextureArray[1].Create();
_renderTextureArray[2].Create();
_colorBuffers = new RenderBuffer[]{ _renderTextureArray[0].colorBuffer, _renderTextureArray[1].colorBuffer, _renderTextureArray[2].colorBuffer };
_depthBuffer = new RenderTexture(640, 480, 24, RenderTextureFormat.Depth);
_depthBuffer.Create();
var o1 = Instantiate(Template, new Vector3(0, 2, 0), Quaternion.identity);
o1.GetComponent<Renderer>().material = new Material(StandardMaterial) { mainTexture = _renderTextureArray[0] };
var o2 = Instantiate(Template, new Vector3(0, 3, 0), Quaternion.identity);
o2.GetComponent<Renderer>().material = new Material(StandardMaterial) { mainTexture = _renderTextureArray[1] };
var o3 = Instantiate(Template, new Vector3(0, 4, 0), Quaternion.identity);
o3.GetComponent<Renderer>().material = new Material(StandardMaterial) { mainTexture = _renderTextureArray[2] };
}
void Update()
{
_camera.SetTargetBuffers(this._colorBuffers, this._depthBuffer.depthBuffer);
_camera.RenderWithShader(MrtShader, "");
}
void OnDestroy()
{
_renderTextureArray[0].Release();
_renderTextureArray[1].Release();
_renderTextureArray[2].Release();
_depthBuffer.Release();
}
}
解决方案
推荐阅读
- postgresql - 如何在 POSTGRESQL 服务器中对具有 TLS 配置的用户使用基于 SCRAM-SHA-256 的身份验证?
- ontology - virtuoso 7.x 中的推理
- react-native - 禁用按钮的可访问性 - React Native
- netsuite - 如果客户余额发生更改,NetSuite 不会更新上次修改日期
- javascript - 如何 JSON.parse 数组数组
- http - 使http无状态背后的原因
- r - 如何更改图标
- java - Eclipse - 将 JAR 导入项目
- powerapps - 是否可以进行多阶段工作表格和审批?
- python - 为每次运行代码设置不同的种子