【shadertoy】向量场可视化实例分析(1)

在写之前,首先给大家介绍一个学习shader的网站shadertoy。最近因为做项目要显示向量场,学习了一些GLSL着色语言的知识。虽然GLSL本身不难学,但对一个初学者来说,没有强大的数学和图形学功底,基本很难想写出好的shader。shadertoy提供了很多shader的例子,大家可以直接借鉴这些例子,编辑自己的shader。

向量场可视化

绘制向量场的方法有很多种,常见的有LIC(线积分卷积)纹理流场和箭头向量场(详细的介绍见:http://www.zhanpingliu.org/Research/FlowVis/FlowVis.htm)。这篇文章介绍的就是箭头向量场。箭头向量场的制作过程通常是先对区域进行划分,划分成一个个的四边形网格。每个网格里都画有一个箭头,箭头的长度表示向量的大小,箭头的指向表示向量的方向。

下面是shadertoy提供的一种二维向量场的画法(https://www.shadertoy.com/view/4s23DG):

绘制步骤有下面3个步骤:

1)建立模拟向量场

shadertoy提供了一个画布,画布上每一个像素点都有一个位置坐标vec2(x, y)。对应的,每个像素点在向量场上也应该有一个向量vec2(vx,vy)。

vec2 field(vec2 pos) {
    return vec2(cos(pos.x * 0.01 + pos.y * 0.01) + cos(pos.y * 0.005 + iGlobalTime), 2.0 * cos(pos.y * 0.01  + iGlobalTime * 0.3)) * 0.5;

2)划分网格

vec2 arrowTileCenterCoord(vec2 pos) {
    return (floor(pos / ARROW_TILE_SIZE) + 0.5) * ARROW_TILE_SIZE;
}

ARROW_TILE_SIZE 表示每个网格切片的边长。通过上述代码,可以求得每个像素点所在网格中心的坐标。

3)绘制箭头

根据网格中心的坐标,绘制一个箭头。箭头的大小、方向要与网格中心在向量场的向量一致。

之后,计算每个像素点与箭头的距离,如果距离足够小,就显示黑色。

float arrow(vec2 p, vec2 v) {
    // Make everything relative to the center, which may be fractional
    p -= arrowTileCenterCoord(p);

    float mag_v = length(v), mag_p = length(p);

    if (mag_v > 0.0) {
        // Non-zero velocity case
        vec2 dir_p = p / mag_p, dir_v = v / mag_v;

        // We can‘t draw arrows larger than the tile radius, so clamp magnitude.
        // Enforce a minimum length to help see direction
        mag_v = clamp(mag_v, 5.0, ARROW_TILE_SIZE / 2.0);

        // Arrow tip location
        v = dir_v * mag_v;

        // Define a 2D implicit surface so that the arrow is antialiased.
        // In each line, the left expression defines a shape and the right controls
        // how quickly it fades in or out.

        float dist;
        if (ARROW_STYLE == ARROW_LINE_STYLE) {
            // Signed distance from a line segment based on https://www.shadertoy.com/view/ls2GWG by
            // Matthias Reitinger, @mreitinger

            // Line arrow style
            dist =
                max(
                    // Shaft
                    ARROW_SHAFT_THICKNESS / 4.0 -
                        max(abs(dot(p, vec2(dir_v.y, -dir_v.x))), // Width
                            abs(dot(p, dir_v)) - mag_v + ARROW_HEAD_LENGTH / 2.0), // Length

                        // Arrow head
                     min(0.0, dot(v - p, dir_v) - cos(ARROW_HEAD_ANGLE / 2.0) * length(v - p)) * 2.0 + // Front sides
                     min(0.0, dot(p, dir_v) + ARROW_HEAD_LENGTH - mag_v)); // Back
        } else {
            // V arrow style
            dist = min(0.0, mag_v - mag_p) * 2.0 + // length
                   min(0.0, dot(normalize(v - p), dir_v) - cos(ARROW_HEAD_ANGLE / 2.0)) * 2.0 * length(v - p) + // head sides
                   min(0.0, dot(p, dir_v) + 1.0) + // head back
                   min(0.0, cos(ARROW_HEAD_ANGLE / 2.0) - dot(normalize(v * 0.33 - p), dir_v)) * mag_v * 0.8; // cutout
        }

        return clamp(1.0 + dist, 0.0, 1.0);
    } else {
        // Center of the pixel is always on the arrow
        return max(0.0, 1.2 - mag_p);
    }
}

最后,加上背景色就可以得到上图的效果:

void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
    fragColor =
        (1.0 - arrow(fragCoord.xy, field(arrowTileCenterCoord(fragCoord.xy)) * ARROW_TILE_SIZE * 0.4)) *
        vec4(field(fragCoord.xy) * 0.5 + 0.5, 0.5, 1.0);
}
时间: 2024-10-08 11:49:30

【shadertoy】向量场可视化实例分析(1)的相关文章

【OpenGL】Shader实例分析(七)- 雪花飘落效果

