zoukankan      html  css  js  c++  java
  • 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;
     
    }
  • 相关阅读:
    ios framework 使用图片资源
    XCode 6.4 Alcatraz 安装的插件不可用
    prefix pch 中引用cocoapods 中的头文件失败
    Xcode 6添加模板无效
    获取当前日期是星期几
    玩转iOS开发:《使用系统自带的UIActivityViewController和UIActivity进行内容分享》
    玩转iOS开发:《iOS设计模式 — 代理模式》
    玩转iOS开发:《iOS设计模式 — 单例模式》
    iOS开发技巧-Swift版本: 3.Storyboard传参小技巧
    UIKit应用
  • 原文地址:https://www.cnblogs.com/stratrail/p/3277176.html
Copyright © 2011-2022 走看看