[Unity] Shader(着色器)输入输出和语义
在Unity5.x后, 已经支持了基于物理的光照模型,也就是常说的次时代引擎所必须具备的功能。
如果在Properties使用2D,CG里要用sampler2D,代表使用的是2维纹理
如果在Properties使用color, CG里要用fixed4
如果在Properties使用Range, CG里要用half,实际上描述的是一个float
struct Input 用于描述UV坐标的结构体。在 Input 中, 变量名必须是 uv_ 开始, 变量名必须是官方文档中已经指定的名称(也就是说不可以随意设定)
CGPROGRAM ... ENDCG 代码块,表示从这一句下面开始直到EndCG,表示我们是使用了CG语言编写的代码
#pragma 编译指令: #pargma 关键词 函数名 光照模型 [其它选项] 函数名在cginc中,实际上会在前部加上 Lighting ,如 LightingStandard , 我们用的时候只取后部分 , 也就是 Standard
#pragma target 3.0 使用model 3.0 可以得到一个更好的光照效果, 默认是2.0
#pragma surface surf Standard fullforwardshadows 表示当前是一个 surface 着色器, 函数名是 surf, 使用 Standard 基于物理系统光照模式, 有一个完整的向前的阴影 (Standard 必须是Unity 5.x后才有) #pragma surface surf Lambert addshadow 表示当前是一个 surfac 着色器, 函数名是 surf, 使用 Lambert 兰伯特光照模型, addshadow 表示给物体添加一个阴影 示例代码:
Shader "Sbin/sf" {
Properties {
// 颜色值
_Color ("Color", Color) = (,,,)
// 主纹理
_MainTex ("Albedo (RGB)", 2D) = "white" {}
// 高光光泽度
_Glossiness ("Smoothness", Range(,)) = 0.5
// 材质金属光泽
_Metallic ("Metallic", Range(,)) = 0.0
}
// 在surfaceShader不需要有Pass通道,否则会报错
SubShader {
// 渲染类型,是一个不透明物体
//Tags { "RenderType"="Opaque" }
Tags { "RenderType"="Opaque" "Queue" = "Transparent" }
// 层级细节
LOD
// 代码块,表示从这一句下面开始直到EndCG,表示我们是使用了CG语言编写的代码
CGPROGRAM
// #pragma 编译指令
// 格式:
// #pragma surface surfaceFunction lightModel [optionalparams]
// #pargma 关键词 函数名 光照模型 [其它选项]
// Physically based Standard lighting model, and enable shadows on all light types
//#pragma surface surf Standard fullforwardshadows
//#pragma surface surf Lambert
//#pragma surface surf Lambert alpha
#pragma surface surf Lambert addshadow
// 使用model 3.0 可以得到一个更好的光照效果, 默认是2.0
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
// 如果在Properties使用2D,CG里要用sampler2D,代表使用的是2维纹理
// 如果在Properties使用color, CG里要用fixed4
// 如果在Properties使用Range, CG里要用half,实际上描述的是一个float
sampler2D _MainTex;
// 输入结构体用于模述UV的坐标。
struct Input {
// 变量必须是uv_开头,_号后面的_MainTex自动对应Properties中的_MainTex和sampler2D
// _MainTex 也是不能变的。
float2 uv_MainTex;
};
// half _Glossiness;
// half _Metallic;
// fixed4 _Color;
// in 参数是输入的
// out 参数是输出的
// inout 参数即是输入,又是输出
// SurfaceOutputStandard 可以使用基于物理的光照模型(次时代)
//void surf (Input IN, inout SurfaceOutputStandard o) {
void surf (Input IN, inout SurfaceOutput o) {
// Albedo comes from a texture tinted by color
// 从纹理中进行采样
//fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb; // 基本的漫反射
// Metallic and smoothness come from slider variables
//o.Metallic = _Metallic;
//o.Smoothness = _Glossiness;
o.Alpha = c.a; // 透明度
}
ENDCG
}
// FallBack 当我们的surfaceshader编译后没有一个阴影通道时,会自动添加一个阴影通道
//FallBack "Diffuse"
}
在 SurfaceShader 中, 不可以有 Pass 通道, 否则会报错。
以上内容只是笔记, 有错误请指正。
官方示例:
我们将开始用一个非常简单的着色,并建立在。这里的一个着色,只设置表面颜色“白”。它使用内置的Lambert(扩散)照明模型。
Shader "Example/Diffuse Simple" {
SubShader {
Tags { "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Lambert
struct Input {
float4 color : COLOR;
};
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = ;
}
ENDCG
}
Fallback "Diffuse"
}

Texture 使用纹理
An all-white object is quite boring, so let’s add a texture. We’ll add a Properties block to the shader, so we get a texture selector in our Material. Other changes are in bold below.
所有的白色物体都很无聊,所以让我们添加一个纹理。我们将添加一个属性块到着色,所以我们得到一个纹理选择器在我们的材料。其他变化是在大胆下面。
Shader "Example/Diffuse Texture" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
}
SubShader {
Tags { "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Lambert
struct Input {
float2 uv_MainTex;
};
sampler2D _MainTex;
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
}
ENDCG
}
Fallback "Diffuse"
}

Normal mapping 法线贴图
Let’s add some normal mapping:
让我们添加一些法线贴图:
Shader "Example/Diffuse Bump" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
_BumpMap ("Bumpmap", 2D) = "bump" {}
}
SubShader {
Tags { "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Lambert
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
};
sampler2D _MainTex;
sampler2D _BumpMap;
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
}
ENDCG
}
Fallback "Diffuse"
}

