Raytracing in One Weekend

Everything related to 3D programming
threedslider
Enthusiast
Enthusiast
Posts: 397
Joined: Sat Feb 12, 2022 7:15 pm

Raytracing in One Weekend

Post by threedslider »

Hello

Hope I will do in PB from the inspiration to Ray tracing in One Weekend :) : https://raytracing.github.io/books/RayT ... ekend.html

Dunno if it will be working cause it coded in C++ from this article :mrgreen: but I was making an image test in ppm as this article show.

Here my code so far :

Code: Select all

image_width = 256
image_height = 256

If CreateFile(0, "image_test.ppm")
  WriteStringN(0,"P3")
  WriteString(0,Str(image_width))
  WriteString(0," ")
  WriteString(0,Str(image_height))
  WriteStringN(0," ")
  WriteStringN(0,"255")
  WriteStringN(0," ")
  
  For j = 0 To image_height-1
    For i = 0 To image_width-1
      
      ii.f = i
      jj.f = j
      
      r.f =  ii / (image_width - 1)
      g.f =  jj / (image_height- 1)
      b.f = 0.0
      
      ir.i = Int(255.999 * r)
      ig.i = Int(255.999 * g)
      ib.i = Int(255.999 * b)
      
      WriteString(0,Str(ir))
      WriteString(0," ")
      WriteString(0,Str(ig))
      WriteString(0," ")
      WriteString(0,Str(ib))
      WriteStringN(0," ")
    Next
  Next
  CloseFile(0)
EndIf


See you soon :shock:
threedslider
Enthusiast
Enthusiast
Posts: 397
Joined: Sat Feb 12, 2022 7:15 pm

Re: Raytracing in One Weekend

Post by threedslider »

Same here but with Vector structure to output for color :)

Code: Select all

image_width = 512
image_height = 512


; Vector 
Structure Vec3
  x.f
  y.f
  z.f
EndStructure

; Write the translated [0,255] value of each color component.
Procedure write_color(*pixel_color.Vec3)
  WriteString(0, Str(Int(255.999 * *pixel_color\x)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * *pixel_color\y)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * *pixel_color\z)))
  WriteStringN(0, " ")
EndProcedure

; Output the image in PPM
If CreateFile(0, "image_test2.ppm")
  WriteStringN(0,"P3")
  WriteString(0,Str(image_width))
  WriteString(0," ")
  WriteString(0,Str(image_height))
  WriteStringN(0," ")
  WriteStringN(0,"255")
  WriteStringN(0," ")
  
  For j = 0 To image_height-1
    For i = 0 To image_width-1
      
      ii.f = i
      jj.f = j
      
      pix_color.Vec3
      
      pix_color\x = ii / (image_width - 1)
      pix_color\y = jj / (image_height - 1)
      pix_color\z = 0.0
      
     write_color(pix_color)      
     
    Next
  Next
   CloseFile(0)
EndIf
threedslider
Enthusiast
Enthusiast
Posts: 397
Joined: Sat Feb 12, 2022 7:15 pm

Re: Raytracing in One Weekend

Post by threedslider »

Ok I try to make a blue sky as article show but I'm hurt by the incorrect display :?

Are they well writing in PB from C++ ? Can you help me ?

Here the codes :

Code: Select all

aspect_ratio.f = 16.0 / 9.0
image_width = 400

;Debug aspect_ratio

image_height = Int(image_width / aspect_ratio)

;Debug image_height

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

focal_length.f = 1.0
viewport_height.f = 2.0

i_w.f = image_width
i_h.f = image_height
viewport_width.f = viewport_height * (i_w/i_h)

;Debug i_w/i_h
;Debug viewport_width


; Vector 
Structure Vec3
  x.f
  y.f
  z.f
EndStructure

; Ray
Structure Ray
  orig.Vec3
  dir.Vec3
EndStructure

point3.Vec3

point3\x = 0
point3\y = 0
point3\z = 0

ray_direction.Vec3

ray_direction\x = 0
ray_direction\y = 0
ray_direction\z = 0

viewport_u.Vec3

viewport_u\x = viewport_width
viewport_u\y = 0
viewport_u\z = 0

viewport_v.Vec3

viewport_v\x = 0
viewport_v\y = -viewport_height
viewport_v\z = 0

pixel_delta_u.Vec3

pixel_delta_u\x = viewport_u\x / i_w
pixel_delta_u\y = viewport_u\y / i_w
pixel_delta_u\z = viewport_u\z / i_w

;Debug pixel_delta_u\x

pixel_delta_v.Vec3

pixel_delta_v\x = viewport_v\x / i_h
pixel_delta_v\y = viewport_v\y / i_h
pixel_delta_v\z = viewport_v\z / i_h

;Debug pixel_delta_v\y

viewport_upper_left.Vec3

v_f.Vec3
v_f\x = 0.0
v_f\y = 0.0
v_f\z = focal_length

viewport_upper_left\x = point3\x - v_f\x - viewport_u\x / 2 - viewport_v\x / 2
viewport_upper_left\y = point3\y - v_f\y - viewport_u\y / 2 - viewport_v\y / 2
viewport_upper_left\z = point3\z - v_f\z - viewport_u\z / 2 - viewport_v\z / 2

;Debug viewport_u\x / 2 
;Debug viewport_upper_left\x

pixel_100_loc.Vec3

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)

;Debug pixel_100_loc\x

Procedure v_square_length(*v.Vec3)
  
  result.f = (*v\x * *v\x + *v\y * *v\y + *v\z * *v\z)
  
  ;Debug result
  
  ProcedureReturn result
EndProcedure


Procedure unit_vector_x(*vx.Vec3)
  len.f = Sqr(v_square_length(*vx))
  
  ;Debug len
  
  If Not len = 0 ;And Not len < 0
    *vx\x = *vx\x * ( 1.0 / len )
  EndIf
  
  
  ;Debug *vx\x
  
  ProcedureReturn *vx\x
EndProcedure

Procedure unit_vector_y(*vy.Vec3)
    
   len.f = Sqr(v_square_length(*vy)) 
  
  If Not len = 0 ;And Not len < 0
    *vy\y = *vy\y * ( 1.0 / len )
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn *vy\y
EndProcedure

Procedure unit_vector_z(*vz.Vec3)
    
 len.f = Sqr(v_square_length(*vz)) 

  If Not len = 0 ;And Not len < 0
    *vz\z = *vz\z * ( 1.0 / len )
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn *vz\z
EndProcedure

Procedure ray_color_x(*rx.Ray)
  color1.Vec3
  color2.Vec3
  result.Vec3
  rc.Vec3
  unit_direction.Vec3
  
  unit_direction\x = unit_vector_x(*rx\dir)
  unit_direction\y = unit_vector_y(*rx\dir)
  unit_direction\z = unit_vector_z(*rx\dir)
  
  ;Debug unit_direction\y
  
  a.f = 0.5 * (unit_direction\y + 1.0)
  
  ;Debug a
  
  color1\x = 1.0
  color1\y = 1.0
  color1\z = 1.0
  color2\x = 0.5
  color2\y = 0.7
  color2\z = 1.0
  result\x = (1.0 - a) * color1\x + a * color2\x
  result\y = (1.0 - a) * color1\y + a * color2\y
  result\z = (1.0 - a) * color1\z + a * color2\z
  
  ;Debug x
  ProcedureReturn result\x
EndProcedure

Procedure ray_color_y(*rx.Ray)
  color1.Vec3
  color2.Vec3
  result.Vec3
  unit_direction.Vec3
  
  unit_direction\x = unit_vector_x(*rx\dir)
  unit_direction\y = unit_vector_y(*rx\dir)
  unit_direction\z = unit_vector_z(*rx\dir)
  
  a.f = 0.5 * (unit_direction\y + 1.0)
  
  color1\x = 1.0
  color1\y = 1.0
  color1\z = 1.0
  color2\x = 0.5
  color2\y = 0.7
  color2\z = 1.0
  result\x = (1.0 - a) * color1\x + a * color2\x
  result\y = (1.0 - a) * color1\y + a * color2\y
  result\z = (1.0 - a) * color1\z + a * color2\z
  ProcedureReturn result\y
EndProcedure

Procedure ray_color_z(*rx.Ray)
  color1.Vec3
  color2.Vec3
  result.Vec3
  unit_direction.Vec3
  
  unit_direction\x = unit_vector_x(*rx\dir)
  unit_direction\y = unit_vector_y(*rx\dir)
  unit_direction\z = unit_vector_z(*rx\dir)
  
  a.f = 0.5 * (unit_direction\y + 1.0)
  
  color1\x = 1.0
  color1\y = 1.0
  color1\z = 1.0
  color2\x = 0.5
  color2\y = 0.7
  color2\z = 1.0
  result\x = (1.0 - a) * color1\x + a * color2\x
  result\y = (1.0 - a) * color1\y + a * color2\y
  result\z = (1.0 - a) * color1\z + a * color2\z
  ProcedureReturn result\z
EndProcedure

  

; Write the translated [0,255] value of each color component.
Procedure write_color(*pixel_color.Vec3)
  WriteString(0, Str(Int(255.999 * *pixel_color\x)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * *pixel_color\y)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * *pixel_color\z)))
  WriteStringN(0, " ")
EndProcedure

; Output the image in PPM
If CreateFile(0, "image_test3.ppm")
  WriteStringN(0,"P3")
  WriteString(0,Str(image_width))
  WriteString(0," ")
  WriteString(0,Str(image_height))
  WriteStringN(0," ")
  WriteStringN(0,"255")
  WriteStringN(0," ")
  
  For j = 0 To image_height-1
    For i = 0 To image_width-1
      
      ii.f = i
      jj.f = j
      
      pixel_center.Vec3
      
      Define.Vec3 pixel_color
      
      pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
      pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
      pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
      
      ;Debug pixel_center\x
      
      ray_direction\x = pixel_center\x - point3\x
      ray_direction\y = pixel_center\y - point3\y
      ray_direction\z = pixel_center\z - point3\z
      
      ;Debug ray_direction\x
      
      Define.Ray r
      
      r\orig = point3
      r\dir = ray_direction
     
      pixel_color\x = ray_color_x(@r)
      pixel_color\y = ray_color_y(@r)
      pixel_color\z = ray_color_z(@r)
          
      ;Debug pixel_color\x
      write_color(@pixel_color)    
      ;Debug pixel_color
     
    Next
  Next
   CloseFile(0)
EndIf
Hope you can help me thank you.
threedslider
Enthusiast
Enthusiast
Posts: 397
Joined: Sat Feb 12, 2022 7:15 pm

Re: Raytracing in One Weekend

Post by threedslider »

Yay ! I fixed a lot of my codes :D

Now the blue sky is correct :mrgreen:

Code: Select all


aspect_ratio.f = 16.0 / 9.0
image_width = 800

;Debug aspect_ratio

image_height = Int(image_width / aspect_ratio)

;Debug image_height

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

focal_length.f = 1.0
viewport_height.f = 2.0

i_w.f = image_width
i_h.f = image_height
viewport_width.f = viewport_height * (i_w/i_h)

;Debug i_w/i_h
;Debug viewport_width


; Vector 
Structure Vec3
  x.f
  y.f
  z.f
EndStructure

; Ray
Structure Ray
  orig.Vec3
  dir.Vec3
EndStructure

