http://www.cnblogs.com/Zephyroal/archive/2011/10/10/2206530.html

一天干掉一只Monkey计划(一)——基本光照模型及RT后处理

1, 首先复习一下基本的光照模型:

Ambient Diffuse Specluar。。。不用多谈,不清楚自己复习,^_^~

然后建立一个基本的RenderMonkey工程,就可以开始着手建立一个基本的光照模型了。

2,VertexShader

bool bViewSpace;

float4x4 matView;

float4x4 matViewProjection;

float3 vecLight;

float fSinTime0_X;

float4 vViewPosition;

struct VS_INPUT

{

float4 Position: POSITION0;

float2 TexCoord: TEXCOORD0;

float3 Normal: NORMAL0;

float3 Binormal: BINORMAL0;

float3 Tangent: TANGENT0;

};

struct VS_OUTPUT

{

float4 Position: POSITION0;

float2 TexCoord: TEXCOORD0;

float3 Normal: TEXCOORD1;

float3 Binormal: TEXCOORD2;

float3 Tangent: TEXCOORD3;

float3 Light:TEXCOORD4;

float3 View:TEXCOORD5;

};

VS_OUTPUT vs_main( VS_INPUT Input )

{

VS_OUTPUT Output;

float4x4 matTransform = { 1.0f, 0.0f, 0.0f, 0.0f,

0.0f, 1.0f, 0.0f, 0.0f,

0.0f, 0.0f, 1.0f, 0.0f,

0.0f, 0.0f, 0.0f, 1.0f };

if( bViewSpace )

{

matTransform = matView;

} // end if( bViewSpace )

Output.Position = mul( Input.Position, matViewProjection );

Output.View =Output.Position-vViewPosition;

Output.TexCoord = Input.TexCoord;

Output.Normal = normalize(mul( Input.Normal, matTransform ));

Output.Binormal = ( mul( Input.Binormal, matTransform ) + 1.0f ) / 2.0f;

Output.Tangent = ( mul( Input.Tangent, matTransform ) + 1.0f ) / 2.0f;

Output.Light=normalize(vecLight);

//加上这一句可以使光源位置动态改变

//Output.Light.x+=fSinTime0_X*2;

return(Output);

}

3,PixelShader

sampler2D my2DTexture;

struct PS_INPUT

{

float2 TexCoord: TEXCOORD0;

float3 Normal: TEXCOORD1;

float3 Binormal: TEXCOORD2;

float3 Tangent: TEXCOORD3;

float3 Light:TEXCOORD4;

float3 View:TEXCOORD5;

};

float4 ps_main( PS_INPUT Input ) : COLOR0

{

float4 color = float4( 0.0f, 0.0f, 0.0f, 0.0f );

float4 ambient = { 0.3686f, 0.3686f, 0.3686f, 1.0f};

float4 diffuse = { 0.88f, 0.88f, 0.88f, 1.0f};

float3 Normal = normalize( Input.Normal);

float3 LightDir = normalize( Input.Light);

float3 ViewDir = normalize( Input.View);

float4 diff = saturate( dot( Normal, LightDir));

float3 Reflect = normalize( 2 * diff * Normal - LightDir);

float4 specular = pow(saturate(dot(Reflect, ViewDir)), 8);

float4 fvBaseColor = tex2D( my2DTexture, Input.TexCoord );

float4 fvTotalAmbient = ambient * fvBaseColor;

float4 fvTotalDiffuse = diffuse * diff * fvBaseColor;

return fvTotalAmbient + fvTotalDiffuse + specular;

}

4,最后显示结果(先关的配置 RenderMonkey可以非常轻松地实现):

5,RenderMonkey中的后处理

RenderMonkey可以在pass中简单地建立一个RenderTarget,通过试手几个RT的处理

,可以预热下相关的屏幕空间后处理

VertexShader

struct VS_OUTPUT

{

float4 pos : POSITION0;

float2 texCoord : TEXCOORD0;

};

VS_OUTPUT vs_main( float4 inPos: POSITION )

