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变量和语句的更多相关文章

  1. 微软BI 之SSIS 系列 - 变量查询语句引起列输出顺序不一致的解决方法

    开篇介绍 这个问题来自于 天善BI社区,看了一下比较有意思,因为我自己认为在 SSIS中处理各种类型文件的经验还比较丰富(有一年的时间几乎所有ETL都跟文件相关),但是这个问题确实之前没有特别考虑过. ...

  2. ADO方式,VC调用Execute执行INSERT INTO插入变量SQL语句的写法

    ADO方式,VC调用Execute执行INSERT INTO插入变量SQL语句的写法 有些情况下,SQL SERVER 2008r2中需要保存float,int类型的数据,当C 中的变量为double ...

  3. [C][变量作用域]语句块

    概述 C语言作用域有点类似于链式结构,就是下层能访问上层声明的变量,但是上层则不能访问下层声明的变量: #include <stdio.h> #define TRUE 1 int main ...

  4. python基础,变量,if语句

     一.python初识 python是一门 解释型弱类型编程语言. 特点: 简单.明确.优雅 二.python的解释器 CPython. 官方提供的. 内部使用c语言来实现 PyPy. 一次性把我们的 ...

  5. javascript前端三层,字面量,变量,语句(if,switch,三元运算符,for,do while等)

    1:前端三层: 结构层 HTML 样式层 CSS 行为层 JavaScript  2:JavaScript语句和语句之间的换行.空格.缩进都不敏感.alert("你");alert ...

  6. 什么是常量?变量? if语句介绍

    1.python 的历史 2004 年 Django 的产生 phyton2与 python3 的区别 Python2:源码不统一,有重复的代码功能 Python3:源码统一,没有有重复的代码功能 2 ...

  7. 变量————if语句——结构使用

    1简述变量的命名规范 变量是以字母 数字 下划线组合而成 不能以数字开头 不能使用python中的关键字命名 变量要具有可描述性 区分大小写 name变量是什么数据类型通过代码检测 name = in ...

  8. 测开之路九十八:js变量和语句

    这里为了方便调试,在jsbin网站上面编写js脚本:https://jsbin.com/?js,console 可以点击增加/减少对应展示分页,Console为控制台部分,Output为页面部分 变量 ...

  9. JavaScript 变量,语句

    定义变量的方式: var   变量可以没有初始值,变量可以修改,变量可以覆盖,存在变量提升. // 变量提升机制 console.log(name)// undefined var name = &q ...

随机推荐

  1. C#中载入界面的几种做法

    1. 采用事件委托的方法  对象:主窗体:FrmMain 加载窗体:FrmLoading  思路:  在主窗体加载前显示窗体FrmLoading,当主窗体加载完毕后(第一次显示的时候),关闭FrmLo ...

  2. SWFUpload 已上传成功数量控制 插件(用于解决队列满问题)

    当我们在使用 SWFUpload 做文件上传时,我们需要把已经上传的文件列表做一个删除, 但在我们把已上传列表删除后,再重新上传时,会发现提示 上传队列满 的问题,原因就是有一个状态对象中的一个 成功 ...

  3. Android -- Messenger与Service

    如果你需要你的service和其他进程通信,那么你可以使用一个Messenger来提供这个接口. 这种方法允许你在不使用 AIDL的情况下,进行跨进程通信IPC. 实现步骤 下面是一个如何使用 Mes ...

  4. android学习的网站收集

    1. http://mob.com/#/index 提供分享等统一解决方案 2. http://bbs.apkbus.com/explore/ 这个类似的quroa问答模块,覆盖不错.就是人气,稍差. ...

  5. SpringMVC基于代码的配置方式(零配置,无web.xml)直接继承WebMvcConfigurerAdapter

    基于配置文件的web项目维护起来可能会更方便,但是有时候我们会有一些特殊的需求,比如防止客户胡乱更改配置,这时候我们需要给配置隐藏到代码中. 1.创建一个动态web项目(无需web.xml) 2.右键 ...

  6. JavaScript中isPrototypeOf函数

    转自:http://www.ijavascript.cn/shouce/javascript-isprototypeof-247.html JavaScript中 isPrototypeOf 函数方法 ...

  7. Python 面向对象编程 继承 和多态

    Python 面向对象编程 继承 和多态 一:多继承性 对于java我们熟悉的是一个类只能继承一个父类:但是对于C++ 一个子类可以有多个父亲,同样对于 Python一个类也可以有多个父亲 格式: c ...

  8. 推送未找到应用程序的“aps-environment”的权利字符串错误

    一:使用百度推送,或是苹果自带的推送出,才配置好anps-cer文件之后,出现错误 推送未找到应用程序的“aps-environment”的权利字符串错误 二:错误原因: 此原因是配置好推送证书之后, ...

  9. Quartz.NET——作业调度组件

    之前有个旧同事说他在项目中碰到某些功能需要使用到作业调度,于是找到了这个组件,据说相当好用,叫我有时间的话去了解一下.哈,于是小了解了一下,基本的使用算是明白了,深层次的东西就不了解了,本文简单记录一 ...

  10. JavaScript中字符串的match与replace方法

    1.match方法 match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配. match()方法的返回值为:存放匹配结果的数组. 2.replace方法 replace() 方 ...