point3.Vec3

point3\x = 0
point3\y = 0
point3\z = 0

ray_direction.Vec3

ray_direction\x = 0
ray_direction\y = 0
ray_direction\z = 0

viewport_u.Vec3

viewport_u\x = viewport_width
viewport_u\y = 0
viewport_u\z = 0

viewport_v.Vec3

viewport_v\x = 0
viewport_v\y = -viewport_height
viewport_v\z = 0

pixel_delta_u.Vec3

pixel_delta_u\x = viewport_u\x / i_w
pixel_delta_u\y = viewport_u\y / i_w
pixel_delta_u\z = viewport_u\z / i_w

;Debug pixel_delta_u\x

pixel_delta_v.Vec3

pixel_delta_v\x = viewport_v\x / i_h
pixel_delta_v\y = viewport_v\y / i_h
pixel_delta_v\z = viewport_v\z / i_h

;Debug pixel_delta_v\y

viewport_upper_left.Vec3

v_f.Vec3
v_f\x = 0.0
v_f\y = 0.0
v_f\z = focal_length

viewport_upper_left\x = point3\x - v_f\x - viewport_u\x / 2 - viewport_v\x / 2
viewport_upper_left\y = point3\y - v_f\y - viewport_u\y / 2 - viewport_v\y / 2
viewport_upper_left\z = point3\z - v_f\z - viewport_u\z / 2 - viewport_v\z / 2

;Debug viewport_u\x / 2 
;Debug viewport_upper_left\x

pixel_100_loc.Vec3

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)

;Debug pixel_100_loc\x

Procedure.f v_length(*v.Ray)
  
  result.f = Sqr(*v\dir\x * *v\dir\x + *v\dir\y * *v\dir\y + *v\dir\z * *v\dir\z)
  
  ;Debug result
  
  ProcedureReturn result
EndProcedure


Procedure.f unit_vector_x(*vx.Ray)
    
  len.f = v_length(*vx) 
  
  ;Debug len
  
  If Not len = 0 ;And Not len < 0
    *vx\dir\x = *vx\dir\x / len
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn *vx\dir\x
EndProcedure

Procedure.f unit_vector_y(*vy.Ray)
    
  len.f = v_length(*vy) 
  
  ;Debug len
  
  If Not len = 0 ;And Not len < 0
    *vy\dir\y = *vy\dir\y / len
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn *vy\dir\y
EndProcedure

Procedure.f unit_vector_z(*vz.Ray)
    
  len.f = v_length(*vz) 
  
  ;Debug len
  
  If Not len = 0 ;And Not len < 0
    *vz\dir\z = *vz\dir\z / len
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn *vz\dir\z
EndProcedure

Procedure.f ray_color_x(*rx.Ray)
 
  unit_direction.Vec3
  

  unit_direction\y = unit_vector_y(*rx)

  
  ;Debug unit_direction\y
  
  a.f = 0.5 * (unit_direction\y + 1.0)
  
  ;Debug a
  
  color1.f = 1.0
  color2.f = 0.5
  
  x.f =  (1.0 - a) * color1 + a * color2
   
  ProcedureReturn x
EndProcedure

Procedure.f ray_color_y(*ry.Ray)
 
  unit_direction.Vec3
  

  unit_direction\y = unit_vector_y(*ry)

  
  ;Debug unit_direction\y
  
  a.f = 0.5 * (unit_direction\y + 1.0)
  
  ;Debug a
  
  color1.f = 1.0
  color2.f = 0.7
  
  y.f =  (1.0 - a) * color1 + a * color2
   
  
  ProcedureReturn y
EndProcedure

Procedure.f ray_color_z(*rz.Ray)
 
  unit_direction.Vec3
  

  unit_direction\y = unit_vector_y(*rz)

  
  ;Debug unit_direction\y
  
  a.f = 0.5 * (unit_direction\y + 1.0)
  
  ;Debug a
  
  color1.f = 1.0
  color2.f = 1.0
  
  z.f =  (1.0 - a) * color1 + a * color2
   
  
  ProcedureReturn z
EndProcedure

  

; Write the translated [0,255] value of each color component.
Procedure write_color()
  Shared pixel_color.Vec3
  
  WriteString(0, Str(Int(255.999 * pixel_color\x)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\y)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\z)))
  WriteStringN(0, " ")
  
  ;Debug Str(Int(255.999 * pixel_color\x))
EndProcedure

; Output the image in PPM
If CreateFile(0, "image_test3.ppm")
  WriteStringN(0,"P3")
  WriteString(0,Str(image_width))
  WriteString(0," ")
  WriteString(0,Str(image_height))
  WriteStringN(0," ")
  WriteStringN(0,"255")
  WriteStringN(0," ")
  
  For j = 0 To image_height-1
    For i = 0 To image_width-1
      
      ii.f = i
      jj.f = j
      
      pixel_center.Vec3
      
      Define.Vec3 pixel_color
      
      pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
      pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
      pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
      
      ;Debug pixel_center\x
      
      ray_direction\x = pixel_center\x - point3\x
      ray_direction\y = pixel_center\y - point3\y
      ray_direction\z = pixel_center\z - point3\z
      
      ;Debug ray_direction\x
      
      Define.Ray r
      
      r\orig = point3
      r\dir = ray_direction
     
      pixel_color\x = ray_color_x(r)
      pixel_color\y = ray_color_y(r)
      pixel_color\z = ray_color_z(r)
    
          
      ;Debug pixel_color\x
      write_color()    
     
     
    Next
  Next
   CloseFile(0)
EndIf
threedslider
Enthusiast
Enthusiast
Posts: 397
Joined: Sat Feb 12, 2022 7:15 pm

Re: Raytracing in One Weekend

Post by threedslider »

Hi !

A sphere on blue sky :wink:

Code: Select all

aspect_ratio.f = 16.0 / 9.0
image_width = 800

;Debug aspect_ratio

image_height = Int(image_width / aspect_ratio)

;Debug image_height

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

focal_length.f = 1.0
viewport_height.f = 2.0

i_w.f = image_width
i_h.f = image_height
viewport_width.f = viewport_height * (i_w/i_h)

;Debug i_w/i_h
;Debug viewport_width


; Vector 
Structure Vec3
  x.f
  y.f
  z.f
EndStructure

; Ray
Structure Ray
  orig.Vec3
  dir.Vec3
EndStructure

point3.Vec3

point3\x = 0
point3\y = 0
point3\z = 0

ray_direction.Vec3

ray_direction\x = 0
ray_direction\y = 0
ray_direction\z = 0

viewport_u.Vec3

viewport_u\x = viewport_width
viewport_u\y = 0
viewport_u\z = 0

viewport_v.Vec3

viewport_v\x = 0
viewport_v\y = -viewport_height
viewport_v\z = 0

pixel_delta_u.Vec3

pixel_delta_u\x = viewport_u\x / i_w
pixel_delta_u\y = viewport_u\y / i_w
pixel_delta_u\z = viewport_u\z / i_w

;Debug pixel_delta_u\x

pixel_delta_v.Vec3

pixel_delta_v\x = viewport_v\x / i_h
pixel_delta_v\y = viewport_v\y / i_h
pixel_delta_v\z = viewport_v\z / i_h

;Debug pixel_delta_v\y

viewport_upper_left.Vec3

v_f.Vec3
v_f\x = 0.0
v_f\y = 0.0
v_f\z = focal_length

viewport_upper_left\x = point3\x - v_f\x - viewport_u\x / 2 - viewport_v\x / 2
viewport_upper_left\y = point3\y - v_f\y - viewport_u\y / 2 - viewport_v\y / 2
viewport_upper_left\z = point3\z - v_f\z - viewport_u\z / 2 - viewport_v\z / 2

;Debug viewport_u\x / 2 
;Debug viewport_upper_left\x

pixel_100_loc.Vec3

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)

;Debug pixel_100_loc\x

Procedure.f dot(*v1.Vec3, *v2.Vec3)
  result.f = *v1\x * *v2\x + *v1\y * *v2\y + *v1\z * *v2\z
  
  ProcedureReturn result
EndProcedure




Procedure.f v_length(*v.Ray)
  
  result.f = Sqr(*v\dir\x * *v\dir\x + *v\dir\y * *v\dir\y + *v\dir\z * *v\dir\z)
  
  ;Debug result
  
  ProcedureReturn result
EndProcedure


Procedure.f unit_vector_x(*vx.Ray)
    
  len.f = v_length(*vx) 
  
  ;Debug len
  
  If Not len = 0 ;And Not len < 0
    *vx\dir\x = *vx\dir\x / len
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn *vx\dir\x
EndProcedure

Procedure.f unit_vector_y(*vy.Ray)
    
  len.f = v_length(*vy) 
  
  ;Debug len
  
  If Not len = 0 ;And Not len < 0
    *vy\dir\y = *vy\dir\y / len
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn *vy\dir\y
EndProcedure

Procedure.f unit_vector_z(*vz.Ray)
    
  len.f = v_length(*vz) 
  
  ;Debug len
  
  If Not len = 0 ;And Not len < 0
    *vz\dir\z = *vz\dir\z / len
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn *vz\dir\z
EndProcedure

Procedure.f ray_color_sphere()
  
  color1.f = 1.0
  
  
  ProcedureReturn color1

  
EndProcedure

Procedure.f ray_color_x(*rx.Ray)
  
  color1.f = 1.0
  color2.f = 0.5
  
  
    unit_direction.Vec3
  

  unit_direction\y = unit_vector_y(*rx)

  
  ;Debug unit_direction\y
  
  a.f = 0.5 * (unit_direction\y + 1.0)
  
  ;Debug a
  

  
  x.f =  (1.0 - a) * color1 + a * color2
  
   
    

     ProcedureReturn x

  
EndProcedure

Procedure.f ray_color_y(*ry.Ray)
  
  color1.f = 1.0
  color2.f = 0.7
  
   unit_direction.Vec3
  

  unit_direction\y = unit_vector_y(*ry)

  
  ;Debug unit_direction\y
  
  a.f = 0.5 * (unit_direction\y + 1.0)
  
  ;Debug a
  
  
  y.f =  (1.0 - a) * color1 + a * color2
  
  ProcedureReturn y;
  
EndProcedure

Procedure.f ray_color_z(*rz.Ray)
  
  color1.f = 1.0
  color2.f = 1.0
  
  unit_direction.Vec3
  

  unit_direction\y = unit_vector_y(*rz)

  
  ;Debug unit_direction\y
  
  a.f = 0.5 * (unit_direction\y + 1.0)
  
  ;Debug a
  
  z.f =  (1.0 - a) * color1 + a * color2
  

    ProcedureReturn z


EndProcedure
  
  Procedure.f hit_sphere(*posx.Vec3, radius.f, *vx.Ray)
  oc.Vec3
  oc\x = *vx\orig\x - *posx\x
  oc\y = *vx\orig\y - *posx\y
  oc\z = *vx\orig\z - *posx\z
  a.f = dot(*vx\dir, *vx\dir)
  b.f = 2.0 * dot(oc,*vx\dir)
  c.f = dot(oc,oc) - radius*radius
  
  discriminant.f = b*b - 4*a*c
  
  ProcedureReturn Bool(discriminant >= 0)

EndProcedure

