Unity渲染(一):Shader着色器基础入门之纯色Shader

2023-11-21 21:20

本文主要是介绍Unity渲染(一):Shader着色器基础入门之纯色Shader,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Unity渲染(一):纯色Shader

通过这里,你可以学习到UnityShader基本语法,CG语义,GPU渲染流水线等编写着色器的基础知识

开发环境:Unity5.0或者更高


在这里插入图片描述

最终效果

概述

1. Unity shader 基本语法
2. 顶点着色器与片元着色器参数传递
3. 基本shader语义
4. GPU渲染流水线

1.1 开始

  • 创建场景并取名为SolidColor并在场景中添加CameraCube

在这里插入图片描述

Hierachy
  • 创建MaterialShader

在这里插入图片描述

  • 删除Shader中所有代码后,写入如下代码, 这是shader的基本结构
Shader "Toturial/SolidColor"
{SubShader{Pass{CGPROGRAMENDCG}}
}

此时Console出现了两条警告信息,第一条表示该Shader代码中的所有SubShader都不支持,第二条表示需要该Shader对GPU顶点着色器和片元着色器进行编程,在

Shader warning in 'Toturial/SolidColor': Toturial/SolidColor shader is not supported on this GPU (none of subshaders/fallbacks are suitable)
Shader warning in 'Toturial/SolidColor': Both vertex and fragment programs must be present in a shader snippet. Excluding it from compilation

代码说明
  1. Shader "xx/xx"表示在Unity材质面板的路径
    d
  2. SubShader{ ... } 中编写着色代码,可以写多个,GPU会选择一个最合适的来进行渲染
  3. Pass{ ... } 写在SubShader中 ,渲染逻辑和渲染配置写在这里面,可以写多个,有几个就会渲染几次
  4. CGPROGRAM ... ENDCG CG代码,渲染逻辑写在这里面

1.2 简化的GPU渲染管线

在这里插入图片描述

简化的GPU渲染管线

管线说明(重要!!!)
  1. Unity将顶点数据、顶点颜色等属性传入Shader ,进入GPU顶点着色器处理,之后进入裁剪阶段,裁剪完成后数据将进入片元着色器,最后输出到屏幕
  2. 其中顶点着色器和片元着色器是可编程的(表示可以在Shader中写代码进行控制)
  3. 裁剪阶段是可配置的(表示可以在Shader中使用一些特定的语法进行设置 例如 Cut off)

1.3 顶点着色器和片元着色器

在我们对顶点着色器(Vertex Shader)以及片元着色器(Fragment Shader)进行编程之前,需要先从获取对象的属性,例如图片的顶点位置和颜色,模型的顶点位置、法线方向、颜色等。

我们通过语义绑定来获取模型数据或者图片的位置和颜色

语义说明
  1. 类型 变量名 :POSITION; 获取输入的顶点 (例如:float4 vertex : POSITION)
  2. 类型 变量名 : COLOR 获取输入的颜色,SpriteRenderer 和Image组件上的Color
  3. :SV_POSITION 顶点着色器输出的顶点位置,SV表示System Value的缩写
  4. :SV_TARGET 片元着色器输出的值

了解了语义之后,我们需要定义函数为顶点着色器和片元着色器进行编程控制。

宏定义

#pragma vertex vert 定义顶点着色器,vert为函数名 可以改成其他的
#pragma fragment frag 定义片元着色器 ,frag为函数名 可以改成其他的

之后我们在CGPROGRAM … ENDCG中写入如下代码:

Shader "Toturial/SolidColor"
{SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag float4 vert(float4 vertex : POSITION): SV_POSITION{return UnityObjectToClipPos(vertex);}fixed4 frag() : SV_TARGET{return fixed4(0,0,1,1);}ENDCG}}
}

其中UnityObjectToClipPos(vertex)表示将顶点位置从对象空间转换到裁剪空间,这一步是为了将3D的场景最终输出到一张2D的屏幕上。参考Unity官方文档 https://docs.unity3d.com/cn/current/Manual/SL-BuiltinFunctions.html

最终返回了蓝色fixed4(0,0,1,1);,之后给场景中的Cube添加材质Custom_SolidColor

在这里插入图片描述

最终效果

1.4 代码结构优化

上面的代码中我们只用到了顶点位置:POSITION语义,当我们需要多个参数的时候,例如还需要颜色,法线方向等我们可以使用结构体给顶点着色器函数传参

修改 CGPROGRAM … ENDCG 中的代码,首先我们定义一个结构体名为a2v,他是application to vertex 的缩写,意思是表示数据从应用传递到顶点着色器

struct a2v
{float4 vertex : POSITION;fixed4 color : COLOR;
};

我们再定义一个结构体用于将数据从顶点着色器输出后传递到片元着色器,结构体名为v2f ,它是vertex to fragment的缩写,

struct v2f
{float4 pos : SV_POSITION;fixed4 color : COLOR;
};

之后修改顶点着色器函数返回值和参数

v2f vert(a2v v)
{v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.color = v.color;return o;
}

完整代码

Shader "Toturial/SolidColor"
{SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag struct a2v{float4 vertex : POSITION;fixed4 color : COLOR;};struct v2f{float4 pos : SV_POSITION;fixed4 color : COLOR;};v2f vert(a2v v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.color = v.color;return o;}fixed4 frag(v2f i) : SV_TARGET{return fixed4(0,0,1,1);}ENDCG}}
}

最终结果
在这里插入图片描述

最终效果

1.5 使用Properties属性

在场景中创建一个Image与2D Sprite

在这里插入图片描述
Image组件的Material设置为Custom_SolidColor
SpriteRenderer 的Material设置为Custom_SolidColor

