unity shader入门(二)语义,结构体,逐顶点光照
下为一个逐顶点漫反射光照shader
Shader "study/Chapter6/vertexShader"{
Properties{
_Diffuse("Diffuse",Color)=(1, 1, 1, 1)//材质的漫反射属性
//声明一个Color类型的属性
}
SubShader{
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//unity的内置文件,为了可以使用unity的一些内置变量,如后面的——LightColor0
#include "Lighting.cginc"
//匹配属性的变量,关于属性和变量的匹配,下面有
fixed4 _Diffuse;
//顶点着色器输入结构体,结构体下面有
struct a2v{
float4 vertex:POSITION;//存储模型顶点
float3 normal:NORMAL; //存储模型顶点法线
};
//顶点着色器输出结构体,同时也是片元着色器输入结构体
struct v2f{
float4 pos:SV_POSITION;
fixed3 color:COLOR;//将顶点着色器计算的光照颜色传递给片元着色器
};
//顶点着色器
v2f vert(a2v v){
v2f o;
//将顶点从模型空间转化到裁剪空间
o.pos=UnityObjectToClipPos(v.vertex);
//获取外部项,通过unity内置函数UNITY_LIGHTMODEL_AMBIENT获取环境光部分
fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;
//将法线从模型空间转化到世界空间
fixed3 worldNormal=normalize(mul(v.normal,(float3x3)unity_WorldToObject));
//光源方向,_WorldSpaceLightPos0假设场景中只有一个平行光源才能得到正确方向
fixed3 worldLight=normalize(_WorldSpaceLightPos0.xyz);
//_LightColor0为unity内置变量访问该Pass处理的光源的颜色和强度信息
//下面给出漫反射计算公式
fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLight));
o.color=ambient+diffuse;
return o;
}
//片元着色器
fixed4 frag(v2f i):SV_TARGET{
return fixed4(i.color,1.0);
}
ENDCG
}
}
//把这个unity shader的回调设置为内置的Diffuse
FallBack "Diffuse"
}
首先下边是Unity支持的语义



现在来看看顶点输入结构体
struct a2v{
float4 vertex:POSITION;//存储模型顶点
float3 normal:NORMAL; //存储模型顶点法线
};
这个叫a2v的结构体包含了顶点着色器需要的模型数据,a2v表示application to vertex shader,把数据从应用阶段传递到顶点着色器中
一个结构体的格式如下
struct structname{
Type(数据类型) Name(变量名):Semantic(语义);
Type(数据类型) Name(变量名):Semantic(语义);
Type(数据类型) Name(变量名):Semantic(语义);
......
};
我们一般是从顶点着色器输出一些数据比如模型的法线,坐标纹理等给片元着色器就需要通过上述代码中的v2f结构体来实现两者通信。
顶点着色器是逐顶点调用的,片元着色器是逐片元调用的。片元着色器实际上是吧顶点着色器的输出进行差值后得到的结果。
在顶点着色器中做的就是把顶点着色器输入结构体作为(上为a2v)中顶点的一些信息经过一顿操作转换为v2f(就是个函数),然后将这个v2f丢到片元着色器中再
一顿操作,然后输出一个颜色 下面是属性与变量匹配关系

比如你在properties中声明了一个2D属性,在CG中你就要声明一个sample2D变量来匹配这个2D属性,声明的属性名必须与变量名一致,
比如上面都是_Diffuse。取值范围上fixed<half<float,在移动端平台上需要注意下。 我们看到的光=环境光/自发光+漫反射+高光反射
漫反射计算公式
漫反射=(光源颜色*材质的漫反射颜色)max(0,表面法线*光源的单位矢量) 为了防止法线和光源方向点乘的结果为负值,需要使用去最大值函数
将其截取到0,以防止物体被从后面的光源照亮。
得到的材质球效果如下