Rim Lighting 边缘照明
Now, try to add some Rim Lighting to highlight the edges of an object. We’ll add some emissive light based on angle between surface normal and view direction. For that, we’ll use viewDir built-in surface shader variable.
现在,尝试添加一些边缘照明,以突出对象的边缘。我们将添加一些散射光基于表面法线和视图方向的夹角。这样,我们将使用viewdir内置表面着色器变量。
Shader "Example/Rim" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
_BumpMap ("Bumpmap", 2D) = "bump" {}
_RimColor ("Rim Color", Color) = (0.26,0.19,0.16,0.0)
_RimPower ("Rim Power", Range(0.5,8.0)) = 3.0
}
SubShader {
Tags { "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Lambert
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
float3 viewDir;
};
sampler2D _MainTex;
sampler2D _BumpMap;
float4 _RimColor;
float _RimPower;
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
o.Emission = _RimColor.rgb * pow (rim, _RimPower);
}
ENDCG
}
Fallback "Diffuse"
}

更多资料参考 Unity 官方文档: Unity/Editor/Data/Documentation/en/Manual/SL-SurfaceShaderExamples.html
[Unity] Shader(着色器)输入输出和语义的更多相关文章
- Unity Shader着色器优化
https://mp.weixin.qq.com/s?__biz=MzU5MjQ1NTEwOA==&mid=2247493518&idx=1&sn=c51b92e9300bcf ...
- [Unity] Shader(着色器)之纹理贴图
在Shader中,我们除了可以设定各种光线处理外,还可以增加纹理贴图. 使用 settexture 命令可以为着色器指定纹理. 示例代码: Shader "Sbin/ff2" { ...
- [Unity] Shader(着色器)之固定管线
在Unity中,固定管线Shader的性能是最好的. 什么是固定管线呢? 固定渲染管线 —— 这是标准的几何&光照(T&L)管线,功能是固定的,它控制着世界.视.投影变换及固定光照控制 ...
- Unity3D学习笔记(三十四):Shader着色器(1)
一.GPU:图形处理器,Graphics Processing Unit 显卡的处理器就是图形处理器.与CPU类似. GPU和CPU的区别? 1.CPU主要是为了串行指令设计,GPU则是为了大规模 ...
- Unity 几何着色器
Unity 几何着色器 shaderGeometry Shader几何着色器 Unity 几何着色器 如果学习不能带来价值,那将毫无意义 简介 在顶点和片段着色器之间有一个可选的着色器,叫做几 ...
- Unity 5着色器系统代码介绍(上)
http://forum.china.unity3d.com/thread-25724-1-10.html Unity 5着色器系统代码介绍(上) Unity在着色器开发方面提供了很大的灵活性.有些工 ...
- Unity3D学习笔记(三十五):Shader着色器(2)- 顶点片元着色器
Alpha测试 AlphaTest Great:大于 AlphaTest Less:小于 AlphaTest Equal:等于 AlphaTest GEqual:大于等于 AlphaTest LEqu ...
- unity shader入门(二)语义,结构体,逐顶点光照
下为一个逐顶点漫反射光照shader Shader "study/Chapter6/vertexShader"{ Properties{_Diffuse("Diffuse ...
- 【Unity Shader】---准确认识SubShader语义块结构、渲染状态设定、Tags标签
一[SubShader] 每个UnityShader文件可以包含多个SubShader语义块,但至少要有一个.当Unity需要加载这个UnityShader时,Unity会扫描所有的SubShader ...
随机推荐
- Json解析工具Jackson(使用注解)
原文http://blog.csdn.net/nomousewch/article/details/8955796 接上一篇文章Json解析工具Jackson(简单应用),jackson在实际应用中给 ...
- web也是区分前端与后端的,session\cookie辨析
<1>Ajax交互方式 Ext.Ajax.request( { //被用来向服务器发起请求默认的url url : "", //请求时发送后台的参数,既可以是Json对 ...
- Android(Linux)控制GPIO方法二
前文<Android(Linux)控制GPIO的方法及实时性分析>主要使用Linux shell命令控制GPIO,该方法可在调试过程中快速确定GPIO硬件是否有问题,即对应的GPIO是否受 ...
- bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)
题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...
- MATLAB的一些基础知识
1.已知a1=sin(sym(pi/4)+exp(sym(0.7)+sym(pi/3)))产生精准符号数字,请回答:以下产生的各种符号数哪些是精准的?若不精准,误差又是多少?能说出产生误差的原因吗? ...
- python高级之生成器&迭代器
python高级之生成器&迭代器 本机内容 概念梳理 容器 可迭代对象 迭代器 for循环内部实现 生成器 1.概念梳理 容器(container):多个元素组织在一起的数据结构 可迭代对象( ...
- 洛谷P1111 修复公路
题目背景 A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数N,和公路数M,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你什么时 ...
- HTML5的postMessage使用记要
HTML5提出了一个新的用来跨域传值的方法,即postMessage(这个名字太通俗了所以你最好看看是不是自己写过一个同名的把它覆盖了).幸运的是IE8就开始支持了. 我们假设有两个网站,1.com与 ...
- Apache Shiro系列之五,概述 —— 配置
Shiro设计的初衷就是可以运行于任何环境:无论是简单的命令行应用程序还是复杂的企业集群应用.由于运行环境的多样性,所以有多种配置机制可用于配置,本节我们将介绍Shiro内核支持的这几种配置机制. ...
- 大流量网站性能优化:一步一步打造一个适合自己的BigRender插件
BigRender 当一个网站越来越庞大,加载速度越来越慢的时候,开发者们不得不对其进行优化,谁愿意访问一个需要等待 10 秒,20 秒才能出现的网页呢? 常见的也是相对简单易行的一个优化方案是 图片 ...