SSBump2Normal: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
No edit summary
Line 45: Line 45:
== How To Find Ambient Occlusion ==
== How To Find Ambient Occlusion ==
===== Step 1 =====
===== Step 1 =====
Extract the blue channel of your new Normal map.
Desaturate the SSBump map by average.
===== Step 2 =====
===== Step 2 =====
Multiply that channel by your original SSBump map to make a second SSBump map.
Extract the blue channel of the Normal map.
===== Step 3 =====
===== Step 3 =====
Convert the second SSBump map into a second Normal map.
Subtract the desaturated SSBumb by the extracted blue to get your AO map.
===== Step 4 =====
Extract the second Normal map's blue channel which is your new AO map.


== Other Links ==
== Other Links ==

Revision as of 13:18, 1 July 2025

Project

rob5300's "ssbumpToNormal" github

How It Is Done

The Conversion Matrix in Rust

const OO_SQRT_3: f32 = 0.57735025882720947f32;
static BUMP_BASIS_TRANSPOSE: [Vector3<f32>; 3] = [
    Vector3::new( 0.81649661064147949f32, -0.40824833512306213f32, -0.40824833512306213f32 ),
    Vector3::new(  0.0f32, 0.70710676908493042f32, -0.7071068286895752f32 ),
    Vector3::new(  OO_SQRT_3, OO_SQRT_3, OO_SQRT_3 )
];

Converting each pixel of the SSBump Map

for pixel in pixels {
        //Convert pixel colour to a vector
        let rgb = pixel.2;
        let pixel_vector = Vector3::new(rgb[0] as f32 / 255f32, rgb[1] as f32 / 255f32, rgb[2] as f32 / 255f32);
        //Convert normal vector back to traditional tangent normal
        let new_rgb = new_image.get_pixel_mut(pixel.0, pixel.1);
        new_rgb[0] = convert_vector(&pixel_vector, 0);
        new_rgb[1] = convert_vector(&pixel_vector, 1);
        new_rgb[2] = convert_vector(&pixel_vector, 2);
    }

The math function to convert each pixel

fn convert_vector(pixel: &Vector3<f32>, index: usize) -> u8 {
    return (((pixel.dot(BUMP_BASIS_TRANSPOSE[index]) * 0.5f32) + 0.5f32) * 255f32) as u8;
}


Note.pngNote:Inverting the green channel.
//From
new_rgb[1] = convert_vector(&pixel_vector, 1);
//To
new_rgb[1] = 255u8 - convert_vector(&pixel_vector, 1);

How To Find Ambient Occlusion

Step 1

Desaturate the SSBump map by average.

Step 2

Extract the blue channel of the Normal map.

Step 3

Subtract the desaturated SSBumb by the extracted blue to get your AO map.

Other Links

SSBump Page

NormalMap Page

AmbientOcclusion Page