<p>There is also <a href="https://github.com/GLSL-Debugger/GLSL-Debugger">GLSL-Debugger</a>. It is a debugger used to be known as "GLSL Devil".</p>

<p>The Debugger itself is super handy not only for GLSL code, but for OpenGL itself as well. You have the ability to jump between draw calls and break on Shader switches. It also shows you error messages communicated by OpenGL back to the application itself.</p>

CC BY-SA 4.0
2018-08-07T07:00:59.927Z
Note that as of 2018-08-07, it doesn't support anything higher than GLSL 1.2, and it's not actively maintained.
Ruslan
CC BY-SA 4.0
2018-09-30T22:07:55.317Z
That comment legitimately made me sad :(
rdelfin
CC BY-SA 4.0
2019-02-27T13:50:56.877Z
The project is open source and would really love help modernizing it. There's no other tool that does what it did.
XenonofArcticus
CC BY-SA 3.0
2015-08-07T18:39:26.880Z
2015-08-07T18:39:26.880Z
Sepehr
<p>There are several offerings by GPU vendors like AMD's <a href="http://developer.amd.com/tools-and-sdks/opencl-zone/codexl/" rel="noreferrer">CodeXL</a> or NVIDIA's <a href="https://www.nvidia.com/object/nsight.html" rel="noreferrer">nSight</a>/<a href="https://developer.nvidia.com/linux-graphics-debugger" rel="noreferrer">Linux GFX Debugger</a> which allow stepping through shaders but are tied to the respective vendor's hardware.</p>

<p>Let me note that, although they are available under Linux, I always had very little success with using them there. I can't comment on the situation under Windows.</p>

<p>The option which I have come to use recently, is to modularize my shader code via <a href="https://computergraphics.stackexchange.com/questions/100/sharing-code-between-multiple-glsl-shaders"><code>#includes</code></a> and restrict the included code to a common subset of GLSL and C++&amp;<a href="http://glm.g-truc.net" rel="noreferrer">glm</a>.</p>

<p>When I hit a problem I try to reproduce it on another device to see if the problem is the same which hints at a logic error (instead of a driver problem/undefined behavior). There is also the chance of passing wrong data to the GPU (e.g. by incorrectly bound buffers etc.) which I usually rule out either by output debugging like in <a href="https://computergraphics.stackexchange.com/a/101">cifz answer</a> or by inspecting the data via <a href="https://apitrace.github.io/" rel="noreferrer">apitrace</a>.</p>

<p>When it is a logic error I try to rebuild the situation from the GPU on CPU by calling the included code on CPU with the same data.
Then I can step through it on CPU.</p>

<p>Building upon the modularity of the code you can also try to write unittest for it and compare the results between a GPU run and a CPU run. However, you have to be aware that there are corner cases where C++ might behave differently than GLSL, thus giving you false positives in these comparisons.</p>

<p>Finally, when you can't reproduce the problem on another device, you can only start to dig down where the difference comes from. Unittests might help you to narrow down where that happens but in the end you will probably need to write out additional debug information from the shader like in <a href="https://computergraphics.stackexchange.com/a/101">cifz answer</a>.</p>

<p>And to give you an overview here is a flowchart of my debugging process:
<a href="https://i.sstatic.net/S1jUQ.png" rel="noreferrer"><img src="https://i.sstatic.net/S1jUQ.png" alt="Flow chart of the procedure described in the text"></a></p>

<p>To round this off here is a list of random pros and cons:</p>

<p><strong>pro</strong></p>

<ul>
<li>step through with usual debugger</li>
<li>additional (often better) compiler diagnostics</li>
</ul>

<p><strong>con</strong></p>

<ul>
<li>subtle differences in some mathematic primitives (e.g. <a href="https://stackoverflow.com/questions/31915601/pow1-inf-nan">different return values in corner cases</a>)</li>
<li>additional code to reproduce call environment on CPU</li>
</ul>

CC BY-SA 3.0
2016-06-29T10:21:35.590Z
@racarate: I thought about that as well but did not have the time to try yet. I am no expert on mesa but I think it might be hard to debug the shader as the shader debug information has to somehow reach the debugger. Then again, maybe the folks at mesa already have an interface for that to debug mesa itself :)
Nobody moving away from SE
CC BY-SA 3.0
2016-01-22T14:59:56.743Z
2016-01-26T11:23:57.880Z
2016-01-26T11:23:57.880Z
Nobody moving away from SE
<p>While it doesn't seem to be possible to actually step through an OpenGL shader, it is possible to get the compilation results.<br>
The following is taken from the <a href="https://github.com/googlesamples/cardboard-java/blob/master/CardboardSample/src/main/java/com/google/vrtoolkit/cardboard/samples/treasurehunt/MainActivity.java">Android Cardboard Sample</a>.</p>