此时出现了一个报错

Material 'Custom_SolidColor' with Shader 'Toturial/SolidColor' doesn't have a texture property '_MainTex'

这是因为图片组件会将Sprite设置给Shader中的_MainTex,所以我们在Properties中需要定义一个变量名为_MainTex类型为2D的参数,将以下代码写在SubShader上面。

Properties
{_MainTex("MainTex",2D) = "white"{}
}
代码说明
  1. Properties{...} 代码块定义材质属性。参阅 ShaderLab:定义材质属性
    这部分的参数会显示在材质面板上
    在这里插入图片描述
  2. _MainTex("MainTex",2D) = "white"{} _MainTex表示变量名,用于在C#访问,"MainTex"表示在材质面板上的名字,2D为参数类型,“white”{}为默认值

接下来我们给材质属性添加一个设置颜色的功能,首先在Properties属性添加Color

   Properties{_MainTex("MainTex",2D) = "white"{}_Color("Color",Color) = (1,1,1,1)}

之后我们需要在CGPROGRAM… ENDCG 中定义变量用来获取Properties里的_Color值,在 struct a2v上面定义

#pragma vertex vert
#pragma fragment frag fixed4 _Color;struct a2v
{

修改frag函数

fixed4 frag(v2f i) : SV_TARGET
{return _Color;
}

修改材质界面的Color
在这里插入图片描述
完整代码:

Shader "Toturial/SolidColor"
{Properties{_MainTex("MainTex",2D) = "white"{}_Color("Color",Color) = (1,1,1,1)}SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag fixed4 _Color;struct a2v{float4 vertex : POSITION;fixed4 color : COLOR;};struct v2f{float4 pos : SV_POSITION;fixed4 color : COLOR;};v2f vert(a2v v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.color = v.color;return o;}fixed4 frag(v2f i) : SV_TARGET{return _Color;}ENDCG}}
}

最终看到效果

在这里插入图片描述

最终效果

接下来我们将使用Image.Color和SpriteRenderer修改材质的颜色,因为我们在a2v结构体中对color进行了:Color语义绑定,之后将a2v结构体传入顶点着色器vert,在顶点着色器中实例化了一个v2f结构体并对color进行赋值,之后将v2f传递到片元着色器中,所以我们需要把片元着色器frag中的返回值修改为i.color就可以达到效果。

fixed4 frag(v2f i) : SV_TARGET
{return i.color;
}

修改完后我们修改场景中的Image组件上的颜色为#FFDA00 ,将SpriteRenderer上的颜色修改为#3889F1

在这里插入图片描述

最终效果

1.6 完整代码

Shader "Toturial/SolidColor"
{Properties{_MainTex("MainTex",2D) = "white"{}_Color("Color",Color) = (1,1,1,1)}SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag fixed4 _Color;struct a2v{float4 vertex : POSITION;fixed4 color : COLOR;};struct v2f{float4 pos : SV_POSITION;fixed4 color : COLOR;};v2f vert(a2v v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.color = v.color;return o;}fixed4 frag(v2f i) : SV_TARGET{return i.color;}ENDCG}}
}

这篇关于Unity渲染(一):Shader着色器基础入门之纯色Shader的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/405178

相关文章

从入门到精通详解Python虚拟环境完全指南

《从入门到精通详解Python虚拟环境完全指南》Python虚拟环境是一个独立的Python运行环境,它允许你为不同的项目创建隔离的Python环境,下面小编就来和大家详细介绍一下吧... 目录什么是python虚拟环境一、使用venv创建和管理虚拟环境1.1 创建虚拟环境1.2 激活虚拟环境1.3 验证虚

从基础到高级详解Python数值格式化输出的完全指南

《从基础到高级详解Python数值格式化输出的完全指南》在数据分析、金融计算和科学报告领域,数值格式化是提升可读性和专业性的关键技术,本文将深入解析Python中数值格式化输出的相关方法,感兴趣的小伙... 目录引言:数值格式化的核心价值一、基础格式化方法1.1 三种核心格式化方式对比1.2 基础格式化示例

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

Python WebSockets 库从基础到实战使用举例

《PythonWebSockets库从基础到实战使用举例》WebSocket是一种全双工、持久化的网络通信协议,适用于需要低延迟的应用,如实时聊天、股票行情推送、在线协作、多人游戏等,本文给大家介... 目录1. 引言2. 为什么使用 WebSocket?3. 安装 WebSockets 库4. 使用 We

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

Java List 使用举例(从入门到精通)

《JavaList使用举例(从入门到精通)》本文系统讲解JavaList,涵盖基础概念、核心特性、常用实现(如ArrayList、LinkedList)及性能对比,介绍创建、操作、遍历方法,结合实... 目录一、List 基础概念1.1 什么是 List?1.2 List 的核心特性1.3 List 家族成

C#和Unity中的中介者模式使用方式

《C#和Unity中的中介者模式使用方式》中介者模式通过中介者封装对象交互,降低耦合度,集中控制逻辑,适用于复杂系统组件交互场景,C#中可用事件、委托或MediatR实现,提升可维护性与灵活性... 目录C#中的中介者模式详解一、中介者模式的基本概念1. 定义2. 组成要素3. 模式结构二、中介者模式的特点

从基础到高阶详解Python多态实战应用指南

《从基础到高阶详解Python多态实战应用指南》这篇文章主要从基础到高阶为大家详细介绍Python中多态的相关应用与技巧,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、多态的本质:python的“鸭子类型”哲学二、多态的三大实战场景场景1:数据处理管道——统一处理不同数据格式

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c