概述及目录(版权所有,请勿转载 http://www.cnblogs.com/feng-sc)

  本文在上一篇(OpenGL ES 光照模型之——环境光照(RenderMonkey测试))环境光基础上,增加漫反射光照。我们主要使用漫反射光模拟太阳光,实现如下两种效果:

    1、地球自传,太阳光固定的日出效果;

    2、地球静止,太阳光围绕地球旋转的效果。

  本文主要包括如下方面内容:

    1、漫反射光模型简介;

    2、地球自转日出效果Shader实现;

    3、地球静止,太阳光围绕地球旋转Shader实现。

漫反射光照模型简介

  漫反射光的定义网上有各种说法,在此就不描述了,下面通过两个图形来表示:

  

 (平行光)

(“散”射光)

  如上两个图中,有人把第一个图的平行光当做漫反射光,也有人把第二个图的模型当做慢反射光。是的,如果第二个图中光远点T无限远,那么两个光照模型的效果其实是一样的,但模型2更像是没有衰减系数的点光源。

  模型公式如下:

     

  其中:

     IDifuse为漫反射光照强度;

     Id为光源颜色;

     Kd可以理解为漫反射光照输入强度;

     cosθ为光线与发现的夹角;

  我们下面通过介绍的是使用第一种模型实现的效果。

地球自转日出效果Shader实现

  本段内容我们先来看下利用RenderMonkey实现的OpenGL ES Shader日出模型的最终效果图,如下图所示:

(日出模型效果图)

  OK,我们现在来具体看看如何使用RenderMonkey实现如上的效果。

  我们在上一篇(OpenGL ES 光照模型之——环境光照(RenderMonkey测试))的基础上,在RenderMonkey工程中加入三个变量:gDiffStrength、time和angles。具体操作如下:

  

  其中:

  gDiffStrength为模型公式中的Kd,是一个float类型的数据;

  time和angles均为RenderMonkey与设置的float类型数据,且数据会在每一帧中会随时间从0至2π变化。

  GPU的Vertex Shader代码实现如下:

//漫反射光照模型vertex shader示例代码 1.0 http://www.cnblogs.com/feng-sc/
uniform mat4 matViewProjection;
attribute vec4 rm_Vertex;
attribute vec2 rm_TexCoord0;
attribute vec3 rm_Normal; //法线输入
varying vec2 rm_Texcoord;
varying vec3 fNormal;
uniform float angles; mat4 rotate(mat4 matrix, float a,vec3 v ) //矩阵旋转函数shader实现
{
float c = cos(a);
float s = sin(a);
vec3 axis = normalize(v);
vec3 temp = (1.0 - c) * axis;
matrix[][] = c + temp[] * axis[];
matrix[][] = temp[] * axis[] + s * axis[];
matrix[][] = temp[] * axis[] - s * axis[];
matrix[][] = 0.0; matrix[][] = temp[] * axis[] - s * axis[];
matrix[][] = c + temp[] * axis[];
matrix[][] = temp[] * axis[] + s * axis[];
matrix[][] = 0.0; matrix[][] = temp[] * axis[] + s * axis[];
matrix[][] = temp[] * axis[] - s * axis[];
matrix[][] = c + temp[] * axis[];
matrix[][] = 0.0; matrix[][] = 0.0;
matrix[][] = 0.0;
matrix[][] = 0.0;
matrix[][] = 1.0;
return matrix;
}
void main( void )
{
mat4 maxtrixWorld = mat4(1.0);
maxtrixWorld = rotate(maxtrixWorld,angles * 10.0 ,vec3(0.0,1.0,0.0)); //定义模型矩阵,并使其围绕y轴旋转
gl_Position = (matViewProjection * maxtrixWorld * rm_Vertex);
rm_Texcoord = rm_TexCoord0.xy;
fNormal = (maxtrixWorld * vec4(rm_Normal,1.0)).xyz; //法线输出,必须与定点一样,经过模型矩阵变化
}

  GPU的Fragment Shader实现代码如下:

//漫反射光照模型fragment shader示例代码 1.0 http://www.cnblogs.com/feng-sc/
#ifdef GL_FRAGMENT_PRECISION_HIGH
// Default precision
precision highp float;
#else
precision mediump float;
#endif
uniform sampler2D baseMap;
uniform vec4 gAnbientColor;
uniform float gAmbientStrength;
uniform float gDiffStrength;
uniform float time;
varying vec2 rm_Texcoord;
varying vec3 fNormal; vec4 AmbientColor() //计算环境光
{
return gAnbientColor * gAmbientStrength;
} vec4 DiffuseColor() //计算漫反射光
{
//float diffFactor = max(dot(normalize(fNormal),normalize(vec3(sin(time * 10.0),0.0,cos(time * 10.0))) - vec3(0,0,0)),0.0);
float diffFactor = max(dot(normalize(fNormal),vec3(0.0,0.0,1.0)),0.0); //定义光照方向为vec3(0.0,0.0,1.0),与法线求点积
return gAnbientColor * diffFactor * gDiffStrength;
} void main( void )
{
vec4 color = texture2D(baseMap,rm_Texcoord);
vec4 ambientcolor = AmbientColor();
vec4 diffusecolor = DiffuseColor();
gl_FragColor = color * (ambientcolor + diffusecolor); //最后输出颜色为环境光颜色和漫反射光颜色相加,在与文理颜色做乘法混合 }

  编译如上两段shader代码后,RenderMonkey场景中最终可以得到我们刚开始是的显示效果图。

地球静止,太阳光围绕地球旋转Shader实现

  同样,本段内容我们先来看下利用RenderMonkey实现的OpenGL ES Shader太阳围绕地球旋转的效果图:

(太阳围绕地球旋转的效果图)

  GPU的Vertex Shader实现代码如下,与上一段落 (地球自转日出效果Shader实现)的Vertex Shader区别在于屏蔽掉了如下第8行地球自转的代码:

 //漫反射光照模型,太阳围绕地球转 vertex shader示例代码 1.0 http://www.cnblogs.com/feng-sc/
……
……
……
void main( void )
{
mat4 maxtrixWorld = mat4(1.0);
// maxtrixWorld = rotate(maxtrixWorld,angles * 10.0 ,vec3(0.0,1.0,0.0)); //定义模型矩阵,并使其围绕y轴旋转
gl_Position = (matViewProjection * maxtrixWorld * rm_Vertex);
rm_Texcoord = rm_TexCoord0.xy;
fNormal = (maxtrixWorld * vec4(rm_Normal,1.0)).xyz; //法线输出,必须与定点一样,经过模型矩阵变化
}

  GPU的Fragment Shader实现代码如下,与上一段落 (地球自转日出效果Shader实现)的Fragment Shader区别在于屏蔽掉了如下第8行漫反射光照代码,而增加第7行。

  第7行中的vec3(sin(time * 10.0),0.0,cos(time * 10.0)),根据time计算光源方向,time的变化范围为0至2π,因此,让光源方向围绕xz平面旋转,得:

  x = sin(time)

  y = 0

  z = cos(time)

  注:代码中的time*10中10没有特别意义,只是让光源方向移动得更快。

 //漫反射光照模型,太阳围绕地球转 fragment shader示例代码 1.0 http://www.cnblogs.com/feng-sc/
……
……
……
vec4 DiffuseColor() //计算漫反射光
{
float diffFactor = max(dot(normalize(fNormal),normalize(vec3(sin(time * 10.0),0.0,cos(time * 10.0))) - vec3(,,)),0.0);
//float diffFactor = max(dot(normalize(fNormal),vec3(0.0,0.0,1.0)),0.0); //定义光照方向为vec3(0.0,0.0,1.0),与法线求点积
return gAnbientColor * diffFactor * gDiffStrength;
} ……
……
…… 

OpenGL ES 光照模型之——漫反射光(RenderMonkey测试,地球日出效果)的更多相关文章

  1. OpenGL ES 光照模型之——环境光照(RenderMonkey测试)

    概述及目录(版权所有,请勿转载 www.cnblogs.com/feng-sc/) 本文总结如何在RenderMonkey下做简单的OpenGL ES环境光光照模型测试. 主要包括如下内容: 1.使用 ...

  2. iOS实现图形编程可以使用三种API(UIKIT、Core Graphics、OpenGL ES及GLKit)

    这些api包含的绘制操作都在一个图形环境中进行绘制.一个图形环境包含绘制参数和所有的绘制需要的设备特定信息,包括屏幕图形环境.offscreen 位图环境和PDF图形环境,用来在屏幕表面.一个位图或一 ...

  3. OpenGL ES crash notes 01 - Nice to meet you

    这篇笔记完全参照<OpenGL.ES.3.0.Programming.Guide.2nd.Edition>,摘出部分内容只为学习参考. 为什么要用英文:无论是D3D的SDK还是OES的Sp ...

  4. 在 OpenGL ES 2.0 上实现视差贴图(Parallax Mapping)

    在 OpenGL ES 2.0 上实现视差贴图(Parallax Mapping) 视差贴图 最近一直在研究如何在我的 iPad 2(只支持 OpenGL ES 2.0, 不支持 3.0) 上实现 视 ...

  5. Android OpenGL ES 开发教程 从入门到精通

    感谢,摘自:http://blog.csdn.net/mapdigit/article/details/7526556 Android OpenGL ES 简明开发教程 Android OpenGL ...

  6. OpenGL ES应用开发实践指南:iOS卷

    <OpenGL ES应用开发实践指南:iOS卷> 基本信息 原书名:Learning OpenGL ES for iOS:A Hands-On Guide to Modern 3D Gra ...

  7. OpenGL ES 3.0 基础知识

    首先要了解OpenGL的图形管线有哪些内容,再分别去了解其中的相关的关系: 管线分别包括了顶点缓冲区/数组对象,定点着色器,纹理,片段着色器,变换反馈,图元装配,光栅化,逐片段操作,帧缓冲区.其中顶点 ...

  8. OpenGL ES 2.0 混合

    混合技术 混合技术就是将俩个片元调和,主要用于将通过各项测试准备进入帧缓冲的片元(源片元)与原有片元按照设定的比例加权计算出最终片元的颜色值. OpenGL ES 2.0中是通过设置混合因子来指定两个 ...

  9. OpenGL ES着色器语言之语句和结构体(官方文档第六章)内建变量(官方文档第七、八章)

    OpenGL ES着色器语言之语句和结构体(官方文档第六章) OpenGL ES着色器语言的程序块基本构成如下: 语句和声明 函数定义 选择(if-else) 迭代(for, while, do-wh ...

随机推荐

  1. redis启动.停止.重启

    Linux下安装 ]# wget http://download.redis.io/releases/redis-2.8.17.tar.gz ]# tar xzf redis-2.8.17.tar.g ...

  2. java包 命名规范 [转]

    Java的包名都有小写单词组成,类名首字母大写:包的路径符合所开发的 系统模块的 定义,比如生产对生产,物资对物资,基础类对基础类.以便看了包名就明白是哪个模块,从而直接到对应包里找相应的实现. 由于 ...

  3. 【Java】JVM(五)、虚拟机类加载机制

    一.概念 类加载:虚拟机把类的数据从Class文件加载到内存中,并对数据进行校验,转化解析,和初始化,最终形成可以被虚拟机直接使用的Java类型. 二.加载时机 1.加载 加载阶段虚拟机完成的工作为: ...

  4. for of 与 for in 的区别

    遍历数组通常使用for循环,ES5的话也可以使用forEach,ES5具有遍历数组功能的还有map.filter.some.every.reduce.reduceRight等,只不过他们的返回结果不一 ...

  5. Python3 enumerate() 函数

    Python3 enumerate() 函数  Python3 内置函数 描述 enumerate() 函数用于将一个可遍历的数据对象(如列表.元组或字符串)组合为一个索引序列,同时列出数据和数据下标 ...

  6. 网页中引用优酷视频去广告自动播放代码[xyytit]

    很多时候需要在网站中加入视频,可视频太大放自己服务器上太占空间,可以把视频上传到优酷网上,这样节省了空间,打开速度方面也会有不少提升.下面教大家如何引用自动播放的优酷视频.把下面的代码加在你网页适当位 ...

  7. models渲染字典&form表单上传文件&ajax上传文件

    {# {% for u in teacher_d.keys %}#} {# {% for u in teacher_d.values %}#} {% for k,u in teacher_d.item ...

  8. 39. recover rotated sorted array恢复旋转排序数组

    一句话思路:从左边开始的三步翻转法 一刷报错: 不理解start.end是位置随机定义的.i,j是临时变量,为start,end服务 nums.size()区别于nums.length:用于范形变量. ...

  9. c语言定义函数指针和typedef简写

    二种方法来定义函数指针 #include<stdio.h> #include<stdlib.h> #include<Windows.h> int add(int a ...

  10. popupMenu-----弹出菜单

    import android.os.Bundle; import android.app.Activity; import android.graphics.Color; import android ...