我正在使用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环境中测试类似的代码,或者可以用其他方式帮助我,我在等你;)
感谢。
答案 0 :(得分:2)
我认为您需要在纹理坐标上使用ddx / ddy确定循环前的渐变,然后使用tex2D(sampler2D samp, float2 s, float2 dx, float2 dy)
GPU总是渲染四边形而不是像素(即使在像素边框上 - 渲染后端也会丢弃多余的像素)。这样做是因为它允许它始终计算屏幕空间纹理派生,即使您使用计算的纹理坐标。它只需要取像素中心的值之间的差异。
但是当在问题中的代码中使用动态分支时,这不起作用,因为各个像素处的着色器处理器可能在控制流中发散。因此,您需要在程序流可以分散之前通过ddx / ddy手动计算派生。