Alpha测试
AlphaTest Great:大于
AlphaTest Less:小于
AlphaTest Equal:等于
AlphaTest GEqual:大于等于
AlphaTest LEqual:小于等于
AlphaTest Never:全不渲染
AlphaTest Always:全部渲染
如果使用后两项的命名的情况下,比较后的数字项没有意义
 
AlphaTest 比较项 数字
AlphaTest Great 0.5 //表示只渲染alpha值大于0.5的部分
AlphaTest Less 0.5 //表示只渲染alpha值小于0.5的部分
 
混合命令
Blend SrcFactor DstFactor
SrcFactor DstFactor 可以的取值
One表示1
Zero表示0
SrcColor当前的颜色
DstColor已经存在的颜色
SrcAlpha当前的透明度
DstAlpha已经存在的颜色的透明度
OneMinusSrcColor当前的颜色取反向 1-SrcColor
OneMinusSrcAlpha当前的Alpha值取反向 1-SrcAlpha
OneMinusDstColor已经存在的颜色取反向 1-DstColor
OneMinusDstAlpha已经存在的颜色的透明度取反向 1-DstAlpha
 
最终颜色 = 新颜色 * SrcFactor + 旧颜色 * DstFactor
 
新颜色:即将写入到颜色缓冲区的颜色
旧颜色:已经在颜色缓冲区的颜色
 
颜色运算法则(不同于向量运算法则)
(r,g,b) * a = (r*a,g*a,b*a)
(r,g,b) * (x,y,z) = (r*x,g*y,b*z)
(r,g,b) + (x,y,z) = (r+x,g+y,b+z)
A - (r,g,b) = (a-x,a-y,a-z)
 
例如
Blend Zero One //仅仅显示背景的颜色,自身的效果不会显示
Blend One Zero //显示贴图的RGB颜色,即使有透明通道的部分也显示原色,不会透过去
Blend One One //贴图色与背景色叠加,没有透明通道处理,结果可能更趋近于(1,1,1)
Blend SrcAlpha Zero //没有透明通道部分显示的是贴图的原色,有透明通道0的部分,显示黑色,0.5部分更趋近于黑色
Blend SrcAlpha OneMinusSrcAlpha //最终颜色 = 新颜色 * 当前透明度 + 旧颜色 * (1 - 当前透明度),最常用的透明混合方式
Shader "Lesson/AlphaTest" {
Properties {
_Tex("纹理", 2D) = "white"{}
_Alpha("透明度", Range(,)) = }
SubShader {
Pass
{
//表示只渲染alpha值大于0.5的部分
AlphaTest Greater 0.5
AlphaTest Greater [_Alpha] //Blend SrcAlpha OneMinusSrcAlpha
Blend SrcAlpha zero SetTexture[_Tex]
{
Combine texture
}
}
}
FallBack "Diffuse"
}
 
Cg语言,详见PPT
 
顶点/片元着色器
核心:
顶点函数:
片元函数:
 
顶点函数在几何阶段,能从应用程序获取顶点信息。这些信息就是通过顶点函数的参数传递进来的。顶点函数的返回值就是传递到片元函数里的,片元函数也是通过参数去接收的
Float4 vertex:顶点坐标(模型空间下)
Float4 normal:顶点的法线向量
Float4 tangent:顶点的切线向量
Float4 texcoord:第一UV颜色
Float4 texcoord1:第二UV颜色
Float4 color:顶点颜色
 
语义:语句的含义
顶点函数的形参后跟的语义:表示该形参的是接收应用程序传递来的是什么。
对于顶点函数的方法后跟的语义:修饰的返回值,代表该返回值表示的是什么。
对于片元函数的方法后跟的语义:修饰的是片元函数的返回值,代表的是告诉应该GPU是什么
 
从应用程序阶段到顶点函数阶段
1.POSITION:表示应用程序把顶点坐标传递过来并且存储在修饰的参数
2.NORMAL:表示法线,通常是float3
3TANGENT:表示切线
4.TEXCOORD0-N:从第1套UV到第7套UV
5.COLOR:顶点颜色
 
从顶点函数到片元函数能表示的语义
1.SV_POSITION:代表转换之后的齐次空间坐标
2.COLOR0:代表一组颜色
2.COLOR1:代表一组颜色
4.TEXCOORD0-N:从第1套UV到第7套UV
 