; Write the translated [0,255] value of each color component.
Procedure write_color()
  Shared pixel_color.Vec3
  
  WriteString(0, Str(Int(255.999 * pixel_color\x)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\y)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\z)))
  WriteStringN(0, " ")
  
  ;Debug Str(Int(255.999 * pixel_color\x))
EndProcedure

; Output the image in PPM
If CreateFile(0, "image_test4.ppm")
  WriteStringN(0,"P3")
  WriteString(0,Str(image_width))
  WriteString(0," ")
  WriteString(0,Str(image_height))
  WriteStringN(0," ")
  WriteStringN(0,"255")
  WriteStringN(0," ")
  
  For j = 0 To image_height-1
    For i = 0 To image_width-1
      
      ii.f = i
      jj.f = j
      
      pixel_center.Vec3
      
      Define.Vec3 pixel_color
      
      pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
      pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
      pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
      
      ;Debug pixel_center\x
      
      ray_direction\x = pixel_center\x - point3\x
      ray_direction\y = pixel_center\y - point3\y
      ray_direction\z = pixel_center\z - point3\z
      
      ;Debug ray_direction\x
      
      Define.Ray r
      
      r\orig = point3
      r\dir = ray_direction
      
      Define.Ray myray
      
      myray\orig = point3
      myray\dir = ray_direction
      
      p_s.Vec3
      
      p_s\x = 0
      p_s\y = 0
      p_s\z = -1
      
      If hit_sphere(p_s, 0.5, r)
        pixel_color\x = 1.0
        pixel_color\y = 0
        pixel_color\z = 0
      Else
        pixel_color\x = ray_color_x(r)
        pixel_color\y = ray_color_y(r)
        pixel_color\z = ray_color_z(r)
      EndIf
    
      ;Debug pixel_color\x
      write_color()    
     
     
    Next
  Next
   CloseFile(0)
EndIf
threedslider
Enthusiast
Enthusiast
Posts: 397
Joined: Sat Feb 12, 2022 7:15 pm

Re: Raytracing in One Weekend

Post by threedslider »

Nobody say something about my codes ... :?

Maybe you don't see my image in PPM so I make easy for you to render for PB and you can "see" my image :)

Same come but with render in PB :

Code: Select all

aspect_ratio.f = 16.0 / 9.0
image_width = 800

;Debug aspect_ratio

image_height = Int(image_width / aspect_ratio)

;Debug image_height

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

focal_length.f = 1.0
viewport_height.f = 2.0

i_w.f = image_width
i_h.f = image_height
viewport_width.f = viewport_height * (i_w/i_h)

;Debug i_w/i_h
;Debug viewport_width


; Vector 
Structure Vec3
  x.f
  y.f
  z.f
EndStructure

; Ray
Structure Ray
  orig.Vec3
  dir.Vec3
EndStructure

point3.Vec3

point3\x = 0
point3\y = 0
point3\z = 0

ray_direction.Vec3

ray_direction\x = 0
ray_direction\y = 0
ray_direction\z = 0

viewport_u.Vec3

viewport_u\x = viewport_width
viewport_u\y = 0
viewport_u\z = 0

viewport_v.Vec3

viewport_v\x = 0
viewport_v\y = -viewport_height
viewport_v\z = 0

pixel_delta_u.Vec3

pixel_delta_u\x = viewport_u\x / i_w
pixel_delta_u\y = viewport_u\y / i_w
pixel_delta_u\z = viewport_u\z / i_w

;Debug pixel_delta_u\x

pixel_delta_v.Vec3

pixel_delta_v\x = viewport_v\x / i_h
pixel_delta_v\y = viewport_v\y / i_h
pixel_delta_v\z = viewport_v\z / i_h

;Debug pixel_delta_v\y

viewport_upper_left.Vec3

v_f.Vec3
v_f\x = 0.0
v_f\y = 0.0
v_f\z = focal_length

viewport_upper_left\x = point3\x - v_f\x - viewport_u\x / 2 - viewport_v\x / 2
viewport_upper_left\y = point3\y - v_f\y - viewport_u\y / 2 - viewport_v\y / 2
viewport_upper_left\z = point3\z - v_f\z - viewport_u\z / 2 - viewport_v\z / 2

;Debug viewport_u\x / 2 
;Debug viewport_upper_left\x

pixel_100_loc.Vec3

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)

;Debug pixel_100_loc\x

Procedure.f dot(*v1.Vec3, *v2.Vec3)
  result.f = *v1\x * *v2\x + *v1\y * *v2\y + *v1\z * *v2\z
  
  ProcedureReturn result
EndProcedure




Procedure.f v_length(*v.Ray)
  
  result.f = Sqr(*v\dir\x * *v\dir\x + *v\dir\y * *v\dir\y + *v\dir\z * *v\dir\z)
  
  ;Debug result
  
  ProcedureReturn result
EndProcedure


Procedure.f unit_vector_x(*vx.Ray)
    
  len.f = v_length(*vx) 
  
  ;Debug len
  
  If Not len = 0 ;And Not len < 0
    *vx\dir\x = *vx\dir\x / len
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn *vx\dir\x
EndProcedure

Procedure.f unit_vector_y(*vy.Ray)
    
  len.f = v_length(*vy) 
  
  ;Debug len
  
  If Not len = 0 ;And Not len < 0
    *vy\dir\y = *vy\dir\y / len
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn *vy\dir\y
EndProcedure

Procedure.f unit_vector_z(*vz.Ray)
    
  len.f = v_length(*vz) 
  
  ;Debug len
  
  If Not len = 0 ;And Not len < 0
    *vz\dir\z = *vz\dir\z / len
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn *vz\dir\z
EndProcedure

Procedure.f ray_color_sphere()
  
  color1.f = 1.0
  
  
  ProcedureReturn color1

  
EndProcedure

Procedure.f ray_color_x(*rx.Ray)
  
  color1.f = 1.0
  color2.f = 0.5
  
  
    unit_direction.Vec3
  

  unit_direction\y = unit_vector_y(*rx)

  
  ;Debug unit_direction\y
  
  a.f = 0.5 * (unit_direction\y + 1.0)
  
  ;Debug a
  

  
  x.f =  (1.0 - a) * color1 + a * color2
  
   
    

     ProcedureReturn x

  
EndProcedure

Procedure.f ray_color_y(*ry.Ray)
  
  color1.f = 1.0
  color2.f = 0.7
  
   unit_direction.Vec3
  

  unit_direction\y = unit_vector_y(*ry)

  
  ;Debug unit_direction\y
  
  a.f = 0.5 * (unit_direction\y + 1.0)
  
  ;Debug a
  
  
  y.f =  (1.0 - a) * color1 + a * color2
  
  ProcedureReturn y;
  
EndProcedure

Procedure.f ray_color_z(*rz.Ray)
  
  color1.f = 1.0
  color2.f = 1.0
  
  unit_direction.Vec3
  

  unit_direction\y = unit_vector_y(*rz)

  
  ;Debug unit_direction\y
  
  a.f = 0.5 * (unit_direction\y + 1.0)
  
  ;Debug a
  
  z.f =  (1.0 - a) * color1 + a * color2
  

    ProcedureReturn z


EndProcedure
  
Procedure.f hit_sphere(*posx.Vec3, radius.f, *vx.Ray)
  oc.Vec3
  oc\x = *vx\orig\x - *posx\x
  oc\y = *vx\orig\y - *posx\y
  oc\z = *vx\orig\z - *posx\z
  a.f = dot(*vx\dir, *vx\dir)
  b.f = 2.0 * dot(oc,*vx\dir)
  c.f = dot(oc,oc) - radius*radius
  
  discriminant.f = b*b - 4*a*c
  
ProcedureReturn Bool(discriminant >= 0)

EndProcedure

; Write the translated [0,255] value of each color component.
Procedure write_color()
  Shared pixel_color.Vec3
  
  WriteString(0, Str(Int(255.999 * pixel_color\x)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\y)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\z)))
  WriteStringN(0, " ")
  
  ;Debug Str(Int(255.999 * pixel_color\x))
EndProcedure

; Output the image in PPM
; If CreateFile(0, "image_test4.ppm")
;   WriteStringN(0,"P3")
;   WriteString(0,Str(image_width))
;   WriteString(0," ")
;   WriteString(0,Str(image_height))
;   WriteStringN(0," ")
;   WriteStringN(0,"255")
;   WriteStringN(0," ")
;   
;   For j = 0 To image_height-1
;     For i = 0 To image_width-1
;       
;       ii.f = i
;       jj.f = j
;       
;       pixel_center.Vec3
;       
;       Define.Vec3 pixel_color
;       
;       pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
;       pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
;       pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
;       
;       ;Debug pixel_center\x
;       
;       ray_direction\x = pixel_center\x - point3\x
;       ray_direction\y = pixel_center\y - point3\y
;       ray_direction\z = pixel_center\z - point3\z
;       
;       ;Debug ray_direction\x
;       
;       Define.Ray r
;       
;       r\orig = point3
;       r\dir = ray_direction
;       
;       Define.Ray myray
;       
;       myray\orig = point3
;       myray\dir = ray_direction
;       
;       p_s.Vec3
;       
;       p_s\x = 0
;       p_s\y = 0
;       p_s\z = -1
;       
;       If hit_sphere(p_s, 0.5, r)
;         pixel_color\x = 1.0
;         pixel_color\y = 0
;         pixel_color\z = 0
;       Else
;         pixel_color\x = ray_color_x(r)
;         pixel_color\y = ray_color_y(r)
;         pixel_color\z = ray_color_z(r)
;       EndIf
;     
;       ;Debug pixel_color\x
;       write_color()    
;      
;      
;     Next
;   Next
;    CloseFile(0)
;  EndIf
 
 If OpenWindow(0, 0, 0, image_width, image_height, "Inspired from Raytracing in One Weekend", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
 ;OpenWindowedScreen(WindowID(0), 0, 0, 800, 600)
 
  If CreateImage(0, image_width, image_height) And StartDrawing(ImageOutput(0))
    
    For j = 0 To image_height-1
    For i = 0 To image_width-1
      
      ii.f = i
      jj.f = j
      
      pixel_center.Vec3
      
      Define.Vec3 pixel_color
      
      pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
      pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
      pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
      
      ;Debug pixel_center\x
      
      ray_direction\x = pixel_center\x - point3\x
      ray_direction\y = pixel_center\y - point3\y
      ray_direction\z = pixel_center\z - point3\z
      
      ;Debug ray_direction\x
      
      Define.Ray r
      
      r\orig = point3
      r\dir = ray_direction
      
      Define.Ray myray
      
      myray\orig = point3
      myray\dir = ray_direction
      
      p_s.Vec3
      
      p_s\x = 0
      p_s\y = 0
      p_s\z = -1
      
      Debug ray_color_x(r)
      
      If hit_sphere(p_s, 0.5, r)
        Plot(i, j , RGB(255, 0.0, 0.0))
       Else
        Plot(i, j, RGB(Int(255.999 * ray_color_x(r)),Int(255.999 * ray_color_y(r)),Int(255.999* ray_color_z(r))))
      EndIf
      
      Next
  Next
    
   
   StopDrawing() 
   ImageGadget(0, 0, 0, image_width, image_height, ImageID(0))
  EndIf
 
   Repeat
      Event = WaitWindowEvent()
    Until Event = #PB_Event_CloseWindow
EndIf
Hope you enjoy and happy coding !
infratec
Always Here
Always Here
Posts: 7618
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Raytracing in One Weekend

Post by infratec »

With debug enabled and your debug output it is a torture :wink:

So @all testers: disable the debugger

This stuff is good for understanding what's behind, but I don't think that it is useful in praxis.
But only if you understand the math behind.

Btw.: IrfanView can read and write PPM
threedslider
Enthusiast
Enthusiast
Posts: 397
Joined: Sat Feb 12, 2022 7:15 pm

Re: Raytracing in One Weekend

Post by threedslider »

infratec wrote: Sat Feb 10, 2024 10:47 pm With debug enabled and your debug output it is a torture :wink:

So @all testers: disable the debugger

This stuff is good for understanding what's behind, but I don't think that it is useful in praxis.
But only if you understand the math behind.

Btw.: IrfanView can read and write PPM
Yes, sorry for debug I forgot to say you need to make it without debugger :)