转发请保持地址:http://blog.csdn.net/stalendp/article/details/40624603 研究了一个雪花飘落效果.感觉挺不错的.分享给大家,效果例如以下: 代码例如以下: Shader "shadertoy/Flakes" { // https://www.shadertoy.com/view/4d2Xzc Properties{ iMouse ("Mouse Pos", Vector) = (100,100,0,0) iChan

Mahout机器学习平台之聚类算法详细剖析(含实例分析)

第一部分: 学习Mahout必须要知道的资料查找技能: 学会查官方帮助文档: 解压用于安装文件(mahout-distribution-0.6.tar.gz),找到如下位置,我将该文件解压到win7的G盘mahout文件夹下,路径如下所示: G:\mahout\mahout-distribution-0.6\docs 学会查源代码的注释文档: 方案一:用maven创建一个mahout的开发环境(我用的是win7,eclipse作为集成开发环境,之后在Maven Dependencies中找到相应

Android应用测试工具ThreadingTest查错实例分析

1      ThreadingTest产品简介 ZOA公司研发的ThreadingTest智能型测试工具系列一期,是基于程序源代码的白盒测试工具.采取前端分析器和后端结果分析分离的技术路线,实现对多种语言的编译器级分析和多维度测试. ThreadingTest的核心思想来源于非线性复杂软件工程体系.通过ThreadingTest基于测试用例集与动态代码覆盖的双向追溯的专利技术,使得对于大型应用系统的维护和修改变得不再盲目和极易出错,使得对大型软件的系统测试期和维护期的测试过程从无量化依据到有明

实现 | 朴素贝叶斯模型算法研究与实例分析

实现 | 朴素贝叶斯模型算法研究与实例分析(白宁超2018年9月4日09:03:21) 导读:朴素贝叶斯模型是机器学习常用的模型算法之一,其在文本分类方面简单易行,且取得不错的分类效果.所以很受欢迎,对于朴素贝叶斯的学习,本文首先介绍理论知识即朴素贝叶斯相关概念和公式推导,为了加深理解,采用一个维基百科上面性别分类例子进行形式化描述.然后通过编程实现朴素贝叶斯分类算法,并在屏蔽社区言论.垃圾邮件.个人广告中获取区域倾向等几个方面进行应用,包括创建数据集.数据预处理.词集模型和词袋模型.朴素贝叶斯

Apache漏洞利用与安全加固实例分析

Apache 作为Web应用的载体,一旦出现安全问题,那么运行在其上的Web应用的安全也无法得到保障,所以,研究Apache的漏洞与安全性非常有意义.本文将结合实例来谈谈针对Apache的漏洞利用和安全加固措施. Apache HTTP Server(以下简称Apache)是Apache软件基金会的一个开放源码的网页服务器,可以在大多数计算机操作系统中运行,是最流行的Web服务器软件之一.虽然近年来Nginx和Lighttpd等Web Server的市场份额增长得很快,但Apache仍然是这个领

java基础学习05(面向对象基础01--类实例分析)

面向对象基础01(类实例分析) 实现的目标 1.如何分析一个类(类的基本分析思路) 分析的思路 1.根据要求写出类所包含的属性2.所有的属性都必须进行封装(private)3.封装之后的属性通过setter和getter设置和取得4.如果需要可以加入若干构造方法 5.再根据其它要求添加相应的方法6.类中的所有方法都不要直接输出,而是交给被调用处调用 Demo 定义并测试一个名为Student的类,包括属性有"学号"."姓名"以及3门课程"数学".

第十七篇:实例分析(3)--初探WDDM驱动学习笔记(十)

续: 还是记录一下, BltFuncs.cpp中的函数作用: CONVERT_32BPP_TO_16BPP 是将32bit的pixel转换成16bit的形式. 输入是DWORD 32位中, BYTE 0,1,2分别是RGB分量, 而BYTE3则是不用的 为了不减少color的范围, 所以,都是取RGB8,8,8的高RGB5, 6, 5位, 然后将这16位构成一个pixel. CONVERT_16BPP_TO_32BPP是将16bit的pixel转换成32bit的形式 输入是WORD 16BIT中

第十七篇:实例分析(4)--初探WDDM驱动学习笔记(十一)

感觉有必要把 KMDDOD_INITIALIZATION_DATA 中的这些函数指针的意思解释一下, 以便进一步的深入代码. DxgkDdiAddDevice 前面已经说过, 这个函数的主要内容是,将BASIC_DISPLAY_DRIVER实例指针存在context中, 以便后期使用, 支持多实例. DxgkDdiStartDevice 取得设备信息, 往注册表中加入内容, 从POST设备中获取FRAME BUFFER以及相关信息(DxgkCbAcquirePostDisplayOwnershi

实例分析Robots.txt写法

题意:经典八数码问题 思路:HASH+BFS #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 500000; const int size = 1000003; typedef int State[9]; char str[30]; int state[9],goal[9]={