love2d--glsl02变量和语句
Shader分为顶点着色器和片段着色器,GPU先处理顶点再处理片段,大概可以这么理解,
顶点着色器处理模型里的点,输出处理后的数据,这些数据经过GPU其它模块处理后传入
片段着色器,经片段着色器综合后渲染。片段处理器的名字也很恰当,表明了它处理的数
据是一些顶点集合的数据片段。(以上理解仅供参考,如有错误,欢迎指正)
在love2d里片段着色器被称作像素着色器pixelcode,下文也使用像素着色器。
以上过程如下图,来自此文。

另外在泡泡网上找到了这两幅图,仅供参考。


使用shader时需要先检测显卡是否支持,可以用love.graphics.isSupported("shader")来检测,love.graphics.isSupported可以检测某个特性是否被支持,更多功能检测请参照wiki。
下面介绍一下love2d shader里的变量和函数。
变量
基本类型
|
名称 |
注释 |
|
number |
glsl里的float |
|
bool |
true false |
|
int |
整型 |
复合类型
|
名称 |
注释 |
|
Image |
glsl里的sample2d |
|
Texel(tex纹理,uv二维向量) |
glsl里的texture2d |
|
mat2、mat3、mat4 矩阵 |
投影矩阵、变换矩阵等 |
|
vec2、vec3、vec4 向量 |
位置、颜色 |
变量修饰符
|
名称 |
注释 |
|
extern |
glsl里的uniform,用来和外部程序通信,在shader里只读 |
|
const |
常量,只读 |
|
varying |
顶点和像素着色器通信用,必须在两个着色器里都用varying修饰,且在像素着色器里只读 |
更多解释请参照wiki。
还可以使用宏#define,即文本替换
#define A 2,即遇到A就用2替换,关于宏以后遇到再细说。
可以像lua那样使用变量,在shader里变量都有类型,变量名前要加上类型名,即:
number a=2;
Image b;
矩阵(二维的)和向量(一维的)的初始化如下:
vec2 a = vec2(1.0,2.0);//直接赋值
vec2 b = vec2(3.0,4.0);
vec4 c = vec4(a,b)
mat4 m = mat4(1.0) // 用1.0初始化矩阵对角线
mat2 n = mat2(a,b); //用向量赋值,行主序
mat2 k = mat2(1.0,0.0,1.0,0.0); // 直接赋值
还可以使用结构体(类似lua里的table)
struct myobject //定义一个结构体
{
vec2 pos;
vec4 color;
};
myobject mo=myobject(vec2(0.1,0.2),vec4(0.1,0.2,0.3,0));
向量成员可以使用x,y,z,w来访问位置类型的,或者r,g,b,a访问颜色类型的,或者s,t,p,q访问纹理坐标类型的,或者使用数组下标[i]。
矩阵成员可以用数组下标,如m是一个矩阵,m[0]取第一列,m[2][3]取具体值。
注意shader里的数组下标是从0开始的。
结构体可以直接用”.”访问,如上文的mo.pos。
语句
shader里的控制语句和C语言类似,
if(exp)
...;
else
...;
for (initialization; bool expression; loop expression)
...;
while(exp)
...;
do
...;
while(exp);
跳转语句有continue,break,discard,其中discard只在像素shader中使用,它将在不写入帧缓存或者深度缓存的情况下,终止当前的shader。
函数
像素着色器至少包含名为effect的函数,该函数用来处理所绘制对象的颜色变换。
顶点着色器至少包含名为position的函数,该函数用来处理所绘制对象的顶点位置变换。
这两个函数可以理解为shader的入口函数即main。
像素着色器的定义如下:
vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords )
参数详解
vec4 color 和love.graphics.setColor类似,不过它的取值范围是0--1.0,
或者是逐像素的Mesh color(以后再介绍)
Image texture 正在绘制的Image或canvas
vec2 texture_coords 像素相对于纹理的坐标,取值范围是0--1.0,y轴朝上,(1,1)是右上角
vec2 screen_coords 像素相对于屏幕的坐标,没有归一化,和love2d里的类似
返回值
vec4 返回一个rgba类型的颜色向量
注意
如果同时绘制多个canvas(如用love.graphics.setCanvas),可以使用effects替代effect,
单独处理每个canva,effects的原型如下:
void effects( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords )
{
// love_Canvases是一个可写的vec4 colors数组, 每个索引匹配一个canvas。
//如果你没有对所有激活的canvas赋值,将会出错。
love_Canvases[0] = color;
}
顶点着色器定义如下:
vec4 position( mat4 transform_projection, vec4 vertex_position )
参数
mat4 transform_projection 变换矩阵受love.graphics.translate以及投影矩阵影响
vec4 vertex_position 当前向量的原始坐标
返回值
vec4 返回一个vec4向量类型的转换后的坐标
注意
像素着色器在每次绘制像素到屏幕事都会调用,顶点着色器在每次顶点绘制到屏幕都会调用。
可以在一段着色器代码里使用两者,使用宏区分,即
#ifdef VERTEX
...顶点代码
#endif
#ifdef PIXEL
...像素代码
#endif
下面是一段简单的示例:(注意shader是类C的语言,if else和lua不同)
function love.load()
if not love.graphics.isSupported("shader") then
print("your gpu not support shader")
return
end
local shadercode=[[
extern number time; //time变量用来和外部交换,外部程序可以给这个time传值
vec4 test(number x)
{
vec4 color;
if( x>-1 && x<-0.5 )
color = vec4(0.8,0.8,0.8,1.0);
else if(x>-0.5 && x<0 )
color = vec4(0.4,0.4,0.8,1.0);
else if(x>0 && x<0.5)
color = vec4(0.2,0.2,0.4,1.0);
else
color = vec4(0.1,0.1,0.1,1.0);
return color;
}
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords)
{
//(r,g,b,a)颜色,取值0-1,这里对time变量进行操作保证结果在0-1范围内
return test(cos(time));
}
]]
--1 创建shader
myeffect = love.graphics.newShader(shadercode)
end
function love.draw()
-- 2 关闭shader,矩形为默认效果
love.graphics.setShader()
love.graphics.rectangle('fill', ,,,)
-- 2 加载effect shader,矩形效果绚丽
love.graphics.setShader(myeffect)
love.graphics.rectangle('fill', ,,,)
end
local t =
function love.update(dt)
t = t + dt
myeffect:send("time", t) --3 更新
end
附:
参考文章:http://blog.csdn.net/racehorse/article/details/6634830
love2d--glsl02变量和语句的更多相关文章
- 微软BI 之SSIS 系列 - 变量查询语句引起列输出顺序不一致的解决方法
开篇介绍 这个问题来自于 天善BI社区,看了一下比较有意思,因为我自己认为在 SSIS中处理各种类型文件的经验还比较丰富(有一年的时间几乎所有ETL都跟文件相关),但是这个问题确实之前没有特别考虑过. ...
- ADO方式,VC调用Execute执行INSERT INTO插入变量SQL语句的写法
ADO方式,VC调用Execute执行INSERT INTO插入变量SQL语句的写法 有些情况下,SQL SERVER 2008r2中需要保存float,int类型的数据,当C 中的变量为double ...
- [C][变量作用域]语句块
概述 C语言作用域有点类似于链式结构,就是下层能访问上层声明的变量,但是上层则不能访问下层声明的变量: #include <stdio.h> #define TRUE 1 int main ...
- python基础,变量,if语句
一.python初识 python是一门 解释型弱类型编程语言. 特点: 简单.明确.优雅 二.python的解释器 CPython. 官方提供的. 内部使用c语言来实现 PyPy. 一次性把我们的 ...
- javascript前端三层,字面量,变量,语句(if,switch,三元运算符,for,do while等)
1:前端三层: 结构层 HTML 样式层 CSS 行为层 JavaScript 2:JavaScript语句和语句之间的换行.空格.缩进都不敏感.alert("你");alert ...
- 什么是常量?变量? if语句介绍
1.python 的历史 2004 年 Django 的产生 phyton2与 python3 的区别 Python2:源码不统一,有重复的代码功能 Python3:源码统一,没有有重复的代码功能 2 ...
- 变量————if语句——结构使用
1简述变量的命名规范 变量是以字母 数字 下划线组合而成 不能以数字开头 不能使用python中的关键字命名 变量要具有可描述性 区分大小写 name变量是什么数据类型通过代码检测 name = in ...
- 测开之路九十八:js变量和语句
这里为了方便调试,在jsbin网站上面编写js脚本:https://jsbin.com/?js,console 可以点击增加/减少对应展示分页,Console为控制台部分,Output为页面部分 变量 ...
- JavaScript 变量,语句
定义变量的方式: var 变量可以没有初始值,变量可以修改,变量可以覆盖,存在变量提升. // 变量提升机制 console.log(name)// undefined var name = &q ...
随机推荐
- C#中载入界面的几种做法
1. 采用事件委托的方法 对象:主窗体:FrmMain 加载窗体:FrmLoading 思路: 在主窗体加载前显示窗体FrmLoading,当主窗体加载完毕后(第一次显示的时候),关闭FrmLo ...
- SWFUpload 已上传成功数量控制 插件(用于解决队列满问题)
当我们在使用 SWFUpload 做文件上传时,我们需要把已经上传的文件列表做一个删除, 但在我们把已上传列表删除后,再重新上传时,会发现提示 上传队列满 的问题,原因就是有一个状态对象中的一个 成功 ...
- Android -- Messenger与Service
如果你需要你的service和其他进程通信,那么你可以使用一个Messenger来提供这个接口. 这种方法允许你在不使用 AIDL的情况下,进行跨进程通信IPC. 实现步骤 下面是一个如何使用 Mes ...
- android学习的网站收集
1. http://mob.com/#/index 提供分享等统一解决方案 2. http://bbs.apkbus.com/explore/ 这个类似的quroa问答模块,覆盖不错.就是人气,稍差. ...
- SpringMVC基于代码的配置方式(零配置,无web.xml)直接继承WebMvcConfigurerAdapter
基于配置文件的web项目维护起来可能会更方便,但是有时候我们会有一些特殊的需求,比如防止客户胡乱更改配置,这时候我们需要给配置隐藏到代码中. 1.创建一个动态web项目(无需web.xml) 2.右键 ...
- JavaScript中isPrototypeOf函数
转自:http://www.ijavascript.cn/shouce/javascript-isprototypeof-247.html JavaScript中 isPrototypeOf 函数方法 ...
- Python 面向对象编程 继承 和多态
Python 面向对象编程 继承 和多态 一:多继承性 对于java我们熟悉的是一个类只能继承一个父类:但是对于C++ 一个子类可以有多个父亲,同样对于 Python一个类也可以有多个父亲 格式: c ...
- 推送未找到应用程序的“aps-environment”的权利字符串错误
一:使用百度推送,或是苹果自带的推送出,才配置好anps-cer文件之后,出现错误 推送未找到应用程序的“aps-environment”的权利字符串错误 二:错误原因: 此原因是配置好推送证书之后, ...
- Quartz.NET——作业调度组件
之前有个旧同事说他在项目中碰到某些功能需要使用到作业调度,于是找到了这个组件,据说相当好用,叫我有时间的话去了解一下.哈,于是小了解了一下,基本的使用算是明白了,深层次的东西就不了解了,本文简单记录一 ...
- JavaScript中字符串的match与replace方法
1.match方法 match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配. match()方法的返回值为:存放匹配结果的数组. 2.replace方法 replace() 方 ...