I find PB "very" powerful it is almost same as in C o C++, so I think (my taste) yeah it will be useful in practise to someone but not to all and as you say math is important on what it works most in 3D rendering... I don't finish and maybe it is not perfect from my codes too ^^

Raytracing in One weekend is a serious thing for beginner who want to learn on how to render in 3D stuff ! :mrgreen:

I am learning myself and it is good for later with my project in 3D software writing fully in ... PB ! :shock:

Thanks to all for testing my codes and happy coding too :wink:
threedslider
Enthusiast
Enthusiast
Posts: 397
Joined: Sat Feb 12, 2022 7:15 pm

Re: Raytracing in One Weekend

Post by threedslider »

I made my code more shorter now :) and I do as fun for little animation to move the red shpere :shock:

Code: Select all

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

aspect_ratio.f = 16.0 / 9.0
image_width = 800

image_height = Int(image_width / aspect_ratio)

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

focal_length.f = 1.0
viewport_height.f = 2.0

i_w.f = image_width
i_h.f = image_height
viewport_width.f = viewport_height * (i_w/i_h)

; Vector 
Structure Vec3
  x.f
  y.f
  z.f
EndStructure

; Ray
Structure Ray
  orig.Vec3
  dir.Vec3
EndStructure

point3.Vec3

point3\x = 0
point3\y = 0
point3\z = 0

ray_direction.Vec3

ray_direction\x = 0
ray_direction\y = 0
ray_direction\z = 0

viewport_u.Vec3

viewport_u\x = viewport_width
viewport_u\y = 0
viewport_u\z = 0

viewport_v.Vec3

viewport_v\x = 0
viewport_v\y = -viewport_height
viewport_v\z = 0

pixel_delta_u.Vec3

pixel_delta_u\x = viewport_u\x / i_w
pixel_delta_u\y = viewport_u\y / i_w
pixel_delta_u\z = viewport_u\z / i_w

;Debug pixel_delta_u\x

pixel_delta_v.Vec3

pixel_delta_v\x = viewport_v\x / i_h
pixel_delta_v\y = viewport_v\y / i_h
pixel_delta_v\z = viewport_v\z / i_h

;Debug pixel_delta_v\y

viewport_upper_left.Vec3

v_f.Vec3
v_f\x = 0.0
v_f\y = 0.0
v_f\z = focal_length

viewport_upper_left\x = point3\x - v_f\x - viewport_u\x / 2 - viewport_v\x / 2
viewport_upper_left\y = point3\y - v_f\y - viewport_u\y / 2 - viewport_v\y / 2
viewport_upper_left\z = point3\z - v_f\z - viewport_u\z / 2 - viewport_v\z / 2

;Debug viewport_u\x / 2 
;Debug viewport_upper_left\x

pixel_100_loc.Vec3

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)

;Debug pixel_100_loc\x

Procedure.f dot(*v1.Vec3, *v2.Vec3)
  result.f = *v1\x * *v2\x + *v1\y * *v2\y + *v1\z * *v2\z
  
  ProcedureReturn result
EndProcedure

Procedure.f v_length(*v.Ray)
  
  result.f = Sqr(*v\dir\x * *v\dir\x + *v\dir\y * *v\dir\y + *v\dir\z * *v\dir\z)
  
  ;Debug result
  
  ProcedureReturn result
EndProcedure

Procedure.f unit_vector_y(*vy.Ray)
    
  len.f = v_length(*vy) 
  
  y.f = 0
  
  If Not len = 0 ;And Not len < 0
    y = *vy\dir\y / len
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn y
EndProcedure

Procedure.f ray_color(*rr.Ray, axe)
  
  color1.Vec3
  color2.Vec3
  
  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_direction.Vec3
    
  unit_direction\x = unit_vector_y(*rr)
  a1.f = 0.5 * (unit_direction\x + 1.0) 
  x.f =  (1.0 - a1) * color1\x + a1 * color2\x 

  unit_direction\y = unit_vector_y(*rr)
  a2.f = 0.5 * (unit_direction\y + 1.0)
  y.f =  (1.0 - a2) * color1\y + a2 * color2\y
 
  unit_direction\z = unit_vector_y(*rr)
  a3.f = 0.5 * (unit_direction\z + 1.0)
  z.f =  (1.0 - a3) * color1\z + a3 * color2\z
  
  If axe = 1
    ProcedureReturn x
  EndIf
  
  If axe = 2
    ProcedureReturn y
  EndIf
  
  If axe = 3
    ProcedureReturn z
  EndIf
   
EndProcedure
  
Procedure.f hit_sphere(*posx.Vec3, radius.f, *vx.Ray)
  oc.Vec3
  oc\x = *vx\orig\x - *posx\x
  oc\y = *vx\orig\y - *posx\y
  oc\z = *vx\orig\z - *posx\z
  a.f = dot(*vx\dir, *vx\dir)
  b.f = 2.0 * dot(oc,*vx\dir)
  c.f = dot(oc,oc) - radius*radius
  
  discriminant.f = b*b - 4*a*c
  
ProcedureReturn Bool(discriminant >= 0)

EndProcedure

; Write the translated [0,255] value of each color component.
Procedure write_color()
  Shared pixel_color.Vec3
  
  WriteString(0, Str(Int(255.999 * pixel_color\x)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\y)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\z)))
  WriteStringN(0, " ")
  
  ;Debug Str(Int(255.999 * pixel_color\x))
EndProcedure

; Output the image in PPM
; If CreateFile(0, "image_test4.ppm")
;   WriteStringN(0,"P3")
;   WriteString(0,Str(image_width))
;   WriteString(0," ")
;   WriteString(0,Str(image_height))
;   WriteStringN(0," ")
;   WriteStringN(0,"255")
;   WriteStringN(0," ")
;   
;   For j = 0 To image_height-1
;     For i = 0 To image_width-1
;       
;       ii.f = i
;       jj.f = j
;       
;       pixel_center.Vec3
;       
;       Define.Vec3 pixel_color
;       
;       pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
;       pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
;       pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
;       
;       ;Debug pixel_center\x
;       
;       ray_direction\x = pixel_center\x - point3\x
;       ray_direction\y = pixel_center\y - point3\y
;       ray_direction\z = pixel_center\z - point3\z
;       
;       ;Debug ray_direction\x
;       
;       Define.Ray r
;       
;       r\orig = point3
;       r\dir = ray_direction
;       
;       Define.Ray myray
;       
;       myray\orig = point3
;       myray\dir = ray_direction
;       
;       p_s.Vec3
;       
;       p_s\x = 0
;       p_s\y = 0
;       p_s\z = -1
;       
;       If hit_sphere(p_s, 0.5, r)
;         pixel_color\x = 1.0
;         pixel_color\y = 0
;         pixel_color\z = 0
;       Else
;         pixel_color\x = ray_color_x(r)
;         pixel_color\y = ray_color_y(r)
;         pixel_color\z = ray_color_z(r)
;       EndIf
;     
;       ;Debug pixel_color\x
;       write_color()    
;      
;      
;     Next
;   Next
;    CloseFile(0)
;  EndIf

InitSprite()
 
 OpenWindow(0, 0, 0, image_width, image_height, "Inspired from Raytracing in One Weekend", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
 OpenWindowedScreen(WindowID(0), 0, 0, image_width, image_height)
  
  ClearScreen(RGB(0,0,0))
  Repeat
   Event = WindowEvent()
  If StartDrawing(ScreenOutput())
    
    For j = 0 To image_height-1
    For i = 0 To image_width-1
      
      ii.f = i
      jj.f = j
      
      pixel_center.Vec3
      
      Define.Vec3 pixel_color
      
      pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
      pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
      pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
      
      ;Debug pixel_center\x
      
      ray_direction\x = pixel_center\x - point3\x
      ray_direction\y = pixel_center\y - point3\y
      ray_direction\z = pixel_center\z - point3\z
      
      ;Debug ray_direction\x
      
      Define.Ray r
      
      r\orig = point3
      r\dir = ray_direction
      
      Define.Ray myray
      
      myray\orig = point3
      myray\dir = ray_direction
      
      p_s.Vec3
      
      move.f + 1/10000000   
      
      p_s\x = -2 + move 
      
      p_s\y = 0
      p_s\z = -1
      
      If hit_sphere(p_s, 0.5, r)
        Plot(i, j , RGB(255, 0.0, 0.0))
       Else
        Plot(i, j, RGB(Int(255.999 * ray_color(r,1)),Int(255.999 * ray_color(r,2)),Int(255.999* ray_color(r,3))))
      EndIf
     
      Next
  Next
   
  
  StopDrawing() 
  FlipBuffers()
  
EndIf
 
 Until  Event = #PB_Event_CloseWindow
   
End 
Make sure to compile without the debugger :)

PS : Yeah, the sphere deforms as strange, it is due to aspect ratio and voilà :mrgreen:
threedslider
Enthusiast
Enthusiast
Posts: 397
Joined: Sat Feb 12, 2022 7:15 pm

Re: Raytracing in One Weekend

Post by threedslider »

To get the normal color is the most trickier ever I see in PB because in C++ is easy but not PB :/

Here the code :

Code: Select all

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

aspect_ratio.f = 16.0 / 9.0
image_width = 800

image_height = Int(image_width / aspect_ratio)

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

focal_length.f = 1.0
viewport_height.f = 2.0

i_w.f = image_width
i_h.f = image_height
viewport_width.f = viewport_height * (i_w/i_h)

; Vector 
Structure Vec3
  x.f
  y.f
  z.f
EndStructure

; Ray
Structure Ray
  orig.Vec3
  dir.Vec3
EndStructure

point3.Vec3

point3\x = 0
point3\y = 0
point3\z = 0

ray_direction.Vec3

ray_direction\x = 0
ray_direction\y = 0
ray_direction\z = 0

viewport_u.Vec3

viewport_u\x = viewport_width
viewport_u\y = 0
viewport_u\z = 0

viewport_v.Vec3

viewport_v\x = 0
viewport_v\y = -viewport_height
viewport_v\z = 0

pixel_delta_u.Vec3

pixel_delta_u\x = viewport_u\x / i_w
pixel_delta_u\y = viewport_u\y / i_w
pixel_delta_u\z = viewport_u\z / i_w

;Debug pixel_delta_u\x

pixel_delta_v.Vec3

pixel_delta_v\x = viewport_v\x / i_h
pixel_delta_v\y = viewport_v\y / i_h
pixel_delta_v\z = viewport_v\z / i_h

