Pixel-perfect background image in 3D

Everything related to 3D programming
troy
User
User
Posts: 51
Joined: Sat May 31, 2003 2:59 pm

Pixel-perfect background image in 3D

Post by troy »

I used to put a simple sprite with exact screen dimension on background to do that. Now I need to have some 3d stuff added at the scene. Sprites still work but AFTER the 3d stuff is rendered. Is it possible to put a sprite behind the 3d scene? If not, is seems the solution would be to make a plane or billboard with image as a texture. But in this case - how to achieve to have its size pixel-perfect, to match current screen resolution? Other words how to put an image as a background in 3d scene with exact size the screen has, nevertheless is it 800x600 or 1920x1080.
--
troy
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Pixel-perfect background image in 3D

Post by applePi »

how to put an image as a background in 3d scene with exact size the screen has, nevertheless is it 800x600 or 1920x1080.
Hi, i am not expert in the sprites but i have an easier solution, i think skybox is suitable, it is an infinite cube and every face of it from the 6 faces we can texture it alone
from the doc :
TextureName_BK ; BacK face
TextureName_FR ; FRont face
TextureName_DN ; DowN face
TextureName_UP ; UP face
TextureName_LF ; LeFt face
TextureName_RT ; RighT face

the _BK, _FR, ...etc is important, but we refer only to the texture name without extensions like:
SkyBox("ValetCoeur.jpg")
i have added a cat image in the ceiling under the name ValetCoeur_UP.jpg, the other images in the ValetCoeur with extensions. whatever the resolution the infinite cube is the same.
download this FantaBox.zip and put in in the same folder as the code as it is (a zip file) , the packs in the PB examples available in Packs folder
https://www.mediafire.com/file/6h49ikqw ... ntaBox.zip

use the mouse and keyboard

Code: Select all

;
; ------------------------------------------------------------
;
;   PureBasic - SkyBox
;
;    (c) Fantaisie Software
;
; ------------------------------------------------------------
;

#CameraSpeed = 10

Enumeration
  #MainWindow 
  #Editor
EndEnumeration

Define.f KeyX, KeyY, MouseX, MouseY, RatioX, RatioY

