代码之家  ›  专栏  ›  技术社区  ›  Yippie-Ki-Yay

C++着色器问题

  •  0
  • Yippie-Ki-Yay  · 技术社区  · 15 年前

    我正在使用 Nvidia CG Direct3D9 还有关于以下代码的问题。

    它编译,但不“加载”(使用 cgLoadProgram 包装),并简单地描述所产生的故障 D3D failure happened .

    它是像素明暗器的一部分,使用明暗器模型编译为 3.0

    有趣的是,在以下情况下,此明暗器加载良好:

    1) 手动展开while语句 (对许多人) if { } 陈述)。

    2) 用卸下管路 tex2D 循环中的函数。

    3) 切换到着色模型 2_X 手动展开循环。


    着色程序代码的问题部分:

    float2 tex = float2(1, 1);
    float2 dtex = float2(0.01, 0.01);
    
    float h = 1.0 - tex2D(height_texture1, tex);
    float height = 1.00;
    
    while ( h < height )
    {
        height -= 0.1;
        tex += dtex;
    
        // Remove the next line and it works (not as expected,
        // of course)
        h = tex2D( height_texture1, tex );
    }
    

    如果有人知道为什么会发生这种情况,或者可以在非CG环境中测试类似的代码,或者可以在其他方面帮助我,我在等你;)

    谢谢。

    1 回复  |  直到 15 年前
        1
  •  2
  •   Axel Gneiting    15 年前

    我认为你需要在循环之前,在纹理坐标上使用ddx/ddy确定渐变,然后使用 tex2D(sampler2D samp, float2 s, float2 dx, float2 dy)

    GPU始终渲染四个而不是像素(即使在像素边界上-渲染后端会丢弃多余的像素)。这是因为它允许它始终计算屏幕空间纹理派生,即使使用计算的纹理坐标。它只需要取像素中心值之间的差异。

    但是,在使用动态分支时,这不起作用,就像在问题代码中那样,因为每个像素处的着色处理器可能在控制流中分散。因此,在程序流发散之前,需要通过ddx/ddy手动计算派生。