comment créer un laser en traits discontinus?

Questions à propos du scripting Shader.
Avatar de l’utilisateur
Kaloverian
Messages : 356
Inscription : 10 Août 2016 03:03

comment créer un laser en traits discontinus?

Message par Kaloverian » 01 Fév 2025 23:23

bonjour,

Via Shader Graph,comment créer un. shader qui ,appliqué à un line renderer continu,le transforme en ceci:
ligne discontinue.png
ligne discontinue.png (121.28 Kio) Consulté 9507 fois

merci de votre aide

Avatar de l’utilisateur
Kaloverian
Messages : 356
Inscription : 10 Août 2016 03:03

Re: comment créer un laser en traits discontinus?

Message par Kaloverian » 05 Mars 2025 02:55

j'ai réalisé ce shader graph:
pointillés shadergraph.png
pointillés shadergraph.png (147.22 Kio) Consulté 1704 fois
Seulement dans celui-ci qui fonctionne,je n'arrive à remplacer MainText (texture principale) par un noeud Rectangle avec le noeud Fraction
C'est pour pouvoir modifier à volonté la largeur et longueur de la texture(en fait celles du tiret du laser)
Peut-on m'aider?

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6463
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: comment créer un laser en traits discontinus?

Message par boubouk50 » 05 Mars 2025 10:32

J'ai testé et je pense que le souci est au niveau du tile de l'UV.
Le nœud Rectangle n'accepte pas des valeurs d'UV en dehors de 0 et de 1. Il faut donc borner les valeurs d'UV en les répétant grâce à un nœud modulo par exemple.
Ci-joint une image d'un shader fonctionnel.
Pointille.png
Pointille.png (289.22 Kio) Consulté 1684 fois
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Avatar de l’utilisateur
Kaloverian
Messages : 356
Inscription : 10 Août 2016 03:03

Re: comment créer un laser en traits discontinus?

Message par Kaloverian » 05 Mars 2025 15:07

merci bien !
...et le Time et le speed (float) combinés en entrée d'un Multiply dont où dois-je accrocher la sortie du Multiply?

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6463
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: comment créer un laser en traits discontinus?

Message par boubouk50 » 05 Mars 2025 15:15

Je suppose qu'il faut multiplier le time et le speed, et additionner le résultat au X de l'UV (entre le premier split R(1) et le multiply)
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Avatar de l’utilisateur
Kaloverian
Messages : 356
Inscription : 10 Août 2016 03:03

Re: comment créer un laser en traits discontinus?

Message par Kaloverian » 05 Mars 2025 17:51

Voici le shader graph corrigé:
pointilles_rect_time shadergraph.png
pointilles_rect_time shadergraph.png (201.73 Kio) Consulté 1652 fois
Voici le résultat (cf vidéo) que j'attendais:
https://drive.google.com/file/d/1qhsrdb ... sp=sharing

Avatar de l’utilisateur
Kaloverian
Messages : 356
Inscription : 10 Août 2016 03:03

Re: comment créer un laser en traits discontinus?

Message par Kaloverian » 11 Mars 2025 02:32

1)seulement,ce résultat présente encore un défaut comme le montre cette vidéo:
https://drive.google.com/file/d/1-1hYti ... sp=sharing

en s'éloignant,les traits pointillés sont discontinus.C'est en s'approchant qu'on les voit continus.
Peut-on remédier à ce problème?

2)je n'arrive pas à créer un pointillé tubulaire ou volumétrique.Une solution?
Voici le script attaché à l'objet Laser pourvu d'un LineRenderer doté d'un matériau associé au dernier shader graph du post précédent.

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LaserTutorial : MonoBehaviour
{
    public int maxBounces = 5;
    public Vector3 start_direction;
    private LineRenderer lr;
    [SerializeField]
    private Transform startPoint;
    [SerializeField]
    private bool reflectOnlyMirror;
    [SerializeField]
    private void Start()
    {
        lr = GetComponent<LineRenderer>();
        lr.SetPosition(0, startPoint.position);
    }

    // Update is called once per frame
    void Update()
    {
        CastLaser(transform.position, start_direction);
    }

    void CastLaser(Vector3 position, Vector3 direction)
    { lr.SetPosition(0, startPoint.position);

        for (int i = 0; i < maxBounces; i++)
        { Ray ray = new Ray(position, direction);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit, 300, 1))
            { position = hit.point;
                direction = Vector3.Reflect(direction, hit.normal);
                lr.SetPosition(i + 1, hit.point);

                if (hit.transform.name != "Mirror" && reflectOnlyMirror)
                { for (int j=i+1; j <= 5; j++)
                    { lr.SetPosition(j, hit.point); }
                    break;
                }

            }
        }
    }
}


Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6463
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: comment créer un laser en traits discontinus?

