Rendering static image onto models?

Blitz3D Forums/Blitz3D Programming/Rendering static image onto models?

Cubed Inc.(Posted 2014) [#1]
This is gonna be a tough one to explain. Would it be possible to "render" a static image onto a model that does not necessarily map to the model itself and is not affected by depth? I'm experimenting with a 3d game with pre-rendered background (Grim Fandango, Resident Evil, Final Fantasy 7) and I'm trying to make certain parts of the pre-rendered background have depth so that the 3d character can walk in front and behind them. The idea I got was to create a 3d collision model that matched up over the pre-rendered background, and apply the same pre-rendered background image to the collision model so that I could achieve the illusion of depth. The image technique I speak of can be easily seen in this picture from the new Monkey Island games (notice the man's suit.)





If all of this still doesn't make a lick of sense, just let me know and I'll try to explain it better. But if anyone does understand, I'd really appreciate your thoughts, feedback, and suggestions.


Kryzon(Posted 2014) [#2]
The effect for that man's shirt comes from automatic texture coordinate generation. The shirt is mapped based on the view direction; the positions of the vertices of the shirt are used as texture coordinates, so the shirt texture always "faces" the camera.

In D3D (which Blitz3D uses), it's the D3DTSS_TCI_CAMERASPACEPOSITION method:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb172339(v=vs.85).aspx

In OpenGL, the equivalent method is GL_EYE_LINEAR:
http://resumbrae.com/ub/dms424_s04/15/03.html

- - - - -

I don't think this is what you'll use to make 2d-in-3D backgrounds such as those from Alone in the Dark, Resident Evil, Final Fantasy etc.
To do backgrounds such as these...

1) You first render the background from the fixed point of view of your choice. For this you use 3DS Max, Blender etc. to get a nice quality of rendering.

2) Using an image program such as the GIMP or Photoshop, you break that rendered image into separate layers based on how you want the layers to be ordered in relation to the dynamic objects (characters etc.).

3) This is the most complicated part. You don't change the rendering order of any of those layers when rendering them among the characters. Leave them as they are.
Rather, you distance a certain layer away from the camera based on the farthest vertex from the camera that was rendered into that layer.

Reference image:



So the camera distance of that wall layer on the right side is taken as the distance between the red point and the camera - ignore the green dot at the bottom, since it's not the farthest vertex of that object from the camera. You do this in your modelling application, getting the XYZ position of the vertex of that red point and the XYZ position of the camera, and calculating the distance between these 3D points.
Then you use that distance to move the layer away from the camera, in the local Z direction of the camera.

You will also need to scale the layer based on the camera field-of-view to preserve the layer size. You are moving each layer so they are correctly ordered when rendered with characters etc., and when you do this they become smaller the farther they are from the camera and you need to compensate for that.
With a camera of a 90º field-of-view (the default when you create a camera in Blitz3D), I believe you use the distance of a layer as scale factor: it's 1.0 when the layer is right on the near-plane, and 'n' when the distance of the layer to the camera is 'n.'
If you're using a different field-of-view for your camera (you control this with CameraZoom( camera, zoom ) ), I think you scale the layer based on this expression: scale = ( distance_from_camera x ( 1.0 / zoom ) )


Yasha(Posted 2014) [#3]
An alternative method for rendering FF7-style backgrounds is to produce two outputs from your detail scene: a regular image rendered from the desired perspective, and a simplified 3D model.

You can then do a three-pass render: first render the simplified model. Then, draw the image over the whole screen (simple 2D operation). Finally, render your dynamic meshes but with the camera set to not clear the Z-buffer or colour buffer - not clearing the colour buffer will leave the background image in place (common technique), and not clearing the Z-buffer will give it the depth effect from the simplified mesh pass, so that wherever the character would be behind the simple mesh, they aren't drawn over the background image either. Set the camera back to clear the Z buffer for the start of the next frame.


Kryzon(Posted 2014) [#4]
That's fascinating, much simpler.


Cubed Inc.(Posted 2014) [#5]
Yasha
Do you have an example of this method in action in Blitz3d? I was never too savvy with messing around with the program's buffer functions.


Cubed Inc.(Posted 2014) [#6]
Does it entail using the CameraClsMode function of Blitz3d? I'm trying to experiment with it and your method, but I can't get it to work.


Yasha(Posted 2014) [#7]
Yes, you would use that one.

Example:
While ...
    ; 1: draw the simple mesh to get its depth
    HideEntity all dynamic meshes
    ShowEntity simplified world mesh
    CameraClsMode cam, 1, 1    ;Colour flag actually doesn't matter here
    RenderWorld
    
    ; 2: draw the background image
    DrawImage background, 0, 0    ;This step is actually more difficult if you're using a 2D-in-3D draw system
    
    ; 3: draw the foreground objects
    HideEntity simplified world mesh
    ShowEntity all relevant dynamic meshes
    CameraClsMode cam, 0, 0
    RenderWorld
    
    2D HUD, Flip etc
Wend


The important thing is that there are two separate calls to RenderWorld with two separate ClsMode settings for them. The first one has to clear the Z-buffer, because it is creating a new Z buffer for the frame (overwriting the positions of the characters last frame and so on); the second one mustn't clear either buffer, because it uses the specially-created depth map to determine when characters are obscured (and treats the 2D image as though it were the old colour map).