;Debug pixel_delta_v\y

viewport_upper_left.Vec3

v_f.Vec3
v_f\x = 0.0
v_f\y = 0.0
v_f\z = focal_length

viewport_upper_left\x = point3\x - v_f\x - viewport_u\x / 2 - viewport_v\x / 2
viewport_upper_left\y = point3\y - v_f\y - viewport_u\y / 2 - viewport_v\y / 2
viewport_upper_left\z = point3\z - v_f\z - viewport_u\z / 2 - viewport_v\z / 2

;Debug viewport_u\x / 2 
;Debug viewport_upper_left\x

pixel_100_loc.Vec3

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)

Procedure.f dot(*v1.Vec3, *v2.Vec3)
  result.f = *v1\x * *v2\x + *v1\y * *v2\y + *v1\z * *v2\z
  
  ProcedureReturn result
EndProcedure

Procedure.f v_length(*v.Ray)
  
  result.f = Sqr(*v\dir\x * *v\dir\x + *v\dir\y * *v\dir\y + *v\dir\z * *v\dir\z)
  
  ;Debug result
  
  ProcedureReturn result
EndProcedure

Procedure.f unit_vector_y(*vy.Ray)
    
  len.f = v_length(*vy) 
  
  y.f = 0
  
  If Not len = 0 ;And Not len < 0
    y = *vy\dir\y / len
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn y
EndProcedure

Procedure.f at(*rr.Ray, t.f, axe)
  
  If axe = 1 
    x.f = (*rr\orig\x + t * *rr\dir\x) 
    ProcedureReturn (x)
  EndIf
  
  If axe = 2 
    y.f = (*rr\orig\y + t * *rr\dir\y) 
    ProcedureReturn (y)
  EndIf
  
  If axe = 3 
    z.f = (*rr\orig\z + t * *rr\dir\z)
    ProcedureReturn (z)
  EndIf
EndProcedure

Procedure.f unit_vector_normal(x.f, y.f, z.f, axe)
    
  len.f = Sqr(x*x + y*y + z*z) 
  
  xx.f = 0
  yy.f = 0
  zz.f = 0
  
   If Not len = 0 
    xx = x / len
  EndIf
  
  If Not len = 0 
    yy = y / len
  EndIf
  
   If Not len = 0 
    zz = z  / len
  EndIf
  
  If axe = 1
    ProcedureReturn xx
  EndIf
  
  If axe = 2
    ProcedureReturn yy
  EndIf
  
  If axe = 3
    ProcedureReturn zz
  EndIf
  
EndProcedure




Procedure.f ray_color_n(x.f, y.f, z.f, axe)
  
  color1.Vec3
  color2.Vec3
  
  color1\x = x
  color1\y = y
  color1\z = z
  
   
  x.f =  0.5 * color1\x + 1.0

  y.f =  0.5 * color1\y + 1.0
 
  z.f =  0.5 * color1\z + 1.0
  
  If axe = 1
    ProcedureReturn x
  EndIf
  
  If axe = 2
    ProcedureReturn y
  EndIf
  
  If axe = 3
    ProcedureReturn z
  EndIf
   
EndProcedure

Procedure.f ray_color(*rr.Ray, axe)
  
  color1.Vec3
  color2.Vec3
  
  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_direction.Vec3
    
  unit_direction\x = unit_vector_y(*rr)
  a1.f = 0.5 * (unit_direction\x + 1.0) 
  x.f =  (1.0 - a1) * color1\x + a1 * color2\x 

  unit_direction\y = unit_vector_y(*rr)
  a2.f = 0.5 * (unit_direction\y + 1.0)
  y.f =  (1.0 - a2) * color1\y + a2 * color2\y
 
  unit_direction\z = unit_vector_y(*rr)
  a3.f = 0.5 * (unit_direction\z + 1.0)
  z.f =  (1.0 - a3) * color1\z + a3 * color2\z
  
  If axe = 1
    ProcedureReturn x
  EndIf
  
  If axe = 2
    ProcedureReturn y
  EndIf
  
  If axe = 3
    ProcedureReturn z
  EndIf
   
EndProcedure  
  
Procedure.f hit_sphere(*posx.Vec3, radius.f, *vx.Ray)
  oc.Vec3
  oc\x = *vx\orig\x - *posx\x
  oc\y = *vx\orig\y - *posx\y
  oc\z = *vx\orig\z - *posx\z
  a.f = dot(*vx\dir, *vx\dir)
  b.f = 2.0 * dot(oc,*vx\dir)
  c.f = dot(oc,oc) - radius*radius
  
  discriminant.f = b*b - 4*a*c
  
  If discriminant < 0
    ProcedureReturn -1.0
  Else
    dis.f = (-b - Sqr(discriminant) ) / (2.0*a);
    ProcedureReturn dis
   
  EndIf
  

EndProcedure

; Write the translated [0,255] value of each color component.
Procedure write_color()
  Shared pixel_color.Vec3
  
  WriteString(0, Str(Int(255.999 * pixel_color\x)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\y)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\z)))
  WriteStringN(0, " ")
  
  ;Debug Str(Int(255.999 * pixel_color\x))
EndProcedure

; Output the image in PPM
; If CreateFile(0, "image_test4.ppm")
;   WriteStringN(0,"P3")
;   WriteString(0,Str(image_width))
;   WriteString(0," ")
;   WriteString(0,Str(image_height))
;   WriteStringN(0," ")
;   WriteStringN(0,"255")
;   WriteStringN(0," ")
;   
;   For j = 0 To image_height-1
;     For i = 0 To image_width-1
;       
;       ii.f = i
;       jj.f = j
;       
;       pixel_center.Vec3
;       
;       Define.Vec3 pixel_color
;       
;       pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
;       pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
;       pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
;       
;       ;Debug pixel_center\x
;       
;       ray_direction\x = pixel_center\x - point3\x
;       ray_direction\y = pixel_center\y - point3\y
;       ray_direction\z = pixel_center\z - point3\z
;       
;       ;Debug ray_direction\x
;       
;       Define.Ray r
;       
;       r\orig = point3
;       r\dir = ray_direction
;       
;       Define.Ray myray
;       
;       myray\orig = point3
;       myray\dir = ray_direction
;       
;       p_s.Vec3
;       
;       p_s\x = 0
;       p_s\y = 0
;       p_s\z = -1
;       
;       If hit_sphere(p_s, 0.5, r)
;         pixel_color\x = 1.0
;         pixel_color\y = 0
;         pixel_color\z = 0
;       Else
;         pixel_color\x = ray_color_x(r)
;         pixel_color\y = ray_color_y(r)
;         pixel_color\z = ray_color_z(r)
;       EndIf
;     
;       ;Debug pixel_color\x
;       write_color()    
;      
;      
;     Next
;   Next
;    CloseFile(0)
;  EndIf

InitSprite()
 
 OpenWindow(0, 0, 0, image_width, image_height, "Inspired from Raytracing in One Weekend", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
 OpenWindowedScreen(WindowID(0), 0, 0, image_width, image_height)
  
  ClearScreen(RGB(0,0,0))
  
  If StartDrawing(ScreenOutput())
    
    For j = 0 To image_height-1
    For i = 0 To image_width-1
      
      ii.f = i
      jj.f = j
      
      pixel_center.Vec3
      
      Define.Vec3 pixel_color
      
      pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
      pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
      pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
      
      ;Debug pixel_center\x
      
      ray_direction\x = pixel_center\x - point3\x
      ray_direction\y = pixel_center\y - point3\y
      ray_direction\z = pixel_center\z - point3\z
      
      ;Debug ray_direction\x
      
      Define.Ray r
      
      r\orig = point3
      r\dir = ray_direction
      
      Define.Ray myray
      
      myray\orig = point3
      myray\dir = ray_direction
      
      p_s.Vec3
      
       
      
      p_s\x = 0 
      
      p_s\y = 0
      p_s\z = -1
      
      t.f = hit_sphere(p_s, 0.5, r)
      
      ;Debug  Plot(i, j, RGB(Int(255.999 * ray_color_n(1,1,1,1)),0,0) 
      
      If t > 0.0
        Plot(i, j, Plot(i, j, RGB(Int(255.999 * ray_color_n(unit_vector_normal(at(r,t,1),at(r,t,2),at(r,t,3),1),unit_vector_normal(at(r,t,1),at(r,t,2),at(r,t,3),2),unit_vector_normal(at(r,t,1),at(r,t,2),at(r,t,3),3),1)),Int(255.999 * ray_color_n(unit_vector_normal(at(r,t,1),at(r,t,2),at(r,t,3),1),unit_vector_normal(at(r,t,1),at(r,t,2),at(r,t,3),2),unit_vector_normal(at(r,t,1),at(r,t,2),at(r,t,3),3),2)),Int(255.999 * ray_color_n(unit_vector_normal(at(r,t,1),at(r,t,2),at(r,t,3),1),unit_vector_normal(at(r,t,1),at(r,t,2),at(r,t,3),2),unit_vector_normal(at(r,t,1),at(r,t,2),at(r,t,3),3),1))))) 
       Else
        Plot(i, j, RGB(Int(255.999 * ray_color(r,1)),Int(255.999 * ray_color(r,2)),Int(255.999* ray_color(r,3))))
      EndIf
     
      Next
  Next
   
  
  StopDrawing() 
  
EndIf
 Repeat
   Event = WindowEvent()
 Until  Event = #PB_Event_CloseWindow
   
 End 
If you find more easier in PB you are welcome :)

Hard to make it :shock:
threedslider
Enthusiast
Enthusiast
Posts: 397
Joined: Sat Feb 12, 2022 7:15 pm

Re: Raytracing in One Weekend

Post by threedslider »

That is smooth color but not so close from normal color :/

More shorter than before and easy reading to code too and less complex

Code: Select all

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

aspect_ratio.f = 16.0 / 9.0
image_width = 800

image_height = Int(image_width / aspect_ratio)

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

focal_length.f = 1.0
viewport_height.f = 2.0

i_w.f = image_width
i_h.f = image_height
viewport_width.f = viewport_height * (i_w/i_h)

; Vector 
Structure Vec3
  x.f
  y.f
  z.f
EndStructure

; Ray
Structure Ray
  orig.Vec3
  dir.Vec3
EndStructure

point3.Vec3

point3\x = 0
point3\y = 0
point3\z = 0

ray_direction.Vec3

ray_direction\x = 0
ray_direction\y = 0
ray_direction\z = 0

viewport_u.Vec3

viewport_u\x = viewport_width
viewport_u\y = 0
viewport_u\z = 0

viewport_v.Vec3

viewport_v\x = 0
viewport_v\y = -viewport_height
viewport_v\z = 0

pixel_delta_u.Vec3

pixel_delta_u\x = viewport_u\x / i_w
pixel_delta_u\y = viewport_u\y / i_w
pixel_delta_u\z = viewport_u\z / i_w

;Debug pixel_delta_u\x

pixel_delta_v.Vec3

pixel_delta_v\x = viewport_v\x / i_h
pixel_delta_v\y = viewport_v\y / i_h
pixel_delta_v\z = viewport_v\z / i_h

;Debug pixel_delta_v\y

viewport_upper_left.Vec3

v_f.Vec3
v_f\x = 0.0
v_f\y = 0.0
v_f\z = focal_length

viewport_upper_left\x = point3\x - v_f\x - viewport_u\x / 2 - viewport_v\x / 2
viewport_upper_left\y = point3\y - v_f\y - viewport_u\y / 2 - viewport_v\y / 2
viewport_upper_left\z = point3\z - v_f\z - viewport_u\z / 2 - viewport_v\z / 2

;Debug viewport_u\x / 2 
;Debug viewport_upper_left\x

pixel_100_loc.Vec3

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)

