镜面高光

效果如图19。

图19

图19

计算高光我们用逐片元计算,顶点shader不用修改,在片元shader中计算镜面高光。

<script id = "per-fragment-lighting-fs" type = "x-shader/x-fragment">
    //...
    uniform float uMaterialShininess;
    uniform bool uShowSpecularHighlights;

    uniform vec3 uPointLightingLocation;
    uniform vec3 uPointLightingSpecularColor;
    uniform vec3 uPointLightingDiffuseColor;

    uniform sampler2D uSampler;

    void main(void)
    {
        vec3 lightWeighting;
        if (!uUseLighting)
        {
            lightWeighting = vec3(1.0, 1.0, 1.0);
        }
        else
        {
            vec3 lightDirection =
                normalize(uPointLightingLocation - vPosition.xyz);
            vec3 normal = normalize(vTransformedNormal);

            float specularLightWeighting = 0.0;

            if(uShowSpecularHighlights)
            {

这里我们保留了在片元shader前已插值的法向量并归一化,作为中间变量。

高光开关如果是关闭的话增益为0 。

计算镜面反射亮度的方程为:

(Rm * V)α

Rm是光线在该点镜面反射后的归一化方向向量,V是眼(相机)到该点的归一化方向向量,α描述光洁度,α越大则越光亮,相当于材质的反光特征。

                vec3 eyeDirection = normalize(-vPosition.xyz);

我们的相机一直在原点,所以这个向量很好算。

                vec3 reflectionDirection = reflect(-lightDirection, normal);

GLSL提供了计算反射向量的函数reflect,lightDirection加负号是因为为了方便计算漫反射颜色,我们前面计算的lightDirection变量方向和光线是相反的。

                specularLightWeighting =
                    pow(max(dot(reflectionDirection, eyeDirection), 0.0),
                    uMaterialShininess);
            }

用公式计算镜面反射增益。

            float diffuseLightWeighting = max(dot(normal, lightDirection), 0.0);
            lightWeighting = uAmbientColor +
                uPointLightingSpecularColor * specularLightWeighting +
                uPointLightingDiffuseColor * diffuseLightWeighting;
        }

        ////vec4 fragmentColor;
        //...
        gl_FragColor = vec4(fragmentColor.rgb * lightWeighting, fragmentColor.a);
    }
</script>

最后计算总颜色增益还是把它们加起来。

前面我们加载过json数据,这一节一样方式加载茶壶的数据,具体参考完整代码。

results matching ""

    No results matching ""