Ooops
January 26, 2021, 11:33:50 AM

Author Topic: [bb] Dolly-Zoom effect by Kryzon [ 1+ years ago ]  (Read 650 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] Dolly-Zoom effect by Kryzon [ 1+ years ago ]
« on: June 29, 2017, 12:28:40 AM »
Title : Dolly-Zoom effect
Author : Kryzon
Posted : 1+ years ago

Description : Included are three possible ways to perform this zoom effect.

They all consist on mostly the same:
- Store the original distance from the camera to the subject.
- Move the camera by a small amount.
- Update the camera's zoom to preserve the screen size of the subject based on the ratio (CurrentDistance / OriginalDistance).
- The screen size of the subject remains the same, but the perspective changes and that's what gives the effect.

The Distance method is best suited if you're working with Blitz3D.
The FOV (field-of-view) method is best suited for other game engines where you change a camera's zoom based on this property alone.

Original thread: <a href="../Community/posts799a.html?topic=99719" target="_blank">http://blitzbasic.com/Community/posts.php?topic=99719[/url]


Code :
Code: BlitzBasic
  1. ;**************************************************
  2. ;
  3. ;  3 Recipes for the Dolly-Zoom effect
  4. ;  (also known as Push-Pull or Vertigo zoom).
  5. ;
  6. ;  Demo and Distance-Zoom method by Floyd.
  7. ;  Adaptation, FOV and Z-Scale methods by Kryzon.
  8. ;
  9. ;  ----------------------------------------------
  10. ;  Press SPACE to change the zoom method.
  11. ;  Hold A or Z to move the camera.
  12. ;
  13. ;  Jan 6th 2013
  14. ;
  15. ;**************************************************
  16.  
  17. ;Zoom methods:
  18. ;1 - Distance-Zoom
  19. ;2 - FOV
  20. ;3 - Z-Scale (messes up the lighting, here only for "academic" purposes.)
  21.  
  22. Local dollyMethod% = 1
  23.  
  24. AppTitle "Dolly-Zoom effect demo"
  25. Graphics3D 800, 600, 0, 2
  26. SetBuffer BackBuffer()
  27. HidePointer
  28.  
  29. Local sphere% = CreateSphere()
  30. Local camera% = CreateCamera() : PositionEntity camera, 0, 5, -5
  31. CameraRange camera, 0.5, 1000 : PointEntity camera, sphere
  32. TurnEntity CreateLight(), 30, 70, 0
  33. VariousOtherThings 30
  34.  
  35. ;Setup for Distance-Zoom method:
  36. Local zoom_over_distance# = 1.0 / EntityDistance( camera, sphere )   ; CameraZoom is 1.0
  37.  
  38. ;Setup for FOV method:
  39. Local subjectDistance# = EntityDistance( camera, sphere )
  40. Local originalFOV# = 90.0 ;In Blitz3D, the equivalent of a CameraZoom of 1.0
  41. Local originalTan# = Tan(originalFOV / 2.0)
  42. Local currentFOV# = 90.0
  43. Local distanceRatio# = 1.0
  44.  
  45. ;Setup for Z-Scale method:
  46. subjectDistance# = EntityDistance( camera, sphere)
  47. Local cameraScale# = 1.0
  48. distanceRatio# = 1.0
  49.  
  50. ;Main Loop.
  51. While Not KeyDown(1)
  52.        
  53.         ;Move the camera.
  54.         z# = EntityZ( camera )
  55.         If KeyDown(44) Then z = z * 1.01
  56.         If KeyDown(30) Then z = z / 1.01
  57.         PositionEntity camera, 0, -z, z
  58.        
  59.         ;Select a zoom method.
  60.         If KeyHit(57) Then
  61.                 dollyMethod = dollyMethod + 1
  62.                 If dollyMethod > 3 Then dollyMethod = 1
  63.                
  64.                 If dollyMethod <> 3 Then
  65.                         ScaleEntity camera, 1.0, 1.0, 1.0
  66.                 Else
  67.                         CameraZoom camera, 1.0
  68.                 EndIf
  69.         EndIf
  70.                
  71.         Select dollyMethod
  72.                 Case 1 ;Distance-Zoom
  73.                         CameraZoom camera, zoom_over_distance * EntityDistance( camera, sphere )
  74.                         PointEntity camera, sphere
  75.                        
  76.                         RenderWorld
  77.                         Text 10, 10, "Method: Distance-Zoom"
  78.                         Text 10, 30, "Distance = " + EntityDistance( camera, sphere )
  79.                         Text 10, 50, "CameraZoom = " + zoom_over_distance * EntityDistance( camera, sphere )
  80.                
  81.                 Case 2 ;FOV
  82.                         distanceRatio# = subjectDistance / EntityDistance( camera, sphere )
  83.                        
  84.                         ;The FOV (field-of-view) is an angle value that several engines use for setting up a camera's zoom.
  85.                         currentFOV = 2.0 * ATan(distanceRatio * originalTan)
  86.                
  87.                         ;You apply that FOV angle in whatever way your engine does it (matrix, function, etc.). In case of Blitz3D...
  88.                         CameraZoom camera, ( 1.0 / Tan(currentFOV/2.0) )
  89.                        
  90.                         PointEntity camera, sphere
  91.                        
  92.                         RenderWorld
  93.                         Text 10, 10, "Method: FOV"
  94.                         Text 10, 30, "Distance = " + EntityDistance( camera, sphere )
  95.                         Text 10, 50, "CameraZoom = " + (1.0 / Tan(currentFOV/2.0 )) + " ("+currentFOV+" degrees)"
  96.                
  97.                 Case 3 ;Z-Scale
  98.                         distanceRatio# = subjectDistance / EntityDistance( camera, sphere )
  99.                         ScaleEntity( camera, 1.0, 1.0, (1.0 / distanceRatio) )
  100.  
  101.                         RenderWorld
  102.                         Text 10, 10, "Method: Z-Scale"
  103.                         Text 10, 30, "Distance = " + EntityDistance( camera, sphere )
  104.                         Text 10, 50, "CameraZoom = " + ( 1.0 / distanceRatio ) 
  105.         End Select
  106.        
  107.         Flip
  108. Wend
  109.  
  110. ;Aesthetics.
  111. Function VariousOtherThings( quantity )
  112.         For n = 1 To quantity
  113.                 Select Rand( 1, 4 )
  114.                         Case 1 : temp = CreateSphere()
  115.                         Case 2 : temp = CreateCone()
  116.                         Case 3 : temp = CreateCylinder()
  117.                         Case 4 : temp = CreateCube()
  118.                 End Select
  119.                 ScaleEntity temp, Rnd( 0.6, 1.5 ), Rnd( 0.6, 1.5 ), Rnd( 0.6, 1.5 )
  120.                 EntityColor temp, Rand( 100, 255 ), Rand( 100, 255 ), Rand( 100, 255 )
  121.                 RotateEntity temp, Rnd( -20, 20 ), Rnd( -50, 50 ), Rnd( -20, 20 )
  122.                 angle# = Rnd( -45, 225)
  123.                 dist#  = Rnd( 2.5, 6 )
  124.                 PositionEntity temp, dist * Cos( angle ), Rnd( - 3, 3 ), dist * Sin( angle )
  125.         Next
  126. End Function
  127.  
  128. End


Comments :


Blitzplotter(Posted 1+ years ago)

 This is great, was pondering/wondering how to go about achieving this very thing - thanks for the post.


_PJ_(Posted 1+ years ago)

 Just curious as to the actual effect of the z scale parameter with respect to a camera entity here:ScaleEntity( camera, 1.0, 1.0, (1.0 / distanceRatio) )


Kryzon(Posted 1+ years ago)

 Hi _PJ_, sorry for the delay!I'm not sure of the internals, but what I think is happening is you're transforming the camera's matrix.Internally, when you're going to render a mesh, you need to transform it in relation to the camera (something called Model View), and since this Model View was transformed itself (when we scale the camera), everything will appear different.The Model View's scale is always the default [1,1,1], and when you change it in any way you're going to have some out-worldly result.That's why lighting seems to change: it is a mesh's vertices' positions (after being transformed by the Model View) that are used to calculate lighting.  This phenomenon is only happening "visually"."Logically", all entity positions, vertices, scales, collisions etc. remain the same. So if you scale your camera in the middle of your game nothing logical-wise should change, only visually.


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal