我需要调试一个GLSL程序,但我不知道如何输出中间结果。 是否有可能使用GLSL进行一些调试跟踪(如printf) ?
当前回答
我正在分享一个片段着色器的例子,我实际上是如何调试的。
#version 410 core
uniform sampler2D samp;
in VS_OUT
{
vec4 color;
vec2 texcoord;
} fs_in;
out vec4 color;
void main(void)
{
vec4 sampColor;
if( texture2D(samp, fs_in.texcoord).x > 0.8f) //Check if Color contains red
sampColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); //If yes, set it to white
else
sampColor = texture2D(samp, fs_in.texcoord); //else sample from original
color = sampColor;
}
其他回答
苏这
vec3 dd(vec3 finalColor,vec3 valueToDebug){
//debugging
finalColor.x = (v_uv.y < 0.3 && v_uv.x < 0.3) ? valueToDebug.x : finalColor.x;
finalColor.y = (v_uv.y < 0.3 && v_uv.x < 0.3) ? valueToDebug.y : finalColor.y;
finalColor.z = (v_uv.y < 0.3 && v_uv.x < 0.3) ? valueToDebug.z : finalColor.z;
return finalColor;
}
//on the main function, second argument is the value to debug
colour = dd(colour,vec3(0.0,1.0,1.));
gl_FragColor = vec4(clamp(colour * 20., 0., 1.),1.0);
你不能轻易地从GLSL内部与CPU通信。使用glslDevil或其他工具是最好的选择。
printf需要尝试从运行GLSL代码的GPU返回到CPU。相反,你可以试着推到显示器前。不要尝试输出文本,而是输出一些在屏幕上有视觉区别的东西。例如,只有当您到达代码中想要添加printf的位置时,才可以将某些东西涂成特定的颜色。如果你需要打印一个值,你可以根据这个值设置颜色。
现有的答案都是好东西,但我想分享更多的小宝石,在调试棘手的精度问题在GLSL着色器有价值。对于以浮点数表示的非常大的int数,需要注意正确使用floor(n)和floor(n + 0.5)来实现round()为精确的int。然后,可以通过以下逻辑将字节组件打包到R、G和B输出值中,呈现一个精确int的浮点值。
// Break components out of 24 bit float with rounded int value
// scaledWOB = (offset >> 8) & 0xFFFF
float scaledWOB = floor(offset / 256.0);
// c2 = (scaledWOB >> 8) & 0xFF
float c2 = floor(scaledWOB / 256.0);
// c0 = offset - (scaledWOB << 8)
float c0 = offset - floor(scaledWOB * 256.0);
// c1 = scaledWOB - (c2 << 8)
float c1 = scaledWOB - floor(c2 * 256.0);
// Normalize to byte range
vec4 pix;
pix.r = c0 / 255.0;
pix.g = c1 / 255.0;
pix.b = c2 / 255.0;
pix.a = 1.0;
gl_FragColor = pix;
对纹理进行离线渲染,并评估纹理的数据。 你可以通过google“render to texture”opengl找到相关代码 然后使用glReadPixels将输出读入数组并对其执行断言(因为在调试器中查看如此巨大的数组通常并不真正有用)。
此外,你可能想要禁用钳制输出值不是在0到1之间,这只支持浮点纹理。
我个人一度被调试着色器的问题所困扰。似乎没有一个好的方法-如果有人发现一个好的(并且没有过时/过时)调试器,请告诉我。
我发现了一个非常好的github库(https://github.com/msqrt/shader-printf) 你可以在着色器文件中使用printf函数。
推荐文章
- 如何为KnockoutJS调试模板绑定错误?
- 如何在构建目标之外生成gcc调试符号?
- 调试器是如何工作的?
- 当有命令行参数时,如何使用GDB分析程序的核心转储文件?
- OpenGL 4.1版本的文本渲染技术是怎样的?
- 如何在Visual Studio中找到堆栈跟踪?
- 有一个好的Valgrind Windows的替代品吗?
- Eclipse调试器总是阻塞在ThreadPoolExecutor上,没有任何明显的异常,为什么?
- Visual Studio:如何打破处理异常?
- 确保您的项目构建设置正在生成一个dSYM文件。对于所有配置,DEBUG_INFORMATION_FORMAT都应该设置为dwarf-with-dsym
- 如何获得GDB中所有线程的回溯?
- 如何检测IE11?
- 如何通过参数和重定向stdin从一个文件到程序运行在gdb?
- 我如何调试git/git-shell相关的问题?
- Visual Studio拒绝忘记断点?