转自:http://www.cnblogs.com/cxrs/archive/2009/11/01/1594155.html

Nvidia和ATI都有相应的工具把Heightmap转成NormalMap,有了NormalMap,我们就可以用NormalMapping技术进行Per Pixel Lighting计算了。那么HeightMap是怎么转化成NormalMap的呢?      其实并不难,在《3D游戏与计算机图形学方法》中,提供了一种由高度图生成法向图的方法。其思想是根据高度图中的象素与其周围象素的高度差,在切空间构造S向量和T向量,由SXT得到法线向量。

设H(i,j)表示在height map上(i,j)象素点的高度值,则在切线空间S和T方向的切向量可以表示成:
S(i,j) = (1,0,H(i+1,j) - H(i-1,j) )
T(i,j) = (0,1,H(i,j+1) - H(i,j-1) )
Normal(i,j) = S(i,j) X T(i,j)
H(i+1,j) – H(i-1,j)为沿S方向的高度差,也就是S方向的坡度,H(i,j+1) - H(i,j-1)为沿T方向的高度差,也就是T方向的坡度。当相邻象素高度差为0时,则算出的Normal(i,j) = (0,0,1),表示法线垂直于平面,当有高度差时,法线就会分别朝S方向或T方向偏移。

用shader来实现也很简单,VS和PS代码如下,上边左图为HeightMap,右图为由下面shader生成的NormalMap,这个方法生成的NormalMap并不够好,在RenderMonkey中有一个叫NormalmapFilter的Sample,会生成更高质理的NormalMap,有兴趣的朋友可以参考。

VS_OUTPUT main(float4 Pos: POSITION){

VS_OUTPUT Out;

// Clean up inaccuracies

Pos.xy = sign(Pos.xy);

Out.Pos = float4(Pos.xy, 0, 1);

// Image-space

Out.texCoord.x = 0.5 * (1 + Pos.x);

Out.texCoord.y = 0.5 * (1 - Pos.y);

return Out;

}

float4 main(float2 texCoord: TEXCOORD) : COLOR {

float2 off = 1.0 / HeightMapSize;

float Scale = 1;

// Sample teh neighbor

float s0 = tex2D(Heightmap, texCoord + float2(-off.x,0)).r;

float s1 = tex2D(Heightmap, texCoord + float2( off.x,0)).r;

float s2 = tex2D(Heightmap, texCoord + float2( 0,-off.y)).r;

float s3 = tex2D(Heightmap, texCoord + float2(0,off.y)).r;

float3 U = float3(1,0,s1 - s0);

float3 V = float3(0,1,s3 - s2);

float3 normal = normalize(Scale * cross(U,V));

// Pack [-1, 1] into [0, 1]

return float4(normal * 0.5 + 0.5,1);

}

如何由Height Map生成Normal Map的更多相关文章

  1. Bumped Map And Normal Map

    http://freespace.virgin.net/hugo.elias/graphics/x_polybm.htm 先留着,准备以后开垦

  2. shader复杂与深入:Normal Map(法线贴图)1

    转自:http://www.zwqxin.com/archives/shaderglsl/review-normal-map-bump-map.htmlNormal Map法线贴图,想必每个学习计算机 ...

  3. [Unity3D] Normal map、Diffuse map 和 Speculer map

    Normal map : Normal map (法线贴图) 它的作用是模拟出高模上的一些细节纹理,特别是将高模上的圆滑和粗糙度投射到低模上,让低模也有高模的效果. 因为高模的面数非常多,导入引擎后电 ...

  4. Normal Map中的值, Tangent Space, 求算 Tangent 与 Binormal 与 TBN Matrix

      - Normal Map中的值 -   有没有想过,Normal Map(法线贴图)为什么看上去都是“偏蓝色”的?这是因为,在map中存储的值都是在Tangent Space(切空间)下的.比如, ...

  5. go语言之进阶篇通过map生成json

    1.通过map生成json 示例1: package main import ( "encoding/json" "fmt" ) func main() { / ...

  6. 【Unity Shader】六、使用法线贴图(Normal Map)的Shader

    学习资料: http://www.sikiedu.com/course/37/task/456/show# http://www.sikiedu.com/course/37/task/458/show ...

  7. [转]Normal Map中的值, Tangent Space, 求算 Tangent 与 Binormal 与 TBN Matrix

    原文出处 https://www.cnblogs.com/lookof/p/3509970.html - Normal Map中的值 -   有没有想过,Normal Map(法线贴图)为什么看上去都 ...

  8. Map接口,Map.Entry,hashMap类,TreeMap类,WeakHashMap。

    Collection接口之前接触过,每次保存的对象是一个对象,但是在map中保存的是一对对象,是以key->value形式保存的. 定义: public interface Map<K,V ...

  9. Map java中的map 如何修改Map中的对应元素

    Map java中的map 如何修改Map中的对应元素 Map以按键/数值对的形式存储数据,和数组非常相似,在数组中存在的索引,它们本身也是对象.         Map的接口         Map ...

随机推荐

  1. GRUB4DOS入门

    目 录 第1章 GRUB4DOS入门    1 1.1 用途    1 1.2 安装    1 1.2.1 修改MBR    1 1.2.2 修改PBR    3 1.2.3 DOS    4 1.2 ...

  2. SAP 用事务码SQVI 做简单报表 .

    集团计划总监要去德国参展,要一份离当前日期最近的出口欧美国家产品单价. 需要从A903,MARA,KONP,MATK 这4张表里取数. 1)Tcode:SQVI进入,如图 2) 在快速浏览处输入名称: ...

  3. 微软Azure云平台Hbase 的使用

    In this article What is HBase? Prerequisites Provision HBase clusters using Azure Management portal ...

  4. sql server多表数据批量更新

    update wset w.TagCount=x.TagCountfrom (select ItemID,COUNT(*) as TagCount from r where IsValid=1 gro ...

  5. listview加载性能优化ViewHolder

    在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局, 但当listview有大量的数据需要加载的时候 ...

  6. swfobject2.2

    官方网址:http://blog.deconcept.com/swfobject/ Github地址:https://github.com/swfobject/swfobject 谷歌地址 貌似被和谐 ...

  7. 20145236 《Java程序设计》第4周学习总结

    20145236 <Java程序设计>第4周学习总结 教材学习内容总结 第六章 继承与多态 一.继承 •继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类.继承可以理解 ...

  8. NABCD模型(猫咪记单词)

    项目需求分析与建议-NABCD模型(猫咪记单词)   N (Need 需求) 对于现在的学生,尤其是大学生来说,学习英语是一件非常重要的事.我们有四级六级托福雅思等各种各样的英语方面的考试.而学习英语 ...

  9. PHP中的include、include_once、require、require_once

    include.include_once().require.require_once() 作用: 通过 include 或 require 语句,可以将 PHP 文件的内容插入另一个 PHP 文件( ...

  10. Oracle 权限查询

    查看当前用户权限:SQL> select * from session_privs; 查询某个用户被赋予的系统权限. Select * from user_sys_privs; 或者: sele ...