OpenGL ES2.0光照

一、简单光照原理

平行光(正常光)

  光照效果=   环境颜色 + 漫反射颜色 + 镜面反射颜色

点光源

  光照效果=   环境颜色 + (漫反射颜色 + 镜面反射颜色)× 衰减因子

聚光灯

  光照效果=   环境颜色 + (漫反射颜色 + 镜面反射颜色)× 衰减因子 × 聚光灯效果

二、IOS光照

1、导入系统库

  • GLKit
  • OpenGLES
  • CoreGraphics
  • QuartzCore

2、光照类

#import <GLKit/GLKit.h>  
//基础光
@interface BaseLight : NSObject{ 
@public    GLKVector4 Color;
    float AmbientIntensity;//周围无光照的区域亮度
    float DiffuseIntensity;//漫反射
    float SpecularIntensity;//镜面反射
} 
@end
//点光源
@interface PointLight : BaseLight{ 
@public  GLKVector3 DestPos;
    GLKVector3 SourcePos;//光照源位置
    float Shininess;
    struct
    {
        float Constant;
        float Linear;
        float Exp;
    } Attenuation;
}  
@end
//聚光灯
@interface SpotLight : PointLight{
@public    GLKVector3 Direction;
    float Cutoff;//最小夹角cos值
    float Exponent;//聚光灯角度
}
@end

3、实现光源属性槽位获取及更新

@interface BaseLight : NSObject{ 
@public    GLKVector4 Color;
    float AmbientIntensity;//周围无光照的区域亮度
    float DiffuseIntensity;//漫反射
    float SpecularIntensity;//镜面反射
} 
@end
@interface PointLight : BaseLight{ 
@public  GLKVector3 DestPos;
    GLKVector3 SourcePos;//光照源位置
    float Shininess;
    struct
    {
        float Constant;
        float Linear;
        float Exp;
    } Attenuation;
}  
@end

@interface SpotLight : PointLight{
@public    GLKVector3 Direction;
    float Cutoff;//最小夹角cos值
    float Exponent;//聚光灯角度
}
@end

 

在实际项目中调用,初始化,设置,然后更新。。。。

4、GLSL实现

//基础光
struct BaseLight
{
    vec4 Color;
    float AmbientIntensity;
    float DiffuseIntensity;
    float SpecularIntensity;
};
//点光源
struct PointLight{
    BaseLight Base;
    
    vec3 SourcePos;
    vec3 DestPos;
    float Shininess; //亮度
    struct
    {
        float Constant;
        float Linear;
        float Exp;
    } Attenuation;
};
//聚光灯
struct SpotLight{
    PointLight Base;
    vec3 Direction;
    float Cutoff;
    float Exponent;
};

vec3 vPos;
vec3 vEyePos;

uniform SpotLight u_spotLight; 

//基础光计算
vec4 CalcLightInternal(BaseLight Light, vec3 LightDirection, vec3 Normal)
{ 
    float DiffuseFactor = dot(Normal, LightDirection);
    vec4 DiffuseColor = vec4(0, 0, 0, 0);
    vec4 SpecularColor = vec4(0, 0, 0, 0);
    if (DiffuseFactor > 0.0) {
        DiffuseColor = Light.Color * Light.DiffuseIntensity * DiffuseFactor;
        vec3 VertexToEye = normalize(vEyePos - vPos);
        vec3 LightReflect = normalize(reflect(LightDirection, Normal));
        vec3 H = normalize(LightDirection + VertexToEye);
        float SpecularFactor = max(0.0, dot(Normal, H)); 
        SpecularFactor = pow(SpecularFactor, 10.0);
        if (SpecularFactor > 0.0) {
            SpecularColor = Light.Color *
            Light.SpecularIntensity * SpecularFactor;
        }
    }
    return DiffuseColor + SpecularColor; 
}

//pointlight 点光源计算
vec4 CalcPointLight(PointLight l,vec3 Normal)
{ 
    vec3 LightDirection = normalize(l.SourcePos-l.DestPos);
    float Distance =length(vPos - l.DestPos);
    vec4 Color = CalcLightInternal(l.Base, LightDirection, Normal);
    //衰减因子
    float Attenuation = l.Attenuation.Constant +l.Attenuation.Linear * Distance  +
     l.Attenuation.Exp* Distance * Distance;
    Color=Color*l.Shininess/Attenuation;  
    return Color;
} 
//spotlight实现
vec4 CalcSpotLight(SpotLight l, vec3 Normal)
{
    vec3 LightToPixel = normalize(vPos - l.Base.DestPos);
    vec3 LightDirection = normalize(LightToPixel-l.Direction); 
    //聚光灯因子
    float SpotFactor =pow(max(0.0, dot(LightToPixel, LightDirection)),l.Exponent);
    if (SpotFactor > l.Cutoff) {
        vec4 Color = CalcPointLight(l.Base, Normal);
        return Color * clamp((1.0 - (1.0 - SpotFactor) * 1.0/(1.0 - l.Cutoff)),0.0,1.0);
    }
    else {
        return vec4(0.0,0.0,0.0,0.0);
    }
}

void main()
{ 
  lowp vec4 topColor = texture2D(Texture, TexCoordOut);  
     
  vec3 vNormal=vec3(0, 0, 1);
  vec3 N = normalMatrix * vNormal;
  vPos=vec3(TexCoordOut,0.0) ; //取光照点
  vEyePos=vec3(0.0,0.0,1.0);//观察点
  vec4 AmbientColor = u_spotLight.Base.Base.Color * u_spotLight.Base.Base.AmbientIntensity;
   
  lowp vec4  lightColor =CalcSpotLight(u_spotLight,N)+CalcSpotLight(u_spotLight1,N)+AmbientColor; 
        gl_FragColor =lightColor* topColor;
 
}

 

posted @ 2013-08-23 11:39  稀饭lei___  阅读(996)  评论(0编辑  收藏  举报