[Unity Shader]Shader前述
什么是Shader
- Surface Shaders —— 也称为表面着色器。这大概是Unity的骄傲。它去除了大部分“麻烦的工作”,可以适用于很多情况下
- Fragment Shaders —— 片段着色器。它允许你做更多的工作,但也更难写,而且它还让我们可以做低层的一些东西,像顶点光照,这对于移动设备和多个通道(passes)所必需的更高级的效果会非常有用。
Surface Shaders的代码需要看起来像这样:
你可以使用Pass中的语句来控制这个Z方向的缓存是否对你的着色器代码有影响,或者你的Shader是否写入该缓冲区内,例如: Zwrite Off表明不会更新你的任何输出像素的Z方向的缓存区。
您可以使用这种技术来在其他对象上打孔 —— 通过写入Z缓冲区,但不输出任何实际的像素颜色,那么使用这个Shader的模型背后的对象将不能被写入(因为Z缓冲区中有距离更近的像素了),这样看起来这个对象就像是被打了洞一样。
下面展示了一个最简单的Surface Shader:
Shader "Custom/Hello" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200 CGPROGRAM
#pragma surface surf Lambert sampler2D _MainTex; struct Input {
float2 uv_MainTex;
}; void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
理解Shader代码
Properties
_Name ( "Displayed Name", type ) = default value {options}
- _Name:程序中引用的名字,和我们一般理解的变量名称是一样的。
- Displayed Name:这个字符串将会出现在Unity材质的编辑面板上。
- type:该属性的类型。Unity支持以下几种属性类型:
- Color:表示一个单一的RGBA颜色值;
- 2D: 表示一张大小为2的次方的纹理贴图,可以使用基于模型UV坐标来进行采样;
- Rect:表示一张纹理不是2的次方的纹理贴图;
- Cube:表示一个可用于反射的3D立方体映射贴图,可以进行采样;
- Range(min, max):一个取值范围在min到max之间的浮点值;
- Float: 一个可以为任意值的浮点值;
- Vector:一个4维度的向量。
- default value:该属性的默认值。
- Color:使用浮点值表示的(r, g, b, a),例如(1,1,1,1);
- 2D/Rect/Cube:对于贴图类型的属性,默认值可以是一个空字符串,或者"white", "black", "gray", "bump"这样的字符串;
- Float/Range:在此范围内的值即可;
- Vector:以(x,y,z,w)形式表示的4D向量;
- { options }:只和纹理类型的2D、Rect和Cube相关,它必须至少被指定为{ }。你可以使用空格分隔多个选项,有如下选择:
- TexGen贴图生成模式:该纹理的自动纹理坐标生成模式。可以为ObjectLinear, EyeLinear, SphereMap, CubeReflect, CubeNormal。这些直接对应了OpenGL中的texgen modes。注意,如果你编写了一个顶点函数,那么可以忽略TexGen。
//Define a color with a default value of semi-transparent red
_MainColor ("Main Color", Color) = (1,0,0,0.5)
//Define a texture with a default of white
_Texture ("Texture", 2D) = "white" {}
Tags
Shader结构
Shader "Custom/Hello" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200 CGPROGRAM
//Lambert定义了光照模型
#pragma surface surf Lambert sampler2D _MainTex; struct Input {
float2 uv_MainTex;
}; void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
//Define a float variable
vec2 coordinate;
//Define a color variable
float4 color;
//Multiply out a color
float3 multipliedColor = color.rgb * coordinate.x;
我们可以使用.xyzw和.rgba符号访问存储在这些变量中的值(颜色、位置、法线等)。
从Surface Shader输出信息
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
}
显然,我们是为SurfaceOutput中的Albedo属性进行了设置。SurfaceOutput是Unity为我们定义的一种结构体,它的结构定义如下:
struct SurfaceOutput {
half3 Albedo; //颜色纹理
half3 Normal; //法线
half3 Emission; //自发光,不受照明的影响
half Specular; //高光指数
half Gloss; //光泽度
half Alpha; //Alpha通道
};
只需要通过Input结构体,我们就可以告诉系统,为当前正在处理的像素得到在MainTex中对应的纹理坐标。如果不止一张纹理,例如还有一张_OtherTexture,我们只需要添加如下代码:
struct Input {
float2 uv_MainTex;
float2 uv_OtherTexture;
};
struct Input {
float2 uv_MainTex;
float2 uv2_OtherTexture;
};
Input结构体
- float3 viewDir:视角方向,用于计算视差效果和边缘照明等;
- 使用COLOR语义的float4:包含了插值后的逐顶点颜色;
- float4 screenPos:屏幕空间中的位置;
- float3 worldPos:世界空间中的位置;
- float3 worldRefl:如果Surface Shader没有改写o.Normal,将包含了环境反射向量;
- float3 worldNormal:如果Surface Shader没有改写o.Normal,将包含了环境法线向量;
- INTERNAL_DATA:当我们需要改写o.Normal时,一些函数,如WorldNormalVector等,需要该变量进行计算;
Shader "Custom/Hello" {
Properties {
//1、_MainTex变量名
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD CGPROGRAM
#pragma surface surf Lambert
//2、_MainTex变量名
sampler2D _MainTex; struct Input {
//3、uv_MainTex变量名
float2 uv_MainTex;
}; void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
当该属性是一张文字,而你需要在Input结构中得到对应的uv坐标时,uv或者uv2后面的名称也必须和属性名相同。
在上图中,_MainTex对应了一张纹理贴图,它对应的变量类型就是sampler2D类型,只要得到了一个uv坐标,我们就可以在贴图上进行采样得到颜色值。
surf函数中仅用了一个函数:
o.Albedo = tex2d( _MainTex, IN.uv_MainTex).rgb;
它使用Input中得到的该像素对应的_MainTex中的uv坐标,在_MainTex进行采样,得到一个float4类型的颜色值(包括了透明通道)。如果我们需要得到透明通道的值,可以这样做:
float4 texColor = tex2d( _MainTex, IN.uv_MainTex );
o.Albedo = texColor.rgb;
o.Alpha = texColor.a;
[Unity Shader]Shader前述的更多相关文章
- 【淡墨Unity3D Shader计划】五 圣诞用品: Unity在Shader三种形式的控制&混合操作编译
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/42060963 作者:毛星云(浅墨) ...
- [Unity Shader]Shader分类
Shader的分类: Shader按管线分类一般分为固定渲染管线与可编程渲染管线 (1)固定渲染管线 ——这是标准的几何&光照(Transforming&Lighting)管线,功能是 ...
- Unity的shader学习1
先来看一段我们项目常见的Shader代码,这个是Vertex&Fragment shader,目前已经不常用了,不过还是适合我们理解一些基础知识和理解一些比较老的shader 代码.下次我们再 ...
- unity之shader
渲染流程分为三个阶段:应用阶段,几何阶段,光栅化阶段. Unity Shader的分类: 使用的是ShaderLab编写unity中的的shader 1 表面着色器 Surface Shader 2 ...
- unity, change shader for me and all my children
public void changeShaderForMeAndAllMyChildren(){ Transform[] childrenTransformList = GetComponentsIn ...
- 详解Paint的setShader(Shader shader)
一.概述 setShader(Shader shader)中传入的自然是shader对象了,shader类是Android在图形变换中非常重要的一个类.Shader在三维软件中我们称之为着色器,其作用 ...
- Unity Built-in Shader详解二
这次主要讨论Unity自带的Shader中Transparent Shader Family 这个家族的Shader一共7种,原理和类型与Normal中的上差不多,只不过这些Shader是用在半透明或 ...
- 对Unity一个Shader编译Bug的分析(Unrecognized sampler 'samplerunity_lightmap)
写在前面 Unity的用户量越来越大,越来越有钱,这几年摊子也铺的越来越大,所以各个版本总是有很多Bug.对于一些Bug官方在ReleaseNote里的说明是很不详细的,而对于一些渲染相关的Bug,有 ...
- 关于Unity中Shader的使用
在游戏的开发过程中,程序员不太会自己去写shader,因为写起来很麻烦,而且只有Unity会报错,编译器也没有什么提示. 通常是拿别人的shader改一改,当然,程序员还是要能看懂和会一点shader ...
随机推荐
- 外部连VPN的方法
1)安装网络挂件vpnc使用命令:sudo apt-get install vpnc 2)找到公司的默认配置文件xxx_common.pcf ,使用命令将其转换为对应的配置文件:sudo pcf2vp ...
- PHP中级篇 Apache配置httpd-vhosts虚拟主机总结及注意事项[OK]
经常使用Apache虚拟主机进行开发和测试,但每次需要配置虚拟主机时都习惯性的ctrl+c和ctrl+v,这次由于重装系统,需要配置一个新的PHP开发环境虚拟主机,于是总结一下Apaceh配置http ...
- vbs 截图
'VBS截屏.vbs ' Win7x64 测试通过(已安装Word2007): '参考: ' http://qtp.blogspot.com/2010/02/screenshot-vbscript ...
- ping命令使用技巧(一次Ping多个地址)
打开windows 命令行 窗口, 在命令行输入以下命令: for /l %i in (1,1,255) do ping -n 1 -w 60 192.168.0.%i | find " ...
- 动态规划2-----hdu1069
首先这道题目先要理解题目的意思. 用一些方块堆塔,给出的每种方块个数是无限的,只有满足长宽都小于下面一个方块的方块才能摆上去. 首先这道题需要一个转化. 每个方块有3个不同的面,每个面长宽交换,一共每 ...
- 阿里云资深DBA专家罗龙九:云数据库十大经典案例分析【转载】
阿里云资深DBA专家罗龙九:云数据库十大经典案例分析 2016-07-21 06:33 本文已获阿里云授权发布,转载具体要求见文末 摘要:本文根据阿里云资深DBA专家罗龙九在首届阿里巴巴在线峰会的&l ...
- scp命令报错-bash: scp: command not found
# scp -bash: scp: command not found # which scp /usr/bin/scp # rpm -qf /usr/bin/scp openssh-clients- ...
- 转 图片缓存之内存缓存技术LruCache,软引用
每当碰到一些大图片的时候,我们如果不对图片进行处理就会报OOM异常,这个问题曾经让我觉得很烦恼,后来终于得到了解决,那么现在就让我和大家一起分享一下吧.这篇博文要讲的图片缓存机制,我接触到的有两钟,一 ...
- 写入cookie后只显示一次的DIV提示框代码
<script type="text/javascript"> function cookiesave(n, v, mins, dn, path){ if(n) { i ...
- constraint 摘自群主大大
CONSTRAINT 子句 限制和索引相似,虽然限制也能被用于建立和另一个表的关联. 用 ALTER TABLE 和 CREATE TABLE 语句中的 CONSTRAINT 子句来建立或删除条件.C ...