Unity | Shader基础知识(第十三集:编写内置着色器阶段总结和表面着色器的补充介绍)

目录

前言

 一、表面着色器的补充介绍

二、案例viewDir详解

1.viewDir是什么

2.viewDir的作用

3.使用viewDir写shader


前言

注意观察的小伙伴会发现,这组教程前半部分我们在编写着色器的时候,用的是顶点着色器和片元着色器的组合。

SubShader
    {
            CGPROGRAM
            #pragma vertex vert      //顶点着色器
            #pragma fragment frag    //片元着色器
 
            #include"UnityCG.cginc"
 
            //顶点着色器方法
            appdata_base vert(appdata_base v)
            {
            return v;
            }
             
            //片元着色器方法
            float4 frag(appdata_base v):SV_TARGET
            {
            }
            ENDCG
    }

最近的两个教程,用的是表面着色器

    SubShader
    {
        CGPROGRAM
        #pragma surface surf Standard
        //给表面着色器配的输入结构体
        struct Input
        {

        }; 
        //表面着色器
        void surf (Input IN, inout SurfaceOutputStandard o)
        {

        }
        ENDCG
    }

以上就是内置着色器最常用的两种自定义组合。


如果你还发现了,表面着色器会比顶点着色器用起来简单一点。

unity官方也是这么说的:表面着色器是一种代码生成方法,与使用低级顶点/像素着色器程序顶点/像素着色器程序相比,可以更轻松地编写光照着色器。


 一、表面着色器的补充介绍

前面写的表面着色器,都是从Unity的资源里拿东西,然后直接输出出去,其实,表面着色器本身,也提供了一些可以让你取用的数据。

以下是官方说明,我知道你们可能看不懂,你们可以随便逛逛,现在知道有这么个东西先。

        struct Input
        {
            float3 viewDir      //包含视图方向,用于计算视差效果、边缘光照等等。
            具有 COLOR 语义的 float4 - 包含插值的每顶点颜色。
            float4 screenPos    //包含反射或屏幕空间效果的屏幕空间位置。请注意,这不适合 GrabPass;您需要使用 ComputeGrabScreenPos 函数自己计算自定义 UV。
            float3 worldPos     //包含世界空间位置。
            float3 worldRefl    //在_表面着色器不写入 o.Normal_ 的情况下,包含世界反射矢量。有关示例,请参阅反光漫射 (Reflect-Diffuse) 着色器。
            float3 worldNormal  // 在_表面着色器不写入 o.Normal_ 的情况下,包含世界法线矢量。
            float3 worldRefl;   // INTERNAL_DATA - 在_表面着色器写入 o.Normal_ 的情况下,包含世界反射矢量。要获得基于每像素法线贴图的反射矢量,请使用 WorldReflectionVector (IN, o.Normal)。有关示例,请参阅反光凹凸 (Reflect-Bumped) 着色器。
            float3 worldNormal; // INTERNAL_DATA - 在_表面着色器写入 o.Normal_ 的情况下,包含世界法线矢量。要获得基于每像素法线贴图的法线矢量,请使用 WorldNormalVector (IN, o.Normal)。
        };

这里需要学到的知识点是,不同于顶点着色器需要用语义去获取数据,表面着色器当你创建了对应的Input结构体,就可以直接获取到一些数据。当你看见写“包含”,就说明,你满足他的条件以后,这个数就是直接有数据的,如果没有条件,就是写在Input里就直接有数据。

二、案例viewDir详解

这次就讲一个viewDir,这个比较常用。

数学知识部分,我就直接略过,如果没太懂,到时候查阅这文章就可以了。

Unity | Shader基础知识番外(向量数学知识速成)_shader 叉乘-CSDN博客


1.viewDir是什么

viewDir的直接翻译是视图直线,可以暂时理解为射到人眼中的向量(如图1所示)。

图1 反射光线

 图中的小女孩,如果把眼睛转个方向,就看不见书本了。眼睛看见的那个方向的向量,就是视图viewDir。

2.viewDir的作用

如果我们想写一个球,你面对它的时候才能看见它的颜色,否则看不见。(如图2所示)

图2 只有面对我们才能看见的图
3.使用viewDir写shader

 viewDir是一个向量,当它和法线向量点乘时:

答案>0 在该点的正对面

答案=0 和该点成90度

答案<0 和该点大于90度(在这个情况下,一般就是看不见了)

Shader "Custom/009"
{
    Properties
    {
    //放图片进入
    _MainTex("MainTex",2D)="white"{} 
    }

    SubShader
    {

    CGPROGRAM
    #pragma surface surf Lambert

    sampler2D _MainTex;

    struct Input
    {
        float2 uv_MainTex;
        //直接获取viewDir
        float3 viewDir;
    };

    void surf(Input IN,inout SurfaceOutput o)
    {
                    //点乘在shader里的写法
        half dotp =dot(IN.viewDir,o.Normal);
                                               //如果大于0才会显示颜色,否则是黑色
        o.Albedo =tex2D(_MainTex,IN.uv_MainTex).rgb*dotp;
    }

    ENDCG
    }
}

三、作者的话

shader系列暂时告一段落,如果有粉丝宝宝问,我也会更新相关内容,有粉丝建议我更新Dotween动画讲解,后面应该会写这一方面。

大家有什么建议可以评论,可以发私信,我会根据大家的意见去更新文章,非常感谢大家的喜爱。

  • 10
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,您的第一个问题是关于Unity Shader的学习笔记,具体是在表面着色器中控制顶点变换。那么我可以回答您的问题。 在Unity中,表面着色器是一种用于控制物体表面外观的程序。它们可以控制颜色、纹理和光照等方面。而在表面着色器中,我们可以使用顶点变换来控制物体表面的外观。 顶点变换是一个将物体的顶点坐标从局部空间转换为世界空间或者相机空间的过程。在表面着色器中,我们可以通过在CG程序中编写代码来实现顶点变换。以下是一个简单的例子: ```CG // 定义变换矩阵 float4x4 worldMatrix; float4x4 viewMatrix; float4x4 projectionMatrix; // 定义输入结构体 struct appdata { float4 vertex : POSITION; }; // 定义输出结构体 struct v2f { float4 vertex : SV_POSITION; }; // 顶点变换函数 v2f vert (appdata v) { v2f o; o.vertex = mul(mul(mul(v.vertex, worldMatrix), viewMatrix), projectionMatrix); return o; } ``` 在这个例子中,我们定义了三个变换矩阵:世界矩阵、视图矩阵和投影矩阵。然后定义了一个输入结构体appdata,其中包含了顶点的位置信息。输出结构体v2f则只包含了顶点的位置信息,用于传递给像素着色器。 在vert函数中,我们首先将顶点从局部空间转换到世界空间,然后再从世界空间转换到相机空间,最后再从相机空间转换到屏幕空间。这个过程中使用了mul函数来进行矩阵乘法运算。 通过这样的方式,我们可以在表面着色器中控制顶点变换,从而实现对物体表面外观的控制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

菌菌巧乐兹

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

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

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

打赏作者

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

抵扣说明:

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

余额充值