Unity Shader片段着色器使用基础详解

Unity Shader片段着色器使用基础详解

Unity中的Shader(着色器)用于控制游戏对象的渲染方式,让它们变得更加美观、细致。Shader分为顶点着色器和片段着色器,这篇攻略主要介绍Unity中片段着色器的使用基础,可以帮助开发者更加细致地控制对象的渲染方式。

Shader基础知识

在进入片段着色器的详细使用说明前,我们先来了解一些Shader的基础知识:

  • Shader程序:Shader程序是一个小型程序,它可以用来控制材质表面的渲染效果。在Unity中,Shader是由着色器语言编写的,可以用许多内置的和自定义的函数来描述。

  • ShaderLab语言:这是Unity的一种语言,它用于描述材质、纹理、渲染队列、某个材质的Shader和其它属性。它是一种易于阅读和编写的语言,并且易于维护。

  • Uniform变量:这种变量是可编程的,它的值可以被修改,而且在绘制物体时,它是不一样的,又称之为上传的变量。比如说,全局变量或者纹理。

有了以上的基础知识,我们就可以更好地理解Unity中片段着色器的使用方法。

片段着色器

片段着色器是一种Shader编程技巧,它用于描述一个像素的颜色和属性。它们的作用体现在单个像素上,包括光照模型、着色、透明度、阴影、反射和折射等效果。

片段着色器样例1

下面是一个Unity中片段着色器的基础代码:

