笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。

CSDN视频网址:http://edu.csdn.net/lecturer/144

当前市面上比较流行的引擎无非是Unity3D引擎和UE4虚幻4,但是作为开源的Ogre引擎还是被一部分玩家所喜欢,由于其开源的,而且是针对图形处理的。所以对于学习3D游戏开发者来说,学习Ogre的GPU渲染是一条捷径,各个引擎的渲染Shader编写其实是类似的,它们的区别是在细节方面,虚幻做的最好,其他就是Unity和Ogre了。下面把Ogre的处理方式给读者介绍一下:

高光,法线,环境映射对于Shader来说必须要掌握的,其中Ogre中的渲染需要几个文件一是cg文件还有material文件,先给读者展示cg文件,代码如下所示:

struct VIn
{float4 p    : POSITION;float3 n    : NORMAL;float3 t    : TANGENT;float2 uv   : TEXCOORD0;
};struct VOut
{float4 p    : POSITION;float2 uv   : TEXCOORD0;float4 wp   : TEXCOORD1;float3 n    : TEXCOORD2;float3 t    : TEXCOORD3;float3 b    : TEXCOORD4;float4 lp   : TEXCOORD5;float3 sdir : TEXCOORD6;
};struct PIn
{float2 uv   : TEXCOORD0;float4 wp   : TEXCOORD1;float3 n    : TEXCOORD2;float3 t    : TEXCOORD3;float3 b    : TEXCOORD4;float4 lp   : TEXCOORD5;float3 sdir : TEXCOORD6;
};void ambient_vs(VIn IN,uniform float4x4 wvpMat,out float4 oPos : POSITION,out float2 oUV : TEXCOORD0)
{oPos = mul(wvpMat, IN.p);oUV = IN.uv;
}float4 ambient_ps(in float2 uv : TEXCOORD0,uniform float3 ambient,uniform float4 matDif,uniform sampler2D dMap,uniform sampler2D aoMap): COLOR0
{return tex2D(dMap, uv) * tex2D(aoMap, uv) *float4(ambient, 1) * float4(matDif.rgb, 1);
}VOut diffuse_vs(VIn IN,uniform float4x4 wMat,uniform float4x4 wvpMat,uniform float4x4 tvpMat,uniform float4 spotlightDir)
{VOut OUT;OUT.wp = mul(wMat, IN.p);OUT.p = mul(wvpMat, IN.p);OUT.uv = IN.uv;OUT.n = IN.n;OUT.t = IN.t;OUT.b = cross(IN.t, IN.n);OUT.sdir = mul(wMat, spotlightDir).xyz; // spotlight dir in world spaceOUT.lp = mul(tvpMat, OUT.wp);return OUT;
}float4 diffuse_ps(PIn IN,uniform float3 lightDif0,uniform float4 lightPos0,uniform float4 lightAtt0,uniform float3 lightSpec0,uniform float4 matDif,uniform float4 matSpec,uniform float matShininess,uniform float3 camPos,uniform float4 invSMSize,uniform float4 spotlightParams,uniform float4x4 iTWMat,uniform sampler2D diffuseMap : TEXUNIT0,uniform sampler2D specMap : TEXUNIT1,uniform sampler2D normalMap : TEXUNIT2): COLOR0
{// directionfloat3 ld0 = normalize(lightPos0.xyz - (lightPos0.w * IN.wp.xyz));half lightDist = length(lightPos0.xyz - IN.wp.xyz) / lightAtt0.r;// attenuationhalf ila = lightDist * lightDist; // quadratic falloffhalf la = 1.0 - ila;float4 normalTex = tex2D(normalMap, IN.uv);float3x3 tbn = float3x3(IN.t, IN.b, IN.n);float3 normal = mul(transpose(tbn), normalTex.xyz * 2 - 1); // to object spacenormal = normalize(mul((float3x3)iTWMat, normal));float3 diffuse = max(dot(ld0, normal), 0);// calculate the spotlight effectfloat spot = (spotlightParams.x == 1 &&spotlightParams.y == 0 &&spotlightParams.z == 0 &&spotlightParams.w == 1 ? 1 : // if so, then it's not a spot lightsaturate((dot(ld0, normalize(-IN.sdir)) - spotlightParams.y) /(spotlightParams.x - spotlightParams.y)));float3 camDir = normalize(camPos - IN.wp.xyz);float3 halfVec = normalize(ld0 + camDir);float3 specular = pow(max(dot(normal, halfVec), 0), matShininess);float4 diffuseTex = tex2D(diffuseMap, IN.uv);float4 specTex = tex2D(specMap, IN.uv);float3 diffuseContrib = (diffuse * lightDif0 * diffuseTex.rgb * matDif.rgb);float3 specularContrib = (specular * lightSpec0 * specTex.rgb * matSpec.rgb);float3 light0C = (diffuseContrib + specularContrib) * la * spot;return float4(light0C, diffuseTex.a);
}

