chap6_2 Parallax mapping in OGRE

Parallax mapping(视差映射)是凹凸映射的一种,同样,这里只是在OGRE里面实现,不讲原理.我会写个DX版本的parallax mappiing,到时候再讲原理,敬请期待!微笑


/*------------------------------------------------------------
	main.cpp -- Achieve parallax mapping in OGRE
						(c) Seamanj.2013/7/27
------------------------------------------------------------*/
//Phase1 : Add Framework
//Phase2 : Add knot.mesh 
//Phase3 : Add Light
//Phase4 : Move Light
#define Phase1 1
#define Phase2 1
#define Phase3 1
#define Phase4 1
#if Phase1
#include "ExampleApplication.h"
#include <windows.h>
#if Phase4
class MyFrameListener : public ExampleFrameListener
{
public:
	MyFrameListener(RenderWindow* win, Camera* cam, SceneNode* LightPivot)
		: ExampleFrameListener(win, cam), lightPivot(LightPivot)
	{
	}
	bool frameRenderingQueued(const FrameEvent& evt)
	{
		lightPivot->roll(Degree(evt.timeSinceLastFrame * 30));
		if(mWindow->isClosed())  
                return false;
		return ExampleFrameListener::frameRenderingQueued(evt);
	}
protected:
	SceneNode* lightPivot;
};
#endif
class MyApplication : public ExampleApplication
{
#if Phase3
protected:
	SceneNode* m_LightPivot;
#endif
#if Phase4
	 Ogre::FrameListener* FrameListener;
#endif

public:
	MyApplication()
	{}
	~MyApplication()
	{}
protected:
	void createScene()
	{
#if Phase2
		
		// load each mesh with non-default hardware buffer usage options
		MeshPtr mesh = MeshManager::getSingleton().load("knot.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
			HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
		// build tangent vectors for our mesh

        unsigned short src, dest;
        if (!mesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest))
        {
            mesh->buildTangentVectors(VES_TANGENT, src, dest);
			// this version cleans mirrored and rotated UVs but requires quality models
			// mesh->buildTangentVectors(VES_TANGENT, src, dest, true, true);
        }


		Entity* ent = mSceneMgr->createEntity(mesh->getName(), mesh->getName());
		ent->setMaterialName("Examples/OffsetMapping/Specular");//知识点1
/*知识点1:视差映射材质
---------------------------------------------
来自ogre_src_v1-7-4\Samples\Media\materials\scripts\OffsetMapping.material文件
---------------------------------------------
// Bump map with Parallax offset vertex program, support for this is required 
vertex_program Examples/OffsetMappingVP cg 
{ 
   source OffsetMapping.cg 
   entry_point main_vp 
   profiles vs_1_1 arbvp1 
} 

// Bump map with parallax fragment program 
fragment_program Examples/OffsetMappingFP cg
{ 
   source OffsetMapping.cg
   entry_point main_fp
   profiles ps_2_0 arbfp1
} 

// Bump map with parallax fragment program 
fragment_program Examples/OffsetMappingPS asm 
{ 
   source OffsetMapping_specular.asm 
   // sorry, only for ps_1_4 and above:) 
   syntax ps_1_4 
} 
material Examples/OffsetMapping/Specular 
{ 

  // This is the preferred technique which uses both vertex and 
   // fragment programs, supports coloured lights 
   technique 
   {
   	  // ambient / depth
	  pass
	  {
	      illumination_stage ambient
		  vertex_program_ref Ogre/BasicVertexPrograms/AmbientOneTexture
		  {
		  }
		  
	  }
      // do the lighting  and bump mapping with parallax pass 
      pass 
      {
	     illumination_stage per_light
	     scene_blend add
		 depth_write off
       
         // Vertex program reference 
         vertex_program_ref Examples/OffsetMappingVP 
         { 
            param_named_auto lightPosition light_position_object_space 0 
            param_named_auto eyePosition camera_position_object_space 
            param_named_auto worldViewProj worldviewproj_matrix 
         } 

         // Fragment program 
         fragment_program_ref Examples/OffsetMappingFP
         { 
            param_named_auto lightDiffuse light_diffuse_colour 0 
            param_named_auto lightSpecular light_specular_colour 0 
            // Parallax Height scale and bias 
            param_named scaleBias float4 0.04 -0.02 1 0 
         } 
          
         // Normal + height(alpha) map 
         texture_unit 
         { 
            texture rockwall_NH.tga
            tex_coord_set 0 
         } 

         // Base diffuse texture map 
         texture_unit 
         { 
            texture rockwall.tga
            tex_coord_set 1 
         } 
      } 
   } 


   // This is the preferred technique which uses both vertex and 
   // fragment programs, supports coloured lights 
   technique 
   { 
      // do the lighting  and bump mapping with parallax pass 
      pass 
      { 
       
         // Vertex program reference 
         vertex_program_ref Examples/OffsetMappingVP 
         { 
            param_named_auto lightPosition light_position_object_space 0 
            param_named_auto eyePosition camera_position_object_space 
            param_named_auto worldViewProj worldviewproj_matrix 
         } 

         // Fragment program 
         fragment_program_ref Examples/OffsetMappingPS 
         { 
            param_indexed_auto 0 light_diffuse_colour 0 
            param_indexed_auto 1 light_specular_colour 0 
            // Parallax Height scale and bias 
            param_indexed 2 float4 0.04 -0.02 1 0 
         } 
          
         // Normal + height(alpha) map 
         texture_unit 
         { 
            texture rockwall_NH.tga
            tex_coord_set 0 
         } 

         // Base diffuse texture map 
         texture_unit 
         { 
            texture rockwall.tga
            tex_coord_set 1 
         } 
      } 
   } 
   
   // Simple no-shader fallback
   technique 
   { 
      pass 
      { 
         // Base diffuse texture map 
         texture_unit 
         { 
            texture rockwall.tga
         } 
	  }
   }

}
*/
/*知识点2:视差映射shader
---------------------------------------------
来自ogre_src_v1-7-4\Samples\Media\materials\programs\Example_BumpMapping.cg文件
---------------------------------------------
   Bump mapping vertex program
   In this program, we want to calculate the tangent space light vector
   on a per-vertex level which will get passed to the fragment program,
   or to the fixed function dot3 operation, to produce the per-pixel
   lighting effect. 

void main_vp(float4 position	: POSITION,
			 float3 normal		: NORMAL,
			 float2 uv			: TEXCOORD0,
			 float4 tangent     : TANGENT0,
			 // outputs
			 out float4 oPosition    : POSITION,
			 out float2 oUv			 : TEXCOORD0,
			 out float3 oTSLightDir	 : TEXCOORD1,
			 // parameters
			 uniform float4 lightPosition, // object space
			 uniform float4x4 worldViewProj)
{
	// calculate output position
	oPosition = mul(worldViewProj, position);

	// pass the main uvs straight through unchanged
	oUv = uv;

	// calculate tangent space light vector
	// Get object space light direction
	// Non-normalised since we'll do that in the fragment program anyway
	float3 lightDir = lightPosition.xyz -  (position * lightPosition.w);

	// Calculate the binormal (NB we assume both normal and tangent are
	// already normalised)
	// NB looks like nvidia cross params are BACKWARDS to what you'd expect
	// this equates to NxT, not TxN

#if TANGENTS_HAVE_PARITY
	float3 binormal = cross(tangent.xyz, normal) * tangent.www;
#else
	// fixed handedness
	float3 binormal = cross(tangent.xyz, normal);
#endif
	
	// Form a rotation matrix out of the vectors
	float3x3 rotation = float3x3(tangent.xyz, binormal, normal);
	
	// Transform the light vector according to this matrix
	oTSLightDir = mul(rotation, lightDir);
	
	
}

void main_fp( float2 uv			: TEXCOORD0,
			  float3 TSlightDir : TEXCOORD1,

			  out float4 colour	: COLOR,

			  uniform float4 lightDiffuse,
			  uniform sampler2D   normalMap : register(s0))
{
	// retrieve normalised light vector, expand from range-compressed
	float3 lightVec = normalize(TSlightDir).xyz;

	// get bump map vector, again expand from range-compressed
	float3 bumpVec = expand(tex2D(normalMap, uv).xyz);

	// Calculate dot product
	colour = lightDiffuse * dot(bumpVec, lightVec);
	
}
	
*/
		mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);
#endif

#if Phase3
		mSceneMgr->setAmbientLight(ColourValue::Black);	// disable ambient lighting
		m_LightPivot = mSceneMgr->getRootSceneNode()->createChildSceneNode();
		// create white light
		Light* l = mSceneMgr->createLight();
		l->setPosition(200, 0, 0);
		l->setDiffuseColour(1, 1, 1);
		l->setSpecularColour(1, 1, 1);
		// create white flare
		BillboardSet* bbs = mSceneMgr->createBillboardSet();
		bbs->setMaterialName("Examples/Flare");
		bbs->createBillboard(200, 0, 0)->setColour(ColourValue::White);
		
		m_LightPivot->attachObject(l);
		m_LightPivot->attachObject(bbs);

#endif
	}
#if Phase4
	void createFrameListener()
	{
		FrameListener = new MyFrameListener(mWindow, mCamera, m_LightPivot);
		mRoot->addFrameListener(FrameListener);
	}
#endif

};
INT WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
	MyApplication app;
	try
	{
		app.go();
	}
	catch( Exception& e)
	{
		MessageBoxA( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
	}
	return 0;
}
#endif

/*rockwall.tga

---------------------------------------------
来自ogre_src_v1-7-4\Samples\Media\materials\textures

---------------------------------------------

*/

/*rockwall_NH.tga

---------------------------------------------
来自ogre_src_v1-7-4\Samples\Media\materials\textures

---------------------------------------------


*/


最终运行结果:

 

来个近写

 




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值