OGRE 学习之路(一) Compositor

分类: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 1
        pass
        {
			cull_hardware none
			cull_software none
			depth_func always_pass

            vertex_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 0

                param_named depth_modulator float4 0.6 0 0 0

                // this one can be fixed
                param_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 0
                filtering linear linear none
                tex_address_mode clamp
            }

            // Noise map
            texture_unit
            {
                texture HeatNoise.tga
                tex_coord_set 0
            }

            // heat conversion texture
            texture_unit
            {
                texture HeatLookup.tga
                tex_coord_set 0
                filtering point point none
            }
        }
    }

}

看不懂的可以去瞅瞅。

这里我们知道材质:Fury/HeatVision/LightToHeat对应的vertexProgram是Fury/HeatVision/LightToHeat_vp

//这里只贴出了cg的代码
vertex_program Fury/HeatVision/LightToHeat_Cg_vp cg
{
   source HeatVision.cg
   entry_point LightToHeat_vp
   profiles vs_1_1 arbvp1

    default_params
    {
        param_named_auto flipping render_target_flipping
    }
}

 

对应的fragmentProgram为Fury/HeatVision/LightToHeat_fp

fragment_program Fury/HeatVision/LightToHeat_Cg_fp cg
{
   source HeatVision.cg
   entry_point LightToHeat_fp
   profiles ps_2_0 arbfp1
}

 下面是cg代码:

//
//				 CASTER PASS				//
//				    HEAT					//
//

// vs_1_1
void HeatCaster_vp(
              // in
              float4 vPos: POSITION,
              float4 vNormal: NORMAL,
              
              // out
              out float4 oPos: POSITION,
              out float2 oNDotV: TEXCOORD0,
              
              // parameters
              uniform 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 vp
                        float2 iNDotV: TEXCOORD0
                     ) : COLOR0
{
   return iNDotV.x;
}


//
//				 CASTER PASS				//
//				    COLD					//
//

// vs_1_1
void ColdCaster_vp(
              // in
              float4 vPos: POSITION,
              float4 vNormal: NORMAL,
              
              // out
              out float4 oPos: POSITION,
              out float2 oNDotV: TEXCOORD0,
              
              // parameters
              uniform 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 vp
                        float2 iNDotV: TEXCOORD0
                     ) : COLOR0
{
   return iNDotV.x / 2;
}


//
//	   PASS 1 - Light to heat conversion	//
//

// vs_1_1
void LightToHeat_vp(
                    // in
                    float4 inPos: POSITION,
                    
                    uniform float flipping,

                    // out
                    out 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 vp
                        float4 inDiffuse: COLOR0,
                        float2 inUV0: TEXCOORD0,
                        
                        // out
                        out float4 outColor: COLOR0,
                        
                        // params
                        uniform 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 now
   if (heat > 0)
       heat += heatBiasScale.x;
*/

   // Clamp UVs
   heat  = 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(
                    // in
                    float4 inPos: POSITION,
                    
                    uniform float flipping,

                    // out
                    out 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 vp
                    float4 inDiffuse: COLOR0,
                    float2 inUV0: TEXCOORD0,
                    
                    // out
                    out float4 outColor: COLOR0,
                    
                    // parameters
                    uniform 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 amount
   diffuseGlowFactor = 0.0113f * (2.0 - max( tmpOutColor.r, tmpOutColor.g ));

   // basic blur filter
   for (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;
}

只要四个顶点一张纹理两个三角形进行渲染。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

parkseyoung

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值