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. andriod开发增加一个菜单

      第一步: E:\01.prj\pyscrapy\Cet4\res\menu\main.xml <menu xmlns:android="http://schemas.android ...

  2. UVALIVE 3562 Remember the A La Mode!

    费用流 建图很简单直接上代码 #include <map> #include <set> #include <list> #include <cmath> ...

  3. requests-html的js执行功能简单使用

    #!/usr/bin/env python # encoding: utf-8 import asyncio from requests_html import HTMLSession import ...

  4. Java反射——java.lang.Class 类简介

    Java的基本思想之一是万事万物即对象,类也是一种对象.但是类是什么对象呢?Java中的类是java.lang.Class的实例化对象,这被成为类类型. //java.lang.Class类中的的主要 ...

  5. centos 7 卸载自带的jdk

    # 查看jdk安装信息 rpm -qa|grep java 卸载已安装的jdk: # yum -y remove java java-1.7.0-*

  6. request.getRequestDispatcher(url).forward(request, response)

    request.getRequestDispatcher().forward(request, response) 意思是将客户端的请求转向到 getRequestDispatcher()方法中参数定 ...

  7. codeforces 739D

    这题码量好大…… 首先思考如何构造,不难找到一下两个条件 1. 在长度为i的环上的点一定是i的倍数个 2. 到达长度i的环的点集距离一定是连续的 第一个条件是很好搞的,关键是第二个条件. 因为存在着x ...

  8. POJ 1776 Task Sequences(竞赛图构造哈密顿通路)

    链接:http://poj.org/problem?id=1776 本文链接:http://www.cnblogs.com/Ash-ly/p/5458635.html 题意: 有一个机器要完成一个作业 ...

  9. 使用scrapy爬取金庸小说目录和章节url

    刚接触使用scrapy的时候,如果一开始就想实现特别复杂的配置,显然是不太现实的,用一些小的例子可以帮助自己理解各个模块. 今天的目标:爬取http://www.luoxia.com/shendiao ...

  10. 使用lookup-method解决singleton bean依赖prototype bean的问题

    在Spring里面,当一个singleton bean依赖一个prototype bean,那么,因为singleton bean是单例的,因此prototype bean在singleton bea ...