Luctaris / blender-import-glr

Addon which adds glr import support to Blender, the free 3D modelling suite.
12 stars 2 forks source link

Import fog #9

Closed scurest closed 1 month ago

scurest commented 7 months ago

Bumps the GLR version to 3 and imports fog.
Requires #8 as groundwork.
Companion PR in GLideN64-SceneRipper is https://github.com/Luctaris/GLideN64-SceneRipper/pull/3.

How fog works on an N64

Fogging is performed by a cooperation between the RSP (geometry processor) and the RDP (fragment processor). The RDP receives the fog level, a value between 0 (no fog) and 1 (full fog), from the RSP in the alpha channel of the vertex color. To use fog, the RDP's blender is configured to lerp between the fragment color and the fog color using the fog level.

(1 - FogLevel) FragColor + FogLevel FogColor

The fog color is a register on the RDP giving the color at maximum fog level. It is already imported in main as a color attribute named "Fog". Note that it does vary face-to-face, it is not scene-constant. A good example of this is Jolly Roger Bay; the above-water and below-water portions of the level have different fog colors.

Calculation of the fog level is enabled on the RSP by a flag in the geometry mode register. The fog level is calculated for planes in the viewing frustum parallel to the screen based on the distance between the clipping planes and the fog position, the points where the fog starts and stops.

Since this graph is just y=clamp(ax+b), calculation is usually done in terms of a=FogScale and b=FogOffset instead of the fog position directly.

I am not entirely sure if the fog level is calculated at the vertex or fragment level. I currently think it is calculated at the vertex level on a real N64, but GLideN64 can calculate it at the fragment level as an enhancement.

How fog works in the importer

The fogging formula is easily implemented in the material shader with a Mix node, so the only question is how to import the fog level.

In this PR it is simply baked into a float-type, vertex-domain attribute named "FogLevel".

We could instead just use the vertex color alpha, but (in addition to better readability) a separate attribute has the advantage it can simply be deleted to remove the fog effect, because a missing attribute has everywhere the default value 0 (no fog).

An import option (default on) controls whether fog import is enabled. When fog is disabled, we just skip creating the FogLevel attribute. No change in the shader graph is needed depending on whether fog is enabled or not.

This is a static fog method, meaning the fog does not change as you move around the scene in Blender, but stays where it was when you ripped the scene. The fog level also only increases along the camera axis, instead of radially in all directions like you might expect. There is no fog behind or to the sides of the camera. This is accurate to how it "really works" on the N64.

Example: (The right image is a visualization of the fog level, where 0=blue, 1=red)