从片元函数输出的语义
SV_Target:输出的值会渲染到屏幕上
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Lesson/VFColor" {
Properties {
_Color("颜色", Color) = (,,,)
}
SubShader { //1.顶点片元程序也要写在Pass块里
Pass
{
//2.把Cg语言的开始和结束写出来
//表示Cg语言程序的开始
CGPROGRAM
//3.定义顶点函数和片元函数的名字
//#pragma 不变 vertex 关键字,后跟的是顶点函数的名字,vert顶点函数的名字
#pragma vertex vert //定义函数名为vert的函数为顶点函数
//#pragma 不变 fragment 关键字
#pragma fragment frag //定义函数名为frag的函数为片元函数
fixed4 _Color;//如果要在Cg语言中去使用属性面板定义的一些变量,需要在Cg语言中进行重定义
//4.实现顶点函数
//POSITION修饰的是顶点函数参数vet,证明vet是顶点坐标
//SV_POSITION修饰的是vet函数的返回值,证明返回值是转换之后的坐标
float4 vert(float4 vet : POSITION, float3 normal : NORMAL) : SV_POSITION
{
//顶点函数的核心作用必须做的是空间坐标转换
//mul是Cg语言的提供的API,计算向量与矩阵相乘
float4 position = UnityObjectToClipPos(vet); //
return position;
}
//5.实现片元函数
fixed4 frag() : SV_Target
{
//最重要的必须的做到就是返回一个颜色
return _Color;
}
//表示Cg语言程序的结束
ENDCG
}
}
FallBack "Diffuse"
}
Unity\Editor\Data\CGIncludes\UnityShaderUtilities.cginc里的UnityObjectToClipPos()函数
UnityCG.cginc常用的API
#ifndef UNITY_SHADER_UTILITIES_INCLUDED
#define UNITY_SHADER_UTILITIES_INCLUDED
// This file is always included in all unity shaders.
#include "UnityShaderVariables.cginc"
// Tranforms position from object to homogenous space
inline float4 UnityObjectToClipPos(in float3 pos)
{
// More efficient than computing M*VP matrix product
return mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, float4(pos, 1.0)));
}
inline float4 UnityObjectToClipPos(float4 pos) // overload for float4; avoids "implicit truncation" warning for existing shaders
{
return UnityObjectToClipPos(pos.xyz);
}
#endif
 
UNITY_MATRIX_MVP的MVP是几何阶段的三次转变
M模型到世界
V世界到观察
P观察到剪裁

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Lesson/VFNormal" {
Properties {
}
SubShader {
Pass
{
CGPROGRAM #pragma vertex vert
#pragma fragment frag
//定义一个结构体,作为顶点函数的参数
struct m2v
{
float4 vex : POSITION;//告诉应用程序把模型空间下的顶点坐标放在这
float3 normal : NORMAL;//告诉应用程序把模型空间下的法线放在这
float3 tangent : TANGENT;//告诉应用程序把模型空间下的切线放在这
};
//定义一个结构体,作为顶点函数的返回值和片元函数的参数
struct v2f
{
float4 position : SV_POSITION;//转换之后的顶点坐标
float3 normal : COLOR0;//法线
float3 tangent : COLOR1;//切线
};
//结构体作为参数和返回值
v2f vert(m2v v)
{
v2f f;
f.position = UnityObjectToClipPos(v.vex); //必须变换顶点坐标
f.normal = v.normal;//法线赋值
f.normal = mul(UNITY_MATRIX_M, v.normal);
//f.tangent = v.tangent;//切线赋值
return f;
}
fixed4 frag(v2f f) : SV_Target
{
return fixed4(f.normal.x, f.normal.y, f.normal.z, );//把法线作为颜色输出
//return fixed4(f.tangent.x, f.tangent.y, f.tangent.z, 1);//把切线作为颜色输出
}
ENDCG
}
}
FallBack "Diffuse"
}

