M2PRO - Images
Année 2009-2010

TP 3 - Mon premier shader


Préambule

    Téléchargez et installez les libraries objtoy et sdlkit fournies en Annexes.
    Configurez également votre éditeur pour compiler les shaders avec shadercc (inclus dans sdlkit)
    Vérifiez le bon fonctionnement du sdlkit_testmain et de glsl_testmain.

    Documentation :

        openGL Programming Guide
        openGL Shading Language Specification

        openGL man pages
        GLSL quick reference guide

        libSDL Programming Guide


Partie 1 : mon premier vertex shader

    On souhaite animer un point dont on connait la position de départ et celle d'arrivée. La solution consiste à interpoler (linéairement) la position du point en fonction du temps.

    A l'instant t0, le point se trouve en x0, à l'instant t1, le point devra se trouver en x1.
    Connaissant t (compris entre 0 et 1), comment déterminer la position x du point ?

    Ecrivez le vertex shader permettant de réaliser cette animation.
    Quels paramètres doit connaitre le shader ? Comment les lui transmettre ?
    Ecrivez l'application utilisant le shader.



    Voici le vertex shader minimal :

// simple.vsl : vertex shader minimal
void main(void)
{
    gl_Position= gl_ModelViewProjectionMatrix * gl_Vertex;
}

    Que faut-il ajouter dans l'application pour l'utiliser ?

#include "glsl2.h"

glsl_init()

program= glsl_program_init("simple.vsl", "simple.fsl");
if(program==0)
        return -1;
/* active le programme */
glUseProgram(program);

et glsl_quit() à la fin du programme avant sdlkit_quit().


Partie 2 : prise en main

Q1. écrivez un vertex shader qui donne une couleur constante à tous les sommets qu'il traite. L'application doit pouvoir modifier la couleur.

Q2. fixez les valeurs des parametres :
    quels sont les paramètres transmis par l'application ?
    comment fixer la valeur d'un paramètre float ? mat4 ?
    comment transmettre les positions des sommets ?

Q3. faut-il écrire un fragment shader ?

Partie 3 : plus de paramètres

Q1. écrivez un fragment shader qui multiplie la couleur du fragment par une autre fournie par l'application.

remarque : la couleur est utilisée par le pixel shader, comment transmettre un paramètre a ce type de shader ?
  1. que faut-il modifier dans l'application (et / ou dans les shaders) pour transmettre une couleur constante pour tout l'objet ?
  2. que faut-il modifier dans l'application (et / ou dans les shaders) pour transmettre une couleur pour chaque sommet ?

Partie 4 : lumière !

Q1. modifiez votre/vos shader/s pour représenter la position d'une source de lumière ponctuelle ainsi que sa couleur. Faut-il utiliser un paramètre uniform ? ou un attribut de sommet ?


notations calculs eclairage

Q2. calculez la lumière réfléchie par l'objet (cf. TP lancer de rayons) :

    La physique fournit une solution simple : selon l'orientation de la surface sur laquelle le point P se trouve, le point P ne reçoit pas la même quantité d'énergie : elle est maximale lorsque la normale au point P est orientée vers la source de lumière et décroit proportionnellement au cosinus de l'angle (entre la normale et la direction de la source) dans les autres cas. Ce qui se résume à calculer dot(N, L) pour N et L unitaires, cf. le schema pour l'orientation et la signification des vecteurs N et L.
  1. dans quel shader faire le calcul ? y aurait-il des différences entre le résultat calculé par le vertex shader et celui obtenu avec un fragment shader ?

  2. dans quel repère travailler ? pour évaluer dot(N, L), les 2 vecteurs doivent se "trouver" dans le même repère, lequel ?
  3. quelles sont les coordonnées du point P ? dans quel repère ?
  4. quelles sont les coordonnées de la source de lumière ? dans quel repère ? comment calculer le vecteur L ?
  5. quelles sont les coordonnées de l'oeil / comment calculer V ? dans quel repère ?
  6. il faut connaitre la normale de la surface au point P, un point quelconque des triangles dessinés, comment l'obtenir ?
  7. comment tenir compte de la couleur de la source de lumière ? de la couleur de la matière associée à la surface ? comment transmettre ces propriétés au(x) shader(s) ?
Q3. écrire un shader correspondant à l'autre solution (calculs dans le vertex shader ou calculs dans le pixel shader). Justifiez les différences.

remarques :
exemples :

vertex shader pixel shader
exemple : éclairage calculé dans un vertex shader
exemple : éclairage calculé dans un pixel shader

les figures de ce sujet sont issues de : "the Cg tutorial", nvidia.





Annexe : utilitaires

Installation de sdlkit

Téléchargez sdlkit (build 116, mise à jour du 19/01/2009, fonctionne avec les drivers >= 180.11)

créez un répertoire et dézippez l'archive dedans
cd <répertoire>
tar -zxvf sdlkit_latest.tar.gz
make
make install

si vous souhaitez installer les exemples :
créez un répertoire tests dans le répertoire sdlkit et dézippez l'archive dedans
cd tests
tar -zxvf sdlkit_tests_latest.tar.gz
make

Installation de objtoy

Objtoy est fourni avec sdlkit, dans le répertoire ... objtoy.

tar -zxvf objtoy_latest.tar.gz
make
make install

shadercc

    Pour compiler vos shaders et vérifier qu'il n'y a pas d'erreurs de syntaxe et de casts avant d'éxécuter votre programme complet :

        ~/local/bin/shadercc -c shader.vsl

    Pensez à ajouter #version 120 au début du source des shaders pour détecter le maximum d'erreurs / warnings. shadercc affiche également la ligne du source correspondant à l'erreur détectée par le driver et en utilisant le format d'erreur de gcc, résultat, il s'intègre facilement à un éditeur ...

    Démonstration :

intégration shadercc avec SciTE


Intégration de shadercc dans SciTE

    Ouvrez les propriétés utilisateur : menu 'Options', option 'Open User Options File', copiez - collez les lignes suivantes :

# extensions de fichiers reconnues
file.patterns.cpp=*.c;*.cpp;*.cs;*.h;*.hpp;*.fsl;*.vsl

# compilation des shaders glsl
shadercc=shadercc -c $(FileNameExt)
command.compile.*.vsl=$(shadercc)
command.compile.*.fsl=$(shadercc)

    Enregistrez le fichier, fermez SciTE, rouvrez-le et éditez un shader (utilisez une extension .v?? pour un vertex shader et .f?? pour un fragment shader). Dans le menu Tools, l'option Compile est maintenant disponible (Ctrl-F7). Appuyez ensuite sur F4 pour visualiser les différentes erreurs (éventuelles, bien sur !).

Intégration de shadercc dans Gedit

    Ouvrez le menu Tools / External Tools. Creez un nouvel outil (bouton new), appelez-le shadercc, il ne reste plus qu'à le configurer.
Copiez-collez le script suivant dans la zone commande :

#!/bin/sh
$HOME/local/bin/shadercc -c $GEDIT_CURRENT_DOCUMENT_NAME

et sélectionnez les options d'exécution :
    input : current document,
    ouput : display in bottom pane,
    applicability : all documents


capture configuration gedit


    Par contre, gedit n'a pas l'air d'interpréter les messages d'erreurs ... utilisez plutot scite qui est nettement plus complet et présente une ergonomie plus efficace ...