How to improve my metal effect?

I think if I mix this with a cupemap effect then ill have something pretty good?

Here’s the shader function, it’s a mix from 2 different codes, I thought one was for metal so I played with it until it looked like metal though since then I have learned it was not for metal.
Not too bad for a first attempt? The gold looks good. :slight_smile:
It turns white to silver and yellow to gold.

vec3 CalcMetalPointLight(Light light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 Diffuse, float Specular, float Shadow)
{
    	vec3 lightDir = normalize(light.Position - fragPos);
    // Diffuse shading
    float diff = max(dot(normal, lightDir), 0.0);
     

   // set important material values
    float roughnessValue = 0.1; // 0 : smooth, 1: rough
    float F0 = 0.0; // fresnel reflectance at normal incidence
    float k = 1.0; // fraction of diffuse reflection (specular reflection = 1 - k)
    // do the lighting calculation for each fragment.
    
	float spec = 0.0;
    if(diff > 0.0)
    {
        // calculate intermediary values
        vec3 halfVector = normalize(lightDir + viewDir);
        float NdotH = max(dot(normal, halfVector), 0.0); 
        float NdotV = max(dot(normal, viewDir), 0.0); // note: this could also be diff, which is the same value
        float VdotH = max(dot(viewDir, halfVector), 0.0);
        float mSquared = roughnessValue * roughnessValue;
        
        // geometric attenuation
        float NH2 = 2.0 * NdotH;
        float g1 = (NH2 * NdotV) / VdotH;
        float g2 = (NH2 * diff) / VdotH;
        float geoAtt = min(1.0, min(g1, g2));
     
        // roughness (or: microfacet distribution function)
        // beckmann distribution function
        float r1 = 1.0 / ( 4.0 * mSquared * pow(NdotH, 4.0));
        float r2 = (NdotH * NdotH - 1.0) / (mSquared * NdotH * NdotH);
        float roughness = r1 * exp(r2);
        
        // fresnel
        // Schlick approximation
        float fresnel = pow(1.0 - VdotH, 5.0);
        fresnel *= (1.0 - F0);
        fresnel += F0;
        
		// Specular shading
    vec3 reflectDir = reflect(-lightDir, normal);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 1.0) * (fresnel * geoAtt * roughness) / (NdotV * diff * 3.14);
    }

	// Attenuation
    float distance = length(light.Position - fragPos);
    float attenuation = 1.0f / (1.0 + light.Linear * distance + light.Quadratic * (distance * distance));    
    // Combine results
    vec3 ambient = light.Color * Diffuse;
    vec3 diffuse = light.Color * Diffuse * diff;
    vec3 specular = light.Specular * spec * Specular;
    ambient *= attenuation;
    diffuse *= attenuation;
    specular *= attenuation;
    
    return (ambient + (1.0 - Shadow)) * diff * (k + spec * (1.0 - k)) + 2.0 * (diffuse + specular);
}

The way people are generally doing it is something like this:

With the empirical method:

Have a material that matches metals (with setting ambient, diffuse, specular and shininess)
Use this material in the model
Render the model with Blinn/Phong lighting
Eventually add some extra effects

With some kind of physically accurate rendering, this would look like:

Measure how a metal object reacts to lighting. Store these information into some BRDF/BSDF…
Use these BRDF with a model
Render it threw some accurate lighting models (ie based on Cook Torrance function)

You can have more information for the latter by reading about PBR, global illumation and more generally optical books.

As a basis, notice that metal generally have black diffuse values.