OpenGL ADSPhong着色

在上一节ADSGouraud着色模式下,我们看到当小球旋转时,亮光的部分时隐时现的,这是由于三角形之间的不连续造成的。

我们可以用ADSPhong着色模式来解决这种问题,在ADSGouraud着色模式下,顶点着色器传入片段着色器的是每个顶点的颜色值,顶点之间的颜色是通过线性插值计算出来的,这样在小球旋转的情况先就可能产生亮光的部分时隐时现的的情况 ,ADSPhong着色模式中顶点着色器传入到片段着色器的是顶点表面法线和光源向量,顶点之间的颜色值通过表面法线的插值计算出来,这样就会减弱闪烁的情况。


下面是顶点着色器ADSPhong.vp的全部代码

//需要的OpenGL的最低版本
#version 130


//需要外界传入的参数
//顶点
in vec4 vVertex;
//顶点法线
in vec3 vNormal;

//模型视图变换矩阵
uniform mat4   mvpMatrix;
//视图变换矩阵
uniform mat4   mvMatrix;
//模型视图变换矩阵法线矩阵
uniform mat3   normalMatrix;
//光源的位置
uniform vec3   vLightPosition;


// 表面法线
smooth out vec3 vVaryingNormal;
//光源向量
smooth out vec3 vVaryingLightDir;


void main(void) 
    { 
		// 获取表面法线在照相机坐标系下的值
		vVaryingNormal = normalMatrix * vNormal;


		//获取顶点在照相机坐标系下的值
		vec4 vPosition4 = mvMatrix * vVertex;
		vec3 vPosition3 = vPosition4.xyz / vPosition4.w;


		// 获取光源的向量
		vVaryingLightDir = normalize(vLightPosition - vPosition3);


		// 把顶点变换到照相机坐标系下
		gl_Position = mvpMatrix * vVertex;
    }



下面是片段着色器ADSPhong.fp的全部代码


//需要的OpenGL的最低版本
#version 130

//传出带光栅化阶段的颜色值
out vec4 vFragColor;
//环境光颜色值
uniform vec4    ambientColor;
//漫反射光颜色值
uniform vec4    diffuseColor;   
//镜面光颜色值
uniform vec4    specularColor;

//从顶点着色器传入的值
//表面法线
smooth in vec3 vVaryingNormal;
//光源向量
smooth in vec3 vVaryingLightDir;




void main(void)
    { 
    // 得到漫反射强度
    float diff = max(0.0, dot(normalize(vVaryingNormal), normalize(vVaryingLightDir)));

    // 漫反射颜色*漫反射强度
    vFragColor = diff * diffuseColor;

    // 加上环境光
    vFragColor += ambientColor;


    // 计算镜面光
    vec3 vReflection = normalize(reflect(-normalize(vVaryingLightDir), normalize(vVaryingNormal)));
    float spec = max(0.0, dot(normalize(vVaryingNormal), vReflection));
    if(diff != 0) {
        float fSpec = pow(spec, 128.0);
        vFragColor.rgb += vec3(fSpec, fSpec, fSpec);
        }
    }

代码实现部分只需要把初始化函数SetupRC中的

ADSLightShader = shaderManager.LoadShaderPairWithAttributes("ADSGouraud.vp", "ADSGouraud.fp", 2, GLT_ATTRIBUTE_VERTEX, "vVertex",
				GLT_ATTRIBUTE_NORMAL, "vNormal");

换成

ADSLightShader = shaderManager.LoadShaderPairWithAttributes("ADSPhong.vp", "ADSPhong.fp", 2, GLT_ATTRIBUTE_VERTEX, "vVertex",
			GLT_ATTRIBUTE_NORMAL, "vNormal");

即可





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值