[RESOLU]Crayonner pour révéler un dessin
Re: Crayonner pour révéler un dessin
Tes scripts n'ont rien à voir avec ce que j'ai expliqué...
Re: Crayonner pour révéler un dessin
Si, enfin je crois
"Brush" est l'objet que je déplace sur la feuille "World" pour tracer mes traits
Quand je clique sur ma feuille, le brush se déplace à l'endroit du clic et il suit le curseur tant que je garde le bouton pressé.
C'est ce qui me permet de tracer mes traits, enfin mes taches.
En fait, Brush est la sphere dans le gif du tuto.
"Brush" est l'objet que je déplace sur la feuille "World" pour tracer mes traits
Quand je clique sur ma feuille, le brush se déplace à l'endroit du clic et il suit le curseur tant que je garde le bouton pressé.
C'est ce qui me permet de tracer mes traits, enfin mes taches.
En fait, Brush est la sphere dans le gif du tuto.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.
Re: Crayonner pour révéler un dessin
Oui mais tu n'as pas du tout répercuté ça dans les fonctions qui servent à dessiner dans la texture, donc si tu bouges trop vite ta souris, tu auras des trainées de points et pas des lignes.
Il faut tenir compte du fait qu'entre deux update, ta souris peut avoir parcourue plus de distance que le diamètre de ta brush, c'est pour ça qu'il faut faire une boucle qui va forcer un tracé entre la dernière position connue et la nouvelle.
Il faut tenir compte du fait qu'entre deux update, ta souris peut avoir parcourue plus de distance que le diamètre de ta brush, c'est pour ça qu'il faut faire une boucle qui va forcer un tracé entre la dernière position connue et la nouvelle.
Re: Crayonner pour révéler un dessin
J'ai essayé de mettre en place tes conseils mais je n'arrive encore pas à avoir un trait continu.Alesk a écrit :c'est pour ça qu'il faut faire une boucle qui va forcer un tracé entre la dernière position connue et la nouvelle.
Je crois que je ne sais pas mettre en application la boucle dont tu parles.
Voilà la modification de mon script
Code : Tout sélectionner
Vector3 pos;
Vector3 Expos;
public float speed =0.0001f;
public float mini = 0.0001f;
bool move;
private void Update()
{
if (!move && Input.GetMouseButton(0))
{
//J'ai modifié mon extension pour ne faire qu'un appel
if (Camera.RaycastPos(World, out pos))
{
move = true;
}
}
if (move)
{
Brush.position = Vector3.Lerp(pos, Expos, speed * Time.deltaTime);
if (Vector3.SqrMagnitude(Brush.position - pos)< mini)
{
move = false;
Expos = pos;
}
}
}
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.
Re: Crayonner pour révéler un dessin
Bah y'a pas de boucle là ... Et c'est dans la fonction de dessin qu'elle doit être utilisée.
Là où tu passes les coordonnées pour tracer la brush sur la texture, tu dois utiliser cette boucle pour dessiner plusieurs fois la brush entre l'ancienne position et la nouvelle position de la souris.
Là où tu passes les coordonnées pour tracer la brush sur la texture, tu dois utiliser cette boucle pour dessiner plusieurs fois la brush entre l'ancienne position et la nouvelle position de la souris.
Re: Crayonner pour révéler un dessin
Bon bé écoute, là je ne comprends pas.Alesk a écrit :Bah y'a pas de boucle là ... Et c'est dans la fonction de dessin qu'elle doit être utilisée.
Là où tu passes les coordonnées pour tracer la brush sur la texture, tu dois utiliser cette boucle pour dessiner plusieurs fois la brush entre l'ancienne position et la nouvelle position de la souris.
J'ai mis tous les scripts qui gère cette fonction.
Je pense que ce doit être dans la fonction DoPaint du script Painter peut-être.
Ce n'est pas moi qui l'ai créée, j'ai bien essayé de modifier quelques données mais j'avoue que je ne comprends pas tout dans ce script. Une petite précision serait la bien venue.
En tout cas, merci de te pencher sur mon cas, qui est sévère mais pas désespéré j'espère
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.
Re: Crayonner pour révéler un dessin
Grâce aux patientes explications d'Alesk, j'ai enfin trouvé une solution qui me parait acceptable et avec laquele j'obtiens à peu près le résultat escompté.
J'ai donc modifié le script Painter de cette façon:
Merci encore Alesk pour tes conseils. Il faut dire qu'il sont succinct, mais ils te mettent sur la voie pour trouver la solution par toi même et c'est très enrichissant.
J'ai donc modifié le script Painter de cette façon:
Code : Tout sélectionner
Vector3 expos;
void Update()
{
//pour n'exécuter la boucle que si le brush est déplacé
if (expos != Brush.transform.position)
{
Vector3 position = expos;
for (float i = 0; i < 1f; i += 0.1f)
{
position = Vector3.Lerp(expos, Brush.transform.position, i);
DoPaint(position);
}
expos = Brush.transform.position;
}
}
// Mise à jour du Splat Map en fonction de la position de l'objet Brush
public void DoPaint(Vector3 position)
{
Vector4 worldToRtx = new Vector4(
map(position.x, WorldBounds.center.x - WorldBounds.size.x / 2, WorldBounds.center.x + WorldBounds.size.x / 2, 0, 1),
map(position.z, WorldBounds.center.z - WorldBounds.size.z / 2, WorldBounds.center.z + WorldBounds.size.z / 2, 0, 1),
0,
0
);
drawMaterial.SetVector(rtxCoord, worldToRtx);
drawMaterial.SetFloat(rtxStrength, BrushStrength);
drawMaterial.SetFloat(rtxSize, map(BrushSize, 0, 1, 1, 0));
drawMaterial.SetFloat(rtxFade, FadeSpeed);
RenderTexture temp = RenderTexture.GetTemporary(splatmap.width, splatmap.height, 0, RenderTextureFormat.ARGBFloat);
Graphics.Blit(splatmap, temp);
Graphics.Blit(temp, splatmap, drawMaterial);
RenderTexture.ReleaseTemporary(temp);
}
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.
Re: Crayonner pour révéler un dessin
C'est exactement ce que je cherchais à faire
Maintenant que tu as trouvé, et pour aller plus loin, je peux te donner plus de détails pour essayer d'optimiser un peu le code, si jamais il ne s'exécute pas assez vite :
Au lieu de faire la boucle dans la fonction update, il faudrait la déplacer dans la fonction DoPaint().
En effet : RenderTexture.GetTemporary() et RenderTexture.ReleaseTemporary() peuvent être des fonctions coûteuses en performances, l'idéal est de limiter lors utilisation au maximum.
Donc l'idée ici est de mettre la boucle de dessin dans la fonction DoPaint, entre l'appel à RenderTexture.GetTemporary et celui à RenderTexture.ReleaseTemporary
en gros :
1) RenderTexture.GetTemporary
2) blit blit blit blit blit blit blit blit blit blit blit blitblit blit blit blit
3) RenderTexture.ReleaseTemporary
Il faut donc envoyer deux positions à DoPaint au lieu d'une seule, et y faire le lerp.
Pour le step de la boucle for, actuellement tu utilises une valeur fixe (0.1), il faudrait aussi essayer de la rendre proportionnelle au diametre de ton objet brush, pour faire en sorte qu'il y ait le moins possible d'itérations de la boucle... c'est toujours ça de gagné.
Bon courage !
Re: Crayonner pour révéler un dessin
C'est pour ça que j'ai mis la condition :Alesk a écrit :Maintenant que tu as trouvé, et pour aller plus loin, je peux te donner plus de détails pour essayer d'optimiser un peu le code, si jamais il ne s'exécute pas assez vite :
Au lieu de faire la boucle dans la fonction update, il faudrait la déplacer dans la fonction DoPaint().
En effet : RenderTexture.GetTemporary() et RenderTexture.ReleaseTemporary() peuvent être des fonctions coûteuses en performances, l'idéal est de limiter lors utilisation au maximum.
Code : Tout sélectionner
if (expos != Brush.transform.position)
blit blit blit ... superAlesk a écrit :Donc l'idée ici est de mettre la boucle de dessin dans la fonction DoPaint, entre l'appel à RenderTexture.GetTemporary et celui à RenderTexture.ReleaseTemporary
en gros :
1) RenderTexture.GetTemporary
2) blit blit blit blit blit blit blit blit blit blit blit blitblit blit blit blit
3) RenderTexture.ReleaseTemporary
mais si je comprends bien la position du point dans la texture est calculée dans ces ligne là:
Code : Tout sélectionner
Vector4 worldToRtx = new Vector4(
map(position.x, WorldBounds.center.x - WorldBounds.size.x / 2, WorldBounds.center.x + WorldBounds.size.x / 2, 0, 1),
map(position.z, WorldBounds.center.z - WorldBounds.size.z / 2, WorldBounds.center.z + WorldBounds.size.z / 2, 0, 1),
0,
0
);
drawMaterial.SetVector(rtxCoord, worldToRtx);
Voilà ce que j'obtiens, et ça marche, est-ce bien ça que tu voulais ?
J' ai regroupé aussi le script qui déplace le brush car je ne vois pas l'intérêt d'un script séparé.
Code : Tout sélectionner
Vector3 expos;
void Update()
{
//ceci pour replacer le brush sans faire de trace
if (Input.GetMouseButtonDown(0))
{
if (Camera.RaycastPos(Feuille, out expos))
{
Brush.position = expos;
}
}
if (Input.GetMouseButton(0))
{
if (Camera.RaycastPos(Feuille, out Vector3 pos))
{
Brush.position = pos;
if (expos != Brush.position)
{
//si clic sur la feuille et si déplacement
DoPaint(expos, Brush.position);
expos = Brush.position;
}
}
}
}
public void DoPaint(Vector3 expos, Vector3 newpos)
{
RenderTexture temp = RenderTexture.GetTemporary(splatmap.width, splatmap.height, 0, RenderTextureFormat.ARGBFloat);
for (float i = 0; i < 1f; i += 0.1f)
{
Vector3 position = Vector3.Lerp(expos, newpos, i);
Vector4 worldToRtx = new Vector4(
map(position.x, WorldBounds.center.x - WorldBounds.size.x / 2, WorldBounds.center.x + WorldBounds.size.x / 2, 0, 1),
map(position.z, WorldBounds.center.z - WorldBounds.size.z / 2, WorldBounds.center.z + WorldBounds.size.z / 2, 0, 1),
0,
0
);
drawMaterial.SetVector(rtxCoord, worldToRtx);
drawMaterial.SetFloat(rtxStrength, BrushStrength);
//0.1 pour diminuer l'épaisseur du trait
drawMaterial.SetFloat(rtxSize, map(BrushSize, 0, 1, 1, 0.1f));
drawMaterial.SetFloat(rtxFade, FadeSpeed);
Graphics.Blit(splatmap, temp);
Graphics.Blit(temp, splatmap, drawMaterial);
}
RenderTexture.ReleaseTemporary(temp);
}
J'avoue que là ça coince, (si pour le reste j'ai bien compris).Alesk a écrit :Pour le step de la boucle for, actuellement tu utilises une valeur fixe (0.1), il faudrait aussi essayer de la rendre proportionnelle au diametre de ton objet brush, pour faire en sorte qu'il y ait le moins possible d'itérations de la boucle... c'est toujours ça de gagné.
Dans ma boucle il ne fait que 10 itérations en fait. J'obtiens un bon résultat. C'est trop?.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.
Re: Crayonner pour révéler un dessin
Tu as parfaitement compris pour la boucle !
Pour la taille de la brush, 10 iterations, ça ira dans la plupart des cas je pense, mais essaye avec moins, pour voir ... ça dépend beaucoup de la distance à parcourir.
En fait il faut diviser la distance entre les deux points du tracé par le rayon de la brush pour obtenir le nombre de répétitions nécessaires (et ajuster ensuite en fonction de la forme de la brush, en ajoutant une ou deux répétitions peut-être).
Pour la taille de la brush, 10 iterations, ça ira dans la plupart des cas je pense, mais essaye avec moins, pour voir ... ça dépend beaucoup de la distance à parcourir.
En fait il faut diviser la distance entre les deux points du tracé par le rayon de la brush pour obtenir le nombre de répétitions nécessaires (et ajuster ensuite en fonction de la forme de la brush, en ajoutant une ou deux répétitions peut-être).