PureBasic

Forums PureBasic
Nous sommes le Ven 24/Mai/2013 11:07

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 15 messages ] 
Auteur Message
 Sujet du message: [Tuto] Raytracing , principe de base
MessagePosté: Dim 24/Mai/2009 15:00 
Je vais tenté via un code d'expliquer la base du raytracing en purebasic.

Tout d'abord, vous devez avoir des notions sur les vecteurs :

- un vecteur est un point dans un repère , en gros une position
représenté sous cette forme x,y,z
en purebasic on le represente sous cette forme :

Code:
Structure Vector3D
   x.d
   y.d
   z.d
EndStructure


Code:
Structure Vector3F
   x.f
   y.f
   z.f
EndStructure


3D ou 3F , c'est la notation hongroise , 3 pour les dimension , suivi du type
F pour les float , D pour les doubles. on travaillera avec les double.

2 vecteurs dans l'espace représente une droite , ou un segment ,
une demi-droite possède un vecteur , et une direction , la direction est un vecteur unitaire , on verra plus tard comment le calculé.


Le principe du Raytracing est simple , on lance des rayons à partir du point de vue vers le point visé , si il y a une interection avec un objet on calcul la lumière , on ajoute un pixel , etc...

Image
Source de l'image


Dans cette exemple , nous ne verrons pas le calcul de la lumière


Tout d'abord , il faut initialisé notre "camera"
Il lui faut un point d'origine , un point visé , une direction.

Citation:
L'origine est 0,0,0
le point visé , x,y,distance focale



La distance focale , est importante et il ne faut pas la négligé , si vous mettez une valeur au pif , par exemple 1000 , le rendu ne sera pas pareil selon la résolution.

La distance focale est représenté par "d" sur le schéma plus haut.

Il se calcul de cette façon :

Code:
-(ResolutionX / ( 2 * Tan ( FOV / 2 )   )   )


Plus le FOV est grand , plus la distance focale est petite , et inversement , un FOV de 30 est correct.


Commençons par poser nos jalons
avec des structures de bases :

Code:
Structure Vector3D
   x.d
   y.d
   z.d
EndStructure

Structure Ray
   O.Vector3D
   D.Vector3D
EndStructure

Structure sphere
position.Vector3D
radius.d
EndStructure


Il va nous falloir aussi quelques fonction pour nos vecteurs
on doit pouvoir les soustraires entre eux , obtenir un produit scalaire ( vector_dot ) , etc...

Code:
Procedure vector_normalize(*V.Vector3D)
   id.d = 1/Sqr(  (*V\x * *V\x) + (*V\y * *V\y) + (*V\z * *V\z)  )
   *V\x = *V\x * id
   *V\y = *V\y * id
   *V\z = *V\z * id
EndProcedure

Procedure.d vector_dot(*A.vector3d,*B.vector3d)
ProcedureReturn *A\x * *B\x  + *A\y * *B\y  + *A\z * *B\z 
EndProcedure

Procedure.i vector_copy(*a.vector3d)
   *V.vector3d = AllocateMemory(SizeOf(vector3d))
   *V\x = *a\x
   *V\y = *a\y
   *V\z = *a\z
   ProcedureReturn *V
EndProcedure

Procedure.i vector_sub(*a.vector3d,*b.vector3d)
   *V.vector3d = AllocateMemory(SizeOf(vector3d))
   *V\x = *a\x   - *b\x
   *V\y = *a\y   - *b\y
   *V\z = *a\z   - *b\z
   ProcedureReturn *V
EndProcedure




Revenons à notre point de vue ,

Notre point de vue est le 0,0,0
le point visé Pixel_x , Pixel_y , Distance_Focale

ce qui nous donne :


Code:
; Point d'origine :
A.Vector3D
A\x   = 0
A\y   = 0
A\z   = 0

For pixel_y = 0 To 480 -1
   For pixel_x = 0 To 640 -1

      ; Point visé
      B.Vector3D
      B\x   = pixel_x - (640/2)
      B\y   = pixel_y   - (480/2)
      B\z   = -(640 / (2*Tan(30/2)))      

      ; on le normalize
      vector_normalize(B)



On va donc pouvoir créer notre rayon ,
il nous faut , l'origine ( on l'a déjà 0,0,0 ) est la direction.

La direction est le vecteur directeur entre Origine et le point visé , il se calcule la la manière suivante :

