分类:Effects
描述:A demo of Ogre’s post-processing framework
Compositor即合成器,也就是所谓的后处理。不过后处理都有一个缺陷,就是没有线框模式,看不到网格。
OGRE中Compositor的例子中列出了3页合成器的例子,实际上只要学会一个,流程怎么走就都通了,就挑选最感兴趣的heat Version来学习!也就是我们常说的热力图。
进入ogre的Compositor的例子,首先我们会调用setupContent(void)方法来进行插件的初始化设置。
1.setupContext(void)函数
首先我们获取到CompositorManager(用于管理合成器的创建和删除)的单例。
然后创建监听,通过CompositorManager注册监听。
然后创建一张64*64*64的3D纹理,获取其包围盒,根据到原点的距离的平方与1024判断将其像素值设为0xFF(蓝色)或0xFF(白色)。
然后又创建一张和视口宽高相同的2D纹理,将其各个点的像素值设置为64到192之间(蓝色)。
然后手动创建一个名为Motion Blur的Compositor(一般是通过合成器脚本来创建的)。
然后再创建一个名为Heat Vision的合成器,详细讲一下这个合成器的创建:
1.setCompositorLogicName();我们可以通过这个名字创建一个合成器实例。
2.定义两张名为scene、temp的纹理,宽高都是256
3.定义一个TargetPass,用于说明scene的纹理来自于之前渲染出来的纹理。
4.再定义一个TargetPass,用于说明输出的纹理就是之前定义的temp,然后通过这个TargetPass创建一个pass,设置为全 屏纹理,然后定义监听的passID,设置材质名为Fury/HeatVision/LightToHeat,设置输入为先前定义的scene纹理。
5.最后定义一个TargetPass,再用这个TargetPass创建一个pass,设置为全屏纹理,设置材质名称为Fury/HeatVision/Blur,设置输入纹理为先前定义的temp。
然后setupScene()进行场景的初始化设置。
然后通过CompositorManager注册添加合成器。
然后界面和锁定视角。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
所有都奥秘都放到了那个材质文件中了!!!
/Compositor不懂的点这里
我们知道“scene”这个pass就是之前场景渲染的结果。“temp”这个pass的外部输入没有,内部创建的pass的输入来自于“scene”,材质名称为"Fury/HeatVision/LightToHeat"。我们找到了这个材质如下:
material Fury/HeatVision/LightToHeat
{technique{// pass 1pass{cull_hardware nonecull_software nonedepth_func always_passvertex_program_ref Fury/HeatVision/LightToHeat_vp{}fragment_program_ref Fury/HeatVision/LightToHeat_fp{// these should be *really* random!param_named random_fractions float4 0.3 0.7 0 0param_named depth_modulator float4 0.6 0 0 0// this one can be fixedparam_named heatBiasScale float4 0.0 1.0 0 0}// INPUT (from scene, where entities has "Fury/HeatVision/Caster" material for heat emanation)texture_unit{tex_coord_set 0filtering linear linear nonetex_address_mode clamp}// Noise maptexture_unit{texture HeatNoise.tgatex_coord_set 0}// heat conversion texturetexture_unit{texture HeatLookup.tgatex_coord_set 0filtering point point none}}}}
看不懂的可以去这瞅瞅。
这里我们知道材质:Fury/HeatVision/LightToHeat对应的vertexProgram是Fury/HeatVision/LightToHeat_vp
//这里只贴出了cg的代码
vertex_program Fury/HeatVision/LightToHeat_Cg_vp cg
{source HeatVision.cgentry_point LightToHeat_vpprofiles vs_1_1 arbvp1default_params{param_named_auto flipping render_target_flipping}
}
对应的fragmentProgram为Fury/HeatVision/LightToHeat_fp
fragment_program Fury/HeatVision/LightToHeat_Cg_fp cg
{source HeatVision.cgentry_point LightToHeat_fpprofiles ps_2_0 arbfp1
}
下面是cg代码:
//
// CASTER PASS //
// HEAT //
//// vs_1_1
void HeatCaster_vp(// infloat4 vPos: POSITION,float4 vNormal: NORMAL,// outout float4 oPos: POSITION,out float2 oNDotV: TEXCOORD0,// parametersuniform float4x4 worldViewProj,uniform float3 eyePosition // object space)
{float4 eyeDir = float4(eyePosition - vPos.xyz, 0);eyeDir = normalize(eyeDir);oPos = mul( worldViewProj, vPos );oNDotV = clamp( dot( vNormal, eyeDir ), 0, 1 );
}// ps_2_0
float4 HeatCaster_fp(// input from vpfloat2 iNDotV: TEXCOORD0) : COLOR0
{return iNDotV.x;
}//
// CASTER PASS //
// COLD //
//// vs_1_1
void ColdCaster_vp(// infloat4 vPos: POSITION,float4 vNormal: NORMAL,// outout float4 oPos: POSITION,out float2 oNDotV: TEXCOORD0,// parametersuniform float4x4 worldViewProj,uniform float3 eyePosition // object space)
{float4 eyeDir = float4(eyePosition - vPos.xyz, 0);eyeDir = normalize(eyeDir);oPos = mul( worldViewProj, vPos );oNDotV = clamp( dot( vNormal, eyeDir ), 0, 1 );
}// ps_2_0
float4 ColdCaster_fp(// input from vpfloat2 iNDotV: TEXCOORD0) : COLOR0
{return iNDotV.x / 2;
}//
// PASS 1 - Light to heat conversion //
//// vs_1_1
void LightToHeat_vp(// infloat4 inPos: POSITION,uniform float flipping,// outout float4 Pos: POSITION,out float2 uv0: TEXCOORD0)
{Pos = float4(inPos.x, flipping * inPos.y, 0.0f, 1.0f);inPos.xy = sign(inPos.xy);uv0 = (float2(inPos.x, -inPos.y) + 1.0f)/2.0f;
}// ps_2_0
void LightToHeat_fp(// input from vpfloat4 inDiffuse: COLOR0,float2 inUV0: TEXCOORD0,// outout float4 outColor: COLOR0,// paramsuniform float4 random_fractions,uniform float4 heatBiasScale,uniform float4 depth_modulator,uniform sampler2D Input, // output of HeatVisionCaster_fp (NdotV)uniform sampler2D NoiseMap,uniform sampler2D HeatLookup)
{float depth, heat, interference;// Output constant color:depth = tex2D( Input, inUV0 );depth *= (depth * depth_modulator);heat = (depth * heatBiasScale.y);// if (depth > 0){interference = -0.5 + tex2D( NoiseMap, inUV0 + float2( random_fractions.x, random_fractions.y ) );interference *= interference;interference *= 1 - heat;heat += interference;//+ heatBiasScale.x;}/*heatBias isn't used for nowif (heat > 0)heat += heatBiasScale.x;
*/// Clamp UVsheat = max( 0.005, min( 0.995, heat ) );outColor = tex2D( HeatLookup, float2( heat, 0.f ) );
}//
// PASS 2 - add simple blur (final pass) //
//// vs_1_1
void Blur_vp(// infloat4 inPos: POSITION,uniform float flipping,// outout float4 Pos: POSITION,out float2 uv0: TEXCOORD0)
{Pos = float4(inPos.x, flipping * inPos.y, 0.0f, 1.0f);inPos.xy = sign(inPos.xy);uv0 = (float2(inPos.x, -inPos.y) + 1.0f)/2.0f;
}// ps_2_0
void Blur_fp(// input from vpfloat4 inDiffuse: COLOR0,float2 inUV0: TEXCOORD0,// outout float4 outColor: COLOR0,// parametersuniform sampler2D Input, // output of HeatVision_fp1 (HeatRenderTexture)uniform float4 blurAmount)
{int i;float4 tmpOutColor;float diffuseGlowFactor;const float2 offsets[4] = {
/*// hazy blur-1.8, -1.8,-1.8, 1.8,1.8, -1.8,1.8, 1.8
*/
/*// less-hazy blur-1.0, 2.0,-1.0, -1.0,1.0, -1.0,1.0, 1.0
*/
/*-0.326212, -0.405805,-0.840144, -0.073580,-0.695914, 0.457137,-0.203345, 0.620716
*/-0.3, 0.4,-0.3, -0.4,0.3, -0.4,0.3, 0.4};tmpOutColor = tex2D( Input, inUV0 ); // UV coords are in image space// calculate glow amountdiffuseGlowFactor = 0.0113f * (2.0 - max( tmpOutColor.r, tmpOutColor.g ));// basic blur filterfor (i = 0; i < 4; i++) {tmpOutColor += tex2D( Input, inUV0 + blurAmount.x * diffuseGlowFactor * offsets[i] );}tmpOutColor *= 0.25;// TIPS (old-skool strikes again!)// Pay attention here! If you use the "out float4 outColor" directly// in your steps while creating the output color (like you remove// the "tmpOutColor" var and just use the "outColor" directly)// your pixel-color output IS CHANGING EACH TIME YOU DO AN ASSIGNMENT TOO!// A temporary variable, instead, acts like a per-pixel double buffer, and// best of all, lead to better performance.outColor = tmpOutColor;
}
只要四个顶点一张纹理两个三角形进行渲染。