Skip to content

Creating realistic 3D perspective and sprite scaling in Scratch

💡 Need help with advanced 3D effects and mathematical calculations? 🚀 Get Help Now

PM

Perspective3D_Master

Posted on January 25, 2024 • Advanced

🎯 Need help with sprite sizing in fake 3D perspective!

Hey everyone! I’m working on a simple “fake 3D” project and I’m struggling with getting the sprite scaling right for realistic perspective effects. 😅

The issues I’m facing:

  • Objects scale at a uniform speed instead of proportionally to distance
  • Blue boxes that should line up like a wall don’t align properly
  • Need realistic depth perception like when driving and seeing trees get smaller
  • Want objects to appear to shrink slower as they get further away

I know it might need some exponential math, but I’m not sure how to implement it correctly. Any help would be amazing! 🙏

MM

Math3D_Wizard

Replied 2 hours later • ⭐ Best Answer

Perfect question @Perspective3D_Master! 3D perspective is all about understanding the mathematical relationship between distance and apparent size. Here’s the complete solution:

📐 Understanding Perspective Projection

The key formula for 3D perspective is:

screen_size = object_size × (focal_length ÷ distance)

This creates the realistic “things get smaller with distance” effect you’re looking for!

🔧 Basic 3D Perspective System

Here’s how to implement proper perspective scaling:

    when flag clicked
set [focal_length v] to [200] // Adjust for field of view
set [camera_x v] to [0]
set [camera_y v] to [0]
set [camera_z v] to [0]

// For each 3D object
define project_3d_to_2d (world_x) (world_y) (world_z)
// Calculate relative position to camera
set [relative_x v] to ((world_x) - (camera_x))
set [relative_y v] to ((world_y) - (camera_y))
set [relative_z v] to ((world_z) - (camera_z))

// Prevent division by zero
if <(relative_z) < [1]> then
set [relative_z v] to [1]
end

// Apply perspective projection
set [screen_x v] to ((relative_x) * ((focal_length) / (relative_z)))
set [screen_y v] to ((relative_y) * ((focal_length) / (relative_z)))
set [screen_scale v] to ((focal_length) / (relative_z))

// Apply to sprite
go to x: (screen_x) y: (screen_y)
set size to ((screen_scale) * [100])%
  

🎮 Complete 3D World System

Here’s a full implementation for your fake 3D game:

    // Main camera control
when flag clicked
set [camera_x v] to [0]
set [camera_z v] to [0]
set [focal_length v] to [150]
set [movement_speed v] to [5]

forever
// Camera movement
if <key [w v] pressed?> then
change [camera_z v] by (movement_speed)
end
if <key [s v] pressed?> then
change [camera_z v] by (0 - (movement_speed))
end
if <key [a v] pressed?> then
change [camera_x v] by (0 - (movement_speed))
end
if <key [d v] pressed?> then
change [camera_x v] by (movement_speed)
end

// Update all 3D objects
broadcast [update_3d_objects v]
end

// For each 3D object sprite
when I receive [update_3d_objects v]
// Set object's world position
set [object_world_x v] to [100] // Change for each object
set [object_world_y v] to [0]
set [object_world_z v] to [300] // Distance from camera

// Calculate screen position
project_3d_to_2d (object_world_x) (object_world_y) (object_world_z)

// Apply depth sorting (further objects behind closer ones)
go to [back v] layer
go forward ((1000) - (object_world_z)) layers
  

🏗️ Creating Aligned Wall Objects

For your wall of blue boxes, here’s how to make them line up perfectly:

    // Wall generation system
when flag clicked
set [wall_start_x v] to [-200]
set [wall_end_x v] to [200]
set [wall_z v] to [500]
set [box_spacing v] to [50]

set [current_x v] to (wall_start_x)
repeat until <(current_x) > (wall_end_x)>
create clone of [wall_box v]
set [box_world_x v] to (current_x)
set [box_world_y v] to [0]
set [box_world_z v] to (wall_z)
change [current_x v] by (box_spacing)
end

// Wall box clone behavior
when I start as a clone
forever
// Use the stored world position for this clone
project_3d_to_2d (box_world_x) (box_world_y) (box_world_z)