Citation:
Direction = B - A
Normalize(Direction)


en code :

Code:
      ;Vecteur direction du rayon
      Ray_Direction.Vector3D
      
      Ray_Direction\x = B\x - A\x
      Ray_Direction\y = B\y - A\y
      Ray_Direction\z = B\z - A\z
      
      vector_normalize(Ray_Direction)



Notre rayon est donc :

Code:
      Rayon.Ray
      
      Rayon\O\x = A\x   
      Rayon\O\y = A\y
      Rayon\O\z = A\z
      
      Rayon\D\x = Ray_Direction\x   
      Rayon\D\y = Ray_Direction\y
      Rayon\D\z = Ray_Direction\z



Notre rayon est créer , il nous faut donc savoir si il rentre en collision avec les objets ( ici la sphère )
j'utilise cette fonction , pour testé la collision :


On lui passe en paramètre une sphere , un rayon , un pointeur sur un coefficient que l'on fixe avant avec une grande valeur ( ex:20000 )
si il y a une intersection, le Coef doit être plus petit ( c'est la distance d'impact entre l'objet et la caméra )
Si la sphere est en Z à 100 avec un diamètre de 20 , et si le rayon tape dans le centre , alors le coef doit être de 90...

Code:
Procedure intersection_sphere(*sphere.sphere,*ray.ray,*t)

*dist.vector3d = vector_copy(*sphere\position)

vector_sub(*dist,*ray\o)

B.f = vector_dot(*ray\d,*dist)
D.f = B*B - vector_dot(*dist,*dist) + *sphere\radius * *sphere\radius


If D<0
   ProcedureReturn #False
EndIf

T0.f = B - Sqr(D)
T1.f = B + Sqr(D)
result = #False


If (T0>0.1) And (T0 < PeekD(*t))
   PokeD(*t,T0)
   result = #True
EndIf

If (T1>0.1) And (T1 < PeekD(*t))
   PokeD(*t,T1)
   result = #True
EndIf

ProcedureReturn result
EndProcedure



l'utilisation de la procédure :

Citation:
Coef.d = 20000
Intersection.b = intersection_sphere(Sphere,Rayon,@Coef)


Si intersection <>-1 alors il y a une intersection... simple non ?

voici la boucle principale :

Code:
For pixel_y = 0 To 480 -1
   For pixel_x = 0 To 640 -1

      ; Point visé du rayon
      B.Vector3D
      B\x   = pixel_x - (640/2)
      B\y   = pixel_y   - (480/2)
      B\z   = -(640 / (2*Tan(30/2)))      ; Calcul de la Distance Focale ( Fov = 30 )
      ; on le normalize
      vector_normalize(B)
      
      ;Vecteur direction du rayon
      Ray_Direction.Vector3D
      
      Ray_Direction\x = B\x - A\x
      Ray_Direction\y = B\y - A\y
      Ray_Direction\z = B\z - A\z
      
      vector_normalize(Ray_Direction)
      
      
      ; On a le point de départ
      ; le point visé , on en à donc deduis la direction
      ; on peut construire notre rayon.
      
      Rayon.Ray
      
      Rayon\O\x = A\x   
      Rayon\O\y = A\y
      Rayon\O\z = A\z
      
      Rayon\D\x = Ray_Direction\x   
      Rayon\D\y = Ray_Direction\y
      Rayon\D\z = Ray_Direction\z
      
      
      Coef.d = 20000
      Intersection.b = intersection_sphere(Sphere,Rayon,@Coef)
      
      If Intersection<>-1 And Coef < 20000
         ; Affiche un pixel en X,Y ici !!!!!
      EndIf
      
   
   Next
Next


C'est simple non ?


le code complet :
Code:
Structure Vector3D
   x.d
   y.d
   z.d
EndStructure

Procedure vector_normalize(*V.Vector3D)
   id.d = 1/Sqr(  (*V\x * *V\x) + (*V\y * *V\y) + (*V\z * *V\z)  )
   *V\x = *V\x * id
   *V\y = *V\y * id
   *V\z = *V\z * id
EndProcedure

Procedure.d vector_dot(*A.vector3d,*B.vector3d)
ProcedureReturn *A\x * *B\x  + *A\y * *B\y  + *A\z * *B\z 
EndProcedure

Procedure.i vector_copy(*a.vector3d)
   *V.vector3d = AllocateMemory(SizeOf(vector3d))
   *V\x = *a\x
   *V\y = *a\y
   *V\z = *a\z
   ProcedureReturn *V
EndProcedure

Procedure.i vector_sub(*a.vector3d,*b.vector3d)
   *V.vector3d = AllocateMemory(SizeOf(vector3d))
   *V\x = *a\x   - *b\x
   *V\y = *a\y   - *b\y
   *V\z = *a\z   - *b\z
   ProcedureReturn *V
EndProcedure


Structure Ray
   O.Vector3D
   D.Vector3D
EndStructure

Structure sphere
position.Vector3D
radius.d
EndStructure


Procedure intersection_sphere(*sphere.sphere,*ray.ray,*t)

*dist.vector3d = vector_copy(*sphere\position)

vector_sub(*dist,*ray\o)

B.f = vector_dot(*ray\d,*dist)
D.f = B*B - vector_dot(*dist,*dist) + *sphere\radius * *sphere\radius


If D<0
   ProcedureReturn #False
EndIf

T0.f = B - Sqr(D)
T1.f = B + Sqr(D)
result = #False


If (T0>0.1) And (T0 < PeekD(*t))
   PokeD(*t,T0)
   result = #True
EndIf

If (T1>0.1) And (T1 < PeekD(*t))
   PokeD(*t,T1)
   result = #True
EndIf

ProcedureReturn result
EndProcedure





Sphere.sphere
Sphere\position\z = 200
Sphere\radius = 20*2


; Point de départ du rayon
A.Vector3D
A\x   = 0
A\y   = 0
A\z   = -1

CreateImage(0,640,480)
StartDrawing(ImageOutput(0))

For pixel_y = 0 To 480 -1
   For pixel_x = 0 To 640 -1

      ; Point visé du rayon
      B.Vector3D
      B\x   = pixel_x - (640/2)
      B\y   = pixel_y   - (480/2)
      B\z   = -(640 / (2*Tan(30/2)))      ; Calcul de la Distance Focale ( Fov = 30 )
      ; on le normalize
      vector_normalize(B)
      
      ;Vecteur direction du rayon
      Ray_Direction.Vector3D
      
      Ray_Direction\x = B\x - A\x
      Ray_Direction\y = B\y - A\y
      Ray_Direction\z = B\z - A\z
      
      vector_normalize(Ray_Direction)
      
      
      ; On a le point de départ
      ; le point visé , on en à donc deduis la direction
      ; on peut construire notre rayon.
      
      Rayon.Ray
      
      Rayon\O\x = A\x   
      Rayon\O\y = A\y
      Rayon\O\z = A\z
      
      Rayon\D\x = Ray_Direction\x   
      Rayon\D\y = Ray_Direction\y
      Rayon\D\z = Ray_Direction\z
      
      
      Coef.d = 20000
      Intersection.b = intersection_sphere(Sphere,Rayon,@Coef)
      
      If Intersection<>-1 And Coef < 20000
         Plot(pixel_x,pixel_y,$FF)
      EndIf
      
   
   Next
Next


StopDrawing()
SaveImage(0,"Save.bmp")


l'output du programme , pixar n'a plus qu'a bien se tenir ! :D

Image


Haut
  
 
 Sujet du message:
MessagePosté: Dim 24/Mai/2009 17:47 
Avec de l'éclairage diffus !


Image

tout ce passe entre

Code:
if Norme<>0

endif




Code:
Structure Vector3D
   x.d
   y.d
   z.d
EndStructure

Procedure vector_normalize(*V.Vector3D)
   id.d = 1/Sqr(  (*V\x * *V\x) + (*V\y * *V\y) + (*V\z * *V\z)  )
   *V\x = *V\x * id
   *V\y = *V\y * id
   *V\z = *V\z * id
EndProcedure

Procedure.d vector_dot(*A.vector3d,*B.vector3d)
ProcedureReturn *A\x * *B\x  + *A\y * *B\y  + *A\z * *B\z 
EndProcedure

Procedure.i vector_copy(*a.vector3d)
   *V.vector3d = AllocateMemory(SizeOf(vector3d))
   *V\x = *a\x
   *V\y = *a\y
   *V\z = *a\z
   ProcedureReturn *V
EndProcedure

Procedure.i vector_sub(*a.vector3d,*b.vector3d)
   *V.vector3d = AllocateMemory(SizeOf(vector3d))
   *V\x = *a\x   - *b\x
   *V\y = *a\y   - *b\y
   *V\z = *a\z   - *b\z
   ProcedureReturn *V
EndProcedure

Procedure.i vector_mul(*a.vector3d,*b.vector3d)
   *V.vector3d = AllocateMemory(SizeOf(vector3d))
   *V\x = *a\x   * *b\x
   *V\y = *a\y   * *b\y
   *V\z = *a\z   * *b\z
   ProcedureReturn *V
EndProcedure

Structure Ray
   O.Vector3D
   D.Vector3D
EndStructure

Structure sphere
position.Vector3D
radius.d
EndStructure


Procedure intersection_sphere(*sphere.sphere,*ray.ray,*t)

*dist.vector3d = vector_copy(*sphere\position)

vector_sub(*dist,*ray\o)

B.f = vector_dot(*ray\d,*dist)
D.f = B*B - vector_dot(*dist,*dist) + *sphere\radius * *sphere\radius


If D<0
   ProcedureReturn #False
EndIf

T0.f = B - Sqr(D)
T1.f = B + Sqr(D)
result = #False


If (T0>0.1) And (T0 < PeekD(*t))
   PokeD(*t,T0)
   result = #True
EndIf

If (T1>0.1) And (T1 < PeekD(*t))
   PokeD(*t,T1)
   result = #True
EndIf

ProcedureReturn result
EndProcedure





Sphere.sphere
Sphere\position\z = 750
Sphere\radius = 200

Lumiere.Vector3D
Lumiere\x = -500
Lumiere\y = -500
Lumiere\z = -500

LumiereCouleur.Vector3D
LumiereCouleur\x = 0.5
LumiereCouleur\y = 0.5
LumiereCouleur\z = 0.5

; Point de départ du rayon
A.Vector3D
A\x   = 0
A\y   = 0
A\z   = -1

CreateImage(0,640,480)
StartDrawing(ImageOutput(0))
Box(0,0,640,480,$400000)

Ta.d = ElapsedMilliseconds()

For pixel_y = 0 To 480 -1
   For pixel_x = 0 To 640 -1

      ; Point visé du rayon
      B.Vector3D
      B\x   = pixel_x - (640/2)
      B\y   = pixel_y   - (480/2)
      B\z   = -(640 / (2*Tan(30/2)))      ; Calcul de la Distance Focale ( Fov = 30 )
      ; on le normalize
      vector_normalize(B)
      
      ;Vecteur direction du rayon
      Ray_Direction.Vector3D
      
      Ray_Direction\x = B\x - A\x
      Ray_Direction\y = B\y - A\y
      Ray_Direction\z = B\z - A\z
      
      vector_normalize(Ray_Direction)
      
      
      ; On a le point de départ
      ; le point visé , on en à donc deduis la direction
      ; on peut construire notre rayon.
      
      Rayon.Ray
      
      Rayon\O\x = A\x   
      Rayon\O\y = A\y
      Rayon\O\z = A\z
      
      Rayon\D\x = Ray_Direction\x   
      Rayon\D\y = Ray_Direction\y
      Rayon\D\z = Ray_Direction\z
      
      
      Coef.d = 20000
      Intersection.b = intersection_sphere(Sphere,Rayon,@Coef)
      
      If Intersection<>-1 And Coef < 20000
         
         
         ; On calcul le point d'impact
         Impact.Vector3D
         Impact\x = Rayon\O\x + Rayon\D\x * Coef
         Impact\y = Rayon\O\y + Rayon\D\y * Coef
         Impact\z = Rayon\O\z + Rayon\D\z * Coef
         
         
        ; On calcule la normale sur la sphere     
   
     Direction.vector3d
     Distance.vector3d
     
     Distance\x = Impact\x - Sphere\position\x
       Distance\y = Impact\y - Sphere\position\y
       Distance\z = Impact\z - Sphere\position\z
         
      vector_normalize(Distance)
       ; la norme
       Norme.d = vector_dot(Distance,Distance)
       Temp.f = Norme * Norme
       Temp = 1 / Sqr(Temp)
       Norme = Temp * Norme
      
             
       If Norme<>0
       
        ; On calcul la lumière ici ( Modèle de lambert )


      ; Distance entre la lumière et l'impact
      RayLightDist.Vector3D
      RayLightDist\x = Lumiere\x - Impact\x
      RayLightDist\y = Lumiere\y - Impact\y
      RayLightDist\z = Lumiere\z - Impact\z
      
      ; Produit scalaire
      NormeRayDist.d = vector_dot(RayLightDist,RayLightDist)
      
      RayLightDir.Vector3D
      
      ; la norme
      If NormeRayDist<>0
            RayLightDir\x = RayLightDist\x / Norme
            RayLightDir\y = RayLightDist\y / Norme
            RayLightDir\z = RayLightDist\z / Norme
      EndIf
      

   
   
   
      *IntensityLight.Vector3D
      *IntensityLight = vector_mul(RayLightDir,Distance)
      

      
    lambert.f = (*IntensityLight\x * Norme)+ (*IntensityLight\y * Norme)+(*IntensityLight\z * Norme)
       

          Red.d    = (LumiereCouleur\x * 0.5  * lambert)
        Green.d  = (LumiereCouleur\y * 0.5  * lambert)
        Blue.d   = (LumiereCouleur\z * 0.5  * lambert)
       
                                                                       
        If Red<0    : red   = 0 : EndIf
        If Green<0  : Green = 0 : EndIf
        If blue<0   : blue  = 0 : EndIf
        If Red>255    : red   = 255 : EndIf
        If Green>255  : Green = 255 : EndIf
        If blue>255   : blue  = 255 : EndIf
       
       
        Plot(Pixel_x,Pixel_y,RGB(Red,Green,Blue))
     
       EndIf
      
      
      
      
      
         
      EndIf
      
   
   Next
Next
Tb.d = ElapsedMilliseconds()

DrawText(10,10,"TIME RENDERING = "+StrD(Tb-Ta)+" ms")

StopDrawing()
SaveImage(0,"Save.bmp")


Haut
  
 
 Sujet du message:
MessagePosté: Dim 24/Mai/2009 17:56 
Hors ligne
Avatar de l’utilisateur

Inscription: Lun 26/Avr/2004 0:40
Messages: 12956
ouaip , ben je suis vraiment une bille en math :lol:

_________________
Image


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 24/Mai/2009 17:56 
Avant de vouloir aller plus loin , je tiens à précisé que les codes du dessus sont "pédagogique"

j'entends par là qu'il ne peut pas y avoir plusieurs sphères , ni plusieurs lumières.

Pour cela l'algorithme est le suivant :

Code:
Pour tout les pixels de la scene
  Trouver l'intersection la plus proche
   Si intersection
    Lancer un rayon vers les sources de lumière
     Si le rayon intersecte un autre objet avant d'atteindre la lumière , le pixel est dans l'ombre
     Si le materiau est reflechissant , récuperer la couleur de l'objet touché
        Calcul de la couleur du pixel
pixel suivant


Haut
  
 
 Sujet du message:
MessagePosté: Dim 24/Mai/2009 17:57 
Dobro a écrit:
ouaip , ben je suis vraiment une bille en math :lol:



je te rassure , moi aussi , j'y vais à taton ^^


Haut
  
 
 Sujet du message:
MessagePosté: Dim 24/Mai/2009 18:06 
Hors ligne
Avatar de l’utilisateur

Inscription: Lun 24/Juil/2006 6:44
Messages: 1554
Localisation: vosges (France) 47°54'39.06"N 6°20'06.39"E
Cpl.Bator a écrit:
Avant de vouloir aller plus loin , je tiens à précisé que les codes du dessus sont "pédagogique"

niveau pédagogique, c'est très réussi, beau travail, c'est je pense aussi clair que cela puisse l'être.

Il est sûr que les bases mathématiques nécessaires sont en effet minimum pour tout bien suivre,
mais je pense quelles ne sont pas insurmontable.

Belle série sur le sujet en perspective en tous les cas ;)

