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. hadoop源代码组织结构与阅读技巧

    本文将介绍在 Eclipse 下阅读 Hadoop 源代码的一些技巧, 比如如何查看一个基类有哪些派生类. 一个方法被其他哪些方法调用等. 本文地址:http://www.cnblogs.com/ar ...

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

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

  3. springmvc+jsp引用本地图片文件

    1.图片文件路径,注意图片文件夹和WEB-INFO文件夹同级 2.web.xml配置 <servlet-mapping> <servlet-name>default</s ...

  4. CSS中:before和:after选择器的用法

    在线演示这次给大家带来的是对话气泡效果,主要是演示了 :before / :after 和 border 的用法,赶快来围观吧. 阅读原文:CSS中:before和:after选择器的用法

  5. Scheme 4 Javaer-3.高阶函数

    1.3  Formulating Abstractions with Higher-Order Procedures 教材有时候依照学生的基础.从0讲起:有时候给出一个大图,然后具体地逐一介绍. 本文 ...

  6. 微信小程序 - 展开收缩列表

    代码源自于:微信小程序示例官方 index.wxml <block wx:for-items="{{list}}" wx:key="{{item.id}}" ...

  7. UNIX网络编程调试工具:tcpdump、netstat和lsof

    tcpdump程序 tcpdump一边从网络读入分组一边显示关于这些分组的大量信息.它还能够只显示与所指定的准则匹配的那些分组. netstat程序 netstat服务于多个目的: (1)展示网络端点 ...

  8. QtGui.QGridLayout

    The most universal layout class is the grid layout. This layout divides the space into rows and colu ...

  9. sql通过某个字段名找到数据库中对应的表

    sql通过某个字段名找到数据库中对应的表 SELECT sb.name FROM syscolumns s JOIN sysobjects sb ON s.id=sb.id WHERE s.name= ...

  10. Java lock 能被中断, synchronized 不能被中断

    1.lock是可中断锁,而synchronized 不是可中断锁 线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定, 如果使用 synchronized ,如果A不释放, ...