学习ShaderToy第一天: glsl语言内置函数gl_FragCoord

2023-11-02

运行环境:Android
opengl es版本: 2.0
3D引擎库 : Rajawali3D

ShaderToy上用的shader语言 为glsl , 效果是用webgl跑的,而webgl封装了opengl es, 所以ShaderToy上的例子同样使用于Android端。

ShaderToy基本上 都是用fragment shader 对栅格化后的像素进行处理。 大部分会用到纹理来丰富最终渲染结果的形状和质地,有些也会用到声音,键盘等外部输入信息。 但是,最终都是归结为对栅格化区域内的每个像素进行处理,因此,我们首先来认识gl_FragCoord这个内置变量以及其与屏幕坐标的关系。

gl_FragCoord根据glsl language spec的解释为:
它是fragment shaders的输入变量,并持有该framgent的屏幕相对坐标(x, y, z, 1/w)

什么是屏幕相对坐标,它的坐标范围是多少,这些都没有告诉我们。需要我们实验

假设我们采用2d ortho projection的方式来渲染,输入的顶点信息为屏幕的4个顶点坐标,这样我们最终渲染出来的是一个 铺满屏幕的图。
由于是2D渲染,最终每个fragment的 gl_FragCoord的z接近0.0, 而w 为1.0, 而它的x, y分量,是相对于屏幕左下角为原点的屏幕坐标。什么意思?
假如,我们设定的viewport的渲染区域为(0, 0, 1280, 574) 这么大,那么,gl_Fragment的x分量 范围就在0~1280之间, y分量就在0~574之间。

我们可以用一下测试用例来进行测试:
vertex shader:

precision mediump float ;

uniform mat4 uMVPMatrix;
attribute vec4 aPosition;

void main(){
position = vec3 (uMVPMatrixaPosition);
gl_Position = uMVPMatrix
aPosition;
}

fragment shader:

precision mediump float ;

uniform vec2 screenSize; // step 1 gl_FragCoord的坐标像素范围

void main()
{
vec2 uv = vec2(gl_FragCoord.xy/screenSize.xy); // step 2 将每个fragment的 每个gl_FragCoord归一化,这是一个惯例,利于后面计算,screenSize 表示屏幕的宽度和宽高

//Calculate polar coordinates
 float r = length(uv);
 float c = 0.0;

if(uv.x>0.98 &&uv.x<1.0 )                       // step 3
{
   c = 1.0;
}

 if(uv.y>0.98 &&uv.y<1.0 )                     // step 4
 {
   c = 1.0;
 }

 //Calculate the final color mixing lines and backgrounds.
 vec3 bg = mix(vec3(0.93 , 0.71 ,  0.62 ),  vec3(0.9 , 0.44 , 0.44),   r);  // step 5
 bg = mix(bg, vec3 (0.9 , 0.91 , 0.62 ), c);                                //  step 6

 gl_FragColor = vec4(bg, 1.0);

}

运行后,效果图如下:

这里主要说下 fragment shader:
step 1: 之前说到, gl_FragCoord的坐标范围, 这里screenSize 表示屏幕的宽高。
step 2 : 将每个fragment的 每个gl_FragCoord归一化,这是一个惯例,利于后面计算
step3: 和 step4: 这两个分别表示,当fragment的坐标(x, y) 的x和y分量分别落在这个范围时(即中间)c 的值会发生变化
step5: step5 和 step6都用到了glsl 的 mix内置函数, 考虑到 bg = mix(color1, color2, r)它的意思,就是将color1和color2 两种颜色,按照bg = color1*(1-r)+r*color2的方式混合,其中bg, color1, color2都是表示颜色,有三个分量。 那么,当r=0.0时,表示的是color1颜色,当r = 1.0表示的是color2颜色。 我们利用mix可以在一种背景上标记出另一种颜色。

step3 和 step4 表示,当x, y 分别落在值范围的中间时,c的值从0.0变为1.0, 即在这个范围内,背景色变为我们设置的颜色。

当我们把step3 和 step4 改为:
if (uv.x> 0.09 &&uv.x< 0.11 ) // step 3
{
c = 1.0;
}

  if  (uv.y> 0.09  &&uv.y< 0.11  )                     // step 4
 {
   c = 1.0;
 }

效果图如下:

在这里插入图片描述

通过,以上的例子我们得出gl_FragCoord的正确表示方式。

上面是标准的GLSL语法,如果要改成shadertoy能运行的shader,需要修改:

//void mainImage( out vec4 fragColor, in vec2 fragCoord )
//{
//    // Normalized pixel coordinates (from 0 to 1)
//    vec2 uv = fragCoord/iResolution.xy;
//
//    // Time varying pixel color
//    vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
//
//    // Output to screen
//    fragColor = vec4(col,1.0);
//}



//uniform vec2 screenSize;  // step  1precision mediump float ;
//uniform vec4 gl_FragColor;
//vec4 FragColor;

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    

     vec2 uv = fragCoord/iResolution.xy; // step 2

    //Calculate polar coordinates
     float r = length(uv);
     float c = 0.0;

    if(uv.x>0.98 &&uv.x<1.0 )                       // step 3
    {
       c = 1.0;
    }

     if(uv.y>0.98 &&uv.y<1.0 )                     // step 4
     {
       c = 1.0;
     }

     //Calculate the final color mixing lines and backgrounds.
     vec3 bg = mix(vec3(0.93 , 0.71 ,  0.62 ),  vec3(0.9 , 0.44 , 0.44),   r);  // step 5
     bg = mix(bg, vec3 (0.9 , 0.91 , 0.62 ), c);                                //  step 6

     //fragCoord = vec4(bg, 1.0);
      fragColor = vec4(bg, 1.0);
}


