OpenGL normalMap
参考zwqxin的博客 http://www.zwqxin.com/
shader 来自zwqxin,稍作修改
<-vertex-> attribute vec3 v_Pos;
attribute vec3 v_Normal;
attribute vec2 v_TexCoord;
attribute vec3 v_tangent; uniform vec3 lightpos; //传入光源的模型坐标吧
uniform vec4 eyepos; varying vec3 lightdir;
varying vec3 halfvec;
varying vec3 norm;
varying vec3 eyedir; void main(void)
{
vec4 pos = gl_ModelViewMatrix * vec4(v_Pos,1.0);
pos = pos / pos.w; //把光源和眼睛从模型空间转换到视图空间
vec4 vlightPos = (gl_ModelViewMatrix * vec4(lightpos, 1.0));
vec4 veyePos = (gl_ModelViewMatrix * eyepos); lightdir = normalize(vlightPos.xyz - pos.xyz);
vec3 eyedir = normalize(veyePos.xyz - pos.xyz); //模型空间下的TBN
norm = normalize(gl_NormalMatrix * v_Normal); vec3 vtangent = normalize(gl_NormalMatrix * v_tangent); vec3 vbinormal = cross(norm,vtangent); //将光源向量和视线向量转换到TBN切线空间
lightdir.x = dot(vtangent, lightdir);
lightdir.y = dot(vbinormal, lightdir);
lightdir.z = dot(norm , lightdir);
lightdir = normalize(lightdir); eyedir.x = dot(vtangent, eyedir);
eyedir.y = dot(vbinormal, eyedir);
eyedir.z = dot(norm , eyedir);
eyedir = normalize(eyedir); halfvec = normalize(lightdir + eyedir); gl_TexCoord[0].st = v_TexCoord; gl_Position = gl_ModelViewProjectionMatrix *vec4( v_Pos,1);
} <-fragment-> uniform sampler2D bumptex;
uniform sampler2D basetex; float amb = 0.2;
float diff = 0.2;
float spec = 0.6; varying vec3 lightdir;
varying vec3 halfvec;
varying vec3 norm;
varying vec3 eyedir; void main(void)
{
float shiness =4;
vec4 ambient = vec4(0.2,0.2,0.2,0.2);
vec4 diffuse = vec4(0.3,0.3,0.3,0.3);
vec4 specular = vec4(0.3,0.3,0.3,0.3); vec3 vlightdir = normalize(lightdir);
vec3 veyedir = normalize(eyedir); vec3 vnorm = normalize(norm);
vec3 vhalfvec = normalize(halfvec); vec4 baseCol = texture2D(basetex, gl_TexCoord[0].xy); //Normal Map里的像素normal定义于该像素的切线空间
vec3 tbnnorm = texture2D(bumptex, gl_TexCoord[0].xy).xyz; tbnnorm = normalize((tbnnorm - vec3(0.5))* 2.0); float diffusefract = max( dot(lightdir,tbnnorm) , 0.0);
float specularfract = max( dot(vhalfvec,tbnnorm) , 0.0); if(specularfract > 0.0){
specularfract = pow(specularfract, shiness);
} gl_FragColor = vec4(amb * ambient.xyz * baseCol.xyz
+ diff * diffuse.xyz * diffusefract * baseCol.xyz
+ spec * specular.xyz * specularfract ,1.0)*3.0;
}
c++代码(用自己的框架不方便全部放出来)
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,m_img.Getid()); glActiveTexture(GL_TEXTURE0+1);
glBindTexture(GL_TEXTURE_2D,m_NormalImg.Getid()); m_ShaderNormalMap.Enable();
m_ShaderNormalMap.uniform("bumptex",1);
m_ShaderNormalMap.uniform("basetex",0);
m_ShaderNormalMap.uniform("lightpos",vec3(100,100,100));
m_ShaderNormalMap.uniform("eyepos",vec3(0,0,10));
glPushMatrix();
glTranslatef(0,0,-100); static float angleA =0.0f;
angleA +=0.02f; glRotatef(angleA,1,1,1); m_Mesh.RenderTest(); glActiveTexture( GL_TEXTURE0);

-------------------------------------------分界线
2016年12月1日
重新增加了VAO渲染,改写材质