Procedure.f dot(*v1.Vec3, *v2.Vec3)
  result.f = *v1\x * *v2\x + *v1\y * *v2\y + *v1\z * *v2\z
  
  ProcedureReturn result
EndProcedure

Procedure.f v_length(*v.Ray)
  
  result.f = Sqr(*v\dir\x * *v\dir\x + *v\dir\y * *v\dir\y + *v\dir\z * *v\dir\z)
  
  ;Debug result
  
  ProcedureReturn result
EndProcedure

Procedure.f unit_vector_y(*vy.Ray)
    
  len.f = v_length(*vy) 
  
  y.f = 0
  
  If Not len = 0 ;And Not len < 0
    y = *vy\dir\y / len
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn y
EndProcedure


Procedure.f unit_vector_normal_at(*rr.Ray, t.f, axe)
  Shared p_s.Vec3
  
   x.f = (*rr\orig\x + t * *rr\dir\x) 
   y.f = (*rr\orig\y + t * *rr\dir\y) 
   z.f = (*rr\orig\z + t * *rr\dir\z) 
  
  
  len.f = Sqr(x*x + y*y + z*z)
  
  xx.f = 0
  yy.f = 0
  zz.f = 0
  
   If Not len = 0 
    xx = x  / len
  EndIf
  
  If Not len = 0 
    yy = y / len
  EndIf
  
   If Not len = 0 
    zz = z / len
  EndIf
  
  If axe = 1
    ProcedureReturn xx
  EndIf
  
  If axe = 2
    ProcedureReturn yy
  EndIf
  
  If axe = 3
    ProcedureReturn zz
  EndIf
  
EndProcedure

Procedure.f unit_vector_normal(x.f, y.f, z.f, axe)
    
  len.f = Sqr(x*x + y*y + z*z) 
  
  xx.f = 0
  yy.f = 0
  zz.f = 0
  
   If Not len = 0 
    xx = x / len
  EndIf
  
  If Not len = 0 
    yy = y / len
  EndIf
  
   If Not len = 0 
    zz = z  / len
  EndIf
  
  If axe = 1
    ProcedureReturn xx
  EndIf
  
  If axe = 2
    ProcedureReturn yy
  EndIf
  
  If axe = 3
    ProcedureReturn zz
  EndIf
  
EndProcedure




Procedure.f ray_color_n(*rr.Ray, t.f, axe)
  Shared p_s.Vec3

  x.f =  0.5 * ((unit_vector_normal_at(*rr,t,1)) + 1.0)

  y.f =  0.5 * ((unit_vector_normal_at(*rr,t,2)) + 1.0)
 
  z.f =  0.5 * ((unit_vector_normal_at(*rr,t,3)) + 1.0)
  
  If axe = 1
    ProcedureReturn x
  EndIf
  
  If axe = 2
    ProcedureReturn y
  EndIf
  
  If axe = 3
    ProcedureReturn z
  EndIf
   
EndProcedure

Procedure.f ray_color(*rr.Ray, axe)
  
  color1.Vec3
  color2.Vec3
  
  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_direction.Vec3
    
  unit_direction\x = unit_vector_y(*rr)
  a1.f = 0.5 * (unit_direction\x + 1.0) 
  x.f =  (1.0 - a1) * color1\x + a1 * color2\x 

  unit_direction\y = unit_vector_y(*rr)
  a2.f = 0.5 * (unit_direction\y + 1.0)
  y.f =  (1.0 - a2) * color1\y + a2 * color2\y
 
  unit_direction\z = unit_vector_y(*rr)
  a3.f = 0.5 * (unit_direction\z + 1.0)
  z.f =  (1.0 - a3) * color1\z + a3 * color2\z
  
  If axe = 1
    ProcedureReturn x
  EndIf
  
  If axe = 2
    ProcedureReturn y
  EndIf
  
  If axe = 3
    ProcedureReturn z
  EndIf
   
EndProcedure  
  
Procedure.f hit_sphere(*posx.Vec3, radius.f, *vx.Ray)
  oc.Vec3
  oc\x = *vx\orig\x - *posx\x
  oc\y = *vx\orig\y - *posx\y
  oc\z = *vx\orig\z - *posx\z
  a.f = dot(*vx\dir, *vx\dir)
  b.f = 2.0 * dot(oc,*vx\dir)
  c.f = dot(oc,oc) - radius*radius
  
  discriminant.f = b*b - 4*a*c
  
  If discriminant < 0
    ProcedureReturn -1.0
  Else
    dis.f = (-b - Sqr(discriminant) ) / (2.0*a)
    ProcedureReturn dis
   
  EndIf
  

EndProcedure

; Write the translated [0,255] value of each color component.
Procedure write_color()
  Shared pixel_color.Vec3
  
  WriteString(0, Str(Int(255.999 * pixel_color\x)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\y)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\z)))
  WriteStringN(0, " ")
  
  ;Debug Str(Int(255.999 * pixel_color\x))
EndProcedure

; Output the image in PPM
; If CreateFile(0, "image_test4.ppm")
;   WriteStringN(0,"P3")
;   WriteString(0,Str(image_width))
;   WriteString(0," ")
;   WriteString(0,Str(image_height))
;   WriteStringN(0," ")
;   WriteStringN(0,"255")
;   WriteStringN(0," ")
;   
;   For j = 0 To image_height-1
;     For i = 0 To image_width-1
;       
;       ii.f = i
;       jj.f = j
;       
;       pixel_center.Vec3
;       
;       Define.Vec3 pixel_color
;       
;       pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
;       pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
;       pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
;       
;       ;Debug pixel_center\x
;       
;       ray_direction\x = pixel_center\x - point3\x
;       ray_direction\y = pixel_center\y - point3\y
;       ray_direction\z = pixel_center\z - point3\z
;       
;       ;Debug ray_direction\x
;       
;       Define.Ray r
;       
;       r\orig = point3
;       r\dir = ray_direction
;       
;       Define.Ray myray
;       
;       myray\orig = point3
;       myray\dir = ray_direction
;       
;       p_s.Vec3
;       
;       p_s\x = 0
;       p_s\y = 0
;       p_s\z = -1
;       
;       If hit_sphere(p_s, 0.5, r)
;         pixel_color\x = 1.0
;         pixel_color\y = 0
;         pixel_color\z = 0
;       Else
;         pixel_color\x = ray_color_x(r)
;         pixel_color\y = ray_color_y(r)
;         pixel_color\z = ray_color_z(r)
;       EndIf
;     
;       ;Debug pixel_color\x
;       write_color()    
;      
;      
;     Next
;   Next
;    CloseFile(0)
;  EndIf

InitSprite()
 
 OpenWindow(0, 0, 0, image_width, image_height, "Inspired from Raytracing in One Weekend", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
 OpenWindowedScreen(WindowID(0), 0, 0, image_width, image_height)
  
  ClearScreen(RGB(0,0,0))
  
  If StartDrawing(ScreenOutput())
    
    For j = 0 To image_height-1
    For i = 0 To image_width-1
      
      ii.f = i
      jj.f = j
      
      pixel_center.Vec3
      
      Define.Vec3 pixel_color
      
      pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
      pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
      pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
      
      ;Debug pixel_center\x
      
      ray_direction\x = pixel_center\x - point3\x
      ray_direction\y = pixel_center\y - point3\y
      ray_direction\z = pixel_center\z - point3\z
      
      ;Debug ray_direction\x
      
      Define.Ray r
      
      r\orig = point3
      r\dir = ray_direction
      
      Define.Ray myray
      
      myray\orig = point3
      myray\dir = ray_direction
      
      p_s.Vec3
      
      
      
      p_s\x = 0 
      
      p_s\y = 0
      p_s\z = -1
      
;       ray_direction\x = ray_direction\x - p_s\x
;       ray_direction\y = ray_direction\y - p_s\y
;       ray_direction\z = ray_direction\z - p_s\z
;       
;       Define.Ray r_n
;       
;       
;       r_n\orig = point3
;       r_n\dir = ray_direction
      
      t.f = hit_sphere(p_s, 0.5, r)
      
          
      If t > 0.0
        Plot(i, j, Plot(i, j, RGB(Int(255.999 * ray_color_n(r,t,1)), Int(255.999 * ray_color_n(r,t,2)), Int(255.999 * ray_color_n(r,t,1)))))
      Else
        Plot(i, j, RGB(Int(255.999 * ray_color(r,1)),Int(255.999 * ray_color(r,2)),Int(255.999* ray_color(r,3))))
      EndIf
     
      Next
  Next
   
  
  StopDrawing() 
  
EndIf
 Repeat
   Event = WindowEvent()
 Until  Event = #PB_Event_CloseWindow
   
 End 
threedslider
Enthusiast
Enthusiast
Posts: 397
Joined: Sat Feb 12, 2022 7:15 pm

Re: Raytracing in One Weekend

Post by threedslider »

Improved to smooth color but still not to close it ...

Code: Select all

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

aspect_ratio.f = 16.0 / 9.0
image_width = 800

image_height = Int(image_width / aspect_ratio)

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

focal_length.f = 1.0
viewport_height.f = 2.0

i_w.f = image_width
i_h.f = image_height
viewport_width.f = viewport_height * (i_w/i_h)

; Vector 
Structure Vec3
  x.f
  y.f
  z.f
EndStructure

; Ray
Structure Ray
  orig.Vec3
  dir.Vec3
EndStructure

point3.Vec3

point3\x = 0
point3\y = 0
point3\z = 0

ray_direction.Vec3

ray_direction\x = 0
ray_direction\y = 0
ray_direction\z = 0

viewport_u.Vec3

viewport_u\x = viewport_width
viewport_u\y = 0
viewport_u\z = 0

viewport_v.Vec3

viewport_v\x = 0
viewport_v\y = -viewport_height
viewport_v\z = 0

pixel_delta_u.Vec3

pixel_delta_u\x = viewport_u\x / i_w
pixel_delta_u\y = viewport_u\y / i_w
pixel_delta_u\z = viewport_u\z / i_w

;Debug pixel_delta_u\x

pixel_delta_v.Vec3

pixel_delta_v\x = viewport_v\x / i_h
pixel_delta_v\y = viewport_v\y / i_h
pixel_delta_v\z = viewport_v\z / i_h

;Debug pixel_delta_v\y

viewport_upper_left.Vec3

v_f.Vec3
v_f\x = 0.0
v_f\y = 0.0
v_f\z = focal_length

viewport_upper_left\x = point3\x - v_f\x - viewport_u\x / 2 - viewport_v\x / 2
viewport_upper_left\y = point3\y - v_f\y - viewport_u\y / 2 - viewport_v\y / 2
viewport_upper_left\z = point3\z - v_f\z - viewport_u\z / 2 - viewport_v\z / 2

;Debug viewport_u\x / 2 
;Debug viewport_upper_left\x

pixel_100_loc.Vec3

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)

