我读过的几乎所有的文章和书籍都说,最终颜色的组成是: finalColor = ambientColor + lambertianTerm * diffuseColor (=材料颜色)+ specularIntensity * specularColor (=浅色)
lambertianTerm = dot( surfaceNormal, normalize( lightPos - surfacePos ) );
halfVector = normalize( normalize( lightPos - surfacePos ) + normalize( eyePos - surfacePos );
specularFactor = max( dot( halfVector, surfaceNormal ), 0.0f );
specularIntensity = pow( specularFactor, surfaceShininessLevel );下面是使用上述方法计算最终颜色的一些地方: OpenGL SuperBible第6版->渲染技术、->照明模型、-> Blinn照明、Wikipedia -> Blinn–Phong shading model (see the fragment shader)等。
在计算最终颜色时存在一个问题:光线的颜色(也考虑多个光源的情况)不参与漫射颜色的制定。假设亮度因子是一个很大的数字- 128.0,所以镜面光斑很小,物体的大部分区域都是用漫射项着色的。还要让物体的颜色是绿色的,而光线是红色的。如果没有环境颜色,上述方程的输出是部分照明的纯绿色物体,上面有一个小黄点=绿色+红色=从绿色物体反射的红光光源发出的光:

这不对。当然,绿色+红色是黄色的,但你肯定不会看到纯绿色的球,也不会看到黄色的镜面斑点。手里拿着一个绿色发亮的球--比如台球比赛中的大6球,然后用红灯点亮它--我可以向你保证,你不会只看到绿色的漫射和黄色的镜面。相反,你会看到一个混合绿色+红色的漫射点和更红色的镜面。到目前为止,我找到的计算最终颜色平均混合的最佳方法是:
finalColor = ambient
+ lambertianTerm * ( surfaceColor + lightColor ) / 2.0
+ specularIntensity * lightColor;

尝试覆盖混合:
const vec4 srgbLuminanceFactor = vec4( 0.2125f, 0.7154f, 0.0721f, 1.0f );
vec4 overlay( vec4 baseColor, vec4 blendColor )
{
float luminance = dot( baseColor, srgbLuminanceFactor );
vec4 lowerLumOverlay = 2.0f * blendColor * baseColor;
if ( luminance < 0.45f )
{
return lowerLumOverlay;
}
const vec4 whiteColor = vec4( 1.0 );
vec4 higherLumOverlay = whiteColor - 2.0f * ( whiteColor - blendColor ) * ( whiteColor - baseColor );
return luminance > 0.55f
? higherLumOverlay
: mix( lowerLumOverlay, higherLumOverlay, ( luminance - 0.45f ) * 10.0f );
}..。但看起来不太好。也许光和物体的颜色应该以另一个线性比例混合:
mix( surfaceColor, lightColor, ratio );..。或者以一种我无法想象的非线性方式。
因此,最后一个问题:什么是最佳的计算完整的颜色?此外,告诉我,如果我错过了什么,但在我看来,纯粹的绿色图片+纯黄色镜面亮点是完全不是一个真实的世界场景。
发布于 2015-11-09 01:42:11
表面颜色的意思是“什么光的颜色可以从这个表面扩散”。
镜面颜色的意思是“什么光的颜色可以反射从这个表面”。
浅色的意思是“什么光的颜色到达表面”。
所以你必须把它们相乘:
finalColor = ambient
+ lambertianTerm * surfaceColor * lightColor
+ specularIntensity * specularColor * lightColor;https://stackoverflow.com/questions/33600223
复制相似问题