乐乐姐在15年写下了深度图的实现,但当时乐乐姐只是一个大学生,所分享的代码和工具比较复杂(有点不太工业化)
乐乐姐的例子主要是通过镜头的后期效果,显示深度图
但确,不可避免的避免的牵涉到很多核心技术,例如
-
镜头后制
-
GPU渲染
-
镜头参数设置
-
后期效果基类和扩展
听不明白是吧?直接看例子
//C#代码,关键是:void OnRenderImage(RenderTexture src, RenderTexture des)
/// <summary>
/// h海水深度图,必须用到的类,一般挂载到镜头下
/// </summary>
[ExecuteInEditMode]
public class RenderDepthMap : MonoBehaviour
[Header("可以留空")]
public Material mat;
// Use this for initialization
void Start()
//Camera.main.depthTextureMode = DepthTextureMode.Depth;
void OnEnable()
Camera.main.depthTextureMode = DepthTextureMode.Depth;
void OnRenderImage(RenderTexture src, RenderTexture des)
if(mat!=null)
Graphics.Blit(src, des, mat);//官方这么说,但也不知道这个 mat输出做什么用的
Graphics.Blit(src, des);//这么写就可以了(配置seawater shader etc.)
//Shader完整代码
created by chenjd
http://www.cnblogs.com/murongxiaopifu/
Shader "chenjd/RenderDepthMapShader"
Properties
_MainTex ("Texture", 2D) = "white" {}
SubShader
Tags { "RenderType"="Opaque" }
LOD 100
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;
sampler2D _MainTex;
sampler2D _CameraDepthTexture;
float4 _MainTex_ST;
v2f vert (appdata v)
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
fixed4 frag (v2f i) : SV_Target
float depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, i.uv));
float linear01Depth = Linear01Depth(depth);
return linear01Depth;
ENDCG
没作用,不显示,无法渲染
什么?你用了没效果??
乐乐姐怎么有效果?网上大牛怎么又效果?就你没效果?
又因为你没有调用linear01方法,没对输出值进行处理,所以深度图渲染的效果不明显
linear01原理我也没搞懂
但你Y就是没做转换前的范围就是(0,0.5)
第一,就是官方给你一个控件,默认透明度是0.5的(最大),透明度是0还占大多数,你能看见有鬼了
再来,叔叔我碰到的问题就是自定Unlit的Shader,要写上lightmode==shadowcast才能被官方正确绘制到深度图中
第三,就是表面shader的物体能被绘制,builtin设置不明
网上搜lightmode,最多就是灯光如何设置如何渲染等(可见程序大牛不喜欢分享,美术大牛乱分享)
暂时发现的lightmode如下,具体说明嘛...........................一般写在Pass里面
Pass {
19: Tags { "LightMode" = "Vertex" }
Pass {
19 Name "FORWARD"
20: Tags { "LightMode" = "ForwardBase" }
Pass {
46 Name "ShadowCaster"
47: Tags { "LightMode" = "ShadowCaster" }
解决方法,也就是说
要物体被深度图渲染,ShadowCast必须再写一个
Pass {
Name "ShadowCaster"
Tags { "LightMode" = "ShadowCaster" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#include "UnityCG.cginc"
#include "TerrainEngine.cginc"
struct v2f {
V2F_SHADOW_CASTER;
UNITY_VERTEX_OUTPUT_STEREO
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
fixed4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
v2f vert( appdata v )
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
TerrainAnimateTree(v.vertex, v.color.w);
TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
return o;
float4 frag( v2f i ) : SV_Target
SHADOW_CASTER_FRAGMENT(i)
ENDCG
如果用表面Shader,如何能关闭ShdowCast Pass呢
终于搞明白ViewNormal
一直搞不明白这是什么东西
我们知道normal, uv, vertex等
viewNormal其实就相当于物理相对于镜头的法线(而不是物体本身法线,又或者世界坐标的向量)
其实要是能输出或者打印就好理解很多
一个输出viewNormal的例子:
v2f vert (appdata v)
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.viewNormal = COMPUTE_VIEW_NORMAL;
return o;
float4 frag (v2f i) : SV_Target
return float4(i.viewNormal, 0);
本来想搞搞PBR,结果被海水拖了2个星期,还没搞好PBR例子请看:(待完成)深度图网上的例子都“很多",反正懂了就懂了,不懂的就很难懂,所以网上几乎没一个说清楚的这里也没法说清楚,只是举几个例子,大家感受一一下乐乐姐的例子乐乐姐在15年写下了深度图的实现,但当时乐乐姐只是一个大学生,所分享的代码和工具比较复杂(有点不太工业化)乐乐姐的例子主要是通过镜头的后期效果,显示深度图但确,不可避免的避免的牵涉到很多核心技术,例如镜头后制 GPU渲染 镜头参数设置 后期效果基类和扩
1.开启深度
GetComponent&lt;Camera&gt;().depthTextureMode = DepthTextureMode.Depth; //开启摄像机深度mode
2._CameraDepthTexture
存储深度信息的Tex,需要在Shader中声明;
sampler2D _CameraDepthTexture;
3.ZBuffer (只有ShaderTag是...
float4 GetWorldSpacePosByDepth(float depth, float2 uv, float4x4 IVP)
#if defined(UNITY_REVERSED_Z)
depth = 1- depth;
#endif
学了12年英文,可能你还是不会说,唯一的方法就是去一个全英语的环境,那么你一个月的英语水平提高的速度将绝对比你学12年还快,什么时候去最好?怎么才能准备好,答案是,根本不用准备,而且越快越好!
最近归纳了一下,Shader有几个重点:
Unity做了“”一些“”改版,并不是原生Shader
Shader是一门程序语言
Shader并没有专门的编辑器和Debugger,
Shader是用来控制GPU渲染的
针对以上几点,重点说说:
第一点:Shader被改的乱七八炸,这有点废话,虚幻不改,.
书上关于阴影部分虽然篇幅不多,但实际上有非常多的内容,尤其是相当多的宏与函数,而且官方文档也少得可怜,再翻下一章之前,我决定把这些用到的宏能弄明白的先弄明白,要不然就像狗熊掰棒子一样什么都落不下,在后续的博客中记录一下,当做笔记,如果有哪里说得有错误,还望批评指正。
再
UnityCG.cginc中可以找到TRANSFER_SHADOW_CASTER_NORMALOFFSET唯一的一处定义
本文只是对深度的一些整理和个人理解,基于Unity URP, shader用shader graph 或者HLSL,build-in自行根据对照表更改
1.Eye Depth(观察空间)
Eye Depth是物体相对于摄像机所在平面的距离,因为是相对,所以Z是相反的,Eye Depth的0就是摄像机,1就是一个单位,10就是10个单位,所以有的人会把他称为“World” space Depth,这个depth在所有平台上都是一样的,而且不区分正交透视,因为他在投影之前。在shader graph 中如.
深度纹理实际就是一张渲染纹理,只不过它里面存储的像素值不是颜色值,而是一个高精度的深度值。由于被存储在一张纹理中,深度纹理里的深度值范围是[0, 1],而且通常是非线性分布的。这些深度值来自于顶点变换后得到的归一化的设备坐标(NDC)。
回顾一下,一个模型要想最终被绘制在屏幕上,需要把它的顶点从模型空间变换到齐次裁剪坐标系下,这是通过在顶点着色器中乘以MVP变换矩阵得到的。在变换的最后一步,我们需要使用一个投影矩阵来变换顶点,当我们使用的是透视投影类型的摄像机时,这个投影矩阵就是非线性的,而正交投
今天介绍一下深度图像的获取方法主要有哪些,以及这些方法会导致深度图像中存在什么样的问题。
在计算机视觉系统中,三维场景信息为图像分割、目标检测、物体跟踪等各类计算机视觉应用提供了更多的可能性,而深度图像(Depth map)作为一种普遍的三维场景信息表达方式得到了广泛的应用。深度图像的每个像素点的灰度值可用于表征场景中某一点距离摄像机的远近。
获取深度图像的方法可以分为两类:被动测距传感和主动深度
UnityCG.cginc中原函数如下:
// Z buffer to linear 0..1 depth (0 at eye, 1 at far plane)
inline float Linear01Depth( float z )
return 1.0 / (_ZBufferParams.x * z + _ZBufferParams.y);
// Z buffer to l
转载自 冯乐乐的 《Unity Shader 入门精要》
获取深度和法线纹理
虽然在Unity里获取深度和法线纹理的代码非常简单,但是我们有必要在这之前首先了解它们背后的实现原理。
深度纹理实际上就是一张渲染纹理,只不过它里面存储的像素值不是颜色值而是一个高精度的深度值。由于被存储在一张纹理中,深度纹理里的深度值范围是[0,1],而且通常是非线性分布的。那么,这些深度值是从哪里得到的呢?总体
Unity Shader热力图点位主要是用来表示一个场景中不同区域的热度或密度分布情况。热力图通常用不同的颜色和亮度来表示不同的数值或密度,使得观察者可以直观地看出场景中的热点和热度变化。
实现这个效果的方法是通过在Unity的Shader编程中使用纹理来进行热力图的贴图。首先,我们需要创建一个二维纹理来存储热力图的数据。可以使用Render Texture或者从外部文件中加载纹理来获取热力图的数据,这取决于具体的需求。
接下来,我们需要在Shader中使用这个热力图纹理来给物体进行颜色的渲染。在Shader中,我们可以使用带有UV坐标的采样函数来获取纹理上对应位置的像素颜色值。根据像素的数值或密度,我们可以在Shader中定义一系列的颜色变换规则来决定物体表面的颜色和亮度。
为了达到热力图效果,我们可以使用一组不同颜色的渐变,将纹理上的像素数值或密度映射到对应的颜色上。比如,我们可以使用一组不同亮度的蓝色来表示冷区域,一组不同亮度的绿色来表示温和区域,一组不同亮度的红色来表示热区域。根据实际需求,我们也可以定义更多的颜色渐变来表示不同的热度级别。
最后,使用Shader的时候,我们可以将热力图纹理作为材质的一个属性输入,在渲染场景之前将热力图数据赋给这个属性。当不同物体的Shader使用了相同的热力图纹理时,它们将会按照热力图的数值或密度来进行着色,从而展现出整个场景的热力图效果。
总的来说,Unity Shader热力图点位是通过在Shader中使用纹理和颜色映射来实现场景中不同区域热度或密度分布的可视化效果。这种技术可以用于各种领域,如数据可视化、游戏开发等。
[/code]
会发现打印出来的当前Event的类型是used,这是因为Event被Button控件消耗了,但是仍可以访问Event.current.button来获取当前按下的鼠标按键,因此下面的代码可以实现对控件的右键点击的判定:
[code=csharp]
if(GUI.Button("Test"))
if(Event.current.button == 1)
Debug.log("Right click on button!")
[/code]