{

VS_OUTPUT o = (VS_OUTPUT) 0;

inPos.xy = sign( inPos.xy);

o.pos = float4( inPos.xy, 0.0f, 1.0f);

// get into range [0,1]

o.texCoord = (float2(o.pos.x, -o.pos.y) + 1.0f)/2.0f;

return o;

}

PixelShader

sampler2D Texture0;

float4 ps_main( float2 texCoord : TEXCOORD0 ) : COLOR

{

float4 color=tex2D( Texture0, texCoord );

//转换RGB为强度值

float intensity = color.r * 0.299 + color.g * 0.587 + color.b * 0.184;

return float4(intensity,intensity,intensity,color.a);

}

过程很简单,就是将原先的绘制结果改为输出到了一个指定RT上,然后再在将RT渲染的ps中做了灰度图处理~

6,水下效果

水下效果是游戏中水体处理的常见效果,原理很简单,只要加入一张新的tex为BumpMap,再对结果进行处理即可:

VS不变,PixelShader如下:

sampler2D Texture0;

sampler2D Texture1;

float fTime0_1;

float4 ps_main( float2 texCoord : TEXCOORD0 ) : COLOR

{

float2 bump=tex2D(Texture1,texCoord+fTime0_1*30);

float2 texel=texCoord+bump/60;

float4 color=tex2D( Texture0, texel );

return color;

}

F5,运行,神奇的效果便诞生了:

是不是太简单了,知其然而不知其所以然,是件可耻的事情:

首先来看贴图,可以从代码中发现采样出来只用了RG两个通道的颜色,打开PhotoShop,通过颜色通道面板,可以轻易地发现其中奥秘,RG两种颜色(白)交替出现,换算成float值大概是0.5f,左右,加在纹理的偏移上,即可产生一种“随波逐流”漂的效果。。。