UV坐标,可以通过顶点的UV坐标去获取纹理对应的颜色。对于图片的纹理来说UV的(0,0)点在左下角,UV的(1,1)点在右上角

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Lesson/VFTexture" {
Properties{
//定义一个图片
_MainTex("纹理", 2D) = "white"{}
}
SubShader{
//透明的纹理处理要把渲染队列调高
Tags{ "Queue" = "Transparent" }
Pass
{
//Cull off
//处理带有透明通道贴图的混合
Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//重定义纹理
sampler2D _MainTex; //定义结构体,作为顶点函数的参数
struct m2v
{
float4 vex : POSITION;
float2 uv : TEXCOORD0;//告诉应用程序要UV信息
}; //定义一个结构体,作为顶点函数的返回值和片元函数的参数
struct v2f
{
float4 position : SV_POSITION;
float2 uv : TEXCOORD0;
}; v2f vert(m2v v)
{
v2f f;
//转换顶点坐标
f.position = UnityObjectToClipPos(v.vex);
f.uv = v.uv;
return f;
} fixed4 frag(v2f f) : SV_Target
{
//通过顶点的uv坐标去访问纹理对应的颜色
fixed4 color = tex2D(_MainTex, f.uv);
//return fixed4(f.uv.x,f.uv.y, 0, 1);
return color;
}
ENDCG
}
}
FallBack "Diffuse"
}
属性面板的变量,如果想在Cg程序中去使用,必须在Cg程序中重新定义:
Color - fixed4或float4
Vector - float4
Float - float
Range - float
2D - sampler2D
Rect - samplerRect
Cube - samplerCube
 
裁剪可以做场景切换的幕布效果

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Lesson/VFDiscard" {
Properties{
_MainTex("纹理", 2D) = "white"{}
_Radius("半径", Range(, 0.75)) =
}
SubShader{
Pass
{
CGPROGRAM #pragma vertex vert
#pragma fragment frag sampler2D _MainTex;
float _Radius; struct m2v
{
float4 vex : POSITION;
float2 uv : TEXCOORD0;
}; struct v2f
{
float4 position : SV_POSITION;
float2 uv : TEXCOORD0;
}; v2f vert(m2v v)
{
v2f f;
f.position = UnityObjectToClipPos(v.vex);
f.uv = v.uv;
return f;
} fixed4 frag(v2f f) : SV_Target
{
//discard;//裁剪命令
fixed4 color = tex2D(_MainTex, f.uv); //0.2圆的半径
//圆心是0.5 0.5
float2 current = f.uv;
float2 center = float2(0.5, 0.5); float dis = pow((current.x - center.x), ) + pow((current.y - center.y), ); if (dis < pow(_Radius, ))
{
//在圆内
discard;
} return color;
}
ENDCG
}
}
FallBack "Diffuse"
}
 
Emission,类似RawImage的UV Rect
----Tiling:图片的左右偏移
----Offset:图片的大小比例
 
练习 - 实现西瓜的效果

Shader "Lesson/VFWatermelon" {
Properties {
_LightColor("浅色条纹", Color) = (,,,)
_DarkColor("深色条纹", Color) = (,,,)
_Number("深色条纹数量", int) =
_Width("深色条纹宽度", Range(0.01, 0.2)) = 0.02
}
SubShader{
Pass
{
CGPROGRAM fixed4 _LightColor;
fixed4 _DarkColor;
int _Number;
float _Width;
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc" struct m2v
{
float4 vex : POSITION;
float3 uv : TEXCOORD0;
}; struct v2f
{
float4 position : SV_POSITION;
float3 uv : TEXCOORD0;
}; v2f vert(m2v v)
{
v2f f;
f.position = UnityObjectToClipPos(v.vex);
f.uv = v.uv;
return f;
} fixed4 frag(v2f f) : SV_Target
{
//实现1
//浅色条纹的宽度
float width = 1.0 / _Number - _Width;
for (int i = ; i < _Number; i++)
{
if (f.uv.x > i * (width + _Width) && f.uv.x < width + i * (width + _Width))
{
return _DarkColor;
}
}
return _LightColor;
/*
//实现2
//每对条纹的宽度(1深1浅)
float wid = 1.0 / _Number;
float x = fmod(f.uv.x, wid); //对wid取模(余)
if (x < _Width)
{
return _DarkColor;
}
return _LightColor;
*/
} ENDCG
}
}
FallBack "Diffuse"
}

