  
   gl_FragColor = vec4(color, 1.0);
   //gl_FragColor = vec4(n * 0.5 + 0.5, 1.0);
-  //gl_FragColor = vec4(VdotH, VdotH, VdotH, 1.0);
+  //gl_FragColor = vec4(NdotV, NdotV, NdotV, 1.0);
   //gl_FragColor = vec4(v_UV.rg, 0.0, 1.0);
 }

  return (1. / max((1. + v + l ),0.000001));
}

// spectre G
float SmithVisibilityG1_TrowbridgeReitzGGX(float NdotV, float alphaG){
	float tanSquared = (1.0 - NdotV * NdotV) / max((NdotV * NdotV),0.00001);

	return 2.0 / (1.0 + sqrt(1.0 + alphaG * alphaG * tanSquared));
}

float SmithVisibilityG_TrowbridgeReitzGGX_Walter(PBRInfo pbrInputs){
	return SmithVisibilityG1_TrowbridgeReitzGGX(pbrInputs.NdotL, pbrInputs.roughness) * SmithVisibilityG1_TrowbridgeReitzGGX(pbrInputs.NdotV, pbrInputs.roughness);
}

// D
float GGX(PBRInfo pbrInputs)
{
  float roughnessSq = pbrInputs.roughness*pbrInputs.roughness;
  float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;
  return roughnessSq / (M_PI * f * f);
}

// spectre D
float NormalDistributionFunction_TrowbridgeReitzGGX(PBRInfo pbrInputs){
  float a = pbrInputs.roughness;
	float a2 = a * a;
	float d = pbrInputs.NdotH * pbrInputs.NdotH * (a2 - 1.0) + 1.0;

	return a2 / (M_PI * d * d);
}





  vec3 F = fresnelSchlick2(pbrInputs);
  //vec3 F = fresnelSchlick(pbrInputs);
  //float G = microfacetCookTorrance(pbrInputs);
  //float G = microfacetSmith(pbrInputs);
  //float G = microfacetSchlick(pbrInputs);
  float G = SmithVisibilityGGX(pbrInputs);
  float D = GGX(pbrInputs);

  vec3 specContrib = M_PI * u_LightColor * F * G * D / 4.0*NdotL*NdotV;