但这里还有个问题,如何控制效果,这里使用了一个RenderMonkey预定义的float值--"Time0_1",查阅官方的SDK,(http://developer.amd.com/gpu_assets/RenderMonkey%20Documentation.pdf

"Time0_1"

This variable provides a scaled floating point time value [0..1] which repeats itself

based on the “Cycle time” set in the RenderMonkey Preferences dialog. By

default this “Cycle time” is set to 120 seconds. This means that the value of this

variable cycles from 0 to 1 in 120 seconds and then goes back to 0 again.

可以得知其值为指定时间(默认两分钟内)从0~1的循环值,float2 bump=tex2D(Texture1,texCoord+fTime0_1*30);float2 texel=texCoord+bump/60;

尝试改变其中30,60几个值,可以明白对noise贴图上的偏移值决定了偏移的频率(速度),而加载对RT采样的实际纹理坐标texel上的除数决定了振幅,粗略理解fTime乘以一个m,则水流飘动的频率为1/( (120/m)/4 ),4为估计的寻址从0~1内出现的黑白交替数~

还有,进一步观察可以发现,有的像素由于扰动的纹理由屏幕左边被移到了屏幕有右边。

在逍遥剑客的blog中看到了相应的解决方法,直接设置RT的寻址模式为clamp,问题解决;

7,热流扰动

本来想实现下水下水纹扰动效果的,结果一时找不到合适的图,倒是意外实现了热流扰动的效果,想起多年前第一次玩到战地里边直升机出风口空气扰动的效果,当时十分震惊,以致自己从没敢想过去实现它,其实原理一模一样(真的是人有画地为牢,固步自封啊)

Noise贴图如下:

结果静态贴图看不清,可以自行实现,但结果还不够平滑,同样还是在逍遥剑客(真是pf前辈啊,学习)的blog上发现了解决方法,松柏分布,具体明天再一一详谈。

一天下来,颇为兴奋,还做了马赛克等等n多神奇的屏幕空间后处理,及预备下了延迟渲染,当然,我的目的是实践运用,到真正继承还需要克服各种问题,想各种方案和trick,额,不能想太多,博文都全写乱了,明天开始得每天专注于一个问题,好好精心思考~~

努力吧~~无止境~~~

一天干掉一只Monkey计划(一)——基本光照模型及RT后处理 【转】的更多相关文章

  1. 一天干掉一只Monkey计划(序)【转】

    http://www.cnblogs.com/Zephyroal/archive/2011/10/10/2206509.html 一天干掉一只Monkey计划(序) 一天干掉一只Monkey计划(序) ...

  2. Monkey学习(2)简单命令合集

    Monkey命令的简单帮助 执行所有命令的前提是,必须先链接模拟器或者实体机,否则会报如下错误信息: 打开命令行窗口,WIN+R,输入CMD 在命令行窗口执行:adb shell monkey –he ...

  3. 转——Android测试之monkey

    一.为什么要用Monkey 测试?   简单在说就是象猴子一样乱点,为了测试软件的稳定性,健壮性.号称最快速有效的方法.有时候运行相同系列的测试,即使是复杂的测试,但是以相同的顺序和路径,即使一遍又一 ...

  4. 为我所用之Monkey

    文章由来:有朋友问到Monkey的使用的问题,就整理一下Monkey的基本使用,以备后用查询. Monkey是一Android中的一个命令行工具,eclipse中有自带此工具,可以运行在模拟器以及真实 ...

  5. WIN7使用过360系统急救箱后出现的任务计划程序文件夹删除的办法

    直接进主题(怀疑系统有问题用了下360系统急救箱,用完后发现计划任务多了个360superkiller文件夹,右键直接是删除不了的) 尝试了各种方法都是不爽,突然想到计划任务不是在在系统盘下的一个文件 ...

  6. monkey工具使用(未完待续)

    monkey命令详解: 转自:http://blog.csdn.net/jlminghui/article/details/38238443 http://www.cnblogs.com/wfh198 ...

  7. Java 内存区域和GC机制分析

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

  8. Java GC回收机制

    优秀Java程序员必须了解的GC工作原理 一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只 ...

  9. Java 内存区域和GC机制

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

随机推荐

  1. linux下源码安装netcat

    linux下源码安装netcat http://blog.chinaunix.net/uid-20783755-id-4211230.html 1,下载netcat源码,netcat-0.7.1-13 ...

  2. linux下C的GBD调试学习笔记(转载)

    1. 单步执行和跟踪函数调用 看下面的程序: 例 10.1. 函数调试实例 #include <stdio.h> int add_range(int low, int high) { in ...

  3. [ 总结 ] Linux kickstart 无人值守安装系统构建过程

    环境:Vmare + Linux虚拟机 注意:网卡桥接

  4. 【C++】继承时构造函数和析构函数

    1. 顺序 先调用基类的构造函数,再调用派生类构造函数.析构顺序相反. 2. 构造函数 派生类 不用初始化列表调用基类构造函数->调用基类的默认构造函数 派生类 使用初始化列表调用基类带参构造函 ...

  5. node.js的全局变量的注意

    在node.js中,如果一个变量没有用var来声明,就会变为全局变量: 看如下代码: 1)6.js function myadd(a) { return a+abc; } function conta ...

  6. 云平台资源挂盘办法V1.2

    一.优先使用mount 方式进行挂盘,记得使用sync参数,如果对方网络限制了445端口,我们被迫采用第二种办法. mount -t cifs -o sync,username='Administra ...

  7. php split 和 explode 的区别

    php split 和 explode 的区别 split (PHP   3,   PHP   4   ) split   --   用正则表达式将字符串分割到数组中 说明 array   split ...

  8. Servlet 调用过程

    上图的大概意思: 前台输入访问路径后,浏览器会去访问本地的host文件查询有木有与之匹配域名的IP地址,若无则在访问DNS服务器查询与之匹配的IP地址.解析IP后则开始发起HTTP请求,根据请求中的基 ...

  9. 【cocos2d-js官方文档】二、资源管理器Assets Manager

    这篇文档将介绍Cocos2d-JS 3.0的一个重量级新特性:资源管理器(仅支持JSB).资源管理器是为游戏运行时的资源热更新而设计的,这里的资源可以是图片,音频甚至游戏脚本本身.使用资源管理器,你将 ...

  10. onethink 插件模板定位

    <?php // +---------------------------------------------------------------------- // | OneThink [ ...