博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何由Height Map生成Normal Map
阅读量:4155 次
发布时间:2019-05-25

本文共 1481 字,大约阅读时间需要 4 分钟。

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); }

转载地址:http://wswxi.baihongyu.com/

你可能感兴趣的文章
配置文件的重要性------轻化操作
查看>>
又是缓存惹的祸!!!
查看>>
为什么要实现程序指令和程序数据的分离?
查看>>
我对C++ string和length方法的一个长期误解------从protobuf序列化说起(没处理好会引起数据丢失、反序列化失败哦!)
查看>>
一起来看看protobuf中容易引起bug的一个细节
查看>>
无protobuf协议情况下的反序列化------貌似无解, 其实有解!
查看>>
make -n(仅列出命令, 但不会执行)用于调试makefile
查看>>
makefile中“-“符号的使用
查看>>
go语言如何从终端逐行读取数据?------用bufio包
查看>>
go的值类型和引用类型------重要的概念
查看>>
求二叉树中结点的最大值(所有结点的值都是正整数)
查看>>
用go的flag包来解析命令行参数
查看>>
来玩下go的http get
查看>>
队列和栈的本质区别
查看>>
matlab中inline的用法
查看>>
如何用matlab求函数的最值?
查看>>
Git从入门到放弃
查看>>
java8采用stream对集合的常用操作
查看>>
EasySwift/YXJOnePixelLine 极其方便的画出真正的一个像素的线
查看>>
Ubuntu系统上安装Nginx服务器的简单方法
查看>>