Xcode+Opengl学习(11)ADS光照模型

光照模型
ADS代表环境光(Ambient)、漫射光(Diffuse)、镜面光(Specular)。

环境光
环境光所照射的物体在所有方向的表面都是均匀照亮的,我们可以把环境光看成应用到每个光源的全局照明因子。

    vVaryingColor += ambientColor;

漫射光
关于漫射光的算法,上篇叙述很详细了,此处不多赘述。

    vec3 vEyeNormal = normalMatrix * vNormal;

    vec4 vPosition4 = mvMatrix * vVertex;
    vec3 vPosition3 = vPosition4.xyz / vPosition4.w;

    vec3 vLightDir = normalize(vLightPosition - vPosition3);

    float diff = max(0.0, dot(vEyeNormal, vLightDir));

    vVaryingColor = diff * diffuseColor;

镜面光
镜面光的反射角度很锐利,只沿一个特定的方向反射,高强度的镜面光趋向于在它所照射的表面形成一个亮点,成为镜面亮点。
计算方法:把反射的表面法线向量和反向的光线向量点乘,然后取反光度(shininess)次幂,反光度数值越大,结果得到镜面反射的高亮区越小,最高的镜面指数(specular power)被设置为128,大于这个数字的值效果会逐渐减弱。

    vec3 vReflection = normalize(reflect(-vLightDir, vEyeNormal));
    float spec = max(0.0, dot(vEyeNormal, vReflection));
    if(diff != 0.0f) {
        float fSpec = pow(spec, 128.0);
        vVaryingColor.rgb += vec3(fSpec, fSpec, fSpec);
	}
	

main.cpp

#include<GLTools.h>
#include<GLFrame.h>
#include<GLFrustum.h>
#include<GLMatrixStack.h>
#include<StopWatch.h>
#include<GLGeometryTransform.h>
#include<math.h>
#include<GLUT/GLUT.h>

GLFrame viewFrame;
GLFrustum  viewFrustum;
GLGeometryTransform transformPipeline;
GLMatrixStack modelViewMatrix;
GLMatrixStack projectionMatrix;
GLTriangleBatch sphereBatch;

GLuint ADSLightShader;
GLint locAmbient;
GLint locDiffuse;
GLint locSpecular;
GLint locLight;
GLint locMVP;
GLint locMV;
GLint locNM;

void SetupRC(void)
{
    glClearColor(1.0f,1.0f,1.0f,1.0f);
    
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    
    viewFrame.MoveForward(4.0f);
    
    gltMakeSphere(sphereBatch,1.0f,26,13);
    
    ADSLightShader=gltLoadShaderPairWithAttributes("/Users/mac/Downloads/1/ADSGouraud.vp","/Users/mac/Downloads/1/ADSGouraud.fp",2,GLT_ATTRIBUTE_VERTEX,"vVertex",GLT_ATTRIBUTE_NORMAL,"vNormal");
    
    locAmbient = glGetUniformLocation(ADSLightShader, "ambientColor");
    locDiffuse = glGetUniformLocation(ADSLightShader, "diffuseColor");
    locSpecular = glGetUniformLocation(ADSLightShader, "specularColor");
    locLight = glGetUniformLocation(ADSLightShader, "vLightPosition");
    locMVP = glGetUniformLocation(ADSLightShader, "mvpMatrix");
    locMV  = glGetUniformLocation(ADSLightShader, "mvMatrix");
    locNM  = glGetUniformLocation(ADSLightShader, "normalMatrix");
}

void ShutdownRC()
{
    
}

void RenderScene(void)
{
    static CStopWatch rotTimer;
    
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    
    modelViewMatrix.PushMatrix(viewFrame);
    modelViewMatrix.Rotate(rotTimer.GetElapsedSeconds()*5.0f,0.0f,1.0f,0.0f);
    GLfloat vEyeLight[]={-100.0f,100.0f,100.0f};
    GLfloat vAmbientColor[]={0.1f,0.1,0.1f,1.0f};
    GLfloat vDiffuseColor[] = { 0.0f, 0.0f, 1.0f, 1.0f };
    GLfloat vSpecularColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    
    glUseProgram(ADSLightShader);
    glUniform4fv(locAmbient, 1, vAmbientColor);
    glUniform4fv(locDiffuse, 1, vDiffuseColor);
    glUniform4fv(locSpecular, 1, vSpecularColor);
    glUniform3fv(locLight, 1, vEyeLight);
    glUniformMatrix4fv(locMVP, 1, GL_FALSE, transformPipeline.GetModelViewProjectionMatrix());
    glUniformMatrix4fv(locMV, 1, GL_FALSE, transformPipeline.GetModelViewMatrix());
    glUniformMatrix3fv(locNM, 1, GL_FALSE, transformPipeline.GetNormalMatrix());
    
    sphereBatch.Draw();
    
    modelViewMatrix.PopMatrix();
    
    glutSwapBuffers();
    glutPostRedisplay();
}

void ChangeSize(int w,int h)
{
    glViewport(0,0,w,h);
    
    viewFrustum.SetPerspective(35.0f,float(w)/float(h),1.0f,100.0f);
    
    projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
    transformPipeline.SetMatrixStacks(modelViewMatrix,projectionMatrix);
}

int main(int argc, char* argv[])
{
    gltSetWorkingDirectory(argv[0]);
    
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
    glutInitWindowSize(800, 600);
    glutCreateWindow("ADS Lighting, Gouraud Shading");
    glutReshapeFunc(ChangeSize);
    glutDisplayFunc(RenderScene);
    
    GLenum err = glewInit();
    if (GLEW_OK != err) {
        fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
        return 1;
    }
    
    SetupRC();
    glutMainLoop();
    ShutdownRC();
    return 0;
}




.vp

#version 120

// Incoming per vertex... position and normal
attribute vec4 vVertex;
attribute vec3 vNormal;

// Set per batch
uniform vec4    ambientColor;
uniform vec4    diffuseColor;	
uniform vec4    specularColor;

uniform vec3	vLightPosition;
uniform mat4	mvpMatrix;
uniform mat4	mvMatrix;
uniform mat3	normalMatrix;

// Color to fragment program
varying vec4 vVaryingColor;

void main(void) 
    { 
    // Get surface normal in eye coordinates
    vec3 vEyeNormal = normalMatrix * vNormal;

    // Get vertex position in eye coordinates
    vec4 vPosition4 = mvMatrix * vVertex;
    vec3 vPosition3 = vPosition4.xyz / vPosition4.w;

    // Get vector to light source
    vec3 vLightDir = normalize(vLightPosition - vPosition3);

    // Dot product gives us diffuse intensity
    float diff = max(0.0, dot(vEyeNormal, vLightDir));

    // Multiply intensity by diffuse color, force alpha to 1.0
    vVaryingColor = diff * diffuseColor;

    // Add in ambient light
    vVaryingColor += ambientColor;


    // Specular Light
    vec3 vReflection = normalize(reflect(-vLightDir, vEyeNormal));
    float spec = max(0.0, dot(vEyeNormal, vReflection));
    if(diff != 0.0f) {
        float fSpec = pow(spec, 128.0);
        vVaryingColor.rgb += vec3(fSpec, fSpec, fSpec);
	}


    // Don't forget to transform the geometry!
    gl_Position = mvpMatrix * vVertex;
    }

.fp

#version 120

varying vec4 vVaryingColor;

void main(void)
   { 
   gl_FragColor = vVaryingColor;
   }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值