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. javascript刷新父页面方法总结

    用iframe.弹出子页面刷新父页面iframe <script language=JavaScript> parent.location.reload(); </script> ...

  2. SQL IN

    here are some additional clause in the SQL language that can be used to simplify queries by decrease ...

  3. build path libraries java基础--Jar包添加到build path方式说明--01

    摘自: http://blog.csdn.net/haolongabc/article/details/7007701 java基础--Jar包添加到build path方式说明--01 前言:这段短 ...

  4. 转:Mac OS X下Sublime Text (V2.0.1)破解

    Mac OS X下Sublime Text (V2.0.1)破解 Mac OS X下Sublime Text (V2.0.1)破解 (2013-03-07 14:02:54) 转载▼     正版的买 ...

  5. Oracle的操作系统身份认证

    Oracle的操作系统身份认证 oraclelogin数据库远程登录authenticationos sqlnet.authentication_services=(NTS),在$ORACLE_HOM ...

  6. 对hadoop 执行mapreduce时发生异常Illegal partition for的解决过程

    来自:http://blog.csdn.net/hezuoxiang/article/details/6878026 写了个mapreduce的JAVA程序,自定义了个partition class ...

  7. MQTT---HiveMQ源代码具体解释(四)插件载入

    源博客地址:http://blog.csdn.net/pipinet123 MQTT交流群:221405150 实现功能 将全部放在plugins文件夹下的全部符合plugin编写规范的plugin ...

  8. xampp集成包如何重置mysql的密码

    转自:http://blog.sina.com.cn/s/blog_4b2bcac501013s4l.html 安装使用xampp,装好后root默认没有密码,phpmyadmin是用config文件 ...

  9. PotPlayer 禁止更新

      PotPlayer设置禁止更新 CreateTime--2016年10月15日22:37:49 迁移时间:2017年8月9日15:36:48 Author:Marydon UpdateTime-- ...

  10. Java中try catch finally的执行顺序问题

    finally 语句块是在 try 或者 catch 中的 return 语句之前执行的.更加一般的说法是,finally 语句块应该是在控制转移语句之前执行,控制转移语句除了 return 外,还有 ...