_________________
Force et sagesse...


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 24/Mai/2009 18:10 
Le SuperSampling


Le Supersampling est une technique qui permet d'éviter l'effet escalier entre les pixels , la mise en place est très facile.

Sans supersampling
Image


Avec supersampling 2x
Image

ps : imageshack à l'air de déformé le résultat BMP->PNG :/
a testé chez vous donc :D



Le principe est simple , on veut un rendu dans une image de
640x480 pixel , et bien avec un supersampling de 2
on travaillera dans une image de 1280x960 pixels
Ce qui engendre forcement plus de lancer de rayon ( 4x plus pour une même scène )
une fois notre scene dessiné , on re-dimensionne notre grande image de
1280x960 à 640x480 , grace à la fonction resizeimage() par exemple , pas besoin de se casser plus la tête :D

ReCode :

Code:
Structure Vector3D
   x.d
   y.d
   z.d
EndStructure

Procedure vector_normalize(*V.Vector3D)
   id.d = 1/Sqr(  (*V\x * *V\x) + (*V\y * *V\y) + (*V\z * *V\z)  )
   *V\x = *V\x * id
   *V\y = *V\y * id
   *V\z = *V\z * id
EndProcedure

Procedure.d vector_dot(*A.vector3d,*B.vector3d)
ProcedureReturn *A\x * *B\x  + *A\y * *B\y  + *A\z * *B\z 
EndProcedure

