断言调试失败时,在GLSL中引发运行时错误

时间:2019-07-24 15:09:54

标签: runtime-error glsl webgl assert

在函数distSigned中,我假设为l.p != vec2(0)。如果不是这种情况,则可能很难发现bug,从而破坏了整个着色器。有什么方法可以验证这一点,如果参数无效,则抛出运行时错误?这将使调试变得容易得多。我知道GLSL没有像Java那样的throw,但是也许有某种黑客手段?

struct parallel {
    vec2 p;
    vec2 d;
};

struct pt {vec2 v;};

float distSigned(pt p, parallel l) {
    vec2 l2o = fromOrigo(l);
    float d = length(l2o);
    return dot(p.v, l2o/d) - d;
}

编辑:我看了一下GLSL规范并发现了:

“必须为词法或语言返回编译时错误 语法错误的着色器。其他错误在编译时或链接时报告为 指示。”

我猜这意味着GLSL没有运行时错误?如果是这样,也许我可以自行实现异常?是否有某种设计模式?

2 个答案:

答案 0 :(得分:3)

向谁抛出运行时错误 ?什么时候扔?会引发多少个着色器调用,接收代码将如何接收它们?

只要GPU围绕着色器,着色器就会执行,而不是在运行绘制调用时执行。因此,此类错误将被“抛出”的时间可能在“您发出抽签通知时”到任意未来的任何时间。那么您将如何接收它们?谁来接收?

此外,您正在执行多个着色器调用;每个顶点和每个片段都有各自的调用。因此,每个顶点和栅格化的片段都可能“抛出”某种运行时错误。对于大小和复杂性的场景,可能有数百万个这样的错误。您将如何处理?

否,如果要调试着色器,则需要专用的工具,或者需要执行与printf调试等效的着色器。也就是说,将场景降低到可以减少的最低复杂度,然后根据某种错误情况是通过一种方法还是另一种方法来写输出值。

答案 1 :(得分:1)

错误像素实现,Webgl2:

//:ES2_AA2_MAC_DEB: My debug macro, true if positive.
//:        pix_err: PIXel ERRor    ( Stores Hex Error Code )
//:        pix_fra: PIXel FRAgment ( fragment color        )

#if( ES2_AA2_MAC_DEB > 0 ) //:///////////////////////////://

    //:ASSIGN_TO_ZERO_AT_TOP_OF_FUNCTION!!!!!!!!!!!!!!!!!!!!
    uint pix_err =( 0x00000000 ); 

#endif //:///////////////////////////////////////////////://


//: ...Later when you want to error check....


#if( ES2_AA2_MAC_DEB > 0 ) //:///////////////////////////://

    if( Ax1-Ax0+uint(1) != ES2_zoo_wid ||
        Ay1-Ay0+uint(1) != ES2_zoo_hig ){

        //: The first error encountered puts program     ://
        //: into invalid state, so we want to make sure  ://
        //: we never override the first error tripped.   ://
        //: So always guard with comparison to           ://
        //: 0x00000000 before setting to the error color.://
        if( uint(0x00000000) == pix_err ){
            pix_err=( uint(0xFF9000FF) );
        };; 
    };;

#endif //:///////////////////////////////////////////////://


... Do more code.......................................
... DONT TRY TO EXIT EARLY if error is tripped ........
... that will just turn your code into spaghetti ......


#if( ES2_AA2_MAC_DEB > 0 )  //://////////////////////////://

    if( uint(0x000000) != pix_err ){

        #define F_F uint(0xFF)" //://////////////////////://
        pix_fra=( vec4(  //://///////////////////////////:// 
                                                      
         float( ( pix_err >> 24  ) & F_F ) / 255.0    
        ,float( ( pix_err >> 16  ) & F_F ) / 255.0    
        ,float( ( pix_err >>  8  ) & F_F ) / 255.0    
        ,float( ( pix_err >>  0  ) & F_F ) / 255.0    
                                                      
        ));; //://///////////////////////////////////////:// 
        #undef F_F  //://////////////////////////////////://         

    };;

#endif //:///////////////////////////////////////////////://


//: Now in debug mode, you can color sample the pixel    ://
//: and type in the hex code to find the exact error.    ://
//: Might not be helpful for minor edge cases, but       ://
//: should be very helpful for gross mistakes in         ://
//: your programming logic.                              ://
return( pix_fra );