2010-11-11 5 views
0

J'utilise Nvidia CG et Direct3D9 et vous avez la question concernant le code suivant.C++ shader question

Il compile, mais ne "charge" pas (en utilisant l'enveloppe cgLoadProgram) et la défaillance qui en résulte est décrite simplement comme D3D failure happened.

Il est une partie du pixel shader compilé avec le modèle de shaders mis à 3.0

Ce qui peut être intéressant est que cette charge de shaders fines dans les cas suivants:

1) manuellement déroulement de l'instruction while (à plusieurs instructions if { }).

2) Retrait de la ligne avec la fonction tex2D dans la boucle.

3) Passer au modèle de nuanceur 2_X et dérouler manuellement la boucle.


partie du problème du code de shaders:

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); 
} 

Si quelqu'un sait pourquoi cela peut se produire ou pourrait tester le code similaire dans un environnement non-CG ou pourrait me aider d'une autre manière, Je vous attends;)

Merci.

Répondre

2

Je pense que vous devez déterminer les gradients avant la boucle à l'aide DDX/ddy sur les coordonnées de texture, puis utilisez tex2D(sampler2D samp, float2 s, float2 dx, float2 dy)

Le GPU rend toujours quadriceps pas pixels (même sur les frontières de pixels - pixels superflus sont mis au rebut par la rendre le backend). Ceci est fait car cela lui permet de toujours calculer les dérivées de la texture de l'espace écran même lorsque vous utilisez des coordonnées de texture calculées. Il suffit de prendre la différence entre les valeurs des centres de pixels.

Mais cela ne fonctionne pas lorsque vous utilisez une dérivation dynamique comme dans le code de la question, car les processeurs de shader sur les pixels individuels peuvent diverger dans le flux de contrôle. Vous devez donc calculer les dérivations manuellement via ddx/ddy avant que le flux du programme puisse diverger.