Procedure.i vector_copy(*a.vector3d)
   *V.vector3d = AllocateMemory(SizeOf(vector3d))
   *V\x = *a\x
   *V\y = *a\y
   *V\z = *a\z
   ProcedureReturn *V
EndProcedure

Procedure.i vector_sub(*a.vector3d,*b.vector3d)
   *V.vector3d = AllocateMemory(SizeOf(vector3d))
   *V\x = *a\x   - *b\x
   *V\y = *a\y   - *b\y
   *V\z = *a\z   - *b\z
   ProcedureReturn *V
EndProcedure

Procedure.i vector_mul(*a.vector3d,*b.vector3d)
   *V.vector3d = AllocateMemory(SizeOf(vector3d))
   *V\x = *a\x   * *b\x
   *V\y = *a\y   * *b\y
   *V\z = *a\z   * *b\z
   ProcedureReturn *V
EndProcedure

Structure Ray
   O.Vector3D
   D.Vector3D
EndStructure

Structure sphere
position.Vector3D
radius.d
EndStructure


Procedure intersection_sphere(*sphere.sphere,*ray.ray,*t)

*dist.vector3d = vector_copy(*sphere\position)

vector_sub(*dist,*ray\o)

B.f = vector_dot(*ray\d,*dist)
D.f = B*B - vector_dot(*dist,*dist) + *sphere\radius * *sphere\radius


