Huhu, mais tu passes toujours le même rayon pour tous les pixels, comment veux-tu que ça marche ?
La position fixe, okay, mais tu peux pas passer le même "view".
Faut que t'écrives ça plutôt :
float4 raymarchingCast( float2 _UV )
{
//c'est la que je force la position de la camera...
float3 p = float3( 0.0, 0.0, 0.0 ); //original pos of cam
float3 v = normalize( float3( 2.0 * _UV.x - 1.0, 1.0 - 2.0 * _UV.y, 1.0 ) ); // direction of cam
// Ensuite, t'utilises (p,v) pour ray-marcher. Pas la peine d'utiliser des float4 partout, ça complique pour rien...
}
Et là, le paramètre UV c'est les coordonnées UV de ton quad. Ca devrait être (0,0) en haut à gauche de l'écran et (1,1) en bas à droite...
Sinon, essaie d'utiliser des swizzles et des vector operations dès que tu peux. Au lieu de :
float distanceToSphere(float4 center, float radius, float4 pos)
{
return sqrt(
pow(pos.x - center.x,2) +
pow(pos.y - center.y,2) +
pow(pos.z - center.z,2) -
radius
);
}
Ecris plutôt (toujours avec des float3, sinon c'est chiant pour rien) :
float distanceToSphere( float3 center, float radius, float3 pos )
{
float3 Pos2Center = center - pos; // Là tu laisses le GPU traiter le float3, plutôt que faire les calculs sur chaque composante x,y,z
return length( Pos2Center ) - radius; // length() fait exactement sqrt( x²+y²+z² ), pourquoi s'embêter ?
}
Et surtout ! Surtout ! Il vaut 100 fois mieux écrire x*x que pow( x, 2 ) !!!!! La première fait juste une multiplication, la seconde écriture fait appel à une fonction qu'est pas spécialement gratos...
Pareil, petite technique avec swizzle. Au lieu de :
color = float4(NdotL,NdotL,NdotL,1.0);
Ecris :
color = float4( NdotL.xxx, 1.0 ); // Un float est un vecteur particulier à une seule composante : x
Sinon, écrire :
float4 n = normalize(position);
Je sais vraiment pas ce que ça va faire ! Déjà il faut vraiment que "position" soit un float3, pas un float4, sinon tu normalises avec le w=1, ça va donner n'importe nawak. Pourquoi t'as choisi de foutre des float4 partout en fait, je comprends pas ?
Ensuite, comme expliqué un peu plus haut : tu essaies de normaliser une position, pas un vecteur. En l'occurence, tu dis : "prends la position où je touche la sphère et fais-en un vecteur". Ca va pas marcher.
Tu as une position, et tu cherches la normale. La normale est une direction. La différence entre position et direction est fondamentale ! Donc déjà, tu peux pas te servir d'une position comme direction. En fait, ça va marcher mais ça va te donner la direction [position - (0,0,0)] (depuis le centre du monde, là où t'as placé ta caméra, donc ça va donner une truc, mais cheulou (et en plus, dans ce cas, toujours négatif donc t'auras sans doute du noir. Prends la valeur absolue pour avoir qqchose).
Ce que tu veux c'est vraiment la normale à la surface à la position où t'as touché la sphère. Du coup, faut que t'utilises la routine de calcul de normale qu'est filée dans le papier d'iQ, je l'ai pas sous les yeux mais elle est assez facile à recopier. En ce qui concerne son fonctionnement, bah en gros ça va aller sampler le distance field partout autour de ta position en +X, -X, +Y, -Y, +Z et -Z et faire la différence entre toutes ces distances : ça te donne ce qu'on appelle un gradient. C'est la variation de distance en X, Y et Z autour de ton point. Et, magie, il se trouve que c'est également la direction de la normale de ta surface ! Tadaaaa !
Il faut donc que t'écrives :
float3 FonctionDeCalculDeNormaleRepompéeDansLeDocDiQ( float3 position )
{
(...)
}
(...)
float3 n = FonctionDeCalculDeNormaleRepompéeDansLeDocDiQ(position);
float3 l = 1.0;
float NdotL = dot(n,l);
color = float4(NdotL.xxx,1.0);
Bon courage !