InitEngine3D()

  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Packs/FantaBox.zip", #PB_3DArchive_Zip)
  Add3DArchive(".", #PB_3DArchive_Zip)
  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
      
    OpenWindow(0, 0, 0, 800, 600, "skybox", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
    OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, 0, 0, 0)
    AmbientColor(RGB(255, 255, 255))
   
    CreateMaterial(3, LoadTexture(3, "ground_diffuse.png"))
   
    ;- Camera
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 400, 400, 400, #PB_Absolute)
    CameraLookAt(0,0,0,0)
    CameraBackColor(0, RGB(19, 34, 49))
    CreatePlane(3, 1000, 1000, 1, 1, 1, 1)
    CreateEntity(3,MeshID(3),MaterialID(3), 0, 0, 0)
    EntityRenderMode(3, 0) 
    CreateEntityBody(3, #PB_Entity_BoxBody, 0, 1, 1)

    CreateMaterial(0, LoadTexture(0, "r2skin.jpg"))
    
;
    LoadMesh(1, "robot.mesh")
    
    ; Entity
    ;
    CreateEntity(1, MeshID(1), #PB_Material_None, -100,0,200)
    
    ; Animation
    ;
    StartEntityAnimation(1, "Walk", #PB_EntityAnimation_Average)
   
    ;SkyBox("desert07.jpg")
    SkyBox("ValetCoeur.jpg")
        
    Repeat
      Repeat   
        Event = WindowEvent()
        Until Event = 0
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      EndIf
      
      If ExamineKeyboard()
               
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed 
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed 
        Else
          KeyX = 0
        EndIf
                  
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed 
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed 
        Else
          KeyY = 0
        EndIf

      EndIf
        
      RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera  (0, KeyX, 0, KeyY)
     
      RenderWorld()
       
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
      

End
Bitblazer
Enthusiast
Enthusiast
Posts: 733
Joined: Mon Apr 10, 2017 6:17 pm
Location: Germany
Contact:

Re: Pixel-perfect background image in 3D

Post by Bitblazer »

Isnt that a typical case for an Orthographic projection camera?

https://www.google.de/search?ei=Xk8RWvL ... _yu3hNHKlw

Afaik its just a matter of setting the camera and the orteographic projection up correctly, but its been a while that i did that myself.
Last edited by Bitblazer on Sun Nov 19, 2017 10:39 am, edited 1 time in total.
DarkDragon
Addict
Addict
Posts: 2218
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Re: Pixel-perfect background image in 3D

Post by DarkDragon »

You could draw something surrounding your scene in an infinite distance (by disabling drawing into depth buffer) and inside the fragment shader you'd map the texture onto it by screen coordinates. That would be the best option in PureBasic I think.
bye,
Daniel
troy
User
User
Posts: 51
Joined: Sat May 31, 2003 2:59 pm

Re: Pixel-perfect background image in 3D

Post by troy »

Thanks for suggestions!

applePi, the example is great, but a skybox is not quite what I need, the background should stay intact and has the best possible image quality.

Bitblazer, good point, didn't try this approach...

DarkDragon, can't say. Shaders sound a bit complicated to me so far, an example would be great.

That's what I came up to. The background image always fits the current screen (independently on screen resolution and camera distance). Not quite sure about the image quality, it's a texture, not a sprite. Improvements and further suggestions are appreciated.

Code: Select all

#CameraSpeed = 0.04

Enumeration
  #MainWindow
EndEnumeration

Define.f KeyX, KeyY, MouseX, MouseY, RatioX, RatioY

InitEngine3D()

  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
  Parse3DScripts()
 
  InitSprite()
  InitKeyboard()
  InitMouse()
 
  
  w.l = 800
  h.l = 600
  ratio.f = w/h
  
  OpenWindow(0, 0, 0, w, h, "background sprite", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
  OpenWindowedScreen(WindowID(0), 0, 0, w, h, 0, 0, 0)
  AmbientColor(RGB(255, 255, 255))
  ;CreateLight(#PB_Any, RGB(25, 25, 180), -5, 10, 5, #PB_Light_Point)

  
  ;- Camera
  factor.f = 0.935
  distance.l = 20
  CreateCamera(0, 0, 0, 100, 100)
  CameraFOV(0, 50)
  MoveCamera(0, 0, 0, distance, #PB_Absolute)
  CameraLookAt(0,0,0,0)
  CameraBackColor(0, RGB(0, 255, 0))
  
  ; Plane
  wt.l = 512
  ht.l = 512
  sizeZ.f = distance * factor
  sizeX.f = sizeZ * ratio
  ;CreateMaterial(0, LoadTexture(0, "ground_diffuse.png"))
  CreateTexture(0, wt, ht, "background")
  StartDrawing(TextureOutput(0))
  FillArea(1, 1, -1, $996633)
  FrontColor(RGB(255, 0, 255))
  Circle(wt/2, ht/2, wt/2 - 2, $999933)
  StopDrawing()
  CreateMaterial(0, TextureID(0))
  CreatePlane(0, sizeX, sizeZ, 1, 1, 1, 1)
  CreateEntity(0, MeshID(0), MaterialID(0), 0, 0, 0)
  RotateEntity(0, 90, 0, 0)
  
  ; Robot
  ;CreateMaterial(1, LoadTexture(1, "r2skin.jpg"))
  LoadMesh(1, "robot.mesh")
  CreateEntity(1, MeshID(1), #PB_Material_None, 0, 0, 10)
  ScaleEntity(1, 0.02, 0.02, 0.02)
  StartEntityAnimation(1, "Walk", #PB_EntityAnimation_Average)
   
    Repeat
      Repeat   
        Event = WindowEvent()
        Until Event = 0
     
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      EndIf
     
      If ExamineKeyboard()
               
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed
        Else
          KeyX = 0
        EndIf
                 
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed
        Else
          KeyY = 0
        EndIf

      EndIf
       
      RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera  (0, KeyX, 0, KeyY)
     
      RenderWorld()
       
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
     

End
--
troy
User avatar
Comtois
Addict
Addict
Posts: 1429
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: Pixel-perfect background image in 3D

Post by Comtois »

With node

Code: Select all

#CameraSpeed = 0.04

Enumeration
  #MainWindow
EndEnumeration

Define.f KeyX, KeyY, MouseX, MouseY, RatioX, RatioY

InitEngine3D()

  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
  Parse3DScripts()
 
  InitSprite()
  InitKeyboard()
  InitMouse()
 
 
  w.l = 800
  h.l = 600
  ratio.f = w/h
 
  OpenWindow(0, 0, 0, w, h, "background sprite", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
  OpenWindowedScreen(WindowID(0), 0, 0, w, h, 0, 0, 0)
  AmbientColor(RGB(255, 255, 255))
  ;CreateLight(#PB_Any, RGB(25, 25, 180), -5, 10, 5, #PB_Light_Point)

 
  ;- Camera
  factor.f = 0.935
  distance.l = 20
  CreateCamera(0, 0, 0, 100, 100)
  CameraFOV(0, 50)
  MoveCamera(0, 0, 0, distance, #PB_Absolute)
  CameraLookAt(0,0,0,0)
  CameraBackColor(0, RGB(0, 255, 0))
 
  ; Plane
  wt.l = 512
  ht.l = 512
  sizeZ.f = distance * factor
  sizeX.f = sizeZ * ratio
  ;CreateMaterial(0, LoadTexture(0, "ground_diffuse.png"))
  CreateTexture(0, wt, ht, "background")
  StartDrawing(TextureOutput(0))
  FillArea(1, 1, -1, $996633)
  FrontColor(RGB(255, 0, 255))
  Circle(wt/2, ht/2, wt/2 - 2, $999933)
  StopDrawing()
  CreateMaterial(0, TextureID(0))
  SetMaterialAttribute(0,#PB_Material_DepthCheck , #False)
  SetMaterialAttribute(0, #PB_Material_DepthWrite, #False)  
  
  CreatePlane(0, sizeX, sizeZ, 1, 1, 1, 1)
  CreateEntity(0, MeshID(0), MaterialID(0), 0, 0, 0)
  RotateEntity(0, 90, 0, 0)
  ;SetRenderQueue(EntityID(0), 0)
  
 
  ; Robot
  ;CreateMaterial(1, LoadTexture(1, "r2skin.jpg"))
  LoadMesh(1, "robot.mesh")
  CreateEntity(1, MeshID(1), #PB_Material_None, 0, 0, 15)
  ScaleEntity(1, 0.02, 0.02, 0.02)
  StartEntityAnimation(1, "Walk", #PB_EntityAnimation_Average)
  
  CreateNode(0)
  AttachNodeObject(0, CameraID(0))
  AttachNodeObject(0,EntityID(0))

  
  
    Repeat
      Repeat   
        Event = WindowEvent()
        Until Event = 0
     
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      EndIf
     
      If ExamineKeyboard()
               
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed
        Else
          KeyX = 0
        EndIf
                 
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed
        Else
          KeyY = 0
        EndIf

      EndIf
       
      RotateNode(0, MouseY, MouseX, 0, #PB_Relative)
      MoveNode  (0, KeyX, 0, KeyY)
     
      RenderWorld()
       
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
 

End
Please correct my english
http://purebasic.developpez.com/
Post Reply