If D<0
   ProcedureReturn #False
EndIf

T0.f = B - Sqr(D)
T1.f = B + Sqr(D)
result = #False


If (T0>0.1) And (T0 < PeekD(*t))
   PokeD(*t,T0)
   result = #True
EndIf

If (T1>0.1) And (T1 < PeekD(*t))
   PokeD(*t,T1)
   result = #True
EndIf

ProcedureReturn result
EndProcedure





Sphere.sphere
Sphere\position\z = 750
Sphere\radius = 200

Lumiere.Vector3D
Lumiere\x = -500
Lumiere\y = -500
Lumiere\z = -500

LumiereCouleur.Vector3D
LumiereCouleur\x = 0.5
LumiereCouleur\y = 0.5
LumiereCouleur\z = 0.5

; Point de départ du rayon
A.Vector3D
A\x   = 0
A\y   = 0
A\z   = -1


SuperSampling = 2


CreateImage(0,640*SuperSampling,480*SuperSampling)
StartDrawing(ImageOutput(0))
Box(0,0,640*SuperSampling,480*SuperSampling,$400000)

Ta.d = ElapsedMilliseconds()

For pixel_y = 0 To 480*SuperSampling -1
   For pixel_x = 0 To 640*SuperSampling -1

      ; Point visé du rayon
      B.Vector3D
      B\x   = pixel_x - ((640*SuperSampling)/2)
      B\y   = pixel_y   - ((480*SuperSampling)/2)
      B\z   = -((640*SuperSampling) / (2*Tan(30/2)))      ; Calcul de la Distance Focale ( Fov = 30 )
      ; on le normalize
      vector_normalize(B)
      
      ;Vecteur direction du rayon
      Ray_Direction.Vector3D
      
      Ray_Direction\x = B\x - A\x
      Ray_Direction\y = B\y - A\y
      Ray_Direction\z = B\z - A\z
      
      vector_normalize(Ray_Direction)
      
      
      ; On a le point de départ
      ; le point visé , on en à donc deduis la direction
      ; on peut construire notre rayon.
      
      Rayon.Ray
      
      Rayon\O\x = A\x   
      Rayon\O\y = A\y
      Rayon\O\z = A\z
      
      Rayon\D\x = Ray_Direction\x   
      Rayon\D\y = Ray_Direction\y
      Rayon\D\z = Ray_Direction\z
      
      
      Coef.d = 20000
      Intersection.b = intersection_sphere(Sphere,Rayon,@Coef)
      
      If Intersection<>-1 And Coef < 20000
         
         
         ; On calcul le point d'impact
         Impact.Vector3D
         Impact\x = Rayon\O\x + Rayon\D\x * Coef
         Impact\y = Rayon\O\y + Rayon\D\y * Coef
         Impact\z = Rayon\O\z + Rayon\D\z * Coef
         
         
        ; On calcule la normale sur la sphere     
   
     Direction.vector3d
     Distance.vector3d
     
     Distance\x = Impact\x - Sphere\position\x
       Distance\y = Impact\y - Sphere\position\y
       Distance\z = Impact\z - Sphere\position\z
         
      vector_normalize(Distance)
       ; la norme
       Norme.d = vector_dot(Distance,Distance)
       Temp.f = Norme * Norme
       Temp = 1 / Sqr(Temp)
       Norme = Temp * Norme
      
             
       If Norme<>0
       
        ; On calcul la lumière ici ( Modèle de lambert )


      ; Distance entre la lumière et l'impact
      RayLightDist.Vector3D
      RayLightDist\x = Lumiere\x - Impact\x
      RayLightDist\y = Lumiere\y - Impact\y
      RayLightDist\z = Lumiere\z - Impact\z
      
      ; Produit scalaire
      NormeRayDist.d = vector_dot(RayLightDist,RayLightDist)
      
      RayLightDir.Vector3D
      
      ; la norme
      If NormeRayDist<>0
            RayLightDir\x = RayLightDist\x / Norme
            RayLightDir\y = RayLightDist\y / Norme
            RayLightDir\z = RayLightDist\z / Norme
      EndIf
      

   
   
   
      *IntensityLight.Vector3D
      *IntensityLight = vector_mul(RayLightDir,Distance)
      

      
    lambert.f = (*IntensityLight\x * Norme)+ (*IntensityLight\y * Norme)+(*IntensityLight\z * Norme)
       

          Red.d    = (LumiereCouleur\x * 0.5  * lambert)
        Green.d  = (LumiereCouleur\y * 0.5  * lambert)
        Blue.d   = (LumiereCouleur\z * 0.5  * lambert)
       
                                                                       
        If Red<0    : red   = 0 : EndIf
        If Green<0  : Green = 0 : EndIf
        If blue<0   : blue  = 0 : EndIf
        If Red>255    : red   = 255 : EndIf
        If Green>255  : Green = 255 : EndIf
        If blue>255   : blue  = 255 : EndIf
       
       
        Plot(Pixel_x,Pixel_y,RGB(Red,Green,Blue))
     
       EndIf
      
      
      
      
      
         
      EndIf
      
   
   Next
Next
Tb.d = ElapsedMilliseconds()
StopDrawing()

ResizeImage(0,640,480)
StartDrawing(ImageOutput(0))
DrawText(10,10,"TIME RENDERING = "+StrD(Tb-Ta)+" ms")
StopDrawing()
SaveImage(0,"Save.bmp")


Haut
  
 
 Sujet du message:
MessagePosté: Lun 25/Mai/2009 19:18 
Hors ligne
Avatar de l’utilisateur

Inscription: Mar 26/Avr/2005 15:19
Messages: 315
mon boitier Cpl!! tu t' attaque a un sujet dont je n osais apréhender.
je t encourage sur cette voie.
et rassures toi !!moi non plus je ne comprends rien a tes codes....
Si tu pouvais faire voir ce que ca donne en temps réel? 8)
Je suis le sujet avec beaucoup d' attention!!


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Lun 25/Mai/2009 19:32 
Code:
Si tu pouvais faire voir ce que ca donne en temps réel?


Impensable , 200 ms un rendu , ca fait environ 5fps...

je vais voir pour combiné mes connaissances en la matière pour faire cohabité
du polygonale simple et le raytracing en temps réel , avec une technique de subsampling cela devrais le faire pour des petites scenes pas trop complexe.


Haut
  
 
 Sujet du message:
MessagePosté: Lun 25/Mai/2009 20:58 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 11/Fév/2005 17:34
Messages: 3063
Localisation: Arras, France
S'il y a quelqu'un qui peut optimiser ton code, c'est bien tonton! Figure-toi qu'on arrivait à faire des scènes simples en temps réel sur Amiga (7,14Mhz, je le rappelle); certes, c'était en 160x100 mais quand même (trois sphères de mémoire, avec réflexions)! Bien sûr avant d'optimiser, il vaut mieux avoir quelque chose de plus complet.

PS: Pareil que tonton, c'est génial de se lancer là-dedans! Pfiou moi j'ai jamais eu le courage! Je n'en reviens pas de ce que tu oses :)

_________________
The shooting crew ~> http://www.shootingcrew.com
Bobble Puzzle ~> http://djes.free.fr


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Lun 25/Mai/2009 21:07 
Bah forcement qu'en 160x100 je peut faire un truc fluide sans problèmes
mais adapter cela sur du 640x480 ou 800x600... pas la même histoire , on peut le faire , j'ai pensé utilisé les shaders pour faire les calculs vectoriel , afin de gardé les ressource CPU ( j'avais lu un truc sur le sujet. )
Mais bon... j'vais pas m'embarquer pour du temps réel avec de tel résolutions :D