在这里插入图片描述
最后附上一张shadertoy官网的图片,凑够三张图,哈哈
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

学习ShaderToy第一天: glsl语言内置函数gl_FragCoord 的相关文章

随机推荐

  • git 拉取大文件超时解决方案

    1 设置深度 git clone depth 1 https gitee com tcwong pengExpressMS git cd yyyy 目录下 2 配置文件 git config add core compression 1 3
  • Git实战之git客户端上传文件到github

    Git实战之git客户端上传文件到github 一 Git介绍 1 Git简介 2 版本控制系统的分类 二 检查本地系统版本 三 windows安装Git客户端 1 进入windows的powershell 2 安装git客户端 3 检查安
  • 阿里云服务器部署flask项目「gunicorn + nginx + 支持https」

    最近做了一个微信小程序 使用 flask 实现了对应的后台 上线需要部署到服务器上 之前只是了解并没有全链路试过 靠着网上的资料最终完成部署上线 但中间遇到了较多的一些问题 网上的资料也比较零碎 所以整理了这篇文章 一方面是作为记录方便后续
  • JSP关闭触发事件,当点关闭页面按钮触发JS函数、事件,调用退出方法

    JSP控制关闭浏览器调用事件 第一种方法 window onbeforeunload function var n window event screenX window screenLeft var b n gt document doc
  • 关于虚拟化的问题解决记录

    一 背景 在去年购买了机械革命Code1 搭配的AMD芯片 但是由于虚拟化问题 虚拟机和Docker都迟迟没有进行安装 最近由于上Linux和学习云原生等 必须得安装 以下则进行了一些探索 解决 二 问题记录 关于Code1的虚拟化 对于机
  • 查看文件大小ls -l

  • Redis 基本属性

    redis 概念 redis是一个存储key value的非关系型数据库 数据存储在缓存中 读取速度很快 可以很好的解决每次都去数据库执行数据查询时间消耗问题 数据库支持的并发有限 redis单机可以支持上万并发 作用 缓存高频读的数据 减
  • linux sudo su 免密码,Ubuntu的sudo免密码设置

    正常情况下 在使用sudo命令时 系统是要求输入密码的 输入的密码会保存一小段时间 在这段时间内 sudo不再要求输入密码 之后 再使用sudo 系统仍会要求输入密码 但是在制作镜像过程中 我们可能会在系统自启动项启动很多服务 而且可能有些
  • 使用VS2019将c#生成dll文件

    生成dll部分 1 新建一个项目 选择 类库 用于创建C 类库dll项目 2 将Class1 cs改名自己要创建的文件名 Operate cs 并填入代码 3 贴入代码 using System using System Collectio
  • C++数据结构之--单向链表(SingleList)

    单向链表 单向链表 Singly Linked List 是一种常见的数据结构 它由一系列节点 Node 构成 每个节点包含数据 value 和一个指向下一个节点的指针 next 每个节点只知道它指向的下一个节点 而无法直接访问前一个节点
  • 设置多个dns_公共DNS全面故障:114.114.114.114 和 8.8.8.8

    2019年4月4日上午 全国大范围内的互联网用户在使用114 114 114 114 和 8 8 8 8 DNS服务器时 出现网站打开缓慢 或者打不开等现象 本次收到影响的地区包括北京 陕西 四川 重庆 贵州 广西 湖北 江西以及上海等地
  • 17、 Flutter Widgets 之 内置各种Button

    flutter内置各种buttons Author wywinstonwy Date 2022 1 2 10 52 下午 Description import package demo202112 utils common appbar d
  • 如何实现百度的跨域案例?

  • 前端开发-echarts 横坐标与数据动态变化

    在这次项目开发中使用了ajax 进行前端和后端的数据交互 获取数据使用定时器 本文以横坐标动态变化的折线图为例进行说明 最终效果在文末 但是横坐标会随时间不停变化 在JS中 首先要初始化一个div来存放echarts
  • Java模拟一个简单的双向链表

    Java模拟一个简单的双向链表 1 链表结构 Node实体类代码 public class Node public Object item 存放数据的地方 public Node next 指向下一个结点 public Node pre 指
  • arduino 土壤温湿度传感器_Arduino温度湿度传感器-Moisture Sensor土壤湿度传感器

    外观 概述 这是一个简易的水分传感器可用于检测土壤的水分 当土壤缺水时 传感器输出值将减小 反之将增大 使用这个传感器制作一款自动浇花装置 让您的花园里的植物不用人去管理 传感器表面做了镀金处理 可以延长它的使用寿命 将它插入土壤 然后使用
  • WPF软件导致Win10系统的平板电脑小键盘自动隐藏问题

    在Win10系统下 开发WPF软件的时候 点入TextBox框内的时候 出现小键盘自动隐藏问题 通过检查发现 附加属性里面 触发了以下代码 从而触发小键盘隐藏 InputMethod SetIsInputMethodEnabled Asso
  • 华为OD机试真题-自动曝光 【2023.Q1】

    题目内容 一个图像有n个像素点 存储在一个长度为n的数组img里 每个像素点的取值范围 0 255 的正整数 请你给图像每个像素点值加上一个整数k 可以是负数 得到新图newImg 使得新图newImg的所有像素平均值最接近中位值128 请
  • Onvif协议学习:8、设备校时

    Onvif协议学习 8 设备校时 文章目录 Onvif协议学习 8 设备校时 1 编码流程 2 注意事项 3 示例代码 原文链接 https blog csdn net benkaoya article details 72486511 1
  • 学习ShaderToy第一天: glsl语言内置函数gl_FragCoord

    运行环境 Android opengl es版本 2 0 3D引擎库 Rajawali3D ShaderToy上用的shader语言 为glsl 效果是用webgl跑的 而webgl封装了opengl es 所以ShaderToy上的例子同