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;
     
    }
  • 相关阅读:
    Leetcode 349. Intersection of Two Arrays
    hdu 1016 Prime Ring Problem
    map 树木品种
    油田合并
    函数学习
    Leetcode 103. Binary Tree Zigzag Level Order Traversal
    Leetcode 102. Binary Tree Level Order Traversal
    Leetcode 101. Symmetric Tree
    poj 2524 Ubiquitous Religions(宗教信仰)
    pat 1009. 说反话 (20)
  • 原文地址:https://www.cnblogs.com/stratrail/p/3277176.html
Copyright © 2011-2022 走看看