其中VIn表示的是顶点输入的结构体,VOut表示的是顶点输出的结构体,PIn表示的是片段着色器的输入结构体,在下面的函数实现中首先实现的是ambient  occlusion mapping也包括顶点和片段处理。最后是diffuse的顶点和片段处理也就是高光specluar和法线normal的处理,这样整个Shader就完成了。

下面实现的是material的编写,代码如下所示:

material base_material
{set $diffuseCol "1 1 1 1"set $specularCol "1 1 1"set $shininess "32"technique{pass{illumination_stage ambientambient 1 1 1 1diffuse $diffuseColspecular 0 0 0 0emissive 0 0 0 0vertex_program_ref ambient_vs{}fragment_program_ref ambient_ps{}texture_unit diffuseMap{texture white.png}texture_unit aoMap{texture white.png}}pass{illumination_stage per_lightscene_blend add
//            iteration once_per_light   not needed while   illumination_stage per_light   is usedvertex_program_ref diffuse_vs{}fragment_program_ref diffuse_ps{}diffuse $diffuseColspecular $specularCol $shininessambient 0 0 0 0texture_unit diffuseMap{texture white.png}texture_unit specMap{texture white.png}texture_unit normalMap{texture flat_n.png}}}
}// examples (require the appropriate [[textures]], all found in the Ogre samples)material rockwall : base_material
{set_texture_alias diffuseMap rockwall.tgaset_texture_alias specMap rockwall.tgaset_texture_alias normalMap rockwall_NH.tga
}material metal : base_material
{set_texture_alias diffuseMap RustedMetal.jpgset_texture_alias specMap RustedMetal.jpg
}material ogre : base_material
{set_texture_alias diffuseMap GreenSkin.jpgset_texture_alias specMap GreenSkin.jpgset_texture_alias normalMap NMHollyBumps.png
}

该文件实现了一个基材质 base_material其它材质可以继承,这个对于开发者来说非常灵活。另外还需要一个program程序文件用于shader和图片的配置,代码如下所示:

vertex_program diffuse_vs cg
{source general.cgprofiles vs_1_1 arbvp1entry_point diffuse_vsdefault_params{param_named_auto wMat world_matrixparam_named_auto wvpMat worldviewproj_matrixparam_named_auto tvpMat texture_viewproj_matrix 0param_named_auto spotlightDir light_direction_object_space 0}
}vertex_program ambient_vs cg
{source general.cgprofiles vs_1_1 arbvp1entry_point ambient_vsdefault_params{param_named_auto wvpMat worldviewproj_matrix}
}fragment_program ambient_ps cg
{source general.cgprofiles ps_2_0 arbfp1entry_point ambient_psdefault_params{param_named_auto ambient ambient_light_colourparam_named_auto matDif surface_diffuse_colour}
}fragment_program diffuse_ps cg
{source general.cgprofiles ps_2_x arbfp1entry_point diffuse_psdefault_params{param_named_auto lightDif0 light_diffuse_colour 0param_named_auto lightSpec0 light_specular_colour 0param_named_auto camPos camera_positionparam_named_auto matShininess surface_shininessparam_named_auto matDif surface_diffuse_colourparam_named_auto matSpec surface_specular_colourparam_named_auto lightPos0 light_position 0param_named_auto lightAtt0 light_attenuation 0param_named_auto iTWMat inverse_transpose_world_matrixparam_named_auto spotlightParams spotlight_params 0}
}

以上就完成了高光,法线以及ambient Shader的实现,当然学习Shader编程不能仅限于功能实现,还需要举一反三,比如我们上面封装的base_material。还是可以继续去扩展的,代码如下所示:

 material some_material : base_material
{// any of these maps can be left out if you don't have oneset_texture_alias diffuseMap some_dif.pngset_texture_alias specMap some_spec.pngset_texture_alias normalMap some_norm.pngset_texture_alias aoMap some_ao.png// diffuse colour multiplier (for example, green-ish)set $diffuseCol "0.1 1 0.1"// specular colour multiplier (for example, red-ish)set $specularCol "1 0.1 0.1"// specular power (shininess) (the higher, the sharper the highlights)set $shininess "128"// once again, you can leave any of these configurables out if you don't need them
}

我们还可以在此Shader的基础上实现UV镜像处理,修改代码如下所示:

一、首先将VIn输入结构体修改如下所示:

struct VIn
{float4 p    : POSITION;float3 n    : NORMAL;float4 t    : TANGENT; // <- this was changedfloat2 uv   : TEXCOORD0;
};

二、修改Vout输出结构体代码如下:

struct VOut
{float4 p    : POSITION;float2 uv   : TEXCOORD0;float4 wp   : TEXCOORD1;float3 n    : TEXCOORD2;float4 t    : TEXCOORD3; //<- this was changedfloat3 b    : TEXCOORD4;float4 lp   : TEXCOORD5;float3 sdir : TEXCOORD6;
};

三、修改diffuse_vs函数代码修改如下所示:

VOut diffuse_vs(VIn IN,uniform float4x4 wMat,uniform float4x4 wvpMat,uniform float4x4 tvpMat,uniform float4 spotlightDir)
{VOut OUT;OUT.wp = mul(wMat, IN.p);OUT.p = mul(wvpMat, IN.p);OUT.uv = IN.uv;OUT.n = IN.n;OUT.t = IN.t;OUT.b = cross(IN.t.xyz, IN.n) * IN.t.w; //<-this was changedOUT.sdir = mul(wMat, spotlightDir).xyz; // spotlight dir in world spaceOUT.lp = mul(tvpMat, OUT.wp);return OUT;
}

关于变动的代码都加了注释,对比源代码既可以看明白,到此结束。。。。。。。

Ogre引擎渲染系列之Normal Specular Mapping相关推荐

  1. Ogre内部渲染流程分析系列

    come from:http://blog.csdn.net/weiqubo/article/details/6956005 要理解OGRE引擎,就要理解其中占很重要位置的 Renderable接口, ...

  2. 基于多核平台优化的OGRE 3D渲染引擎

    基于多核平台优化的OGRE 3D渲染引擎 陈天洲1+,陈学亮1, 施青松1 1(浙江大学计算机学院,浙江杭州,310027) 摘 要:近年来,随着计算机体系结构的发展,多核平台的应用越来越广泛.多核平 ...

  3. [转]《战地3》寒霜2引擎渲染流程图文详解

    一直一来受制于技术.预言和环境,中国国内玩家.开发者对于国外先进游戏引擎的渲染流程知之甚少,虽然没有技术封锁缺更似自我封锁,在GDC上很少看到中国开发者的身影,无法学习到先进的开发经验. 首先来回味一 ...

  4. 老人关于OGRE引擎的总体介绍

    [Ogre总揽],转至http://edu.gamfe.com/tutor/d/16715.html Ogre是一个庞大而纷杂的对象和模块集合,如果初学者希望直接从对象列表中得到什么信息的话,可能会感 ...

  5. 2D游戏引擎Allegro 系列教程(二) Hello world!

    本系列文章由sky编写,转载请注明出处. http://blog.csdn.net/qq573011406/article/details/8172949 作者:袁全伟   邮箱: qq5730114 ...

  6. Unity引擎渲染模块知识Tree

    渲染效果是游戏表现力的核心卖点之一.尤其近几年随着引擎技术的革命翻新,硬件技术的突飞猛进,以及玩家愈发挑剔的要求,游戏的表现力正在进入到崭新的层面.有哪些主流的Shader.自阴影.后处理技术?如何加 ...

  7. Cocos2d-x 3.x 图形学渲染系列十二

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...

  8. 如何将一个字典转换为玲阶矩阵_基础渲染系列(一)图形学的基石——矩阵

    本文重点内容: 1.创建一个立方体构建的Grid网格 2.支持缩放.位移.旋转 3.变换矩阵 4.创建简单的相机投影 译注:从原创作者博客转为公众号文章非常复杂,我需要先将原文翻译一遍,然后在公众号再 ...

  9. [摘]全文检索引擎Solr系列—–全文检索基本原理

    原文链接--http://www.importnew.com/12707.html 全文检索引擎Solr系列-–全文检索基本原理 2014/08/18 | 分类: 基础技术, 教程 | 2 条评论 | ...

  10. vantabs多页渲染_选择引擎渲染页面

    X-UA-Compatible是针对ie8新加的一个设置,对于ie8之外的浏览器是不识别的,这个区别与content="IE=7"在无论页面是否 包含指令,都像是使用了 Windo ...

最新文章

  1. 深度学习深陷可解释性泥淖,而这个研究领域正逐步焕发生机
  2. 3.3. shutdown
  3. python如何修改excel数据库_python修改excel数据库
  4. flask-session 在redis中存储session
  5. 介绍了如何取成员函数的地址以及调用该地址
  6. Ruby与Google 2009编程之夏
  7. Android RecyclerView实现九宫格效果
  8. 红帽补丁安装的方法_为什么红帽采取“上游优先”的方法
  9. python教程视频哪个好-Python入门视频哪个好?
  10. Spring教程– Spring Core Framework教程
  11. unity 平移图片_unity实现贴图矩阵运算(旋转平移缩放)
  12. 如何对一个变量数据进行正则判定_数值数据与数值数据的分析
  13. 开发Windows物流管理系统——(一)前期准备
  14. 一、最简单的爬虫(python3 爬虫小白系列文章)
  15. 100个最励志最科学的无敌成功法则
  16. ajax 传参json字符串
  17. QT 读BIN文件的两种方式
  18. 易企秀H5 json配置文件解密分析
  19. android圆形菜单,android 圆形旋转菜单例子
  20. 趋势交易法之区间跨度

热门文章

  1. [论文笔记]Rob-GAN: Generator, Discriminator, and Adversarial Attacker(CVPR 2019)
  2. 课后习题7.11 医院内科有A,B,C,D,E,F,G共7位医生,每人在一周内要值一次夜班,排班的要求是: (1)A医生值班日比C医生晚1天; (2)D医生值班日比E医生晚2天; (3)B医生值班日比
  3. CF838D Airplane Arrangements
  4. android 投屏 电脑,安卓王者荣耀投屏电脑
  5. xxljob默认登录_XXL-JOB快速入门
  6. 山海镜花vivo服务器微信号,《山海镜花》正式公测!开服说明
  7. 课堂派“互动课件”文件下载
  8. 程序员为什么不写注释
  9. 第三方邮箱登录126,163等服务器配置STMP
  10. SAP ABAP 工作区,内表,标题行的定义和区别