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日

相关文章

  • c#实现服务器性能监控并发送邮件保存日志

    下面就详细讲解“c#实现服务器性能监控并发送邮件保存日志”的完整攻略。 简介 在任何一个需要稳定运行的系统中,服务器的性能监控是非常关键的。我们需要通过服务器性能监控,来检测服务器是否在正常工作,并且在服务器发生异常性能的时候,及时发送邮件通知管理员。本文将介绍如何使用C#来实现服务器性能监控并发送邮件保存日志。 实现方法 以下是实现服务器性能监控并发送邮件…

    C# 2023年6月1日
    00
  • .NET从优酷专辑中采集所有视频及信息(VB.NET代码)

    为了采集优酷专辑中的视频及信息,我们需要进行以下步骤: 分析优酷专辑页面 首先,我们需要分析优酷专辑页面的源代码,确定需要采集的信息所在的位置。可以使用Chrome的开发者工具,通过查看页面源代码和网络请求来确定: 打开Chrome开发者工具(快捷键:F12)。 进入优酷专辑页面,并切换到“Elements”选项卡。 在页面中找到需要采集的信息(比如视频标题…

    C# 2023年5月31日
    00
  • C#计算程序执行过程花费时间的方法

    一、通过System.Diagnostics.Stopwatch类获取程序执行过程花费时间 引用命名空间System.Diagnostics。 创建Stopwatch实例。 使用Start()方法启动计时器。 执行需要计时的代码逻辑。 使用Stop()方法停止计时器。 使用ElapsedMilliseconds属性获取程序执行的毫秒数。 示例一: using…

    C# 2023年6月1日
    00
  • 如何利用FluentMigrator实现数据库迁移

    如何利用FluentMigrator实现数据库迁移 FluentMigrator 是一个用于 .NET 平台下的数据库迁移工具。它的主要目标是让数据迁移变得容易和明显。它提供了一套基于 Fluent Syntax 的 API,可让您定义和记录迁移的状态和方法。 FluentMigrator 可以通过不同的目标数据库来生成不同的 SQL 语句,目前支持的数据库…

    C# 2023年6月3日
    00
  • ASP.NET编程简单实现生成静态页面的方法【附demo源码下载】

    为了更好地讲解“ASP.NET编程简单实现生成静态页面的方法”,我们需要分为以下几个部分进行详细讲解: 为什么需要生成静态页面? 静态页面生成的基本思路和流程 实现过程和示例说明 1. 为什么需要生成静态页面? 当我们访问一个网站时,实际上每一次访问都需要服务器去动态生成页面并将结果返回给浏览器。但是,当网站的访问量很大时,频繁地动态生成页面会极大地消耗服务…

    C# 2023年5月31日
    00
  • WEB API .NET环境发布

    1、创建WEBAPI 1 using Dapper; 2 using MesErp.Models; 3 using Microsoft.AspNetCore.Mvc; 4 using Microsoft.Extensions.Configuration; 5 using Newtonsoft.Json; 6 using System; 7 using Sys…

    C# 2023年5月9日
    00
  • C#之多余控件事件及代码删除问题

    标题:C#之多余控件事件及代码删除问题 正文: 在使用C#编写Windows应用程序时,我们有时会再设计界面时添加一些控件,后来又发现这些控件用处不大,或者我们修改了设计,需要删除这些控件,但却发现这些控件和它们绑定的事件和代码并没有完全删除。这就是所谓的多余控件事件及代码删除问题。 问题原因 造成多余控件事件及代码删除问题的原因主要有两个: 控件从设计器中…

    C# 2023年5月14日
    00
  • 深入讲解.Net Core中的Api版本控制

    在 .NET Core 中,API 版本控制是一种常见的需求。API 版本控制可以帮助我们管理 API 的演变,确保客户端和服务器之间的兼容性。本文将深入讲解 .NET Core 中的 API 版本控制,包括路由、策略和文档。 路由 在 .NET Core 中,可以使用路由来实现 API 版本控制。以下是一个示例: [ApiController] [Rout…

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