Procedure.f dot(*v1.Vec3, *v2.Vec3)
  result.f = *v1\x * *v2\x + *v1\y * *v2\y + *v1\z * *v2\z
  
  ProcedureReturn result
EndProcedure

Procedure.f v_length(*v.Ray)
  
  result.f = Sqr(*v\dir\x * *v\dir\x + *v\dir\y * *v\dir\y + *v\dir\z * *v\dir\z)
  
  ;Debug result
  
  ProcedureReturn result
EndProcedure

Procedure.f At(*rr.Ray, t.f, axe)
  
  x.f = *rr\orig\x + t * *rr\dir\x
  y.f = *rr\orig\y + t * *rr\dir\y
  z.f = *rr\orig\z + t * *rr\dir\z
  
  If axe = 1
    ProcedureReturn x
  EndIf
  
  If axe = 2
    ProcedureReturn y
  EndIf
  
  If axe = 3
    ProcedureReturn z
  EndIf
EndProcedure

Procedure.f unit_vector_y(*vy.Ray)
    
  len.f = v_length(*vy) 
  
  y.f = 0
  
  If Not len = 0 ;And Not len < 0
    y = *vy\dir\y / len
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn y
EndProcedure


Procedure.f unit_vector_normal_at(*rr.Ray, t.f, axe)
  Shared p_s.Vec3
  
   x.f = (*rr\orig\x + t * *rr\dir\x) 
   y.f = (*rr\orig\y + t * *rr\dir\y) 
   z.f = (*rr\orig\z + t * *rr\dir\z) 
  
  
  len.f = Sqr(x*x + y*y + z*z)
  
  xx.f = 0
  yy.f = 0
  zz.f = 0
  
   If Not len = 0 
    xx = x  / len
  EndIf
  
  If Not len = 0 
    yy = y / len
  EndIf
  
   If Not len = 0 
    zz = z / len
  EndIf
  
  If axe = 1
    ProcedureReturn xx
  EndIf
  
  If axe = 2
    ProcedureReturn yy
  EndIf
  
  If axe = 3
    ProcedureReturn zz
  EndIf
  
EndProcedure

Procedure.f unit_vector_normal(*rr.Ray, axe)
    
  len.f = Sqr(*rr\orig\x * *rr\orig\x + *rr\orig\y * *rr\orig\y + *rr\orig\z  * *rr\orig\z )
  
  xx.f = 0
  yy.f = 0
  zz.f = 0
  
   If Not len = 0 
    xx = *rr\orig\x / len
  EndIf
  
  If Not len = 0 
    yy = *rr\orig\y / len
  EndIf
  
   If Not len = 0 
    zz = *rr\orig\z  / len
  EndIf
  
  If axe = 1
    ProcedureReturn xx
  EndIf
  
  If axe = 2
    ProcedureReturn yy
  EndIf
  
  If axe = 3
    ProcedureReturn zz
  EndIf
  
EndProcedure




Procedure.f ray_color_n(*rr.Ray, axe)
  Shared p_s.Vec3

  x.f =  0.5 * ((unit_vector_normal(*rr,1) + 1.0) )

  y.f =  0.5 * ((unit_vector_normal(*rr,2) + 1.0) )
 
  z.f =  0.5 * ((unit_vector_normal(*rr,3) + 1.0) )
  
  If axe = 1
    ProcedureReturn x
  EndIf
  
  If axe = 2
    ProcedureReturn y
  EndIf
  
  If axe = 3
    ProcedureReturn z
  EndIf
   
EndProcedure

Procedure.f ray_color(*rr.Ray, axe)
  
  color1.Vec3
  color2.Vec3
  
  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_direction.Vec3
    
  unit_direction\x = unit_vector_y(*rr)
  a1.f = 0.5 * (unit_direction\x + 1.0) 
  x.f =  (1.0 - a1) * color1\x + a1 * color2\x 

  unit_direction\y = unit_vector_y(*rr)
  a2.f = 0.5 * (unit_direction\y + 1.0)
  y.f =  (1.0 - a2) * color1\y + a2 * color2\y
 
  unit_direction\z = unit_vector_y(*rr)
  a3.f = 0.5 * (unit_direction\z + 1.0)
  z.f =  (1.0 - a3) * color1\z + a3 * color2\z
  
  If axe = 1
    ProcedureReturn x
  EndIf
  
  If axe = 2
    ProcedureReturn y
  EndIf
  
  If axe = 3
    ProcedureReturn z
  EndIf
   
EndProcedure  
  
Procedure.f hit_sphere(*posx.Vec3, radius.f, *vx.Ray)
  oc.Vec3
  oc\x = *vx\orig\x - *posx\x
  oc\y = *vx\orig\y - *posx\y
  oc\z = *vx\orig\z - *posx\z
  a.f = dot(*vx\dir, *vx\dir)
  b.f = 2.0 * dot(oc,*vx\dir)
  c.f = dot(oc,oc) - radius*radius
  
  discriminant.f = b*b - 4*a*c
  
  If discriminant < 0
    ProcedureReturn -1.0
  Else
    dis.f = (-b - Sqr(discriminant) ) / (2.0*a)
    ProcedureReturn dis
   
  EndIf
  

EndProcedure

; Write the translated [0,255] value of each color component.
Procedure write_color()
  Shared pixel_color.Vec3
  
  WriteString(0, Str(Int(255.999 * pixel_color\x)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\y)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\z)))
  WriteStringN(0, " ")
  
  ;Debug Str(Int(255.999 * pixel_color\x))
EndProcedure

; Output the image in PPM
; If CreateFile(0, "image_test4.ppm")
;   WriteStringN(0,"P3")
;   WriteString(0,Str(image_width))
;   WriteString(0," ")
;   WriteString(0,Str(image_height))
;   WriteStringN(0," ")
;   WriteStringN(0,"255")
;   WriteStringN(0," ")
;   
;   For j = 0 To image_height-1
;     For i = 0 To image_width-1
;       
;       ii.f = i
;       jj.f = j
;       
;       pixel_center.Vec3
;       
;       Define.Vec3 pixel_color
;       
;       pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
;       pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
;       pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
;       
;       ;Debug pixel_center\x
;       
;       ray_direction\x = pixel_center\x - point3\x
;       ray_direction\y = pixel_center\y - point3\y
;       ray_direction\z = pixel_center\z - point3\z
;       
;       ;Debug ray_direction\x
;       
;       Define.Ray r
;       
;       r\orig = point3
;       r\dir = ray_direction
;       
;       Define.Ray myray
;       
;       myray\orig = point3
;       myray\dir = ray_direction
;       
;       p_s.Vec3
;       
;       p_s\x = 0
;       p_s\y = 0
;       p_s\z = -1
;       
;       If hit_sphere(p_s, 0.5, r)
;         pixel_color\x = 1.0
;         pixel_color\y = 0
;         pixel_color\z = 0
;       Else
;         pixel_color\x = ray_color_x(r)
;         pixel_color\y = ray_color_y(r)
;         pixel_color\z = ray_color_z(r)
;       EndIf
;     
;       ;Debug pixel_color\x
;       write_color()    
;      
;      
;     Next
;   Next
;    CloseFile(0)
;  EndIf

InitSprite()
 
 OpenWindow(0, 0, 0, image_width, image_height, "Inspired from Raytracing in One Weekend", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
 OpenWindowedScreen(WindowID(0), 0, 0, image_width, image_height)
  
  ClearScreen(RGB(0,0,0))
  
  If StartDrawing(ScreenOutput())
    
    For j = 0 To image_height-1
    For i = 0 To image_width-1
      
      ii.f = i
      jj.f = j
      
      pixel_center.Vec3
      
      Define.Vec3 pixel_color
      
      pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
      pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
      pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
      
      ;Debug pixel_center\x
      
      ray_direction\x = pixel_center\x - point3\x
      ray_direction\y = pixel_center\y - point3\y
      ray_direction\z = pixel_center\z - point3\z
      
      ;Debug ray_direction\x
      
      Define.Ray r
      
      r\orig = point3
      r\dir = ray_direction
      
      Define.Ray myray
      
      myray\orig = point3
      myray\dir = ray_direction
      
      p_s.Vec3
      
      
      
      p_s\x = 0 
      
      p_s\y = 0
      p_s\z = -1
      
     
      
      t.f = hit_sphere(p_s, 0.5, r)
      
      ray_direction\x =  At(r,t,1) - p_s\x
      ray_direction\y =  At(r,t,2) - p_s\y
      ray_direction\z =  At(r,t,3) - p_s\z
      
      Define.Ray r_n
      
      
      r_n\orig = ray_direction
      
      
          
      If t > 0.0
        Plot(i, j, Plot(i, j, RGB(Int(255.999 * ray_color_n(r_n,1)), Int(255.999 * ray_color_n(r_n,2)), Int(255.999 * ray_color_n(r_n,1)))))
      Else
        Plot(i, j, RGB(Int(255.999 * ray_color(r,1)),Int(255.999 * ray_color(r,2)),Int(255.999* ray_color(r,3))))
      EndIf
     
      Next
  Next
   
  
  StopDrawing() 
  
EndIf
 Repeat
   Event = WindowEvent()
 Until  Event = #PB_Event_CloseWindow
   
 End 
threedslider
Enthusiast
Enthusiast
Posts: 397
Joined: Sat Feb 12, 2022 7:15 pm

Re: Raytracing in One Weekend

Post by threedslider »

Adding blue to the line 463 :

Code: Select all

Plot(i, j, Plot(i, j, RGB(Int(255.999 * ray_color_n(r_n,1)), Int(255.999 * ray_color_n(r_n,2)), Int(255.999 * ray_color_n(r_n,1))*255)))
Good but not good as normal color only Red, Green and Blue ... I think in my code the color blue is zero and don't bright the color blue for mixing with other color :cry:

If I can't find the solution so I continue other stuff in this article from Ray tracing in One Weekend :)
threedslider
Enthusiast
Enthusiast
Posts: 397
Joined: Sat Feb 12, 2022 7:15 pm

Re: Raytracing in One Weekend

Post by threedslider »

Yay ! It is near to normal color !! :mrgreen:

Better it is, so my code is here :

Code: Select all

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

aspect_ratio.f = 16.0 / 9.0
image_width = 800

image_height = Int(image_width / aspect_ratio)

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

focal_length.f = 1.0
viewport_height.f = 2.0

i_w.f = image_width
i_h.f = image_height
viewport_width.f = viewport_height * (i_w/i_h)

; Vector 
Structure Vec3
  x.f
  y.f
  z.f
EndStructure

; Ray
Structure Ray
  orig.Vec3
  dir.Vec3
EndStructure

point3.Vec3

point3\x = 0
point3\y = 0
point3\z = 0

ray_direction.Vec3

ray_direction\x = 0
ray_direction\y = 0
ray_direction\z = 0

viewport_u.Vec3

viewport_u\x = viewport_width
viewport_u\y = 0
viewport_u\z = 0

viewport_v.Vec3

viewport_v\x = 0
viewport_v\y = -viewport_height
viewport_v\z = 0

pixel_delta_u.Vec3

pixel_delta_u\x = viewport_u\x / i_w
pixel_delta_u\y = viewport_u\y / i_w
pixel_delta_u\z = viewport_u\z / i_w

;Debug pixel_delta_u\x

pixel_delta_v.Vec3

pixel_delta_v\x = viewport_v\x / i_h
pixel_delta_v\y = viewport_v\y / i_h
pixel_delta_v\z = viewport_v\z / i_h

;Debug pixel_delta_v\y

viewport_upper_left.Vec3

v_f.Vec3
v_f\x = 0.0
v_f\y = 0.0
v_f\z = focal_length

viewport_upper_left\x = point3\x - v_f\x - viewport_u\x / 2 - viewport_v\x / 2
viewport_upper_left\y = point3\y - v_f\y - viewport_u\y / 2 - viewport_v\y / 2
viewport_upper_left\z = point3\z - v_f\z - viewport_u\z / 2 - viewport_v\z / 2

;Debug viewport_u\x / 2 
;Debug viewport_upper_left\x

pixel_100_loc.Vec3

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)