Message par boubouk50 » 11 Mars 2025 10:11

Ce n'est pas un problème de shader réellement.
Plus la ligne est loin, plus elle est fine, moins elle est visible. Lorsque sa taille fait moins d'un pixel, elle peut ne pas être rendue au profit des autres couleurs qui remplissent le pixel. Tu as donc des discontinuités qui apparaissent.
C'est normal et c'est présent dans tous les jeux existants.

Un moyen existant de contrer cet effet est de modifier la largeur de ta ligne en fonction de la distance. Plus elle est loin, plus elle est large.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Avatar de l’utilisateur
Kaloverian
Messages : 356
Inscription : 10 Août 2016 03:03

Re: comment créer un laser en traits discontinus?

Message par Kaloverian » 14 Mars 2025 02:49

Voici le script à attacher au LaserGun pour un laser en pointillés et tubulaire:

Code : Tout sélectionner

using UnityEngine;
using System.Collections.Generic;


public class multiRaycast : MonoBehaviour
{
    public int maxBounces = 5;
    public Vector3 start_direction = Vector3.forward;
    public Material lineMaterial;
    public float wd = 0.1f;//width du linerenderer
    public int nb_cotes_poly = 6; // Nombre de côtés du polygone
    public float circleRadius = 0.5f; // Rayon du cercle
    public float f = 0.1f; // Incrément du rayon

    [SerializeField]
    private Transform startPoint;
    [SerializeField]
    private bool reflectOnlyMirror;

    private LineRenderer[] lrs;
    private List<Vector3> polygonPoints = new List<Vector3>(); // Liste des points du polygone

    private void Start()
    {
        // Calcul du plan orthogonal à la direction de départ
        Vector3 planeNormal = start_direction.normalized;
        Vector3 right = Vector3.Cross(planeNormal, Vector3.up).normalized;
        Vector3 up = Vector3.Cross(right, planeNormal).normalized;

        // Génération des points du polygone
        for (float hexRadius = 0; hexRadius <= circleRadius; hexRadius += f)
        {
            for (int i = 0; i < nb_cotes_poly; i++)
            {
                float angle = 360f / nb_cotes_poly * i * Mathf.Deg2Rad;
                Vector3 offset = (right * Mathf.Cos(angle) + up * Mathf.Sin(angle)) * hexRadius;
                polygonPoints.Add(startPoint.position + offset);
            }
        }

        // Création des LineRenderers
        lrs = new LineRenderer[polygonPoints.Count];
        for (int i = 0; i < polygonPoints.Count; i++)
        {
            GameObject lrObj = new GameObject("Laser_" + i);
            lrObj.transform.SetParent(transform);
            lrs[i] = lrObj.AddComponent<LineRenderer>();
            lrs[i].SetPosition(0, startPoint.position);

            if (lineMaterial != null)
            {
                lrs[i].material = new Material(lineMaterial);
                lrs[i].material.SetFloat("_Width", wd);
            }
            lrs[i].startWidth = wd;
            lrs[i].endWidth = wd;
        }
    }

    void Update()
    {
        // Lancement des raycasts à partir des points du polygone
        for (int i = 0; i < polygonPoints.Count; i++)
        {
            CastLaser(polygonPoints[i], start_direction, lrs[i]);
        }
    }

    void CastLaser(Vector3 position, Vector3 direction, LineRenderer lr)
    {
        lr.positionCount = 1;
        lr.SetPosition(0, position);

        for (int i = 0; i < maxBounces; i++)
        {
            Ray ray = new Ray(position, direction);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit, 300, 1))
            {
                position = hit.point;
                direction = Vector3.Reflect(direction, hit.normal);
                lr.positionCount++;
                lr.SetPosition(i + 1, hit.point);

                if (hit.transform.name != "Mirror" && reflectOnlyMirror)
                {
                    for (int j = i + 1; j <= maxBounces; j++)
                    {
                        lr.positionCount++;
                        lr.SetPosition(j, hit.point);
                    }
                    break;
                }
            }
            else
            {
                lr.positionCount++;
                lr.SetPosition(i + 1, position + direction * 300);
                break;
            }
        }
    }
}
Les objets réfléchissant doivent comporter une seule face ( 1 seule normale pour tous les raycasts)

cf lien vidéo:
https://drive.google.com/file/d/1DGyErO ... sp=sharing

Répondre

Revenir vers « les Shaders »