Unity3D学习笔记(三十五):Shader着色器(2)- 顶点片元着色器的更多相关文章

  1. 【Unity 3D】学习笔记三十五:游戏实例——摄像机切换镜头

    摄像机切换镜头 在游戏中常常会切换摄像机来观察某一个游戏对象,能够说.在3D游戏开发中,摄像头的切换是不可或缺的. 这次我们学习总结下摄像机怎么切换镜头. 代码: private var Camera ...

  2. PHP学习笔记三十五【Try】

    <?php function AddUser($name) { if($name=="张三") { echo "add success"; return ...

  3. Unity3D学习笔记(十五):寻路系统

    动画生硬切换:animation.play();//极少使用,常用融合方法 动画融合淡入:animation.CrossFade(“Idle”, 0.2f);//0.2f为与前一动画的融合百分比为20 ...

  4. angular学习笔记(三十)-指令(6)-transclude()方法(又称linker()方法)-模拟ng-repeat指令

    在angular学习笔记(三十)-指令(4)-transclude文章的末尾提到了,如果在指令中需要反复使用被嵌套的那一坨,需要使用transclude()方法. 在angular学习笔记(三十)-指 ...

  5. angular学习笔记(三十)-指令(5)-link

    这篇主要介绍angular指令中的link属性: link:function(scope,iEle,iAttrs,ctrl,linker){ .... } link属性值为一个函数,这个函数有五个参数 ...

  6. VSTO学习笔记(十五)Office 2013 初体验

    原文:VSTO学习笔记(十五)Office 2013 初体验 Office 2013 近期发布了首个面向消费者的预览版本,我也于第一时间进行了更新试用.从此开始VSTO系列全面转向Office 201 ...

  7. Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

    目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装项目其它需要包 清除冗余文件并重新规划项目目录 配置文件 规划示例路由,并新建相关文件 实现数据访问和业务逻辑相关方法 编写mys ...

  8. [转]Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

    本文转自:https://www.cnblogs.com/zhongweiv/p/nodejs_koa2_webapp.html 目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装 ...

  9. angular学习笔记(三十)-指令(10)-require和controller

    本篇介绍指令的最后两个属性,require和controller 当一个指令需要和父元素指令进行通信的时候,它们就会用到这两个属性,什么意思还是要看栗子: html: <outer‐direct ...

  10. angular学习笔记(三十)-指令(7)-compile和link(2)

    继续上一篇:angular学习笔记(三十)-指令(7)-compile和link(1) 上一篇讲了compile函数的基本概念,接下来详细讲解compile和link的执行顺序. 看一段三个指令嵌套的 ...

随机推荐

  1. [mysql]Date和String相互转换(DATE_FORMAT&STR_TO_DATE)

    1.Date  ——>  String 使用的函数:DATE_FORMAT(date,format)     date:需要转换的日期       format:格式化的样式 format样式整 ...

  2. Linux基础命令---调整程序优先级renice

    renice renice指令可以重新调整程序运行的优先级,可以通过进程id.用户id.组id来修改优先级.修改组的等级,影响组内所有用户的所有进程优先级:修改用户等级,影响该用户的所有进程优先级.除 ...

  3. ESB(Enterprise Service Bus)企业服务总线介绍

    ESB(Enterprise Service Bus)企业服务总线介绍 ESB全称为Enterprise Service Bus,即企业服务总线.它是传统中间件技术与XML.Web服务等技术结合的产物 ...

  4. mac电脑设置USB键盘按键方法,设置多显示屏镜像显示器的方法

    mac电脑设置USB键盘按键方法,设置多显示屏镜像显示器的方法 设置多显示屏镜像显示器的方法 ==================== mac电脑复制粘贴使用command+c command+v - ...

  5. Codeforces 456A - Laptops

    题目链接:http://codeforces.com/problemset/problem/456/A One day Dima and Alex had an argument about the ...

  6. Ford VCM II Ford VCM2 Diagnostic Tool with Ford IDS v108 Installed On Laptop Ready to Use

    HOW to VCM2 Ford VCM II with Ford IDS v108 Work Well? VCM2 Ford VCM2 Ford diagnostic tool hot sale i ...

  7. 使用隐含参数testMappingSpeed排查GoldenGate抽取慢的步骤

    OGG经典抽取模式读取redo慢的检查步骤,可以采用以下几个步骤来排查. 步骤一,确认是否抽取进程的写入有问题 1. 在原有抽取进程上,执行如下命令,统计抽取进程的效率 GGSCI> stats ...

  8. Qt发布可执行程序

    在Qt Creator下用release跑一遍程序,生成相应的EXE文件.   在Qt Creator下编译好的release下的 youProgramName.exe 拷贝到一个文件夹下面:   在 ...

  9. scrapy 自定义图片路径保存,并存到数据库中

    scrapy中有个自带的pipeline工具,ImagesPipeline,可以专门用来储存图片到本地. 但默认储存地址无法配置,所以我们需要写一个自己的pipeline用于储存图片. 先分析一下我们 ...

  10. P5290 [十二省联考2019]春节十二响(堆+启发式合并)

    P5290 [十二省联考2019]春节十二响 从特殊到一般 我们先看链的情况. 我们把点$1$左右的两条子链分别扔入堆里 每次取出两个堆的最大值,把答案累加上更大的那个(另一堆为空则直接加上去). 那 ...