@
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