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;
   }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章