BSL:Frustum and fog: Difference between revisions

From OniGalore
Jump to navigation Jump to search
(layout and language improvements, external link updates, and math fixes (last calculation was converting Z=0.975 instead of 0.925; world units are not 10 cm, they are 4 inches))
(moving most technical parts to Graphics to slim this down (lots more commands will be going here once this becomes BSL:Graphics))
Line 1: Line 1:
==Frustum==
==Frustum==
:''In 3D computer graphics, the viewing frustum or view frustum is the region of space in the modeled world that may appear on the screen; it is the field of view of the notional camera. The exact shape of this region varies depending on what kind of camera lens is being simulated, but typically it is a frustum of a rectangular pyramid (hence the name). The planes that cut the frustum perpendicular to the viewing direction are called the near plane and the far plane. Objects closer to the camera than the near plane or beyond the far plane are not drawn.'' -- [[wikipedia:Viewing_frustum|"Viewing frustum"]], Wikipedia
:''See [[Graphics#Frustum|Graphics]] for an explanation of frustum.''


;void gs_farclipplane_set(float plane)
;void gs_farclipplane_set(float plane)
:This sets the distance of the far clipping plane in world units. If you call '''gs_farclipplane_set(1000)''', then all polygons whose closest point is more than 83 feet away from the camera will be culled. The default distance of the far clipping distance is 10,000 world units (833 ft).
:This sets the distance of the far clipping plane in world units. If you call '''gs_farclipplane_set(1000)''', then all polygons whose closest point is more than 1,000 world units (83 ft) away from the camera will be culled. The default distance of the far clipping distance is 10,000 world units (833 ft).


;void gs_fov_set(float fov_degrees)
;void gs_fov_set(float fov_degrees)
:(not available on PC demo or Mac) This sets the angle between the top and bottom planes of the frustum. If you call '''gs_fov_set(90)''', then the angle at the camera between the top and bottom of the frustum will be 90°. The default value of that angle is 45°.
:This sets the angle between the top and bottom planes of the frustum. If you call '''gs_fov_set(90)''', then the angle at the camera between the top and bottom of the frustum will be 90°. The default value of that angle is 45°.
:The aspect ratio of the frustum stays constant (defined by the current screen resolution), so the view will get wider as you increase the vertical FOV. For the defaut FOV and on a 4:3 screen, the horizontal viewing angle is 2 * arctan(4/3 * tan(45° / 2)) = 57.8224°
:The aspect ratio of the frustum stays constant (defined by the current screen resolution), so the view will get wider as you increase the vertical FOV. For the default FOV and on a 4:3 screen, the horizontal viewing angle is 2 * arctan(4/3 * tan(45° / 2)) = 57.8224°


;Widescreen FOV
;Notes
:On a 16:9 or 16:10 screen, the horizontal viewing angle is larger: 2 * arctan(16/9 * tan(45° / 2)) = 72.73435° and 2 * arctan(16/10 * tan(45° / 2)) = 67.0682°, respectively. This causes insufficient frustum culling in some of Oni's cutscenes (intro sequences of {{C|2}}, {{C|11}}, and {{C|14}} for example). A quick way to fix this is to bring the horizontal viewing angle down to the supposed 57.8224° during the cutscene: the 4:3 viewport will then effectively be trimmed vertically rather than extended sideways. On 16:9 and 16:10 screens, the corrected vertical FOV will be 2 * arctan(3/4 * tan(45° / 2)) = 34.515877° and 2 * arctan(5/6 * tan(45° / 2)) = 38.0871°, respectively. Remember to set it back to 45° after the cutscene to fully enjoy the extended viewport.
 
;NOTE
:The far clip plane and FOV are only reset when Oni starts, not when you load a level, so mind their default values and the side effect of other scripts.
:The far clip plane and FOV are only reset when Oni starts, not when you load a level, so mind their default values and the side effect of other scripts.
;ALSO NOTE
:There is no control over Oni's ''near'' clipping plane: its distance is always 4 units (16 inches).
:There is no control over Oni's ''near'' clipping plane: its distance is always 4 units (16 inches).


==Distance fog==
==Fog==
:''In mid-to-late 1990s games, when processing power was not enough to render far viewing distances, clipping was employed. However, the effect could be very distracting since bits and pieces of [objects] would flicker in and out of view instantly; by applying a medium-ranged fog, the clipped polygons would fade in more realistically from the haze.'' -- [[wikipedia:Distance_fog|"Distance fog"]], Wikipedia
:''See [[Graphics#Fog|Graphics]] for an explanation of fog.''
:''For more technical information on fog and on frustum-based space (or whatever it's called), see [http://msdn2.microsoft.com/en-us/library/ms537113.aspx here] and [https://msdn.microsoft.com/en-us/library/bb205332%28v=vs.85%29.aspx here] and [https://web.archive.org/web/20130520191527/http://cs.fit.edu/~wds/classes/graphics/PTOC/ptoc/ elsewhere].


===BSL interface===
There are 5 fog-related variables: 3 color components (RGB) and 2 distances in frustum space (see below) between which the fog gradient builds up. All five values are reset to their default values at level load.
There are 5 fog-related variables: 3 color components (RGB) and 2 distances in frustum space (see below) between which the fog gradient builds up. All five values are reset to their default values at level load.


Line 34: Line 27:
:;float gl_fog_start=0.925
:;float gl_fog_start=0.925
:;float gl_fog_end=1.0
:;float gl_fog_end=1.0
Keep in mind that those "distances" are percentages of the frustum length: 1.0 corresponds to the far clipping plane, so 0.925 corresponds to a plane about 17.7 feet from the camera if the far clip plane is at its default 833 feet (see below for conversion formulas).
Keep in mind that those "distances" are percentages of the frustum length: 1.0 corresponds to the far clipping plane, so 0.925 corresponds to a plane about 17.7 feet from the camera if the far clip plane is at its default 833 feet (see [[Graphics#Fog|Graphics]] for conversion formulas).


That the "end" fog plane is at 1.0 means that the fog will completely hide objects only at the far end of the viewing frustum. Objects closer than the "start" fog plane won't be affected by fog at all. In between, there will be a fog gradient.
That the "end" fog plane is at 1.0 means that the fog will completely hide objects only at the far end of the viewing frustum. Objects closer than the "start" fog plane won't be affected by fog at all. In between, there will be a fog gradient.
Line 40: Line 33:
Typically, tweaking the "start" plane is enough to achieve a good-looking distance fog: once set, the fog/haze can be kept the same for the whole level. However, in some situations (e.g., in the dream level), the fog starts closer to the player.
Typically, tweaking the "start" plane is enough to achieve a good-looking distance fog: once set, the fog/haze can be kept the same for the whole level. However, in some situations (e.g., in the dream level), the fog starts closer to the player.


In that case the correct values of gl_fog_start (and gl_fog_end) may be hard to guess, and you may want to have a look at the conversion rules below. You may also want to use smooth transitions rather than set the variables to new values instantly.
In that case the correct values of gl_fog_start (and gl_fog_end) may be hard to guess, and you may want to have a look at the conversion formulas on the Graphics page. You may also want to use smooth transitions rather than set the variables to new values instantly.


The smooth transition functions are:
The smooth transition functions are:
Line 51: Line 44:


Note that you can invert the effect, to obtain short-distance fog rather than the usual long-distance fog. All you have to do is to make gl_fog_end smaller than gl_fog_start (and gl_fog_start small enough so that the player character is visible).
Note that you can invert the effect, to obtain short-distance fog rather than the usual long-distance fog. All you have to do is to make gl_fog_end smaller than gl_fog_start (and gl_fog_start small enough so that the player character is visible).
===Technical background===
The frustum (see above), defines a set of coordinates in which the near plane is at Z = 0 and the far plane at Z = 1 (X = -1 and X = 1 correspond to the left and right side of the frustum; the top and bottom of the frustum are planes with Y = -a and Y = a, with "a" the aspect ratio of the screen).
The important thing for fog is "Z" (the depth coordinate in frustum-based space). Every pixel of every object within the frustum is blended with a color (the fog color), depending on the amount "f" of fog in front of that pixel. The default fog color is 25% gray.
For f < 0, there is no fog in front of the object and the pixel retains its original color. For f > 1 the object is completely fogged and the pixel has the color of the fog. For 0 < f < 1, the color is interpolated linearly between the original pixel color and that of the fog.
The value of "f" is taken to be 0 on the fog's "start" plane and 1 on the fog's "end" plane and is interpolated/extrapolated linearly elsewhere, in the frustum-based coordinates. The natural order is: near clip plane, fog "start" plane, fog "end" plane, far clip plane.
The conversion formulas between "z" (units of distance from the camera) and "Z" (frustum percentage-based depth) are:
:Z = z_f * ( z - z_n ) / [ z * ( z_f - z_n ) ]
:z = z_n * z_f / [ z_f - Z * ( z_f - z_n )]
By default, z_f is 10,000 and z_n is 4, so Z = 0.925 corresponds roughly to z = 53.07.


[[Category:Scripting tasks]]
[[Category:Scripting tasks]]

Revision as of 04:47, 7 December 2015

Frustum

See Graphics for an explanation of frustum.
void gs_farclipplane_set(float plane)
This sets the distance of the far clipping plane in world units. If you call gs_farclipplane_set(1000), then all polygons whose closest point is more than 1,000 world units (83 ft) away from the camera will be culled. The default distance of the far clipping distance is 10,000 world units (833 ft).
void gs_fov_set(float fov_degrees)
This sets the angle between the top and bottom planes of the frustum. If you call gs_fov_set(90), then the angle at the camera between the top and bottom of the frustum will be 90°. The default value of that angle is 45°.
The aspect ratio of the frustum stays constant (defined by the current screen resolution), so the view will get wider as you increase the vertical FOV. For the default FOV and on a 4:3 screen, the horizontal viewing angle is 2 * arctan(4/3 * tan(45° / 2)) = 57.8224°
Notes
The far clip plane and FOV are only reset when Oni starts, not when you load a level, so mind their default values and the side effect of other scripts.
There is no control over Oni's near clipping plane: its distance is always 4 units (16 inches).

Fog

See Graphics for an explanation of fog.

There are 5 fog-related variables: 3 color components (RGB) and 2 distances in frustum space (see below) between which the fog gradient builds up. All five values are reset to their default values at level load.

The color components and their default values are:

float gl_fog_red=0.25
float gl_fog_green=0.25
float gl_fog_blue=0.25

This corresponds to dark gray (25% gray). For nighttime and outdoors environments, the three components are typically set to 0 (black fog), but in daytime or indoors environments the fog/haze color may be brighter (and possibly chosen to roughly match the dominant color of the skybox, which is not affected by fog). In CHAPTER 01 . TRIAL RUN, CHAPTER 02 . ENGINES OF EVIL, CHAPTER 10 . CAT AND MOUSE and CHAPTER 12 . SINS OF THE FATHER, the fog color is 15% gray. In CHAPTER 03 . PUZZLE PIECES, the color red is dominant: (0.3, 0.17, 0.15).

The "start" and "end" distances and their default values are:

float gl_fog_start=0.925
float gl_fog_end=1.0

Keep in mind that those "distances" are percentages of the frustum length: 1.0 corresponds to the far clipping plane, so 0.925 corresponds to a plane about 17.7 feet from the camera if the far clip plane is at its default 833 feet (see Graphics for conversion formulas).

That the "end" fog plane is at 1.0 means that the fog will completely hide objects only at the far end of the viewing frustum. Objects closer than the "start" fog plane won't be affected by fog at all. In between, there will be a fog gradient.

Typically, tweaking the "start" plane is enough to achieve a good-looking distance fog: once set, the fog/haze can be kept the same for the whole level. However, in some situations (e.g., in the dream level), the fog starts closer to the player.

In that case the correct values of gl_fog_start (and gl_fog_end) may be hard to guess, and you may want to have a look at the conversion formulas on the Graphics page. You may also want to use smooth transitions rather than set the variables to new values instantly.

The smooth transition functions are:

void gl_fog_start_changeto(float start_val=0, int frames=0)
If the far clip plane is at 10,000, calling gl_fog_start_changeto(0.88, 60) moves the "start" of the fog gradient to about 11.1 feet in front of the camera, over one second.
Calling gl_fog_start_changeto(0.88) does the same instantly, since the default value of the frames argument is 0.
void gl_fog_end_changeto(float end_val=0, int frames=0)
If the far clip plane is at 10,000, calling gl_fog_end_changeto(0.88001, 60) moves the "end" of the fog gradient to about 11.1 feet in front of the camera, over one second.
Calling gl_fog_end_changeto(0.88) does the same instantly, since the default value of the frames argument is 0.

Note that you can invert the effect, to obtain short-distance fog rather than the usual long-distance fog. All you have to do is to make gl_fog_end smaller than gl_fog_start (and gl_fog_start small enough so that the player character is visible).