OpenGL normalMap的更多相关文章
- 在 OpenGL ES 2.0 上实现视差贴图(Parallax Mapping)
在 OpenGL ES 2.0 上实现视差贴图(Parallax Mapping) 视差贴图 最近一直在研究如何在我的 iPad 2(只支持 OpenGL ES 2.0, 不支持 3.0) 上实现 视 ...
- NormalMap原理详细解析
NormalMap的实现标志着对渲染流水线的各个环节以及矩阵变化有了正确和深入的认识.这里记录一下学习过程,以及关于NormalMap的诸多细节. 刚开始想要实现NormalMap程序的时候,查阅的是 ...
- RenderMonkey 练习 第五天 【OpenGL NormalMapping】
1. 新建一个OpenGL 空effect; 2. 添加相关变量 右击Effect节点选择Add Variable->float->float / float3 添加镜面光强度.灯光位置和 ...
- NormalMap 贴图 【转】
转载: http://www.zwqxin.com/archives/shaderglsl/review-normal-map-bump-map.html 说起Normal Map(法线贴图),就 ...
- NormalMap 贴图 [转]
转载: http://www.zwqxin.com/archives/shaderglsl/review-normal-map-bump-map.html 说起Normal Map(法线贴图),就 ...
- 【AR实验室】OpenGL ES绘制相机(OpenGL ES 1.0版本)
0x00 - 前言 之前做一些移动端的AR应用以及目前看到的一些AR应用,基本上都是这样一个套路:手机背景显示现实场景,然后在该背景上进行图形学绘制.至于图形学绘制时,相机外参的解算使用的是V-SLA ...
- [OpenGL超级宝典]专栏前言
我小时候的梦想呢,是做宇航员或者科学家或者是做一款属于自己的游戏,后来前面两个梦想都没有实现,于是我就来实现我的第三个梦想了,,,我呢,也算是零基础,因为我的专业是物联网工程,这个专业覆盖面之广,简直 ...
- OpenGL超级宝典笔记----渲染管线
在OpenGL中任何事物都在3D空间中,但是屏幕和窗口是一个2D像素阵列,所以OpenGL的大部分工作都是关于如何把3D坐标转变为适应你屏幕的2D像素.3D坐标转为2D坐标的处理过程是由OpenGL的 ...
- OpenGL超级宝典笔记----框架搭建
自从工作后,总是或多或少的会接触到客户端3d图形渲染,正好自己对于3d图形的渲染也很感兴趣,所以最近打算从学习OpenGL的图形API出发,进而了解3d图形的渲染技术.到网上查了一些资料,OpenGL ...
随机推荐
- 安装django及配置
安装 diango官网下载地址 https://www.djangoproject.com/download/ 安装最新的LTS版本 pip安装(在windows的crm中或pycharm中的Term ...
- AtCoder Regular Contest 080 [CDEF]
C - 4-adjacent Time limit : 2sec / Memory limit : 256MB Problem Statement We have a sequence of leng ...
- elastic-job详解(四):失效转移
elastic-job中最关键的特性之一就是失效转移.配置了失效转移之后,如果在任务执行过程中有一个执行实例挂了,那么之前被分配到这个实例的任务(或者分片)会在下次任务执行之前被重新分配到其他正常节点 ...
- JS_高程6.面向对象的程序设计(2)创建对象_3 构造函数存在的问题
# 上次讲到用构造函数的模式来创建对象,相对于工厂模式,解决可对象识别的问题. function Person(name,age,job){ this.name=name; this.age=age; ...
- C. Playing Piano 动态规划
题目意思是给你一个n长度的数字串为a,让你构造一个n长度的数字串b值都为1-5满足以下条件: 正常的dfs暴力构造会超时,我试过了.. 可以开一个二维数组dp[i][j]用来表示b的第i个数字为j是否 ...
- 【转】SQL Server 事务隔离级别详解
SQL 事务隔离级别 概述 隔离级别用于决定如果控制并发用户如何读写数据的操作,同时对性能也有一定的影响作用. 步骤 事务隔离级别通过影响读操作来间接地影响写操作:可以在回话级别上设置事务隔离级别也可 ...
- embOS ARM and Cortex Library Object and Symbol List
OS_Alloc.o OS_free OS_Alloc.o OS_malloc OS_Alloc.o OS_realloc OS_ARM720_MMU.o OS_ARM720_CACHE_CleanR ...
- C#轻量级配置文件组件EasyJsonConfig
一.课程介绍 一.本次分享课程<C#轻量级配置文件EasyJsonConfig>适合人群如下: 1.有一定的NET开发基础. 2.喜欢阿笨的干货分享课程的童鞋们. 二.今天我们要如何优雅解 ...
- ASP.NET微信公众号获取AccessToken
access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token.开发者需要进行妥善保存.access_token的存储至少要保留512个字符空间.acces ...
- SAP传输请求自动发布
最近公司服务器做迁移,原R3 PRE需要迁到另外的地方,迁移后一段时间内,需要两套PRE环境同时运行,过一段时间后才将传输路线切换到新的PRE.在切换前,要求新PRE环境也要正常同步发布请求, ...