Shader "Custom/MyFragmentShader" {
Properties {
    _MainTex ("Texture", 2D) = "white" {}
    _Color ("Color", Color) = (1,1,1,1)
}
SubShader {
    Tags {"Queue"="Transparent" "RenderType"="Opaque"}
    LOD 100

    Pass {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        struct appdata {
            float4 vertex : POSITION;
            float2 uv : TEXCOORD0;
        };
        struct v2f {
            float2 uv : TEXCOORD0;
            float4 vertex : SV_POSITION;
        };

        sampler2D _MainTex;
        float4 _MainTex_ST;
        fixed4 _Color;

        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 {
            fixed4 col = tex2D(_MainTex, i.uv) * _Color;
            col.a = _Color.a * col.a;
            return col;
        }
        ENDCG
    }
}

在这个例子中,我们定义了一个名为“ Custom/MyFragmentShader”的着色器。在Properties区块中,我们定义了_MainTex(主纹理)和_Color(颜色)两个Uniform属性,同时它们的默认值分别为白色和纯白色。

在SubShader区块中,我们通过Tags指令定义了它们的渲染顺序和类型,并且设置了LOD(LOD表示level of details)

在内部的Pass语句中,我们定义了一个传递着色器的CGPROGRAM块,在这里我们定义了一个输入参数appdata和一个输出参数v2f。

vert函数定义了输入参数v并输出了v的顶点着色阶段的处理结果,同时重映射了_MainTex的uv坐标到图像的正确位置。固定函数TEXCOORD0包含了uv坐标, float4类型包含64位浮点数,表示精度很高的浮点坐标。

frag`函数定义了输入参数i并输出了颜色。在这个函数中,我们首先获取_MainTex的颜色,然后将它与颜色变量_Color进行乘法运算,最后将颜色的Alpha通道值设置为变量_Color的Alpha值,最终返回这个颜色值。

这么一看,Unity中的片段着色器相比OpenGL,其着色代码相对比较简单易用。

片段着色器样例2

现在,我们来看一个更复杂一点的例子。这个例子中,我们要使用屏幕空间反射技术让我们的地面反射画面中的物体。

Shader "Custom/ShaderExample" {
Properties {
    [HDR] _ReflColor ("Reflection Color", Color) = (1, 1, 1, 1)
    _DiffuseColor ("Diffuse Color", Color) = (1, 1, 1, 1)
    _MainTex ("Base (RGB)", 2D) = "white" {}
}

SubShader {
    Tags { "RenderType"="Opaque" }
    CGPROGRAM
    #pragma surface surf Standard

    struct Input {
        float2 uv_MainTex; 
    };

    half4 _ReflColor;
    half4 _DiffuseColor;
    sampler2D _MainTex;
    float4 _MainTex_ST;

    void surf (Input IN, inout SurfaceOutputStandard o) 
    {
        o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb * _DiffuseColor.rgb;
        o.Metallic = 0.5;
        o.Smoothness = 0.5;
        o.Normal = float3(0,0,1);
        o.Emission = _ReflColor.rgb * tex2D(_MainTex, reflect(IN.uv_MainTex, o.Normal)).rgb;
        o.Alpha = 1;
    }
    ENDCG
} 
FallBack "Diffuse"

在这个例子中,我们定义了一个名为“ Custom/ShaderExample”的着色器。在Properties区块中,我们定义了三个Uniform属性:_ReflColor_DiffuseColor的颜色属性以及_MainTex的主纹理属性。

在SubShader区块中,我们通过Tags指令定义这个着色器的渲染类型为不透明的。在此后的CGPROGRAM块中,我们使用了 #pragma surface surf Standard 指令来使用Standard Shader Surface Functions。

这里的函数 surf(Input IN, inout SurfaceOutputStandard o)用于将输入的Mesh顶点所对应的表面输出为SurfaceOutputStandard的实例化对象,后续的混合、渲染、反射和折射拆分都是在o的实例上操作。

在这个例子中,我们使用了反射矩阵传入INPUT并用其获取屏幕空间反射的纹理坐标来改变当前表面的反射色。我们通过纹理采样方式tex2D把纹理坐标的颜色值结合DiffusColor和Diffuse纹理纹理颜色进行混合。

Shader的局限性

使用Unity内置的Shader是可以在游戏中实现很多复杂效果的。但是,由于Shader编程需要对OpenGL或Metal等底层渲染API有一定的了解,所以它对于新手来说可能有些陌生。同时,由于Shader的执行是在GPU上完成的,所以在某些情况下,Shader的执行会占用大量的系统资源,从而降低游戏的帧率。

另外,对于非高端设备的手机来说,也可能会出现一些兼容性问题,特别是一些老旧的手机。因此,在制作游戏时,我们需要对不同的设备进行适当的优化。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Unity Shader片段着色器使用基础详解 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • ASP.NET Core的日志系统介绍

    ASP.NET Core的日志系统介绍 在本攻略中,我们将详细讲解ASP.NET Core的日志系统,并提供两个示例说明。 日志系统简介 ASP.NET Core的日志系统是一个灵活、可扩展的日志框架,可以记录应用程序的运行状态和错误信息。它支持多种日志提供程序,包括控制台、文件、数据库等,可以根据应用程序的需求进行配置和扩展。 日志系统的使用 在ASP.N…

    C# 2023年5月16日
    00
  • asp.net Forms身份验证和基于角色的权限访问

    ASP.NET Forms身份验证是一种通过验证用户的凭据来确保用户身份的机制,它可以让我们得知当前访问网站的用户是谁。ASP.NET 基于角色的访问控制则是用于控制网站的权限管理,即按照用户的角色来限制他们在网站上的操作。 下面我们将详细介绍如何使用ASP.NET Forms身份验证和基于角色的权限访问来管理网站的权限。 步骤1:配置Web.config …

    C# 2023年5月31日
    00
  • C#中设计、使用Fluent API

    设计和使用Fluent API是C#的一个非常重要的特性,它可以极大地提升我们代码的可读性和可维护性。在本篇文章中,我将为大家详细讲解如何在C#中设计和使用Fluent API,并提供两个示例说明。 Fluent API是什么 Fluent API是一种使用方法链的API设计风格,它允许我们编写从上到下的代码,使得我们的逻辑更易于理解和调整。 与传统的API…

    C# 2023年6月7日
    00
  • C#面向对象设计原则之组合/聚合复用原则

    C#面向对象设计原则之组合/聚合复用原则,也称为“C#复合复用原则”,指在一个类中,通过组合或聚合其他类来实现代码的复用和拓展。使用该设计原则可以提高代码的维护性、重用性和可读性。 具体实现该原则的步骤如下: 步骤一:定义一个包含其他类的类(即被组合/聚合的类) 在定义一个类时,可以包含其他的类对象。这些类对象可以通过组合或聚合方式嵌入进来。组合和聚合的主要…

    C# 2023年6月1日
    00
  • C++ 封装 DLL 供 C# 调用详细介绍

    C++封装DLL供C#调用是一种常见的跨语言调用方式,它的主要思想是将C++中的库函数封装成一个动态链接库(DLL),供C#或其他语言调用。下面我会详细介绍如何实现这一过程。 1. 创建一个C++动态链接库 首先,我们需要创建一个C++动态链接库项目。在Visual Studio中,可以通过File->New->Project,然后选择Win32…

    C# 2023年6月7日
    00
  • 基于asp.net实现图片在线上传并在线裁剪功能

    下面是基于asp.net实现图片在线上传并在线裁剪功能的完整攻略: 1. 确定上传插件 为了实现在线上传图片,我们需要选择一个合适的上传插件。目前市场上比较流行的上传插件有uploadify和plupload,我们可以根据需求自行选择。 在这里,我以uploadify为例进行说明。 2. 实现图片上传 需先引入jquery、uploadify相关的js和cs…

    C# 2023年5月31日
    00
  • ASP.NET MVC把数据库中枚举项的数字转换成文字

    以下是“ASP.NET MVC把数据库中枚举项的数字转换成文字”的完整攻略: 什么是枚举 枚举是一种特殊的数据类型,它定义了一组命名的常量。在.NET MVC中,枚举通常用于表示状态、类型等。 ASP.NET MVC把数据库中枚举项的数字转换成文字的过程 以下ASP.NET MVC把数据库中枚举项的数字转换成文字的详细过程: 步骤1:定义枚举 首先,我们需要…

    C# 2023年5月12日
    00
  • 用C#破解Chrome浏览器cookie值

    背景 最近小编接到一个获取网站请求数据的需求,要求抓取网站某个页面请求的数据。我使用Google Chrome浏览器查看了一下请求链接的传入参数,发现需要传入一个Token值才能获取数据。于是我在Chrome中登录后,通过Postman请求成功,并将Token存储到了Cookie中。然而问题又来了,在代码层面如何获取这个Token呢? 解决方案 小编在网上查…

    C# 2023年4月24日
    00
合作推广
合作推广
分享本页
返回顶部