<pre><code>while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
    Log.e(TAG, label + ": glError " + error);
    throw new RuntimeException(label + ": glError " + error);
</code></pre>

<p>If your code compiles properly, then you have little choice but to try out a different way of communicating the program's state to you. You could signal that a part of the code was reached by, for example, changing the color of a vertex or using a different texture. Which is awkward, but seems to be the only way for now.</p>

<p>EDIT: For WebGL, I am looking at <a href="http://benvanik.github.io/WebGL-Inspector/">this project</a>, but I've only just found it... can't vouch for it. </p>

CC BY-SA 3.0
2015-08-07T09:42:23.417Z
Hm yeah, I'm aware that I can get compiler errors. I was hoping for better runtime debugging. I've also used WebGL inspector in the past, but I believe it only shows you state changes, but you can't look into a shader invocation. I guess this could have been clearer in the question.
Martin Ender
CC BY-SA 3.0
2015-08-07T09:39:47.633Z
2015-08-07T09:39:47.633Z
S.L. Barth is on codidact.com
<p>The solution that worked for me is compilation of shader code to C++ - as mentioned by Nobody. It prooved very efficient when working on a complex code even though it requires a bit of setup.</p>

<p>I have been working mostly with HLSL Compute Shaders for which I have developed a proof-of-concept library available here:</p>

<p><a href="https://github.com/cezbloch/shaderator" rel="nofollow noreferrer">https://github.com/cezbloch/shaderator</a></p>

<p>It demonstrates on a Compute Shader from DirectX SDK Samples, how to enable C++ like HLSL debugging and how to setup Unit Tests.</p>

<p>Compilation of GLSL compute shader to C++ looks easier than HLSL. Mainly due to syntax constructions in HLSL. I have added a trivial example of executable Unit Test on a GLSL ray tracer Compute Shader which you can also find in the Shaderator project's sources under link above.</p>

CC BY-SA 3.0
2018-03-07T22:11:50.263Z
2018-03-07T22:11:50.263Z
SpaceKees
<p><em>This is a copy-paste of <a href="https://stackoverflow.com/a/38039733/673852">my answer</a> to the same <a href="https://stackoverflow.com/q/2508818/673852">question at StackOverflow</a></em>.</p>

<hr>

<p>At the bottom of this answer is an example of GLSL code which allows to output the full <code>float</code> value as color, encoding IEEE 754 <code>binary32</code>. I use it like follows (this snippet gives out <code>yy</code> component of modelview matrix):</p>



<pre class="lang-c prettyprint-override"><code>vec4 xAsColor=toColor(gl_ModelViewMatrix[1][1]);
if(bool(1)) // put 0 here to get lowest byte instead of three highest
    gl_FrontColor=vec4(xAsColor.rgb,1);
else
    gl_FrontColor=vec4(xAsColor.a,0,0,1);
</code></pre>