Procedure.f dot(*v1.Vec3, *v2.Vec3)
  result.f = *v1\x * *v2\x + *v1\y * *v2\y + *v1\z * *v2\z
  
  ProcedureReturn result
EndProcedure

Procedure.f v_length(*v.Ray)
  
  result.f = Sqr(*v\dir\x * *v\dir\x + *v\dir\y * *v\dir\y + *v\dir\z * *v\dir\z)
  
  ;Debug result
  
  ProcedureReturn result
EndProcedure

Procedure.f At(*rr.Ray, t.f, axe)
  
  x.f = *rr\orig\x + t * *rr\dir\x
  y.f = *rr\orig\y + t * *rr\dir\y
  z.f = *rr\orig\z + t * *rr\dir\z
  
  If axe = 1
    ProcedureReturn x
  EndIf
  
  If axe = 2
    ProcedureReturn y
  EndIf
  
  If axe = 3
    ProcedureReturn z
  EndIf
EndProcedure

Procedure.f unit_vector_y(*vy.Ray)
    
  len.f = v_length(*vy) 
  
  y.f = 0
  
  If Not len = 0 ;And Not len < 0
    y = *vy\dir\y / len
  EndIf
  
  
  ;Debug vv
  
  ProcedureReturn y
EndProcedure


Procedure.f unit_vector_normal_at(*rr.Ray, t.f, axe)
  Shared p_s.Vec3
  
   x.f = (*rr\orig\x + t * *rr\dir\x) 
   y.f = (*rr\orig\y + t * *rr\dir\y) 
   z.f = (*rr\orig\z + t * *rr\dir\z) 
  
  
  len.f = Sqr(x*x + y*y + z*z)
  
  xx.f = 0
  yy.f = 0
  zz.f = 0
  
   If Not len = 0 
    xx = x  / len
  EndIf
  
  If Not len = 0 
    yy = y / len
  EndIf
  
   If Not len = 0 
    zz = z / len
  EndIf
  
  If axe = 1
    ProcedureReturn xx
  EndIf
  
  If axe = 2
    ProcedureReturn yy
  EndIf
  
  If axe = 3
    ProcedureReturn zz
  EndIf
  
EndProcedure

Procedure.f unit_vector_normal(*rr.Ray, axe)
    
  len.f = Sqr(*rr\dir\x * *rr\dir\x + *rr\dir\y * *rr\dir\y + *rr\dir\z  * *rr\dir\z )
  
  xx.f = 0
  yy.f = 0
  zz.f = 0
  
   If Not len = 0 
    xx = *rr\dir\x / len
  EndIf
  
  If Not len = 0 
    yy = *rr\dir\y / len
  EndIf
  
   If Not len = 0 
     zz = *rr\dir\z  / len
     If axe = 3
      ProcedureReturn zz
    EndIf
  EndIf
  
  If axe = 1
    ProcedureReturn xx
  EndIf
  
  If axe = 2
    ProcedureReturn yy
  EndIf
  
  
  
EndProcedure




Procedure.f ray_color_n(*rr.Ray, axe)
  Shared p_s.Vec3

  x.f =  0.5 * ((unit_vector_normal(*rr,1) + 1.0) )

  y.f =  0.5 * ((unit_vector_normal(*rr,2) + 1.0) )
 
  z.f =  0.5 * ((unit_vector_normal(*rr,3) + 1.0) )
  
  If axe = 1
    ProcedureReturn x
  EndIf
  
  If axe = 2
    ProcedureReturn y
  EndIf
  
  If axe = 3
    ProcedureReturn z
  EndIf
   
EndProcedure



Procedure.f ray_color(*rr.Ray, axe)
  
  color1.Vec3
  color2.Vec3
  
  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_direction.Vec3
    
  unit_direction\x = unit_vector_y(*rr)
  a1.f = 0.5 * (unit_direction\x + 1.0) 
  x.f =  (1.0 - a1) * color1\x + a1 * color2\x 

  unit_direction\y = unit_vector_y(*rr)
  a2.f = 0.5 * (unit_direction\y + 1.0)
  y.f =  (1.0 - a2) * color1\y + a2 * color2\y
 
  unit_direction\z = unit_vector_y(*rr)
  a3.f = 0.5 * (unit_direction\z + 1.0)
  z.f =  (1.0 - a3) * color1\z + a3 * color2\z
  
  If axe = 1
    ProcedureReturn x
  EndIf
  
  If axe = 2
    ProcedureReturn y
  EndIf
  
  If axe = 3
    ProcedureReturn z
  EndIf
   
EndProcedure  
  
Procedure.f hit_sphere(*posx.Vec3, radius.f, *vx.Ray)
  oc.Vec3
  oc\x = *vx\orig\x - *posx\x
  oc\y = *vx\orig\y - *posx\y
  oc\z = *vx\orig\z - *posx\z
  a.f = dot(*vx\dir, *vx\dir)
  b.f = 2.0 * dot(oc,*vx\dir)
  c.f = dot(oc,oc) - radius*radius
  
  discriminant.f = b*b - 4*a*c
  
  If discriminant < 0
    ProcedureReturn -1.0
  Else
    dis.f = (-b - Sqr(discriminant) ) / (2.0*a)
    ProcedureReturn dis
   
  EndIf
  

EndProcedure


; Write the translated [0,255] value of each color component.
Procedure write_color()
  Shared pixel_color.Vec3
  
  WriteString(0, Str(Int(255.999 * pixel_color\x)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\y)))
  WriteString(0, " ")
  WriteString(0, Str(Int(255.999 * pixel_color\z)))
  WriteStringN(0, " ")
  
  ;Debug Str(Int(255.999 * pixel_color\x))
EndProcedure

; Output the image in PPM
; If CreateFile(0, "image_test4.ppm")
;   WriteStringN(0,"P3")
;   WriteString(0,Str(image_width))
;   WriteString(0," ")
;   WriteString(0,Str(image_height))
;   WriteStringN(0," ")
;   WriteStringN(0,"255")
;   WriteStringN(0," ")
;   
;   For j = 0 To image_height-1
;     For i = 0 To image_width-1
;       
;       ii.f = i
;       jj.f = j
;       
;       pixel_center.Vec3
;       
;       Define.Vec3 pixel_color
;       
;       pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
;       pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
;       pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
;       
;       ;Debug pixel_center\x
;       
;       ray_direction\x = pixel_center\x - point3\x
;       ray_direction\y = pixel_center\y - point3\y
;       ray_direction\z = pixel_center\z - point3\z
;       
;       ;Debug ray_direction\x
;       
;       Define.Ray r
;       
;       r\orig = point3
;       r\dir = ray_direction
;       
;       Define.Ray myray
;       
;       myray\orig = point3
;       myray\dir = ray_direction
;       
;       p_s.Vec3
;       
;       p_s\x = 0
;       p_s\y = 0
;       p_s\z = -1
;       
;       If hit_sphere(p_s, 0.5, r)
;         pixel_color\x = 1.0
;         pixel_color\y = 0
;         pixel_color\z = 0
;       Else
;         pixel_color\x = ray_color_x(r)
;         pixel_color\y = ray_color_y(r)
;         pixel_color\z = ray_color_z(r)
;       EndIf
;     
;       ;Debug pixel_color\x
;       write_color()    
;      
;      
;     Next
;   Next
;    CloseFile(0)
;  EndIf

InitSprite()
 
 OpenWindow(0, 0, 0, image_width, image_height, "Inspired from Raytracing in One Weekend", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
 OpenWindowedScreen(WindowID(0), 0, 0, image_width, image_height)
  
  ClearScreen(RGB(0,0,0))
  
  If StartDrawing(ScreenOutput())
    
    For j = 0 To image_height-1
    For i = 0 To image_width-1
      
      ii.f = i
      jj.f = j
      
      pixel_center.Vec3
      
      Define.Vec3 pixel_color
      
      pixel_center\x = pixel_100_loc\x + (ii * pixel_delta_u\x) + (jj * pixel_delta_v\x)
      pixel_center\y = pixel_100_loc\y + (ii * pixel_delta_u\y) + (jj * pixel_delta_v\y)
      pixel_center\z = pixel_100_loc\z + (ii * pixel_delta_u\z) + (jj * pixel_delta_v\z)
      
      ;Debug pixel_center\x
      
      ray_direction\x = pixel_center\x - point3\x
      ray_direction\y = pixel_center\y - point3\y
      ray_direction\z = pixel_center\z - point3\z
      
      ;Debug ray_direction\x
      
      Define.Ray r
      
      r\orig = point3
      r\dir = ray_direction
      
      Define.Ray myray
      
      myray\orig = point3
      myray\dir = ray_direction
      
      p_s.Vec3
      
      
      
      p_s\x = 0.0 
      
      p_s\y = 0.0
      p_s\z = -1.0
      
      vv.Vec3
      
      vv\x = 0
      vv\y = 0
      vv\z = -1
      
     
      
      t.f = hit_sphere(p_s, 0.5, r)
      
      ray_direction\x =  At(r,t,1) - p_s\x
      ray_direction\y =  At(r,t,2) - p_s\y
      ray_direction\z =  At(r,t,3) - p_s\z
      
      Define.Ray r_n
      
      r_n\orig = point3
      r_n\dir = ray_direction
      
      
      
     Debug Int(255.999 * ray_color_n(r_n,1))+155
          
      If t > 0.0
        Plot(i, j, RGB(Int(255.999 * ray_color_n(r_n,1)), Int(255.999 * ray_color_n(r_n,2)), Int(255.999 * ray_color_n(r_n,1)*0.5)*255))
        
      Else
        Plot(i, j, RGB(Int(255.999 * ray_color(r,1)),Int(255.999 * ray_color(r,2)),Int(255.999* ray_color(r,3))))
      EndIf
     
      Next
  Next
   
  
  StopDrawing() 
  
EndIf
 Repeat
   Event = WindowEvent()
 Until  Event = #PB_Event_CloseWindow
   
 End 
threedslider
Enthusiast
Enthusiast
Posts: 397
Joined: Sat Feb 12, 2022 7:15 pm

Re: Raytracing in One Weekend

Post by threedslider »

Quick fixing to color so it is so close to normal color now :mrgreen:

Finally, it is same code but to the line 472 : (Change to this )

Code: Select all

Plot(i, j, RGB(Int(255.999 * ray_color_n(r_n,1)), Int(255.999 * ray_color_n(r_n,2)), Int(255.999 * ray_color_n(r_n,1)*0.2)*255))
Happy coding !
Post Reply