有没有办法调试Javascript中嵌入的WebGL GLSL代码?

时间:2017-01-09 11:50:43

标签: javascript glsl webgl

我正在尝试使用Sketch.js来学习使用粒子,并且遇到了这个我想要重做的例子:

http://soulwire.github.io/Plasmatic-Isosurface/

有问题的代码片段就是这个热点:

GLSL = {
vert: "\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n// Uniforms\nuniform vec2 u_resolution;\n\n// Attributes\nattribute vec2 a_position;\n\nvoid main() {\n    gl_Position = vec4 (a_position, 0, 1);\n}\n",
frag: "\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform bool u_scanlines;\nuniform vec2 u_resolution;\n\nuniform float u_brightness;\nuniform float u_blobiness;\nuniform float u_particles;\nuniform float u_millis;\nuniform float u_energy;\n\n\nfloat noise( vec2 co ){\n    return fract( sin( dot( co.xy, vec2( 12.9898, 78.233 ) ) ) * 43758.5453 );\n}\n\nvoid main( void ) {\n\n    vec2 position = ( gl_FragCoord.xy / u_resolution.x );\n    float t = u_millis * 0.001 * u_energy;\n    \n    float a = 0.0;\n    float b = 0.0;\n    float c = 0.0;\n\n    vec2 pos, center = vec2( 0.5, 0.5 * (u_resolution.y / u_resolution.x) );\n    \n    float na, nb, nc, nd, d;\n    float limit = u_particles / 40.0;\n    float step = 1.0 / u_particles;\n    float n = 0.0;\n    \n    for ( float i = 0.0; i <= 1.0; i += 0.025 ) {\n\n        if ( i <= limit ) {\n\n            vec2 np = vec2(n, 1-1);\n            \n            na = noise( np * 1.1 );\n            nb = noise( np * 2.8 );\n            nc = noise( np * 0.7 );\n            nd = noise( np * 3.2 );\n\n            pos = center;\n            pos.x += sin(t*na) * cos(t*nb) * tan(t*na*0.15) * 0.3;\n            pos.y += tan(t*nc) * sin(t*nd) * 0.1;\n            \n            d = pow( 1.6*na / length( pos - position ), u_blobiness );\n            \n            if ( i < limit * 0.3333 ) a += d;\n            else if ( i < limit * 0.6666 ) b += d;\n            else c += d;\n\n            n += step;\n        }\n    }\n    \n    vec3 col = vec3(a*c,b*c,a*b) * 0.0001 * u_brightness;\n    \n    if ( u_scanlines ) {\n        col -= mod( gl_FragCoord.y, 2.0 ) < 1.0 ? 0.5 : 0.0;\n    }\n    \n    gl_FragColor = vec4( col, 1.0 );\n\n}\n"};

着色器是GLSL的一个奇怪的嵌入位,我无法弄清楚如何调试。我无法理解的这个具体问题是如何设置颜色。 col变量似乎是一个四维向量,但看起来它可以用二维向量构建。我真的不明白发生了什么,这导致了我在这里问的问题,也就是说,有没有办法调试这样的嵌入式代码?

我尝试过一个名为WebGL Insight的Chrome扩展程序,但它不能识别GLSL代码,我不确定它是我正在寻找的内容。对于类似问题(Debug GLSL code in webgl)有这个答案,但我觉得它没有帮助。我是否需要打破着色器并使用外部编译器? (在这种情况下,我需要什么软件和库?)

2 个答案:

答案 0 :(得分:2)

我不知道这是否有帮助,但在Firefox中,您可以看到网页中使用的所有着色器的代码:https://developer.mozilla.org/en-US/docs/Tools/Shader_Editor

答案 1 :(得分:2)

嗯,简单地重新引入换行符会产生非常易读的代码:

#ifdef GL_ES
precision mediump float;
#endif

uniform bool u_scanlines;
uniform vec2 u_resolution;

uniform float u_brightness;
uniform float u_blobiness;
uniform float u_particles;
uniform float u_millis;
uniform float u_energy;


float noise( vec2 co ){
    return fract( sin( dot( co.xy, vec2( 12.9898, 78.233 ) ) ) * 43758.5453 );
}

void main( void ) {

    vec2 position = ( gl_FragCoord.xy / u_resolution.x );
    float t = u_millis * 0.001 * u_energy;

    float a = 0.0;
    float b = 0.0;
    float c = 0.0;

    vec2 pos, center = vec2( 0.5, 0.5 * (u_resolution.y / u_resolution.x) );

    float na, nb, nc, nd, d;
    float limit = u_particles / 40.0;
    float step = 1.0 / u_particles;
    float n = 0.0;

    for ( float i = 0.0; i <= 1.0; i += 0.025 ) {

        if ( i <= limit ) {

            vec2 np = vec2(n, 1-1);

            na = noise( np * 1.1 );
            nb = noise( np * 2.8 );
            nc = noise( np * 0.7 );
            nd = noise( np * 3.2 );

            pos = center;
            pos.x += sin(t*na) * cos(t*nb) * tan(t*na*0.15) * 0.3;
            pos.y += tan(t*nc) * sin(t*nd) * 0.1;

            d = pow( 1.6*na / length( pos - position ), u_blobiness );

            if ( i < limit * 0.3333 ) a += d;
            else if ( i < limit * 0.6666 ) b += d;
            else c += d;

            n += step;
        }
    }

    vec3 col = vec3(a*c,b*c,a*b) * 0.0001 * u_brightness;

    if ( u_scanlines ) {
        col -= mod( gl_FragCoord.y, 2.0 ) < 1.0 ? 0.5 : 0.0;
    }

    gl_FragColor = vec4( col, 1.0 );

}

由于这似乎是一个屏幕空间着色器,因此可以使用glsl-sandboxshadertoy之类的东西来玩它,只需重新映射和/或用未定义的制服替换定义:

//uniform bool u_scanlines;
#define u_scanlines false

//uniform float u_brightness;
#define u_brightness 1.
//uniform float u_blobiness;
#define u_blobiness 1.
//uniform float u_particles;
#define u_particles 20.
//uniform float u_millis;
#define u_millis 1.
//uniform float u_energy;
#define u_energy 1.

//uniform vec2 u_resolution;
uniform vec2 resolution;
#define u_resolution resolution

voila

要调试“在app中”你唯一现成的解决方案是Firefoxs Shader-Editor由Tolokoban推荐。对于其他更复杂的工具,还有桌面着色器调试器,如NVIDIAs FX ComposerAMDs RenderMonkeyGLSL-Debugger(formerly GLSLDevil)