关于Unity中Cg的基本语法和使用
Cg是类似于C语言的发展起来的图形编程语言,Cgraphics,它的很多表达式if...else...和C语言非常相像,也和C#非常相像。
由于Shader是写给显卡执行的,所以没有输出语句来调试,很多地方调试不了,只能靠Unity编辑器来帮我们报错,写起来一定要小心谨慎。
基本类型表达式
1:语法和C语言类是,有对应的编译器,程序是给显卡运行;
2: 可以从渲染流水线中获得对应的输入;
3: 指定的输出能流入下一个流水线模块;
4: 操作符号和C语言一样,可以使用 +, -, * / <, >, <=, >= 等运算;
5: Cg提供了float half double 浮点类型;单精度,半精度,双精度
7: Cg 支持定点数 fixed来高效处理 某些小数;
8: Cg使用int来表示整数;
9: bool 数据类型来表示逻辑类型;
10:sampler*,纹理对象的句柄, sampler/1D/2D/3D/CUBE/RECT,往shader里面关联一个图片,关联纹理Texture,使用sampler
11: 内置向量数据类型: float4(float, float, float, float), 向量长度不能超过4;
12: 内置矩阵数据类型: float1x1 float2x3 float4x3 float4x4;不能超过4x4;
13: 数组类型float a[10]; 10个float, float4 b[10], 10个float4;
14: 语义绑定 float4 a : POSITION,返回值也可以语义绑定;获得上一个工位的数据和流向下一个工位的输出。只有绑定语义如Position,上一个工位才知道要传顶点的位置给它。
fixed定点数:如有一个32bit的Int,我要把前面16位表示整数,后面16位表示小数,用来存放35.4这个数,这个数据类型叫做定点数。实质是用整数表示小数,因为35.4输出的时候是一个比较大的整数,而它的内容里面可以表示小数。
定点数的加减法实际上也就是整数的加减法,性能比浮点数好,颜色就是用fixed类型表示fixed4。
结构体与语义
1: struct name {
类型 名字;
// 尽量不要使用;
返回值 函数名称(参数) { // 如果成员函数里面使用,数据成员,该成员定义在函数前;
}
};
2:输入语义与输出语义:
语义: 一个阶段处理数据,然后传输给下一个阶段,那么每个阶段之间的接口, 例如:顶点处理器的输入数据是处于模型空间的顶点数据(位置、法向量),输出的是投影坐标和光照颜色;片段处理器要将光照颜色做为输入;C/C++用指针,而Cg通过语义绑定的形式;
输入语义: 绑定接收参数,从上一个流水线获得参数;
输出语义: 绑定输出参数到下一个流水线模块;
语义: 入口函数上有意义(顶点着色入口,像素着色入口),普通的函数无意义;
常用语义修饰
1:POSITION : 位置
2:TANGENT : 切线
3: NORMAL: 法线
4: TEXCOORD0: 第一套纹理
5: TEXCOORD1: 第二套纹理
6: TEXCOORD2: 第三套纹理
7: TEXCOORD3: 第四套纹理
8: COLOR: 颜色
标准内置函数
1:abs(num)绝对值;
2: 三角函数;
3: cross(a, b) 两个向量的叉积;
4: determinant(M)矩阵的行列式;
5: dot(a, b) 两个向量的点积;
6: floor(x)向下取整;
7: lerp(a, b, f), 在a, b之间线性插值;
8: log2(x) 基于2为底的x的对数;
9: mul(m, n): 矩阵x矩阵, 矩阵x向量, 向量x矩阵;
10: power(x, y) x的y次方;
11: radians(x) 度转弧度;
12: reflect(v, n) v 关于法线n的反射向量;
13: round(x) 靠近取整;
14: tex2D(smapler, x) 二维纹理查找
15: tex3Dproj(smapler, x) 投影三维纹理查找;
16: texCUBE 立方体贴图纹理查找;
Unity自带函数
1: 引用Unity自带的函数库: #include “UnityCG.cginc” Unity-->Edit-->Data-->CGIncludes;
2: TRANSFORM_TEX: 根据顶点的纹理坐标,计算出对应的纹理的真正的UV坐标;
3: 使用属性的变量: 在shader里面需要使用属性变量还需要在shader中定义一下这个变量的类型和名字;
名字要保持一致;
4: 外部修改shader的编辑器上的参数值;
例子:打开上次的那个MyShader
1.使用编辑器的颜色对物体进行着色
Shader "Custom/MyShader" {
// 属性,可以在编辑器里面bind和修改的;
Properties {
_Color ("Color", Color) = (,,,)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(,)) = 0.5
_Metallic ("Metallic", Range(,)) = 0.0
}
SubShader {
Pass {
CGPROGRAM // 插入Cg代码开始
fixed4 _Color; //必须定义同样的变量才能使用它
#pragma vertex my_vert // 把my_vert作为顶shader的入口
// 怎么样获得这个上一个工位的参数; -->语义bind
float4 my_vert(float4 pos : POSITION) : POSITION {
return mul(UNITY_MATRIX_MVP, pos);
}
#pragma fragment my_frag
fixed4 my_frag() : COLOR{
return _Color;//使用编辑器选择的颜色,着色物体
}
ENDCG // 插入Cg代码结束
}
}
FallBack "Diffuse"
}
2.使用编辑器的纹理对物体进行绘制
Shader "Custom/MyShader" {
// 属性,可以在编辑器里面bind和修改的;
Properties {
_Color ("Color", Color) = (,,,)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(,)) = 0.5
_Metallic ("Metallic", Range(,)) = 0.0
}
SubShader {
Pass {
CGPROGRAM // 插入Cg代码开始
//fixed4 _Color; // 定义同样的变量
sampler2D _MainTex; // 定义同样名字的变量;
#pragma vertex my_vert // 把my_vert作为顶shader的入口
// 怎么样获得这个上一个工位的参数; -->语义bind
float4 my_vert(float4 pos : POSITION) : POSITION {
return mul(UNITY_MATRIX_MVP, pos);
}
#pragma fragment my_frag
fixed4 my_frag(float2 uv : TEXCOORD0) : COLOR{
//return _Color;//使用编辑器选择的颜色,着色物体
return tex2D(_MainTex, uv);//根据uv来查到纹理并返回,我的理解是返回的东西就帮我们绘制了。uv---->_MainTex---->tex2D---->放回tex2D
}
ENDCG // 插入Cg代码结束
}
}
FallBack "Diffuse"
}
编写好代码后把贴图拖进材质球MyShader的纹理属性中,视图中就显示出对应的纹理贴图。
3.定义结构体和函数来使用
Shader "Custom/MyShader" {
// 属性,可以在编辑器里面bind和修改的;
Properties {
_Color ("Color", Color) = (,,,)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(,)) = 0.5
_Metallic ("Metallic", Range(,)) = 0.0
}
SubShader {
Pass {
CGPROGRAM // 插入Cg代码开始
struct my_struct {
int a;
};
float sum(float a, float b) {
return a + b;
}
fixed4 _Color; // 定义同样的变量
#pragma vertex my_vert // 把my_vert作为顶shader的入口
// 怎么样获得这个上一个工位的参数; -->语义bind
float4 my_vert(float4 pos : POSITION) : POSITION {
return mul(UNITY_MATRIX_MVP, pos);
}
#pragma fragment my_frag
fixed4 my_frag() : COLOR{
return _Color;
}
ENDCG // 插入Cg代码结束
}
}
FallBack "Diffuse"
}
4.语义绑定可以绑定一个结构体,在结构体里面再指定哪个属性。Unity其实给我们定义了很多常用的结构体,可以直接使用,在 “UnityCG.cginc” Unity-->Edit-->Data-->CGIncludes;里面查看
Shader "Custom/MyShader" {
// 属性,可以在编辑器里面bind和修改的;
Properties {
_Color ("Color", Color) = (,,,)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(,)) = 0.5
_Metallic ("Metallic", Range(,)) = 0.0
}
SubShader {
Pass {
CGPROGRAM // 插入Cg代码开始
fixed4 _Color; // 定义同样的变量
//结构体包装语义
struct my_vert_data {
float4 pos : POSITION;
};
#pragma vertex my_vert // 把my_vert作为顶shader的入口
// 怎么样获得这个上一个工位的参数; -->语义bind
float4 my_vert(my_vert_data data) : POSITION {
return mul(UNITY_MATRIX_MVP, data.pos);
}
#pragma fragment my_frag
fixed4 my_frag(float2 uv : TEXCOORD0) : COLOR{
return _Color;
}
ENDCG // 插入Cg代码结束
}
}
FallBack "Diffuse"
}
使用C#脚本来控制和编写shader
0.shader文件里面的代码是这样的:
Shader "Custom/MyShader" {
// 属性,可以在编辑器里面bind和修改的;
Properties {
_Color ("Color", Color) = (,,,)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(,)) = 0.5
_Metallic ("Metallic", Range(,)) = 0.0
}
SubShader {
Pass {
CGPROGRAM // 插入Cg代码开始
fixed4 _Color; //必须定义同样的变量才能使用它
#pragma vertex my_vert // 把my_vert作为顶shader的入口
// 怎么样获得这个上一个工位的参数; -->语义bind
float4 my_vert(my_vert_data data) : POSITION {
return mul(UNITY_MATRIX_MVP, data.pos);
}
#pragma fragment my_frag
fixed4 my_frag() : COLOR{
return _Color;//使用编辑器选择的颜色,着色物体
}
ENDCG // 插入Cg代码结束
}
}
FallBack "Diffuse"
}
1.创建一个叫shader_ctrl的脚本
2.挂载到Cube节点下,这个Cube的材质属性就是Myshader材质球,Myshader材质球的shader属性是MyShader.shader文件
3.打开shader_ctrl的脚本,内容如下(记得关联public 材质属性):
using UnityEngine;
using System.Collections; public class shader_ctrl : MonoBehaviour {
public Material material;
// Use this for initialization
void Start () {
material.SetColor("_Color", new Color(1.0f, 0.0f, 0.0f, 1.0f));//修改颜色为红色
} // Update is called once per frame
void Update () { }
}
4.运行,发现cube变红色
关于Unity中Cg的基本语法和使用的更多相关文章
- 解读Unity中的CG编写Shader系列七(不透明度与混合)
转自http://www.itnose.net/detail/6098539.html 1.不透明度 当我们要将两个半透的纹理贴图到一个材质球上的时候就遇到混合的问题,由于前面的知识我们已经知道了片段 ...
- 解读Unity中的CG编写Shader系列八(镜面反射)
转自http://www.itnose.net/detail/6117378.html 讨论完漫反射之后,接下来肯定就是镜面反射了 在开始镜面反射shader的coding之前,要扩充一下前面提到的知 ...
- 解读Unity中的CG编写Shader系列三
转自http://www.itnose.net/detail/6096068.html 在上一个例子中,我们得到了由mesh组件传递的信息经过数学转换至合适的颜色区间以颜色的形式着色到物体上.这篇文章 ...
- Unity中的CG编写Shader系列(Blend)
1.不透明度 当我们要将两个半透的纹理贴图到一个材质球上的时候就遇到混合的问题,由于前面的知识我们已经知道了片段着色器以及后面的环节的主要工作是输出颜色与深度到帧缓存中,所以两个纹理在每个像素上的颜色 ...
- [转]解读Unity中的CG编写Shader系列9——镜面反射
讨论完漫反射之后,接下来肯定就是镜面反射了在开始镜面反射shader的coding之前,要扩充一下前面提到的知识,加深理解镜面反射与漫反射的区别.注:这篇文章实现的镜面反射是逐顶点着色(per-ver ...
- [转]解读Unity中的CG编写Shader系列6——不透明度与混合
1.不透明度当我们要将两个半透的纹理贴图到一个材质球上的时候就遇到混合的问题,由于前面的知识我们已经知道了片段着色器以及后面的环节的主要工作是输出颜色与深度到帧缓存中,所以两个纹理在每个像素上的颜色到 ...
- [转]解读Unity中的CG编写Shader系列3——表面剔除与剪裁模式
在上一个例子中,我们得到了由mesh组件传递的信息经过数学转换至合适的颜色区间以颜色的形式着色到物体上.这篇文章将要在此基础上研究片段的擦除(discarding fragments)和前面剪裁.后面 ...
- 解读Unity中的CG编写Shader系列3——表面剔除与剪裁模式
在上一个样例中,我们得到了由mesh组件传递的信息经过数学转换至合适的颜色区间以颜色的形式着色到物体上. 这篇文章将要在此基础上研究片段的擦除(discarding fragments)和前面剪裁.后 ...
- 使用AVPro Video在Unity中播放开场视频(CG)笔记
游戏中的开场CG(播放视频),采用的插件为AVPro Video1.x(和W的版本一致),Unity版本为2018.4.0f1 Asset Store:AVPro Video - Core Andro ...
随机推荐
- IOS之Accessor method
1 前言 本章主要介绍了Objective-C中的存取方法的相关概念. 2 详述 存储方法是一个可以获得或者设置一个对象的属性值的实例方法.在Cocoa的术语中,一个检索对象属性值的方法提及为gett ...
- POJ 1200 Crazy Search(字符串简单的hash)
题目:http://poj.org/problem?id=1200 最近看了一个关于hash的问题,不是很明白,于是乎就找了些关于这方面的题目,这道题是一道简单的hash 字符串题目,就先从他入手吧. ...
- schema的作用
1,如果schema中定义的字段类型和数据库中该字段存储值的类型不一致(可以不定义,但定义的时候类型必须一致),则该字段查找不到,mongoose不会返回该字段的数据 2,如果数据库中有字段a,而sc ...
- Debugging Java Native Memory Leaks
GZIP造成JAVA Native Memory泄漏案例 https://www.elastic.co/blog/tracking-down-native-memory-leaks-in-elasti ...
- [Windows Azure] Windows Azure Identity
Windows Azure Identity Managing identity is just as important in the public cloud is it is on premis ...
- 基于tcpdump的Android智能移动终端数据包捕获完整解决方案
如何在Android智能手机上捕获数据包? 本文由CSDN-蚍蜉撼青松[主页:http://blog.csdn.net/howeverpf]原创,转载请注明出处! 当前Android系统越来越流行,无 ...
- 【ARM】AD转换器
A/D转换器 A/D转换器,又称模/数转换器,顾名思义,就是把模拟信号数字化. 由于系统的实际处理对象往往都是一些模拟量(如温度.压力.位移.图像等),要使计算机或数字仪表能识别和处理这些信号,必须首 ...
- 说说Python程序的执行过程
1. Python是一门解释型语言? 我初学Python时,听到的关于Python的第一句话就是,Python是一门解释性语言,我就这样一直相信下去,直到发现了*.pyc文件的存在.如果是解释型语言, ...
- Codeforces Round #215 (Div. 2) D. Sereja ans Anagrams
http://codeforces.com/contest/368/problem/D 题意:有a.b两个数组,a数组有n个数,b数组有m个数,现在给出一个p,要你找出所有的位置q,使得位置q q+ ...
- nginx报502 bad GateWay错误的解决方法
nginx+php-fpm+mysql的网站,访问nginx的某个页面,报502 GateWay的错误,一般见到此错误,可以判断是php-fpm的问题,而不是nginx的问题.通过监控nginx的错误 ...