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 ...
随机推荐
- http://blog.csdn.net/steveguoshao/article/details/38414145
http://blog.csdn.net/steveguoshao/article/details/38414145
- JAVA , TOMCAT , AXIS2 环境变量配置
想要成功配置Java的环境变量,那肯定就要安装JDK,才能开始配置的. 安装JDK 向导进行相关参数设置.如图: 正在安装程序的相关功能,如图: 选择安装的路径,可以自定义,也可以默认路径.如图: 成 ...
- Why does Typescript use the keyword “export” to make classes and interfaces public?
原文: https://stackoverflow.com/questions/15760462/why-does-typescript-use-the-keyword-export-to-make- ...
- [Functional Programming] Pointy Functor Factory
A pointed functor is a functor with an of method class IO { // The value we take for IO is always a ...
- JQuery 控制div滚动条保持最下
$("#session_show").animate({ scrollTop: $("#session_show").scrollHeight },1000); ...
- ffmpeg & mplayer & vlc 手册(转)
如何基于FFMPEG和SDL写一个少于1000行代码的视频播放器 http://blog.sina.com.cn/s/blog_51396f890100nd91.html http://lanhy20 ...
- 改善C#程序的建议2:C#中dynamic的正确用法
dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...
- java.lang.IllegalArgumentException: taglib definition not consistent with specification version
web.xml报错 taglib标签错误,3.0要用jsp-config <jsp-config> <taglib> <taglib-uri>& ...
- Android内存泄漏分析实战
内存泄漏简单介绍 java能够保证当没有引用指向对象的时候,对象会被垃圾回收器回收.与c语言自己申请的内存自己释放相比,java程序猿轻松了非常多.可是并不代表java程序猿不用操心内存泄漏.当jav ...
- SpriteKit改变Node锚点其物理对象位置不对的解决
在创建Node的物理对象后,默认情况下物理对象和Node的实际边界相应的非常好,由于此时Node的默认锚点是当中心位置即(0.5,0.5),只是假设我们改变了Node的锚点,就会发现其物理边界还是保持 ...