当前位置: 动力学知识库 > 问答 > 编程问答 >

Any way to debug WebGL GLSL code embedded in Javascript?

问题描述:

I'm trying to learn about using particles using Sketch.js and came across this example, which I am trying to rework:

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

The snippet of code in question is this hot mess:

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"};

The shaders are a weird embedded bit of GLSL, which I can't figure out how to debug. This specific issue that I can't quite understand is how the colours are set. The col variable seems to be a 4-dimensional vector, but it looks like it could be built up with 2-dimensional vectors. I don't really understand what's going on, which leads to the issue that I'm asking about here, which is, is there any way to debug such an embedded bit of code?

I've tried a Chrome extension called WebGL Insight, but that doesn't recognise the GLSL code, and I'm not sure it's what I'm looking for. There is this answer to a similar question (Debug GLSL code in webgl) but I don't find it helpful. Do I need to break the shader out and use an external compiler? (And in that case, what software and libraries do I need?)

网友答案:

Mhh, simply reintroducing the line breaks results in quite the readable code:

#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 );

}

As this seems to be a screenspace shader one can use things like glsl-sandbox or shadertoy to play around with it, just remap and/or substitute the unknown uniforms with defines:

//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

To debug "in app" your only ready made solution is Firefoxs Shader-Editor as mentinoed by Tolokoban. As to other more sophisticated tools, there are the desktop shader debuggers like NVIDIAs FX Composer, AMDs RenderMonkey and GLSL-Debugger(formerly GLSLDevil).

网友答案:

I don't know if this can help, but in Firefox, you can see the code of all shaders used in a web page: https://developer.mozilla.org/en-US/docs/Tools/Shader_Editor.

分享给朋友:
您可能感兴趣的文章:
随机阅读: