Raytracing in One Weekend

Programmation d'applications complexes
Avatar de l’utilisateur
MLD
Messages : 1124
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: Raytracing in One Weekend

Message par MLD »

Bonjour
Pb m'indique une erreur dans ton code ligne 298 - 299
Avatar de l’utilisateur
threedslider
Messages : 452
Inscription : dim. 01/juil./2018 22:38

Re: Raytracing in One Weekend

Message par threedslider »

Bonjour @MLD,

Cela dit quoi ton erreur de message précisément ? S'agit il de random double ? Ou autre problème ?
Avatar de l’utilisateur
MLD
Messages : 1124
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: Raytracing in One Weekend

Message par MLD »

Salut
Le message PB: Random max ne peut pas être négatif.
Bonne journée
Avatar de l’utilisateur
threedslider
Messages : 452
Inscription : dim. 01/juil./2018 22:38

Re: Raytracing in One Weekend

Message par threedslider »

Salut

Bizarre chez moi il marche bien même négatif... T'es sur quelle version de PB ? 32 ou 64 bit ?
Avatar de l’utilisateur
MLD
Messages : 1124
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: Raytracing in One Weekend

Message par MLD »

Re Bonjour
PB 6.10 32 bit et win 64 bit
Avatar de l’utilisateur
threedslider
Messages : 452
Inscription : dim. 01/juil./2018 22:38

Re: Raytracing in One Weekend

Message par threedslider »

Rebonjour

Moi je l'ai testé sur PB 6.11 64 bit, essaye la toute dernière version, peut être cela marchera ?
Avatar de l’utilisateur
threedslider
Messages : 452
Inscription : dim. 01/juil./2018 22:38

Re: Raytracing in One Weekend

Message par threedslider »

Si tu veux fixer ce problème, fais ceci :

Remplace le macro par la procedure à la ligne 40 :

Code : Tout sélectionner

Procedure.d random_double()
  ProcedureReturn (Random(#MAXDWORD) / #MAXDWORD) 
EndProcedure
Normalement cela devrait marcher... Du moins je l'espère 8O :)
Avatar de l’utilisateur
MLD
Messages : 1124
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: Raytracing in One Weekend

Message par MLD »

Bonsoir
Désolé, mais je suis passé PB6.11 J'ai fait ce que tu m'a dit

Code : Tout sélectionner

;
; Inspired from Ray Tracing in One Weekend : 
; https://raytracing.github.io/books/RayTracingInOneWeekend.html
;
; Written and adapted in Purebasic by threedslider

EnableExplicit

Enumeration Shading
  #None
  #Lambertian
  #Metal
EndEnumeration


#Samples_per_pixel = 35
#Max_Depth = 2
#Sample_scale = 1.0 / #Samples_per_pixel

; Vector
Structure Vec3d : x.d : y.d : z.d : EndStructure

Procedure vec3_normalize(*v.vec3d)
  Protected n.d = Sqr(*v\x * *v\x + *v\y * *v\y + *v\z * *v\z)
  If n <> 0.0 : n = 1.0/n : *v\x * n : *v\y * n : *v\z * n : EndIf
EndProcedure

Macro vec3_zero(v) : v\x = 0.0 : v\y = 0.0 : v\z = 0.0 : EndMacro
Macro vec3_length(v) : Sqr(v\direction\x * v\direction\x + v\direction\y * v\direction\y + v\direction\z * v\direction\z) : EndMacro
Macro vec3_length_squared(v) : (v\x * v\x + v\y * v\y + v\z * v\z) : EndMacro
Macro vec3_dot(v1, v2) : (v1\x * v2\x + v1\y * v2\y + v1\z * v2\z) : EndMacro
Macro vec3_copy(v, v1) : v\x = v1\x : v\y = v1\y : v\z = v1\z : EndMacro
Macro vec3_add(v, v1, v2) : v\x = v1\x + v2\x : v\y = v1\y + v2\y : v\z = v1\z + v2\z : EndMacro
Macro vec3_subtract(v, v1, v2) : v\x = v1\x - v2\x : v\y = v1\y - v2\y : v\z = v1\z - v2\z : EndMacro
Macro vec3_mul(v, v1, v2) : v\x = v1\x * v2\x : v\y = v1\y * v2\y : v\z = v1\z * v2\z : EndMacro
Macro vec3_scale(v, v1, s) : v\x = v1\x * s : v\y = v1\y * s : v\z = v1\z * s : EndMacro  
Macro vec3_set(v, vx, vy, vz) : v\x = vx : v\y = vy : v\z = vz : EndMacro
Macro vec3_negate(v, v1) : v\x = -v1\x : v\y = -v1\y : v\z = -v1\z : EndMacro
;Macro random_double() : Random(#MAXDWORD) / #MAXDWORD : EndMacro
Macro random_min_max(min, max) : min + (max-min) * random_double() : EndMacro
Procedure.d random_double()
  ProcedureReturn (Random(#MAXDWORD) / #MAXDWORD) 
EndProcedure

Macro reflect(v, v1, n1) : v\x  = v\x - 2 * vec3_dot(v1, n1) * n1\x : v\y  = v\y - 2 * vec3_dot(v1, n1) * n1\y : v\z  = v\z - 2 * vec3_dot(v1, n1) * n1\z : EndMacro

Structure Ray ; Ray
  origin.vec3d : direction.vec3d
EndStructure

Structure Sphere ; Sphere
  center.vec3d
  color.vec3d
  radius.d
  Shading.i
EndStructure

Structure Material ; Material
  albedo.vec3d
EndStructure

Procedure.d clamp(x.d, min.d, max.d)
  If x < min
    ProcedureReturn min
  ElseIf x > max
    ProcedureReturn max
  EndIf
  ProcedureReturn x
EndProcedure

Procedure unit_vector_vec3(*v.vec3d)
  vec3_normalize(*v)
EndProcedure  

Procedure random_in_unit_sphere(*v.vec3d)
  Repeat
    *v\x = random_min_max(-1.0, 1.0)
    *v\y = random_min_max(-1.0, 1.0)
    *v\z = random_min_max(-1.0, 1.0)
    If vec3_length_squared(*v) < 1.0 : ProcedureReturn : EndIf
  ForEver
EndProcedure
Procedure random_unit_vector(*v.vec3d)
  random_in_unit_sphere(*v)
  unit_vector_vec3(*v)
EndProcedure

Macro surrounds(x, min, max) : Bool(min <= x And x <= max) : EndMacro

; Create Sphere primitve
Macro m_Sphere(center_x, center_y, center_z, radius_, color_x, color_y, color_z, shading_)
  AddElement(scene())
  vec3_set(scene()\center,center_x,center_y,center_z)
  vec3_set(scene()\color,color_x,color_y,color_z)
  scene()\radius = radius_
  scene()\Shading = shading_
EndMacro

Global NewList scene.Sphere()

m_Sphere(0.0, -100.5, -1.0, 100.0, 0.8, 0.8, 0.0, #Lambertian); ; << - PJ240614 - pushed this down
m_Sphere(0.0, 0.0, -1.2, 0.5, 0.1, 0.2, 0.5, #Lambertian)
m_Sphere(-1.0, 0.0, -1.0, 0.5, 0.8, 0.8, 0.8, #Metal)
m_Sphere(1.0, 0.0, -1.0, 0.5, 0.8, 0.6, 0.2, #Metal)

Procedure near_zero (*v.vec3d) ;Near zero for pathtracing calculation
  Protected e.d = 1e-8
  ProcedureReturn Bool((Abs(*v\x) < e) And (Abs(*v\y) < e) And (Abs(*v\z) < e))
EndProcedure


; Hit for 3D objects
Procedure.d hit(*_s.Sphere, *ray.Ray, max.d)
  
  Protected oc.vec3d
  Protected root.d = 0.0
  Protected min.d = 0.0001
  
  vec3_subtract(oc, *_s\center,*ray\origin) 
  
  Protected a.d = vec3_length_squared(*ray\direction)
  Protected h.d = vec3_dot(*ray\direction,oc)
  Protected c.d = vec3_length_squared(oc) - *_s\radius * *_s\radius
  
  Protected discriminant.d = h * h - a * c
  
  If discriminant < 0.0 : ProcedureReturn #False : EndIf
  
  Protected sqrtd.d = Sqr(discriminant)
  
  root = (h - sqrtd) / a
  
  If Not surrounds(root, min, max)
    root = (h + sqrtd) / a
    If Not surrounds(root, min, max) : ProcedureReturn 0.0 : EndIf
  EndIf 

  ProcedureReturn root
  
EndProcedure

; Hit for intersection
Procedure.b intersect( *ray.Ray, *t.double, *id.Integer )
  Protected d.d, inf.d = 999.999
  *t\d = inf
  ForEach scene()
    d = hit(@scene(), *ray, *t\d)
    If d
      *t\d  = d
      *id\i = ListIndex(scene())
    EndIf
  Next
  ProcedureReturn Bool( *t\d < inf )
EndProcedure

; Unit vector Y for background
Procedure.d unit_vector_y(*vy.Ray)
  Protected len.d
  Static y.d : y.d = 0
  len = vec3_length(*vy)
  If len <> 0.0 : y = *vy\direction\y / len  : EndIf
  ProcedureReturn y
EndProcedure

Procedure.d ray_color(*rr.Ray, *in.vec3d)
  Protected a.d
  Static color1.vec3d, color2.vec3d, unit_directionection.vec3d
  
  color1\x = 1.0 : color1\y = 1.0 : color1\z = 1.0
  color2\x = 0.5 : color2\y = 0.7 : color2\z = 1.0

  unit_directionection\y = unit_vector_y(*rr)
  a = 0.5 * (unit_directionection\y + 1.0) 
  *in\x + ((1.0 - a) * color1\x + a * color2\x)
  *in\y + ((1.0 - a) * color1\y + a * color2\y)
  *in\z + ((1.0 - a) * color1\z + a * color2\z)
EndProcedure  

Procedure.d linear_to_gamma(num.d)
  If num > 0.0
    ProcedureReturn Sqr(num)
  EndIf
  
  ProcedureReturn 0.0
  
EndProcedure


Procedure.d ray_color_hit(*ray.Ray, *in.vec3d, depth)
  Protected.vec3d x, p
  Protected t.d = 0.0
  Protected id.i = 0
  Protected.ray rr, unit_vector, scattered
  Protected.Vec3d out, reflected
  
  If depth < 0
    vec3_set(*in,0.0,0.0,0.0) : ProcedureReturn
  EndIf
  Protected.vec3d ruv, n, nl
  If intersect(*ray, @t, @id)
    SelectElement(scene(),id)
    Protected *obj.Sphere = scene()
    
    ; Point at parameter
    x\x = *ray\origin\x + t * *ray\direction\x
    x\y = *ray\origin\y + t * *ray\direction\y
    x\z = *ray\origin\z + t * *ray\direction\z
    
    ; Norm
    vec3_subtract(n, x, *obj\center)
    vec3_normalize(n)
    
    ; Set to normal
    If vec3_dot(n, *ray\direction ) < 0.0
      vec3_copy(nl, n)
    Else
      vec3_negate(nl, n)
    EndIf
    
    
    If *obj\shading = #Lambertian
      vec3_copy(rr\origin, x)
  
      random_unit_vector(@ruv) 
      vec3_add(rr\direction,nl,ruv) 
      
        
      ray_color_hit(rr, *in , depth-1)
      *in\x * *obj\color\x : *in\y * *obj\color\y : *in\z * *obj\color\z 
    
    ElseIf *obj\shading = #Metal
      
      reflect(reflected, *ray\direction, nl)
    
      vec3_copy(rr\origin, x)
      
      vec3_copy(rr\direction, reflected)
      
      ray_color_hit(rr, *in , depth-1)
      *in\x * *obj\color\x : *in\y * *obj\color\y : *in\z * *obj\color\z 
    
    
    EndIf
;     
;     vec3_set(*in,0.0,0.0,0.0)
    
  Else
    
    ray_color(*ray, *in)
    *in\x * 0.5 : *in\y * 0.5 : *in\z * 0.5
  EndIf
  
EndProcedure

Define aspect_ratio.d = 16.0 / 9.0
Define image_width = 800

Define image_height = Int(image_width / aspect_ratio)

If image_height < 1
  image_height = 1
Else
  image_height = image_height
EndIf

; Render engine
Procedure render()
  Shared image_width, image_height
  Static focal_length.d = 1.0, viewport_height.d = 2.0
  Protected i_w.d = image_width, i_h.d = image_height
  Protected viewport_width.d = viewport_height * (i_w/i_h)
  
  Protected.vec3d point3, ray_direction, viewport3_u, viewport3_v, pixel_delta_u, pixel_delta_v, v_f, viewport_upper_left, pixel_100_loc
  
  vec3_set(point3, 0,0,0)
  vec3_set(ray_direction, 0,0,0)
  vec3_set(viewport3_u, viewport_width,0,0)
  vec3_set(viewport3_v, 0,-viewport_height,0)
  vec3_set(pixel_delta_u, viewport3_u\x / i_w, viewport3_u\y / i_w, viewport3_u\z / i_w)
  vec3_set(pixel_delta_v, viewport3_v\x / i_h, viewport3_v\y / i_h, viewport3_v\z / i_h)
  vec3_set(v_f, 0,0,focal_length)
  vec3_set(viewport_upper_left,
           point3\x - v_f\x - viewport3_u\x / 2 - viewport3_v\x / 2,
           point3\y - v_f\y - viewport3_u\y / 2 - viewport3_v\y / 2,
           point3\z - v_f\z - viewport3_u\z / 2 - viewport3_v\z / 2)
  vec3_set(pixel_100_loc, 0,0,focal_length)

  pixel_100_loc\x = viewport_upper_left\x + 0.5 * (pixel_delta_u\x + pixel_delta_v\x)
  pixel_100_loc\y = viewport_upper_left\y + 0.5 * (pixel_delta_u\y + pixel_delta_v\y)
  pixel_100_loc\z = viewport_upper_left\z + 0.5 * (pixel_delta_u\z + pixel_delta_v\z)
  
  Protected x.d, y.d, z.d, v.vec3d
  Protected ray.ray
  Static offset.vec3d, pixel_sample.vec3d
  Protected j,i,jj.d, ii.d, sample
  
  For j = 0 To image_height-1
    glBegin_(#GL_POINTS)
    For i = 0 To image_width-1
      x = 0.0 : y = 0.0 : z = 0.0
      For sample = 1 To #Samples_per_pixel
        ii = i + random_double() - 0.5 
        jj = j + random_double() - 0.5 
        
        pixel_sample\x = pixel_100_loc\x + ii * pixel_delta_u\x +  jj * pixel_delta_v\x
        pixel_sample\y = pixel_100_loc\y + ii * pixel_delta_u\y +  jj * pixel_delta_v\y
        pixel_sample\z = pixel_100_loc\z + ii * pixel_delta_u\z +  jj * pixel_delta_v\z
        
        vec3_subtract(ray_direction,pixel_sample,point3)

        ray\origin = point3
        ray\direction = ray_direction          
        
        ray_color_hit(@ray, @v, #Max_Depth) 
        x = x + v\x : y = y + v\y : z = z + v\z
      Next
      
      glColor3f_(linear_to_gamma(#Sample_scale * x), linear_to_gamma(#Sample_scale * y), linear_to_gamma(#Sample_scale * z)) : glVertex2s_(i,j)

    Next
    glEnd_() : glFlush_()
  Next
  
EndProcedure

OpenWindow(0, 0, 0, image_width / DesktopResolutionX(), image_height / DesktopResolutionY(), "Inspired from Raytracing in One Weekend", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenGLGadget(0,0,0,image_width / DesktopResolutionX(),image_height / DesktopResolutionY(),#PB_OpenGL_NoFlipSynchronization)
glOrtho_(0,image_width,image_height,0,-1,1)
glDrawBuffer_(#GL_FRONT)  

Define time = ElapsedMilliseconds()
render()
  time = ElapsedMilliseconds() - time
SetWindowTitle(0,"Inspired from Raytracing in One Weekend - RenderTime: "+Str(time)+"ms")

Define Event

Repeat
  Event = WindowEvent()
Until  Event = #PB_Event_CloseWindow

End 

Mais le résultat est le même.
Ce n'est pas pour moi car j'ai essaiyé ton code par curiosité. Mais si cela peut te rendre service je serai ravis.
Le problème est certainement le 32bit.
Bon courage pour le débugage
Bonne soirée.
Avatar de l’utilisateur
threedslider
Messages : 452
Inscription : dim. 01/juil./2018 22:38

Re: Raytracing in One Weekend

Message par threedslider »

Encore désolé pour cela d'avoir passer en PB 6.11... Donc non je l'ai conçu pour 64 bit pas 32 bit... car la précision est plutôt énorme.
Avatar de l’utilisateur
threedslider
Messages : 452
Inscription : dim. 01/juil./2018 22:38

Re: Raytracing in One Weekend

Message par threedslider »

Cepedant j'ai installé le PB 6.11 32 bit, tout marche bien ici la seule diffrence c'est l'ombre plus foncé...

Je vois pas pourquoi le tien marche pas... A moins que tu as dû modifier mon code... si c'est pas le cas? Donc c'est impossible que cela ne marche pas :?

Il n'y a rien à debugger...
Avatar de l’utilisateur
MLD
Messages : 1124
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: Raytracing in One Weekend

Message par MLD »

Bonjour
Non je n'est pas touché a ton code.
J'ai l'habitude de faire tous mes programmes en 32 bit comme cela je suis sur que cela fonctionne sur toutes les machines, car tout le monde n'a pas win64 bit.
Si cela fonctionne chez toi en 32 bit, c'est effectivement difficile a comprendre 8O
Il faudrait l'aide d'autres amis de ce forum.
J'ai refait des essais ce matin en essayant plusieurs configurations du compilateur, le résultat est le même :oops: :?: :?:
Désolé a +
Avatar de l’utilisateur
threedslider
Messages : 452
Inscription : dim. 01/juil./2018 22:38

Re: Raytracing in One Weekend

Message par threedslider »

Bonjour

Peut être ta machine est vieille et supporte pas le calcul moderne, mais bon ...

Sinon puisque tu es en 32 bit en ce moment, je te suggeres de remodifier le data type en float (32 bit) comme ceci :

Code : Tout sélectionner

Procedure.f random_double()
  ProcedureReturn (Random(#MAXDWORD) / #MAXDWORD) 
EndProcedure
Et là cela marche ?
Avatar de l’utilisateur
threedslider
Messages : 452
Inscription : dim. 01/juil./2018 22:38

Re: Raytracing in One Weekend

Message par threedslider »

Si jamais ça marche pas, désolé donc faut tout remplacer tout ce qui est double par float dans mon code c'est à dire Vec3D : x.f, y.f, z.f...

T'inquiète pas j'ai fait pour toi :

Code : Tout sélectionner

;
; Inspired from Ray Tracing in One Weekend : 
; https://raytracing.github.io/books/RayTracingInOneWeekend.html
;
; Written and adapted in Purebasic by threedslider

;EnableExplicit

Enumeration Shading
  #None
  #Lambertian
  #Metal
EndEnumeration


#Samples_per_pixel = 35
#Max_Depth = 2
#Sample_scale = 1.0 / #Samples_per_pixel

; Vector
Structure Vec3d : x.f : y.f : z.f : EndStructure

Procedure vec3_normalize(*v.vec3d)
  Protected n.f = Sqr(*v\x * *v\x + *v\y * *v\y + *v\z * *v\z)
  If n <> 0.0 : n = 1.0/n : *v\x * n : *v\y * n : *v\z * n : EndIf
EndProcedure

Macro vec3_zero(v) : v\x = 0.0 : v\y = 0.0 : v\z = 0.0 : EndMacro
Macro vec3_length(v) : Sqr(v\direction\x * v\direction\x + v\direction\y * v\direction\y + v\direction\z * v\direction\z) : EndMacro
Macro vec3_length_squared(v) : (v\x * v\x + v\y * v\y + v\z * v\z) : EndMacro
Macro vec3_dot(v1, v2) : (v1\x * v2\x + v1\y * v2\y + v1\z * v2\z) : EndMacro
Macro vec3_copy(v, v1) : v\x = v1\x : v\y = v1\y : v\z = v1\z : EndMacro
Macro vec3_add(v, v1, v2) : v\x = v1\x + v2\x : v\y = v1\y + v2\y : v\z = v1\z + v2\z : EndMacro
Macro vec3_subtract(v, v1, v2) : v\x = v1\x - v2\x : v\y = v1\y - v2\y : v\z = v1\z - v2\z : EndMacro
Macro vec3_mul(v, v1, v2) : v\x = v1\x * v2\x : v\y = v1\y * v2\y : v\z = v1\z * v2\z : EndMacro
Macro vec3_scale(v, v1, s) : v\x = v1\x * s : v\y = v1\y * s : v\z = v1\z * s : EndMacro  
Macro vec3_set(v, vx, vy, vz) : v\x = vx : v\y = vy : v\z = vz : EndMacro
Macro vec3_negate(v, v1) : v\x = -v1\x : v\y = -v1\y : v\z = -v1\z : EndMacro
Procedure.f random_double()
  ProcedureReturn (Random(#MAXLONG) / #MAXLONG) 
EndProcedure

;Macro random_double() : Random(#MAXWORD) / #MAXWORD : EndMacro
Macro random_min_max(min, max) : min + (max-min) * random_double() : EndMacro
Macro reflect(v, v1, n1) : v\x  = v\x - 2 * vec3_dot(v1, n1) * n1\x : v\y  = v\y - 2 * vec3_dot(v1, n1) * n1\y : v\z  = v\z - 2 * vec3_dot(v1, n1) * n1\z : EndMacro

Structure Ray ; Ray
  origin.vec3d : direction.vec3d
EndStructure

Structure Sphere ; Sphere
  center.vec3d
  color.vec3d
  radius.f
  Shading.i
EndStructure

Structure Material ; Material
  albedo.vec3d
EndStructure

Procedure.f clamp(x.f, min.f, max.f)
  If x < min
    ProcedureReturn min
  ElseIf x > max
    ProcedureReturn max
  EndIf
  ProcedureReturn x
EndProcedure

Procedure unit_vector_vec3(*v.vec3d)
  vec3_normalize(*v)
EndProcedure  

Procedure random_in_unit_sphere(*v.vec3d)
  Repeat
    *v\x = random_min_max(-1.0, 1.0)
    *v\y = random_min_max(-1.0, 1.0)
    *v\z = random_min_max(-1.0, 1.0)
    If vec3_length_squared(*v) < 1.0 : ProcedureReturn : EndIf
  ForEver
EndProcedure
Procedure random_unit_vector(*v.vec3d)
  random_in_unit_sphere(*v)
  unit_vector_vec3(*v)
EndProcedure

Macro surrounds(x, min, max) : Bool(min <= x And x <= max) : EndMacro

; Create Sphere primitve
Macro m_Sphere(center_x, center_y, center_z, radius_, color_x, color_y, color_z, shading_)
  AddElement(scene())
  vec3_set(scene()\center,center_x,center_y,center_z)
  vec3_set(scene()\color,color_x,color_y,color_z)
  scene()\radius = radius_
  scene()\Shading = shading_
EndMacro

Global NewList scene.Sphere()

m_Sphere(0.0, -100.5, -1.0, 100.0, 0.8, 0.8, 0.0, #Lambertian); ; << - PJ240614 - pushed this down
m_Sphere(0.0, 0.0, -1.2, 0.5, 0.1, 0.2, 0.5, #Lambertian)
m_Sphere(-1.0, 0.0, -1.0, 0.5, 0.8, 0.8, 0.8, #Metal)
m_Sphere(1.0, 0.0, -1.0, 0.5, 0.8, 0.6, 0.2, #Metal)

Procedure near_zero (*v.vec3d) ;Near zero for pathtracing calculation
  Protected e.f = 1e-8
  ProcedureReturn Bool((Abs(*v\x) < e) And (Abs(*v\y) < e) And (Abs(*v\z) < e))
EndProcedure


; Hit for 3D objects
Procedure.f hit(*_s.Sphere, *ray.Ray, max.f)
  
  Protected oc.vec3d
  Protected root.f = 0.0
  Protected min.f = 0.0001
  
  vec3_subtract(oc, *_s\center,*ray\origin) 
  
  Protected a.f = vec3_length_squared(*ray\direction)
  Protected h.f = vec3_dot(*ray\direction,oc)
  Protected c.f = vec3_length_squared(oc) - *_s\radius * *_s\radius
  
  Protected discriminant.f = h * h - a * c
  
  If discriminant < 0.0 : ProcedureReturn #False : EndIf
  
  Protected sqrtd.f = Sqr(discriminant)
  
  root = (h - sqrtd) / a
  
  If Not surrounds(root, min, max)
    root = (h + sqrtd) / a
    If Not surrounds(root, min, max) : ProcedureReturn 0.0 : EndIf
  EndIf 

  ProcedureReturn root
  
EndProcedure

; Hit for intersection
Procedure.b intersect( *ray.Ray, *t.float, *id.Integer )
  Protected d.f, inf.f = 999.999
  *t\f = inf
  ForEach scene()
    d = hit(@scene(), *ray, *t\f)
    If d
      *t\f  = d
      *id\i = ListIndex(scene())
    EndIf
  Next
  ProcedureReturn Bool( *t\f < inf )
EndProcedure

; Unit vector Y for background
Procedure.f unit_vector_y(*vy.Ray)
  Protected len.f
  Static y.f : y.f = 0
  len = vec3_length(*vy)
  If len <> 0.0 : y = *vy\direction\y / len  : EndIf
  ProcedureReturn y
EndProcedure

Procedure.f ray_color(*rr.Ray, *in.vec3d)
  Protected a.f
  Static color1.vec3d, color2.vec3d, unit_directionection.vec3d
  
  color1\x = 1.0 : color1\y = 1.0 : color1\z = 1.0
  color2\x = 0.5 : color2\y = 0.7 : color2\z = 1.0

  unit_directionection\y = unit_vector_y(*rr)
  a = 0.5 * (unit_directionection\y + 1.0) 
  *in\x + ((1.0 - a) * color1\x + a * color2\x)
  *in\y + ((1.0 - a) * color1\y + a * color2\y)
  *in\z + ((1.0 - a) * color1\z + a * color2\z)
EndProcedure  

Procedure.f linear_to_gamma(num.f)
  If num > 0.0
    ProcedureReturn Sqr(num)
  EndIf
  
  ProcedureReturn 0.0
  
EndProcedure


Procedure.f ray_color_hit(*ray.Ray, *in.vec3d, depth)
  Protected.vec3d x, p
  Protected t.f = 0.0
  Protected id.i = 0
  Protected.ray rr, unit_vector, scattered
  Protected.Vec3d out, reflected
  
  If depth < 0
    vec3_set(*in,0.0,0.0,0.0) : ProcedureReturn
  EndIf
  Protected.vec3d ruv, n, nl
  If intersect(*ray, @t, @id)
    SelectElement(scene(),id)
    Protected *obj.Sphere = scene()
    
    ; Point at parameter
    x\x = *ray\origin\x + t * *ray\direction\x
    x\y = *ray\origin\y + t * *ray\direction\y
    x\z = *ray\origin\z + t * *ray\direction\z
    
    ; Norm
    vec3_subtract(n, x, *obj\center)
    vec3_normalize(n)
    
    ; Set to normal
    If vec3_dot(n, *ray\direction ) < 0.0
      vec3_copy(nl, n)
    Else
      vec3_negate(nl, n)
    EndIf
    
    
    If *obj\shading = #Lambertian
      vec3_copy(rr\origin, x)
  
      random_unit_vector(@ruv) 
      vec3_add(rr\direction,nl,ruv) 
      
        
      ray_color_hit(rr, *in , depth-1)
      *in\x * *obj\color\x : *in\y * *obj\color\y : *in\z * *obj\color\z 
    
    ElseIf *obj\shading = #Metal
      
      reflect(reflected, *ray\direction, nl)
    
      vec3_copy(rr\origin, x)
      
      vec3_copy(rr\direction, reflected)
      
      ray_color_hit(rr, *in , depth-1)
      *in\x * *obj\color\x : *in\y * *obj\color\y : *in\z * *obj\color\z 
    
    
    EndIf
;     
;     vec3_set(*in,0.0,0.0,0.0)
    
  Else
    
    ray_color(*ray, *in)
    *in\x * 0.5 : *in\y * 0.5 : *in\z * 0.5
  EndIf
  
EndProcedure

Define aspect_ratio.f = 16.0 / 9.0
Define image_width = 800

Define image_height = Int(image_width / aspect_ratio)

If image_height < 1
  image_height = 1
Else
  image_height = image_height
EndIf

; Render engine
Procedure render()
  Shared image_width, image_height
  Static focal_length.f = 1.0, viewport_height.f = 2.0
  Protected i_w.f = image_width, i_h.f = image_height
  Protected viewport_width.f = viewport_height * (i_w/i_h)
  
  Protected.vec3d point3, ray_direction, viewport3_u, viewport3_v, pixel_delta_u, pixel_delta_v, v_f, viewport_upper_left, pixel_100_loc
  
  vec3_set(point3, 0,0,0)
  vec3_set(ray_direction, 0,0,0)
  vec3_set(viewport3_u, viewport_width,0,0)
  vec3_set(viewport3_v, 0,-viewport_height,0)
  vec3_set(pixel_delta_u, viewport3_u\x / i_w, viewport3_u\y / i_w, viewport3_u\z / i_w)
  vec3_set(pixel_delta_v, viewport3_v\x / i_h, viewport3_v\y / i_h, viewport3_v\z / i_h)
  vec3_set(v_f, 0,0,focal_length)
  vec3_set(viewport_upper_left,
           point3\x - v_f\x - viewport3_u\x / 2 - viewport3_v\x / 2,
           point3\y - v_f\y - viewport3_u\y / 2 - viewport3_v\y / 2,
           point3\z - v_f\z - viewport3_u\z / 2 - viewport3_v\z / 2)
  vec3_set(pixel_100_loc, 0,0,focal_length)

  pixel_100_loc\x = viewport_upper_left\x + 0.5 * (pixel_delta_u\x + pixel_delta_v\x)
  pixel_100_loc\y = viewport_upper_left\y + 0.5 * (pixel_delta_u\y + pixel_delta_v\y)
  pixel_100_loc\z = viewport_upper_left\z + 0.5 * (pixel_delta_u\z + pixel_delta_v\z)
  
  Protected x.f, y.f, z.f, v.vec3d
  Protected ray.ray
  Static offset.vec3d, pixel_sample.vec3d
  Protected j,i,jj.f, ii.f, sample
  
  For j = 0 To image_height-1
    glBegin_(#GL_POINTS)
    For i = 0 To image_width-1
      x = 0.0 : y = 0.0 : z = 0.0
      For sample = 1 To #Samples_per_pixel
        ii = i + random_double() - 0.5 
        jj = j + random_double() - 0.5 
        
        pixel_sample\x = pixel_100_loc\x + ii * pixel_delta_u\x +  jj * pixel_delta_v\x
        pixel_sample\y = pixel_100_loc\y + ii * pixel_delta_u\y +  jj * pixel_delta_v\y
        pixel_sample\z = pixel_100_loc\z + ii * pixel_delta_u\z +  jj * pixel_delta_v\z
        
        vec3_subtract(ray_direction,pixel_sample,point3)

        ray\origin = point3
        ray\direction = ray_direction          
        
        ray_color_hit(@ray, @v, #Max_Depth) 
        x = x + v\x : y = y + v\y : z = z + v\z
      Next
      
      glColor3f_(linear_to_gamma(#Sample_scale * x), linear_to_gamma(#Sample_scale * y), linear_to_gamma(#Sample_scale * z)) : glVertex2s_(i,j)

    Next
    glEnd_() : glFlush_()
  Next
  
EndProcedure

OpenWindow(0, 0, 0, image_width / DesktopResolutionX(), image_height / DesktopResolutionY(), "Inspired from Raytracing in One Weekend", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenGLGadget(0,0,0,image_width / DesktopResolutionX(),image_height / DesktopResolutionY(),#PB_OpenGL_NoFlipSynchronization)
glOrtho_(0,image_width,image_height,0,-1,1)
glDrawBuffer_(#GL_FRONT)  

Define time = ElapsedMilliseconds()
render()
  time = ElapsedMilliseconds() - time
SetWindowTitle(0,"Inspired from Raytracing in One Weekend - RenderTime: "+Str(time)+"ms")

Define Event

Repeat
  Event = WindowEvent()
Until  Event = #PB_Event_CloseWindow

End 
Bon là c'est sûr que cela devrait marcher 8O :)

Dis moi si c'est ok pour toi ?
Avatar de l’utilisateur
MLD
Messages : 1124
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: Raytracing in One Weekend

Message par MLD »

Bonjour
ok c'est tout bon.
Pour infos ma machine est assez récente avec un processeur Intel core 7 donc pas de problème de calcul.
joli travail de ta part. c'est très sympa. :lol: :lol:
Il se pourrait que ma carte graphique soit un peu en cause,car elle n'est pas très performante volontairement, car je travaille principalement pour de la burotique qui demande pas de grandes performances graphique.
En entreprise comme les budgets sont serrés les cartes graphiques sont pour les bureaux de piètres performances. Donc il faut que je m'adapte.
a + et encore merci a toi.
Avatar de l’utilisateur
threedslider
Messages : 452
Inscription : dim. 01/juil./2018 22:38

Re: Raytracing in One Weekend

Message par threedslider »

@MLD : Ben voilà tout est en ordre ! :lol:

Info : Le code calcule par le processeur CPU seulement et donc pas spécialement la carte graphique :P

Sinon tu es le bienvenu et de rien pour mon aide à toi :wink:

Happy coding !
Répondre