unity shader入门(二)语义,结构体,逐顶点光照的更多相关文章
- unity shader入门(三)逐像素光照,Blinn-Phong模型
与上篇逐顶点光照很像,只是改为在片元着色器中计算光照,下为逐像素光照shader Shader "study/Chapter6/PixelShader"{ Properties{ ...
- Unity Shader入门精要学习笔记 - 第7章 基础纹理
转自 冯乐乐的 <Unity Shader 入门精要> 纹理最初的目的就是使用一张图片来控制模型的外观.使用纹理映射技术,我们可以把一张图“黏”在模型表面,逐纹素地控制模型的颜色. 在美术 ...
- Unity Shader入门精要学习笔记 - 第6章 开始 Unity 中的基础光照
转自冯乐乐的<Unity Shader入门精要> 通常来讲,我们要模拟真实的光照环境来生成一张图像,需要考虑3种物理现象. 首先,光线从光源中被发射出来. 然后,光线和场景中的一些物体相交 ...
- Unity Shader入门精要学习笔记 - 第4章 学习 Shader 所需的数学基础
摘录自 冯乐乐的<Unity Shader入门精要> 笛卡尔坐标系 1)二维笛卡尔坐标系 在游戏制作中,我们使用的数学绝大部分都是计算位置.距离.角度等变量.而这些计算大部分都是在笛卡尔坐 ...
- unity shader 入门
1.一个简单的顶点/片元着色器基本结构 Shader "Unity Shaders Book/Chapter 5/Simple Shader" { } SubShader { Pa ...
- Unity Shader 入门精要学习 (冯乐乐 著)
第1篇 基础篇 第1章 欢迎来到Shader的世界 第2章 渲染流水线 第3章 Unity Shader 基础 第4章 学习Shader所需的数学基础 第2篇 初级篇 第5章 开始Unity Shad ...
- Unity Shader入门精要学习笔记 - 第17章 Unity的表面着色器探秘
转自 冯乐乐的<Unity Shader 入门精要> 2010年的Unity 3 中,Surface Shader 出现了. 表面着色器的一个例子. 我们先做如下准备工作. 1)新建一个场 ...
- Unity Shader入门精要学习笔记 - 第12章 屏幕后处理效果
建立一个基本的屏幕后处理脚本系统 屏幕后处理,顾名思义,通常指的是在渲染完整个场景得到屏幕图像后,再对这个图像进行一系列操作,实现各种屏幕特效.使用这种技术,可以为游戏画面添加更多艺术效果,例如景深. ...
- Unity Shader入门精要学习笔记 - 第9章 更复杂的光照
转载自 冯乐乐的<Unity Shader入门精要> Unity 的渲染路径 在Unity里,渲染路径决定了光照是如何应该到Unity Shader 中的.因此,如果要和光源打交道,我们需 ...
- Unity Shader入门精要学习笔记 - 第8章 透明效果
转载自 冯乐乐的 <Unity Shader入门精要> 透明是游戏中经常要使用的一种效果.在实时渲染中要实现透明效果,通常会在渲染模型时控制它的透明通道.当开启透明混合后,当一个物体被渲染 ...
随机推荐
- CRT 上传下载文件
yum install -y lrzsz 上传 rz -be 下载 sz 文件名
- J-CUBE Appears at AVATAR Xprize at Geneva 2019
2019年5月27日,瑞士日内瓦,Avatar Xprize发布会隆重举行.非常荣幸的是,J-CUBE也受邀参加此次大会. 关于Avatar Xprize项目的介绍 https://avatar.xp ...
- Centos7下的文件压缩
[root@web01 ~]# yum provides zip 已加载插件:fastestmirror Loading mirror speeds from cached hostfile * ba ...
- WPF Button LinkButton 绑定多个值 Template
效果如下: 代码如下: <Button Click="InventoryDetail_OnClick" Template="{StaticResource Inve ...
- 【Gitlab】宝塔gitlab 修改管理员账号密码
步骤: a. 切换目录:cd /opt/gitlab/bin b.执行 :sudo gitlab-rails console production 命令 开始初始化密码 c.在 irb(main):0 ...
- python:字符串中提取特定的数据
在日志文件中有一大堆,格式相同的文本,需要提取出接口耗时的时间 >>> 运单号:71742507538566,快递100接口耗时:8,返回结果:[{"lengthPre&q ...
- .NetCore中EFCore的使用整理(三)-关联表操作
一.查询关联表数据 StudyAboard_TestContext _context = new StudyAboard_TestContext(); CrmRole role = _context. ...
- vue获取不到后端返回的响应头
Response.ContentType = EPPlusHelpler.ExcelContentType; Response.Headers.Add("FileName", fi ...
- 【ARM-Linux开发】用VS2013+VELT-0.1.4进行海思平台 Linux内核 的开发
1.1 什么是VELT VELT的全称是Visual EmbedLinuxTools,它是一个与visual gdb类似的visual studio插件,用以辅助完成Linux开发.利用这个插件 ...
- Oracle Spatial分区应用研究之七:同等分区粒度下全局索引优于分区索引的原因分析
1.实验结论 同等分区粒度下,使用分区空间索引进行空间查询,比使用全局空间索引进行查询,对数据字典表的访问次数更多.假设分区数为X,则大概多3X次访问.具体说明见6实验结论. 2.实验目的 在之前的测 ...