Jump to content

Ambient Occlusion Map


SpiderPig
 Share

Recommended Posts

As per the workflow here I've create a AO_ROUGH_METAL map with AO in the red channel but it appears to not be showing up on the model when rendered.  Looking at the PBR/Fragment.glsl shader it looks like AO is only being loaded from it's own dedicated slot.  Is this intentional or can t be revised to use the red channel of the same texture that metal & roughness are in?

if (material.textureHandle[TEXTURE_AMBIENTOCCLUSION] != uvec2(0))
{
    float ao = texture(sampler2D(material.textureHandle[TEXTURE_AMBIENTOCCLUSION]), texcoords.xy).r;
    f_diffuse *= ao;

    // apply ambient occlusion to all lighting that is not punctual
    f_specular *=ao;
    f_sheen *= ao;
    f_clearcoat *= ao;
}

 

Link to comment
Share on other sites

To test it I did this.

ambient_occulsion is 1.0f by default.

#ifdef MATERIAL_METALLICROUGHNESS

    //--------------------------------------------------------------------------
    // Metallic roughness
    //--------------------------------------------------------------------------

    materialInfo.metallic = material.metalnessRoughness.r;
    materialInfo.perceptualRoughness = material.metalnessRoughness.g;
    
    if (material.textureHandle[TEXTURE_METALLICROUGHNESS] != uvec2(0))
    {
        // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
        // This layout intentionally reserves the 'r' channel for (optional) occlusion map data
        vec4 mrSample = texture(sampler2D(material.textureHandle[TEXTURE_METALLICROUGHNESS]), texcoords.xy);
	ambient_occlusion = mrSample.r;
        materialInfo.metallic *= mrSample.b;
        materialInfo.perceptualRoughness *= mrSample.g;
    }

    materialInfo.perceptualRoughness = clamp(materialInfo.perceptualRoughness, 0.0f, 1.0f);
    materialInfo.metallic = clamp(materialInfo.metallic, 0.0f, 1.0f);    

    // Achromatic f0 based on IOR.
    materialInfo.c_diff = mix(materialInfo.baseColor.rgb,  vec3(0.0f), materialInfo.metallic);
    materialInfo.f0 = mix(materialInfo.f0, materialInfo.baseColor.rgb, materialInfo.metallic);
#endif

I only use it if there is no AO map specified.

if (material.textureHandle[TEXTURE_AMBIENTOCCLUSION] != uvec2(0))
    {
        float ao = texture(sampler2D(material.textureHandle[TEXTURE_AMBIENTOCCLUSION]), texcoords.xy).r;
        f_diffuse *= ao;

        // apply ambient occlusion to all lighting that is not punctual
        f_specular *=ao;
        f_sheen *= ao;
        f_clearcoat *= ao;
    }
	else{
	f_diffuse *= ambient_occlusion;
	f_specular *= ambient_occlusion;
        f_sheen *= ambient_occlusion;
        f_clearcoat *= ambient_occlusion;
	}

 

Link to comment
Share on other sites

AO will only be rendered when the AO map is assigned to the AO texture channel...BUT...

The AO map and the metal-roughness map can be the same texture. So if you assign it in both slots, you have AO.

This is the way glTF does it. I don't think it really requires an extra texture sample in the fragment shader, because of the texture cache.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...