<p>After you get this on screen, you can just take any color picker, format the color as HTML (appending <code>00</code> to the <code>rgb</code> value if you don't need higher precision, and doing a second pass to get the lower byte if you do), and you get the hexadecimal representation of the <code>float</code> as IEEE 754 <code>binary32</code>.</p>

<p>Here's the actual implementation of <code>toColor()</code>:</p>

<pre class="lang-c prettyprint-override"><code>const int emax=127;
// Input: x&gt;=0
// Output: base 2 exponent of x if (x!=0 &amp;&amp; !isnan(x) &amp;&amp; !isinf(x))
//         -emax if x==0
//         emax+1 otherwise
int floorLog2(float x)
{
    if(x==0.) return -emax;
    // NOTE: there exist values of x, for which floor(log2(x)) will give wrong
    // (off by one) result as compared to the one calculated with infinite precision.
    // Thus we do it in a brute-force way.
    for(int e=emax;e&gt;=1-emax;--e)
        if(x&gt;=exp2(float(e))) return e;
    // If we are here, x must be infinity or NaN
    return emax+1;
}

// Input: any x
// Output: IEEE 754 biased exponent with bias=emax
int biasedExp(float x) { return emax+floorLog2(abs(x)); }

// Input: any x such that (!isnan(x) &amp;&amp; !isinf(x))
// Output: significand AKA mantissa of x if !isnan(x) &amp;&amp; !isinf(x)
//         undefined otherwise
float significand(float x)
{
    // converting int to float so that exp2(genType) gets correctly-typed value
    float expo=float(floorLog2(abs(x)));
    return abs(x)/exp2(expo);
}

// Input: x\in[0,1)
//        N&gt;=0
// Output: Nth byte as counted from the highest byte in the fraction
int part(float x,int N)
{
    // All comments about exactness here assume that underflow and overflow don't occur
    const float byteShift=256.;
    // Multiplication is exact since it's just an increase of exponent by 8
    for(int n=0;n&lt;N;++n)
        x*=byteShift;

    // Cut higher bits away.
    // $q \in [0,1) \cap \mathbb Q'.$
    float q=fract(x);

    // Shift and cut lower bits away. Cutting lower bits prevents potentially unexpected
    // results of rounding by the GPU later in the pipeline when transforming to TrueColor
    // the resulting subpixel value.
    // $c \in [0,255] \cap \mathbb Z.$
    // Multiplication is exact since it's just and increase of exponent by 8
    float c=floor(byteShift*q);
    return int(c);
}

// Input: any x acceptable to significand()
// Output: significand of x split to (8,8,8)-bit data vector
ivec3 significandAsIVec3(float x)
{
    ivec3 result;
    float sig=significand(x)/2.; // shift all bits to fractional part
    result.x=part(sig,0);
    result.y=part(sig,1);
    result.z=part(sig,2);
    return result;
}

// Input: any x such that !isnan(x)
// Output: IEEE 754 defined binary32 number, packed as ivec4(byte3,byte2,byte1,byte0)
ivec4 packIEEE754binary32(float x)
{
    int e = biasedExp(x);
    // sign to bit 7
    int s = x&lt;0. ? 128 : 0;

    ivec4 binary32;
    binary32.yzw=significandAsIVec3(x);
    // clear the implicit integer bit of significand
    if(binary32.y&gt;=128) binary32.y-=128;
    // put lowest bit of exponent into its position, replacing just cleared integer bit
    binary32.y+=128*int(mod(float(e),2.));
    // prepare high bits of exponent for fitting into their positions
    e/=2;
    // pack highest byte
    binary32.x=e+s;

    return binary32;
}

vec4 toColor(float x)
{
    ivec4 binary32=packIEEE754binary32(x);
    // Transform color components to [0,1] range.
    // Division is inexact, but works reliably for all integers from 0 to 255 if
    // the transformation to TrueColor by GPU uses rounding to nearest or upwards.
    // The result will be multiplied by 255 back when transformed
    // to TrueColor subpixel value by OpenGL.
    return vec4(binary32)/255.;
}
</code></pre>

CC BY-SA 3.0
2016-06-26T15:07:15.097Z
2018-04-11T19:25:35.810Z
2018-04-11T19:25:35.810Z
Ruslan
<p>As far as I know there are no tools that allows you to steps through code in a shader (also, in that case you would have to be able to select just a pixel/vertex you want to &quot;debug&quot;, the execution is likely to vary depending on that).
(NOTE: Renderdoc allows you to do so by selecting a specific thread/pixel)</p>
<p>What I personally do is a very hacky &quot;colourful debugging&quot;. So I sprinkle a bunch of dynamic branches with <code>#if DEBUG / #endif</code> guards that basically say</p>
<pre><code>#if DEBUG
if( condition ) 
    outDebugColour = aColorSignal;
#endif

.. rest of code .. 

// Last line of the pixel shader
#if DEBUG
OutColor = outDebugColour;
#endif
</code></pre>
<p>So you can &quot;observe&quot; debug info this way. I usually do various tricks like lerping or blending between various &quot;colour codes&quot; to test various more complex events or non-binary stuff.</p>
<p>In this &quot;framework&quot; I also find useful to have a set of fixed conventions for common cases so that if I don't have to constantly go back and check what colour I associated with what.
The important thing is have a good support for hot-reloading of shader code, so you can almost interactively change your tracked data/event and switch easily on/off the debug visualization.</p>
<p>If need to debug something that you cannot display on screen easily, you can always do the same and use one frame analyser tool to inspect your results. I've listed a couple of them <a href="https://computergraphics.stackexchange.com/questions/23/how-can-i-debug-what-is-being-rendered-to-a-frame-buffer-object-in-opengl/25#25">as answer of this other question.</a></p>
<p>Obv, it goes without saying that if I am not &quot;debugging&quot; a pixel shader or compute shader, I pass this &quot;debugColor&quot; info throughout the pipeline without interpolating it (in GLSL with <code> flat </code> keyword )</p>
<p>Again, this is very hacky and far from proper debugging, but is what I am stuck with not knowing any proper alternative.</p>

CC BY-SA 3.0
2016-01-22T15:10:21.610Z
When they are available you can use SSBOs to get a more flexible output format where you don't need to encode in colors. However, the big drawback of this approach is that it alters the code which can hide/alter bugs, especially when UB is involved. +1 Nevertheless, for it is the most direct method that is available.
Nobody moving away from SE
CC BY-SA 4.0
2015-08-07T13:14:59.983Z
2021-04-15T09:13:43.097Z
2021-04-15T09:13:43.097Z
cifz
<p>When writing non-trivial shaders (just as when writing any other piece of non-trivial code), people make mistakes.<sup>[citation needed]</sup> However, I can't just debug it like any other code - you can't just attach gdb or the Visual Studio debugger after all. You can't even do printf debugging, because there's no form of console output. What I usually do is render the data I want to look at as colour, but that is a very rudimentary and amateurish solution. I'm sure people have come up with better solutions.</p>

<p>So how can I actually debug a shader? Is there a way to step through a shader? Can I look at the execution of the shader on a specific vertex/primitive/fragment?</p>

<p>(This question is specifically about how to debug shader code akin to how one would debug "normal" code, not about debugging things like state changes.)</p>

CC BY-SA 3.0
2015-08-07T11:06:15.930Z
Have you looked into gDEBugger? Quoting the site: "gDEBugger is an advanced OpenGL and OpenCL Debugger, Profiler and Memory Analyzer. gDEBugger does what no other tool can - lets you trace application activity on top of the OpenGL and OpenCL APIs and see what is happening within the system implementation." Granted, no VS style debugging/stepping through code, but it might give you some insight in what your shader does (or should do). Crytec released a similar tool for Direct shader "debugging" called RenderDoc (free, but strictly for HLSL shaders, so maybe not relevant for you).
Bert
CC BY-SA 3.0
2015-08-07T11:47:56.203Z
@Bert Hm yeah, I guess gDEBugger is the OpenGL equivalent to WebGL-Inspector? I've used the latter. It's immensely useful, but it's definitely more debugging OpenGL calls and state changes than shader execution.
Martin Ender
CC BY-SA 3.0
2015-08-07T11:57:21.997Z
I've never done any WebGL programming and hence I'm not familiar with WebGL- Inspector. With gDEBugger you can at least inspect the entire state of your shader pipeline including texture memory, vertex data, etc. Still, no actual stepping through code afaik.
Bert
CC BY-SA 3.0
2015-08-07T12:00:52.567Z
gDEBugger is extremely old and not supported since a while. If you are looking from frame and GPU state analysis you this is other question is strongly related: http://computergraphics.stackexchange.com/questions/23/how-can-i-debug-what-is-being-rendered-to-a-frame-buffer-object-in-opengl/25#25
cifz
CC BY-SA 4.0
2019-10-01T02:32:19.270Z
Here's a debugging method I suggested to a related question: https://stackoverflow.com/a/29816231/758666
wip
CC BY-SA 4.0
2021-04-15T11:47:33.690Z
The vulkan SDK provides a printf for shader debugging, I haven't had the need to use it so I'll just post this as a comment. Here is a link:https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/master/docs/debug_printf.md
pmw1234
<opengl><glsl><debugging>
How can I debug GLSL shaders?
Martin Ender
# How can I debug GLSL shaders?

(Asked by: username_0 on 2015-08-07)

When writing non-trivial shaders (just as when writing any other piece of non-trivial code), people make mistakes.[citation needed] However, I can't just debug it like any other code - you can't just attach gdb or the Visual Studio debugger after all. You can't even do printf debugging, because there's no form of console output. What I usually do is render the data I want to look at as colour, but that is a very rudimentary and amateurish solution. I'm sure people have come up with better solutions.

So how can I actually debug a shader? Is there a way to step through a shader? Can I look at the execution of the shader on a specific vertex/primitive/fragment?

(This question is specifically about how to debug shader code akin to how one would debug "normal" code, not about debugging things like state changes.)

**Tags:** opengl, glsl, debugging

> **Comments:**
> **username_1**: Have you looked into gDEBugger? Quoting the site: "gDEBugger is an advanced OpenGL and OpenCL Debugger, Profiler and Memory Analyzer. gDEBugger does what no other tool can - lets you trace application activity on top of the OpenGL and OpenCL APIs and see what is happening within the system implementation." Granted, no VS style debugging/stepping through code, but it might give you some insight in what your shader does (or should do). Crytec released a similar tool for Direct shader "debugging" called RenderDoc (free, but strictly for HLSL shaders, so maybe not relevant for you).  
> **username_0**: @username_1 Hm yeah, I guess gDEBugger is the OpenGL equivalent to WebGL-Inspector? I've used the latter. It's immensely useful, but it's definitely more debugging OpenGL calls and state changes than shader execution.  
> **username_1**: I've never done any WebGL programming and hence I'm not familiar with WebGL- Inspector. With gDEBugger you can at least inspect the entire state of your shader pipeline including texture memory, vertex data, etc. Still, no actual stepping through code afaik.  
> **username_2**: gDEBugger is extremely old and not supported since a while. If you are looking from frame and GPU state analysis you this is other question is strongly related: http://computergraphics.stackexchange.com/questions/23/how-can-i-debug-what-is-being-rendered-to-a-frame-buffer-object-in-opengl/25#25  
> **username_3**: Here's a debugging method I suggested to a related question: https://stackoverflow.com/a/29816231/758666  
> **username_4**: The vulkan SDK provides a printf for shader debugging, I haven't had the need to use it so I'll just post this as a comment. Here is a link:https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/master/docs/debug_printf.md  

---

## 6 answers

### Answer by username_2 on 2015-08-07. Score: 34 | Accepted answer

As far as I know there are no tools that allows you to steps through code in a shader (also, in that case you would have to be able to select just a pixel/vertex you want to "debug", the execution is likely to vary depending on that).
(NOTE: Renderdoc allows you to do so by selecting a specific thread/pixel)

What I personally do is a very hacky "colourful debugging". So I sprinkle a bunch of dynamic branches with `#if DEBUG / #endif` guards that basically say

```
#if DEBUG
if( condition ) 
    outDebugColour = aColorSignal;
#endif

.. rest of code .. 

// Last line of the pixel shader
#if DEBUG
OutColor = outDebugColour;
#endif

```

So you can "observe" debug info this way. I usually do various tricks like lerping or blending between various "colour codes" to test various more complex events or non-binary stuff.

In this "framework" I also find useful to have a set of fixed conventions for common cases so that if I don't have to constantly go back and check what colour I associated with what.
The important thing is have a good support for hot-reloading of shader code, so you can almost interactively change your tracked data/event and switch easily on/off the debug visualization.

If need to debug something that you cannot display on screen easily, you can always do the same and use one frame analyser tool to inspect your results. I've listed a couple of them [as answer of this other question.](https://computergraphics.stackexchange.com/questions/23/how-can-i-debug-what-is-being-rendered-to-a-frame-buffer-object-in-opengl/25#25)

Obv, it goes without saying that if I am not "debugging" a pixel shader or compute shader, I pass this "debugColor" info throughout the pipeline without interpolating it (in GLSL with  `flat`  keyword )

Again, this is very hacky and far from proper debugging, but is what I am stuck with not knowing any proper alternative.

> **Comments:**
> **username_9**: When they are available you can use SSBOs to get a more flexible output format where you don't need to encode in colors. However, the big drawback of this approach is that it alters the code which can hide/alter bugs, especially when UB is involved. +1 Nevertheless, for it is the most direct method that is available.  

---

### Answer by username_5 on 2015-08-07. Score: 11

There is also [GLSL-Debugger](https://github.com/GLSL-Debugger/GLSL-Debugger). It is a debugger used to be known as "GLSL Devil".

The Debugger itself is super handy not only for GLSL code, but for OpenGL itself as well. You have the ability to jump between draw calls and break on Shader switches. It also shows you error messages communicated by OpenGL back to the application itself.

> **Comments:**
> **username_6**: Note that as of 2018-08-07, it doesn't support anything higher than GLSL 1.2, and it's not actively maintained.  
> **username_7**: That comment legitimately made me sad :(  
> **username_8**: The project is open source and would really love help modernizing it. There's no other tool that does what it did.  

---

### Answer by username_9 on 2016-01-22. Score: 9

There are several offerings by GPU vendors like AMD's [CodeXL](http://developer.amd.com/tools-and-sdks/opencl-zone/codexl/) or NVIDIA's [nSight](https://www.nvidia.com/object/nsight.html)/[Linux GFX Debugger](https://developer.nvidia.com/linux-graphics-debugger) which allow stepping through shaders but are tied to the respective vendor's hardware.

Let me note that, although they are available under Linux, I always had very little success with using them there. I can't comment on the situation under Windows.

The option which I have come to use recently, is to modularize my shader code via [`#includes`](https://computergraphics.stackexchange.com/questions/100/sharing-code-between-multiple-glsl-shaders) and restrict the included code to a common subset of GLSL and C++&[glm](http://glm.g-truc.net).

When I hit a problem I try to reproduce it on another device to see if the problem is the same which hints at a logic error (instead of a driver problem/undefined behavior). There is also the chance of passing wrong data to the GPU (e.g. by incorrectly bound buffers etc.) which I usually rule out either by output debugging like in [username_2 answer](https://computergraphics.stackexchange.com/a/101) or by inspecting the data via [apitrace](https://apitrace.github.io/).

When it is a logic error I try to rebuild the situation from the GPU on CPU by calling the included code on CPU with the same data.
Then I can step through it on CPU.

Building upon the modularity of the code you can also try to write unittest for it and compare the results between a GPU run and a CPU run. However, you have to be aware that there are corner cases where C++ might behave differently than GLSL, thus giving you false positives in these comparisons.

Finally, when you can't reproduce the problem on another device, you can only start to dig down where the difference comes from. Unittests might help you to narrow down where that happens but in the end you will probably need to write out additional debug information from the shader like in [username_2 answer](https://computergraphics.stackexchange.com/a/101).

And to give you an overview here is a flowchart of my debugging process:
[![Flow chart of the procedure described in the text](https://i.sstatic.net/S1jUQ.png)](https://i.sstatic.net/S1jUQ.png)

To round this off here is a list of random pros and cons:

**pro**

* step through with usual debugger
* additional (often better) compiler diagnostics

**con**

* subtle differences in some mathematic primitives (e.g. [different return values in corner cases](https://stackoverflow.com/questions/31915601/pow1-inf-nan))
* additional code to reproduce call environment on CPU

> **Comments:**
> **username_9**: @racarate: I thought about that as well but did not have the time to try yet. I am no expert on mesa but I think it might be hard to debug the shader as the shader debug information has to somehow reach the debugger. Then again, maybe the folks at mesa already have an interface for that to debug mesa itself :)  

---

### Answer by username_10 on 2015-08-07. Score: 5

While it doesn't seem to be possible to actually step through an OpenGL shader, it is possible to get the compilation results.  
The following is taken from the [Android Cardboard Sample](https://github.com/googlesamples/cardboard-java/blob/master/CardboardSample/src/main/java/com/google/vrtoolkit/cardboard/samples/treasurehunt/MainActivity.java).

```
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
    Log.e(TAG, label + ": glError " + error);
    throw new RuntimeException(label + ": glError " + error);

```

If your code compiles properly, then you have little choice but to try out a different way of communicating the program's state to you. You could signal that a part of the code was reached by, for example, changing the color of a vertex or using a different texture. Which is awkward, but seems to be the only way for now.

EDIT: For WebGL, I am looking at [this project](http://benvanik.github.io/WebGL-Inspector/), but I've only just found it... can't vouch for it.

> **Comments:**
> **username_0**: Hm yeah, I'm aware that I can get compiler errors. I was hoping for better runtime debugging. I've also used WebGL inspector in the past, but I believe it only shows you state changes, but you can't look into a shader invocation. I guess this could have been clearer in the question.  

---

### Answer by username_11 on 2018-03-07. Score: 3

The solution that worked for me is compilation of shader code to C++ - as mentioned by username_9. It prooved very efficient when working on a complex code even though it requires a bit of setup.

I have been working mostly with HLSL Compute Shaders for which I have developed a proof-of-concept library available here:

<https://github.com/cezbloch/shaderator>

It demonstrates on a Compute Shader from DirectX SDK Samples, how to enable C++ like HLSL debugging and how to setup Unit Tests.

Compilation of GLSL compute shader to C++ looks easier than HLSL. Mainly due to syntax constructions in HLSL. I have added a trivial example of executable Unit Test on a GLSL ray tracer Compute Shader which you can also find in the Shaderator project's sources under link above.


---

### Answer by username_6 on 2016-06-26. Score: 3

*This is a copy-paste of [my answer](https://stackoverflow.com/a/38039733/673852) to the same [question at StackOverflow](https://stackoverflow.com/q/2508818/673852)*.

---

At the bottom of this answer is an example of GLSL code which allows to output the full `float` value as color, encoding IEEE 754 `binary32`. I use it like follows (this snippet gives out `yy` component of modelview matrix):

```c
vec4 xAsColor=toColor(gl_ModelViewMatrix[1][1]);
if(bool(1)) // put 0 here to get lowest byte instead of three highest
    gl_FrontColor=vec4(xAsColor.rgb,1);
else
    gl_FrontColor=vec4(xAsColor.a,0,0,1);

```

After you get this on screen, you can just take any color picker, format the color as HTML (appending `00` to the `rgb` value if you don't need higher precision, and doing a second pass to get the lower byte if you do), and you get the hexadecimal representation of the `float` as IEEE 754 `binary32`.

Here's the actual implementation of `toColor()`:

```c
const int emax=127;
// Input: x>=0
// Output: base 2 exponent of x if (x!=0 && !isnan(x) && !isinf(x))
//         -emax if x==0
//         emax+1 otherwise
int floorLog2(float x)
{
    if(x==0.) return -emax;
    // NOTE: there exist values of x, for which floor(log2(x)) will give wrong
    // (off by one) result as compared to the one calculated with infinite precision.
    // Thus we do it in a brute-force way.
    for(int e=emax;e>=1-emax;--e)
        if(x>=exp2(float(e))) return e;
    // If we are here, x must be infinity or NaN
    return emax+1;
}

// Input: any x
// Output: IEEE 754 biased exponent with bias=emax
int biasedExp(float x) { return emax+floorLog2(abs(x)); }

// Input: any x such that (!isnan(x) && !isinf(x))
// Output: significand AKA mantissa of x if !isnan(x) && !isinf(x)
//         undefined otherwise
float significand(float x)
{
    // converting int to float so that exp2(genType) gets correctly-typed value
    float expo=float(floorLog2(abs(x)));
    return abs(x)/exp2(expo);
}

// Input: x\in[0,1)
//        N>=0
// Output: Nth byte as counted from the highest byte in the fraction
int part(float x,int N)
{
    // All comments about exactness here assume that underflow and overflow don't occur
    const float byteShift=256.;
    // Multiplication is exact since it's just an increase of exponent by 8
    for(int n=0;n<N;++n)
        x*=byteShift;

    // Cut higher bits away.
    // $q \in [0,1) \cap \mathbb Q'.$
    float q=fract(x);

    // Shift and cut lower bits away. Cutting lower bits prevents potentially unexpected
    // results of rounding by the GPU later in the pipeline when transforming to TrueColor
    // the resulting subpixel value.
    // $c \in [0,255] \cap \mathbb Z.$
    // Multiplication is exact since it's just and increase of exponent by 8
    float c=floor(byteShift*q);
    return int(c);
}

// Input: any x acceptable to significand()
// Output: significand of x split to (8,8,8)-bit data vector
ivec3 significandAsIVec3(float x)
{
    ivec3 result;
    float sig=significand(x)/2.; // shift all bits to fractional part
    result.x=part(sig,0);
    result.y=part(sig,1);
    result.z=part(sig,2);
    return result;
}

// Input: any x such that !isnan(x)
// Output: IEEE 754 defined binary32 number, packed as ivec4(byte3,byte2,byte1,byte0)
ivec4 packIEEE754binary32(float x)
{
    int e = biasedExp(x);
    // sign to bit 7
    int s = x<0. ? 128 : 0;

    ivec4 binary32;
    binary32.yzw=significandAsIVec3(x);
    // clear the implicit integer bit of significand
    if(binary32.y>=128) binary32.y-=128;
    // put lowest bit of exponent into its position, replacing just cleared integer bit
    binary32.y+=128*int(mod(float(e),2.));
    // prepare high bits of exponent for fitting into their positions
    e/=2;
    // pack highest byte
    binary32.x=e+s;

    return binary32;
}

vec4 toColor(float x)
{
    ivec4 binary32=packIEEE754binary32(x);
    // Transform color components to [0,1] range.
    // Division is inexact, but works reliably for all integers from 0 to 255 if
    // the transformation to TrueColor by GPU uses rounding to nearest or upwards.
    // The result will be multiplied by 255 back when transformed
    // to TrueColor subpixel value by OpenGL.
    return vec4(binary32)/255.;
}

```


---