// Add some visual depth cues
set [brightness v] effect to ((0 - (box_world_z)) / [10])
end
  

🌟 Advanced Perspective Effects

Make your 3D world even more realistic:

    // Fog effect for distant objects
define apply_fog_effect (distance)
if <(distance) > [300]> then
set [fog_amount v] to (((distance) - [300]) / [10])
if <(fog_amount) > [100]> then
set [fog_amount v] to [100]
end
set [ghost v] effect to (fog_amount)
else
set [ghost v] effect to [0]
end

// Realistic size scaling with minimum size
define calculate_realistic_scale (distance) (base_size)
set [scale_factor v] to ((focal_length) / (distance))
set [final_scale v] to ((scale_factor) * (base_size))

// Prevent objects from becoming too small
if <(final_scale) < [5]> then
set [final_scale v] to [5]
end

// Prevent objects from becoming too large
if <(final_scale) > [300]> then
set [final_scale v] to [300]
end

set size to (final_scale)%

// Ground plane effect
define create_ground_grid
set [grid_size v] to [100]
set [grid_lines v] to [20]

repeat (grid_lines)
create clone of [grid_line v]
set [line_x v] to ((grid_size) * ((item # of [repeat]) - ((grid_lines) / [2])))
set [line_z_start v] to [100]
set [line_z_end v] to [1000]
end
  

🚀 Pro Tips for Realistic 3D

  • Use consistent focal length - around 150-200 works well for most games
  • Add depth sorting - further objects should be behind closer ones
  • Implement fog effects - distant objects should fade out
  • Use minimum scale limits - prevent objects from disappearing completely
  • Add lighting effects - closer objects should be brighter
  • Test with different camera speeds - find what feels natural

This will give you that realistic “driving past trees” perspective effect you’re looking for! 🎯

PM

Perspective3D_Master

Replied 40 minutes later

@Math3D_Wizard This is absolutely mind-blowing! 🤩 The perspective formula works perfectly and my wall objects finally line up correctly!

One question - how can I add rotation to objects so they can face different directions in 3D space?

RM

Rotation3D_Expert

Replied 1 hour later

@Perspective3D_Master Excellent question! Here’s how to add 3D rotation:

    // 3D rotation system
define rotate_3d_point (x) (y) (z) (angle_y)
// Y-axis rotation (left/right turning)
set [cos_y v] to ([cos v] of (angle_y))
set [sin_y v] to ([sin v] of (angle_y))

// Apply rotation matrix
set [rotated_x v] to (((x) * (cos_y)) - ((z) * (sin_y)))
set [rotated_z v] to (((x) * (sin_y)) + ((z) * (cos_y)))
set [rotated_y v] to (y) // Y stays the same for Y-axis rotation

// Now project the rotated point
project_3d_to_2d (rotated_x) (rotated_y) (rotated_z)

// Object facing direction
define calculate_object_facing (object_angle) (camera_angle)
set [relative_angle v] to ((object_angle) - (camera_angle))
point in direction ((relative_angle) + [90])
  

This adds realistic 3D rotation that responds to camera movement! 🔄

OE

Optimization_Engineer

Replied 2 hours later

Great work everyone! 🎮 Here are some performance tips for complex 3D scenes:

  • Frustum culling: Don’t render objects outside the camera view
  • Level of detail: Use simpler sprites for distant objects
  • Object pooling: Reuse clones instead of creating/deleting constantly
  • Update frequency: Update distant objects less frequently
  • Batch calculations: Group similar math operations together

Remember: start simple and add complexity gradually. Test performance frequently!

VB

Vibelf_Community

Pinned Message • Moderator

🚀 Master Advanced 3D Programming!

Incredible mathematical discussion everyone! For those looking to create even more sophisticated 3D effects, our community can help you implement:

  • 🎯 Advanced matrix transformations
  • 🌟 Real-time lighting and shadows
  • 🎨 Texture mapping and materials
  • ⚡ Performance optimization techniques

📚 Related Topics

Ready to push the boundaries of what’s possible in Scratch? Get personalized guidance from our expert programming tutors!