本文作者:icy

C/C++-从着色器到视觉盛宴:glslViewer 深度指南与实战实例

icy 今天 6 抢沙发
C/C++-从着色器到视觉盛宴:glslViewer 深度指南与实战实例摘要: 探索 glslViewer:实时 GLSL 着色器预览利器 如果你是一名图形程序员、技术艺术家,或者仅仅是对生成艺术(Generative Art)感兴趣的爱好者,那么你一定知道编...

C/C++-从着色器到视觉盛宴:glslViewer 深度指南与实战实例

探索 glslViewer:实时 GLSL 着色器预览利器

如果你是一名图形程序员、技术艺术家,或者仅仅是对生成艺术(Generative Art)感兴趣的爱好者,那么你一定知道编写 GLSL(OpenGL Shading Language)时最痛苦的事情:为了看到一行代码的修改结果,你不得不重启整个 C++ 渲染框架或刷新网页。

glslViewer 正是为了解决这个痛点而生的。它是一个轻量级的、开源的 C/C++ 工具,旨在提供一个极简的实时预览环境,让你能够直接运行 .frag 或 .vert 文件,并在修改代码保存的瞬间,立即在屏幕上看到视觉效果。

1. 什么是 glslViewer?

glslViewer 是一个基于 OpenGL 的命令行工具。它并不要求你构建一个完整的 OpenGL 应用程序(无需处理复杂的 GLFW 窗口初始化、着色器编译链或缓冲区管理),而是将这些底层工作全部封装。

你只需要提供一个着色器文件,glslViewer 就会为你创建一个窗口,加载该着色器,并提供一套标准的 Uniform 变量(如时间、分辨率、鼠标位置),让你能够快速构建动态的视觉效果。

核心特性:

  • 实时热重载 (Hot Reloading):保存文件,画面立即更新。
  • 交互式控制:支持通过命令行或配置文件传递参数。
  • 轻量级:无需庞大的 IDE,一个终端命令即可启动。
  • 跨平台:支持 Windows, macOS, Linux。
  • 支持多种输入:支持顶点着色器、片段着色器以及简单的 3D 模型加载。

2. 快速上手指南

安装

根据你的操作系统,可以通过以下方式安装: - macOS: brew install glslviewer - Linux/Windows: 从 GitHub Releases 下载预编译二进制文件,或通过 CMake 源码编译。

运行第一个着色器

创建一个名为 test.frag 的文件,粘贴以下简单的渐变代码:

text
precision mediump float;
uniform float u_time;
uniform vec2 u_resolution;

void main() {
    vec2 uv = gl_FragCoord.xy / u_resolution.xy;
    vec3 color = 0.5 + 0.5 * cos(u_time + uv.xyx + vec3(0, 2, 4));
    gl_FragCoord = vec4(color, 1.0); // 注意:在某些版本中应为 gl_FragColor
}

注:在 glslViewer 中,通常使用 gl_FragColor 输出颜色。

在终端执行:

text
glslViewer test.frag

此时,你会看到一个随时间流逝而变换颜色的动态渐变屏幕。


3. 核心 Uniform 变量详解

为了让你的着色器“动”起来,glslViewer 默认注入了几个关键的 Uniform 变量,你可以在代码中直接使用:

变量名 类型 说明
u_time float 程序运行的总时间(秒),用于创建动画。
u_resolution vec2 窗口的宽度和高度,用于计算归一化的 UV 坐标。
u_mouse vec2 鼠标在窗口中的当前坐标。
u_window_size vec2 窗口大小(与 resolution 类似)。

4. 进阶实战实例

实例 A:交互式 SDF 圆形(学习鼠标交互)

这个实例将展示如何利用 u_mouse 创建一个跟随鼠标移动的发光圆环。

text
precision mediump float;
uniform float u_time;
uniform vec2 u_resolution;
uniform vec2 u_mouse;

void main() {
    // 归一化坐标 (0.0 到 1.0)
    vec2 uv = gl_FragCoord.xy / u_resolution.xy;
    // 归一化鼠标坐标
    vec2 mouse = u_mouse / u_resolution.xy;
    
    // 计算当前像素点到鼠标点的距离
    float dist = distance(uv, mouse);
    
    // 创建一个带边缘模糊的圆环
    float ring = smoothstep(0.1, 0.11, dist) - smoothstep(0.12, 0.13, dist);
    
    // 颜色随时间变化
    vec3 color = 0.5 + 0.5 * cos(u_time + vec3(0, 2, 4));
    
    gl_FragColor = vec4(color * ring, 1.0);
}

实例 B:简单的 Raymarching 场景(3D 效果)

glslViewer 非常适合测试 Raymarching 算法。以下是一个简单的 3D 球体渲染:

text
precision mediump float;
uniform float u_time;
uniform vec2 u_resolution;

float sdSphere(vec3 p, float s) {
    return length(p) - s;
}

void main() {
    vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution.xy) / u_resolution.y;
    
    vec3 ro = vec3(0, 0, -3); // 摄像机位置
    vec3 rd = normalize(vec3(uv, 1)); // 射线方向
    
    float t = 0.0;
    for(int i = 0; i < 64; i++) {
        vec3 p = ro + t * rd;
        float d = sdSphere(p, 1.0); // 渲染一个半径为 1 的球
        if(d < 0.001) break;
        t += d;
        if(t > 10.0) break;
    }
    
    vec3 col = (t < 10.0) ? vec3(0.2, 0.6, 1.0) : vec3(0.1);
    gl_FragColor = vec4(col, 1.0);
}

5. 高级用法:加载模型与自定义参数

glslViewer 不仅仅能跑片段着色器,它还支持加载 3D 模型(如 .obj 文件)并为其编写自定义着色器。

加载 3D 模型

如果你有一个模型文件 mesh.obj 和一个着色器 shader.frag,你可以运行:

text
glslViewer mesh.obj shader.frag

在这种模式下,glslViewer 会处理顶点数据的传递,你可以在 shader.frag 中通过 v_normal 或 v_texcoord 等内置变量来处理光照和贴图。

使用配置文件 (.json)

如果你有大量的 Uniform 变量需要调整,而不想每次都修改代码,你可以创建一个 JSON 配置文件:

json
{
    "uniforms": {
        "u_brightness": { "type": "float", "value": 1.5 },
        "u_color": { "type": "vec3", "value": [1.0, 0.0, 0.0] }
    }
}

然后运行:

text
glslViewer test.frag -c config.json

6. 为什么选择 glslViewer 而不是 Shadertoy?

虽然 Shadertoy 是目前最流行的 GLSL 平台,但 glslViewer 在以下场景中具有绝对优势:

  1. 本地开发:无需上传代码,直接在本地编辑器(如 VS Code + GLSL 插件)中编写,保存即生效。
  2. 加载本地资源:可以加载本地的 .obj 模型、纹理图片,而 Shadertoy 依赖于其内置的资源库。
  3. 性能调试:直接运行在本地显卡驱动上,方便使用 RenderDoc 等工具进行帧分析。
  4. 集成工作流:可以轻松地将编写
glslViewer_20260906064729.zip
类型:压缩文件|已下载:0|下载方式:免费下载
立即下载
文章版权及转载声明

作者:icy本文地址:https://zelig.cn/cpp/1400.html发布于 今天
文章转载或复制请以超链接形式并注明出处软角落-SoftNook

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

阅读
分享

发表评论

快捷回复:

评论列表 (暂无评论,6人围观)参与讨论

还没有评论,来说两句吧...