Shader深度图到底是怎么回事——UNITY HLSL语法之(零)搞几个例子和截图

本来想搞搞PBR,结果被海水拖了2个星期,还没搞好

PBR例子请看:(待完成)

深度图网上的例子都“很多",反正懂了就懂了,不懂的就很难懂,所以网上几乎没一个说清楚的

这里也没法说清楚,只是举几个例子,大家感受一一下

乐乐姐的例子

乐乐姐在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输出做什么用的
        else
            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

		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;
			};

			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);
            }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

avi9111

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值