Citation:
Je n'en reviens pas de ce que tu oses


C'est pas très compliqué au final , c'est même simple le concept , suffit de s'intéresser :D

D'ailleurs , tant que je t'ai sous la main , j'aurais un truc à te présenté qui va très certainement t'intéresser , chuuuut , j'en dit pas plus pour le moment :D


Haut
  
 
 Sujet du message:
MessagePosté: Lun 25/Mai/2009 21:10 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 11/Fév/2005 17:34
Messages: 3063
Localisation: Arras, France
A ton service! Figure-toi que moi aussi j'aurais un truc à te présenter, et il me faudrait une solide équipe de dév 3d :)

_________________
The shooting crew ~> http://www.shootingcrew.com
Bobble Puzzle ~> http://djes.free.fr


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 26/Juil/2009 15:55 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 26/Mai/2004 0:33
Messages: 684
Super tuto! très simple à comprendre :) (il faudrait faire le même pour les voxels, juste une idée :p)

Citation:
mais adapter cela sur du 640x480 ou 800x600... pas la même histoire , on peut le faire , j'ai pensé utilisé les shaders pour faire les calculs vectoriel , afin de gardé les ressource CPU ( j'avais lu un truc sur le sujet. )


Je me suis faît un petit raytracer temp réel il y à pas longtemps d'ailleurs, si ça t'intéresse les sources (C++ mais facilement portable) sont dispos ici: http://garzul.tonsite.biz/RTR/src.zip

Il utilise pas d'optimisation très agressive mais il tourne plutôt bien (90fps@640x480 sur ma tortue à 3ghz), la moitié des calculs sont precalcs (sauf shading) ce qui ne permet pas de bouger les objets, il me semble que sans ça il tourne à ~50fps.

Je l'ai porté en flash d'ailleurs (20fps ici): http://garzul.tonsite.biz/RTR/AS3/

Une optimisation qui peut être sympa niveau résultat et qui n'est pas difficile c'est d'utiliser les instructions SSE pour les calculs vectoriels, je sais pas si c'est faisable en PB par contre (mais ça devrait l'être) ou sinon la meilleur solution actuellement niveau perf et celle qui est utilisé dans les démos récentes, exemple: http://www.youtube.com/watch?v=hYD58OdL_bA c'est d'utiliser un pixel shader comme tu l'as dit. :)

PS: Un excellent site pour le raytracing temp réel: http://ompf.org/

_________________
http://garzul.tonsite.biz

Ancien site PB :
http://www.garzul.ca.cx


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 26/Juil/2009 16:31 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 25/Aoû/2004 6:31
Messages: 2387
Localisation: Eragny
Bravo Cpl.Bator, j'avais pas vu ce sujet... tes codes sont vraiment super pédagogique ! Vraiment très intéressant !


Haut
 Profil  
 
 Sujet du message:
MessagePosté: Dim 26/Juil/2009 19:06 
Merci. ;)

Citation:
(il faudrait faire le même pour les voxels, juste une idée :p)


je me suis jamais vraiment penché sur le problème , la seule chose que j'avais pensé , c'est d'utiliser un tel système ( voxels ) pour soustraire des formes (CSG) , puis de triangularisé le résultat ( Méthode de Delaunay )
cela peu être utile pour faire des trous dans n'importe quelle forme complexe !


Haut
  
 
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 15 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye