搞定了在 hexo 博客中运行 shader 程序的问题

2019-11-16 03:05:31 +08:00
 mathzhaoliang

写 shader 是一件很苦逼,但是写完以后很爽的事情。 目前写 shader 主要是在 shadertoy 上写,实际上在本地博客里面也能写并调试,最近研究了一下搞定了这个问题。

效果和教程见 http://pywonderland.com/post/how-to-run-shader-in-hexo.html

文章还有一半没写,打算写关于文中那个 shader 项目的讲解,后面两天会补上。

3015 次点击
所在节点    分享创造
3 条回复
codehz
2019-11-17 10:50:15 +08:00
一键 404
mathzhaoliang
2019-11-17 11:36:35 +08:00
@codehz

我写博客的时候有个原则:不写工具配置类的东西,也不写某某库如何调用之类的文章。当时折腾出来 hexo 里面跑 shader 以后很高兴,就发了一文,后来想想又删掉了。

我把方法回复在这里吧:

# 在 Hexo 中运行 shader 的步骤

这里以我使用的 raytaylorism 主题为例来说明,其它主题的具体配置略有区别,但大同小异,请酌情修改。甚至使用 Hugo, Jekyll, Pelican 等生成器也是一样的。

## 下载 js 和 css 文件

在你的网站目录的 `themes/raytaylorism/source` 下面新建一个名为 `glsl` 的文件夹,下载 [glslEditor.js](/glsl/glslEditor.js)、[glslEditor.css](/glsl/glslEditor.css)、[GlslPost.js](/glsl/GlslPost.js)、[GlslCanvas.js](/glsl/glslCanvas.js) 到这个文件夹中。

## 开启可选加载

在你的网站目录的 `themes/raytaylorism/layout/_partial/post` 目录中新建一个名为 `shader.ejs` 的文件,文件中填入如下的内容:

```
<% if (item.glsl) { %>
<script type="text/javascript" src="/glsl/glslEditor.js"></script>

<script type="text/javascript" src="/glsl/GlslCanvas.js"></script>

<script type="text/javascript" src="/glsl/GlslPost.js"></script>

<link type="text/css" rel="stylesheet" href="/glsl/glslEditor.css">
<% } %>
```

并且修改 `themes/raytaylorism/layout/_partial/article.ejs` 文件,在其中加上一行

```
<%- partial('post/shader') %>
```
(加在哪里不用我解释吧~)

这两个步骤的目的是为了能够在某些页面中选择性地开启运行 shader 的功能,毕竟并不是每一篇文章都会跑 shader,对这些文章是没有必要加载 glsl 功能的。于是如果要在一篇文章中开启 shader 功能的话,只要在头部的元信息区加上

```
glsl: true
```
这一句,就可以在正文中插入 shader 程序了。


## 在正文中插入 shader 程序


这一步的方法有若干种,见 github 上 [GlslCanvas 项目]( https://github.com/patriciogonzalezvivo/glslCanvas)的说明,比如本文开头的动画使用的方法是

```
<div align="center">
<canvas class="glslCanvas" data-fragment-url="/shadertoy/mobius-object.frag" data-textures="/shadertoy/rusty_metal.png" width="600" height="480"></canvas>
</div>
```
其中 `data-fragment-url` 是你的 shader 代码路径,`data-textures` 是纹理图片的路径,它会被加载到 `uniform` 变量 `u_tex0` 中。


## 修改 mathjax 渲染器

`glslEditor.css` 的设置对 mathjax 数学公式的显示会有影响,应修改为 SVG 或者 HTML-CSS 渲染,所以需要修改 `layout/_partial/plugin/mathjax.ejs` 文件,在 `MathJax.Hub.Config` 语句的后面加上

```
MathJax.Hub.Queue(
["Typeset",MathJax.Hub,"HTMLCSS-output"],
["setRenderer",MathJax.Hub,"SVG"],
["Typeset",MathJax.Hub,"SVG-output"]
);
```

## 测试运行效果

将下面的代码粘贴到 markdown 文件中查看渲染效果:

```
<div class="codeAndCanvas" data="#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform float u_time;
void main() {
vec2 pos = 256.0 * gl_FragCoord.xy / u_resolution.x + u_time;
vec3 col = vec3(0.0);
for (int i=0; i<6; i++) {
vec2 a = floor(pos);
vec2 b = fract(pos);
vec4 w = fract((sin(a.x * 7.0 + 31.0 * a.y + 0.01 * u_time) +
vec4(0.035, 0.01, 0.0, 0.7)) * 13.545317);
col += w.xyz * smoothstep(0.45, 0.55, w.w) *
sqrt(16.0 * b.x * b.y * (1.0 - b.x) * (1.0 - b.y));
pos /= 2.0;
col /= 2.0;
}
col = pow(2.5 * col, vec3(1.0, 1.0, 0.7));
gl_FragColor = vec4(col, 1.0);
}"></div>
```
<br/>

你可以看看我的这篇文章中的效果:

http://pywonderland.com/post/mobius-cn.html
mathzhaoliang
2019-11-17 11:38:53 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/620085

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX