您的位置:首页 > 编程语言

OGRE DEMO Fresnel 的关键代码

2011-07-30 11:09 429 查看
Fresnel.h



bool frameRenderingQueued(const FrameEvent &evt)
    {
		// update the fish spline path animations and loop as needed
        mFishAnimTime += evt.timeSinceLastFrame;
        while (mFishAnimTime >= FISH_PATH_LENGTH) mFishAnimTime -= FISH_PATH_LENGTH;

        for (unsigned int i = 0; i < NUM_FISH; i++)
        {
            mFishAnimStates[i]->addTime(evt.timeSinceLastFrame * 2);  // update fish swim animation

			// set the new position based on the spline path and set the direction based on displacement
			Vector3 lastPos = mFishNodes[i]->getPosition();
            mFishNodes[i]->setPosition(mFishSplines[i].interpolate(mFishAnimTime / FISH_PATH_LENGTH));
			mFishNodes[i]->setDirection(mFishNodes[i]->getPosition() - lastPos, Node::TS_PARENT, Vector3::NEGATIVE_UNIT_X);
			mFishNodes[i]->setFixedYawAxis(true);
        }

        return SdkSample::frameRenderingQueued(evt);
    }

    void preRenderTargetUpdate(const RenderTargetEvent& evt)
    {
        mWater->setVisible(false);  // hide the water

        if (evt.source == mReflectionTarget)  // for reflection, turn on camera reflection and hide submerged entities
		{
			mCamera->enableReflection(mWaterPlane);
			for (std::vector<Entity*>::iterator i = mSubmergedEnts.begin(); i != mSubmergedEnts.end(); i++)
				(*i)->setVisible(false);
		}
		else  // for refraction, hide surface entities
		{
			for (std::vector<Entity*>::iterator i = mSurfaceEnts.begin(); i != mSurfaceEnts.end(); i++)
				(*i)->setVisible(false);
		}
    }

    void postRenderTargetUpdate(const RenderTargetEvent& evt)
    {
        mWater->setVisible(true);  // unhide the water

        if (evt.source == mReflectionTarget)  // for reflection, turn off camera reflection and unhide submerged entities
		{
			mCamera->disableReflection();
			for (std::vector<Entity*>::iterator i = mSubmergedEnts.begin(); i != mSubmergedEnts.end(); i++)
				(*i)->setVisible(true);
		}
		else  // for refraction, unhide surface entities
		{
			for (std::vector<Entity*>::iterator i = mSurfaceEnts.begin(); i != mSurfaceEnts.end(); i++)
				(*i)->setVisible(true);
		}
    }






void setupWater()
	{
		// create our reflection & refraction render textures, and setup their render targets
		for (unsigned int i = 0; i < 2; i++)
		{
			TexturePtr tex = TextureManager::getSingleton().createManual(i == 0 ? "refraction" : "reflection",
				ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 512, 512, 0, PF_R8G8B8, TU_RENDERTARGET);

			RenderTarget* rtt = tex->getBuffer()->getRenderTarget();
			rtt->addViewport(mCamera)->setOverlaysEnabled(false);
			rtt->addListener(this);

			if (i == 0) mRefractionTarget = rtt;
			else mReflectionTarget = rtt;
		}

		// create our water plane mesh
        mWaterPlane = Plane(Vector3::UNIT_Y, 0);
        MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
            mWaterPlane, 700, 1300, 10, 10, true, 1, 3, 5, Vector3::UNIT_Z);

		// create a water entity using our mesh, give it the shader material, and attach it to the origin
        mWater = mSceneMgr->createEntity("Water", "water");
        mWater->setMaterialName("Examples/FresnelReflectionRefraction");
        mSceneMgr->getRootSceneNode()->attachObject(mWater);
	}


Examples-Advanced.material

//----------------------------
// Distortion effects
//----------------------------

vertex_program Examples/FresnelRefractReflectVP cg
{
	source Example_Fresnel.cg
	entry_point main_vp
	profiles vs_1_1 arbvp1
}
vertex_program Examples/FresnelRefractReflectVPold cg
{
	source Example_Fresnel.cg
	entry_point main_vp_old
	profiles vs_1_1 arbvp1
}
vertex_program Examples/FresnelRefractReflectVPGLSLES glsles
{
	source Example_FresnelVp.glsles
	entry_point main
	profiles glsles
}

fragment_program Examples/FresnelRefractReflectFP cg
{
	source Example_Fresnel.cg
	entry_point main_fp
	// sorry, ps_1_1 and fp20 can't do this
	profiles ps_2_0 arbfp1
}

fragment_program Examples/FresnelRefractReflectPS asm
{
	source Example_FresnelPS.asm
	// sorry, only for ps_1_4 :)
	syntax ps_1_4
}

fragment_program Examples/FresnelRefractReflectFPGLSLES glsles
{
	source Example_FresnelFp.glsles
	entry_point main
	profiles glsles
}

material Examples/FresnelReflectionRefraction
{
	// ps_2_0 / arbfp1
	technique
	{
		pass 
		{
			
			vertex_program_ref Examples/FresnelRefractReflectVP
			{
				param_named_auto worldViewProjMatrix worldviewproj_matrix
				param_named_auto eyePosition camera_position_object_space
				param_named_auto timeVal time 0.05
				param_named scroll float 1  
				param_named scale float 1 
				param_named noise float 1 
				// scroll and noisePos will need updating per frame
			}
			fragment_program_ref Examples/FresnelRefractReflectFP
			{
				param_named fresnelBias float -0.1 
				param_named fresnelScale float 1.8 
				param_named fresnelPower float 8  
				param_named tintColour float4 0 0.05 0.05 1
				param_named noiseScale float 0.05 
			}
			// Noise
			texture_unit
			{
				// Perlin noise volume
				texture waves2.dds
				// min / mag filtering, no mip
				filtering linear linear none
			}
			// Reflection
			texture_unit
			{
				// Will be filled in at runtime
				texture reflection
				tex_address_mode clamp
			}
			// Refraction
			texture_unit
			{
				// Will be filled in at runtime
				texture refraction
				tex_address_mode clamp
			}
		}
		
			
	}

	// ATI 8500 +
	technique
	{
		pass
		{
			vertex_program_ref Examples/FresnelRefractReflectVPold
			{
				param_named_auto worldViewProjMatrix worldviewproj_matrix
				param_named_auto eyePosition camera_position_object_space
				param_named fresnelBias float -0.3
				param_named fresnelScale float 1.4
				param_named fresnelPower float 8
				param_named_auto timeVal time_0_1 20
				param_named scroll float 1 
				param_named scale float 4 
				param_named noise float 1
				// scroll and noisePos will need updating per frame
			}

			// for ATI RADEON 8500 - 9200
			fragment_program_ref Examples/FresnelRefractReflectPS
			{
				// distortionRange
				param_indexed 0  float 0.025  
				// tintColour
				param_indexed 1  float4 0.05 0.12 0.15 1
			}

			// Noise
			texture_unit
			{
				// Perlin noise volume
				texture perlinvolume.dds 3d
				// min / mag filtering, no mip
				filtering linear linear none
			}
			// Reflection
			texture_unit
			{
				// Will be filled in at runtime
				texture Reflection
				tex_address_mode clamp
			}
			// Refraction
			texture_unit
			{
				// Will be filled in at runtime
				texture Refraction
				tex_address_mode clamp
			}
		}
	}

	// glsles
	technique
	{
		pass 
		{
			vertex_program_ref Examples/FresnelRefractReflectVPGLSLES
			{
				param_named_auto worldViewProjMatrix worldviewproj_matrix
				param_named_auto eyePosition camera_position_object_space
				param_named_auto timeVal time 0.05
				param_named scroll float 1  
				param_named scale float 1 
				param_named noise float 1 
				// scroll and noisePos will need updating per frame
			}
			fragment_program_ref Examples/FresnelRefractReflectFPGLSLES
			{
				param_named fresnelBias float -0.1 
				param_named fresnelScale float 1.8 
				param_named fresnelPower float 8  
				param_named tintColour float4 0 0.05 0.05 1
				param_named noiseScale float 0.05 
			}
			// Noise
			texture_unit
			{
				// Perlin noise volume
				texture waves2.dds
				// min / mag filtering, no mip
				filtering linear linear none
			}
			// Reflection
			texture_unit
			{
				// Will be filled in at runtime
				texture reflection
				tex_address_mode clamp
			}
			// Refraction
			texture_unit
			{
				// Will be filled in at runtime
				texture refraction
				tex_address_mode clamp
			}
		}
	}
}


Example_Fresnel.cg



// Vertex program for fresnel reflections / refractions
void main_vp(
		float4 pos			: POSITION,
		float4 normal		: NORMAL,
		float2 tex			: TEXCOORD0,
		
		out float4 oPos		: POSITION,
		out float3 noiseCoord : TEXCOORD0,
		out float4 projectionCoord : TEXCOORD1,
		out float3 oEyeDir : TEXCOORD2, 
		out float3 oNormal : TEXCOORD3, 

		uniform float4x4 worldViewProjMatrix,
		uniform float3 eyePosition, // object space
		uniform float timeVal,
		uniform float scale,  // the amount to scale the noise texture by
		uniform float scroll, // the amount by which to scroll the noise
		uniform float noise  // the noise perturb as a factor of the  time
		)
{
	oPos = mul(worldViewProjMatrix, pos);
	// Projective texture coordinates, adjust for mapping
	float4x4 scalemat = float4x4(0.5,   0,   0, 0.5, 
	                               0,-0.5,   0, 0.5,
								   0,   0, 0.5, 0.5,
								   0,   0,   0,   1);
	projectionCoord = mul(scalemat, oPos);
	// Noise map coords
	noiseCoord.xy = (tex + (timeVal * scroll)) * scale;
	noiseCoord.z = noise * timeVal;

	oEyeDir = normalize(pos.xyz - eyePosition); 
	oNormal = normal.rgb; 
	
}

// Fragment program for distorting a texture using a 3D noise texture
void main_fp(
		float3 noiseCoord			: TEXCOORD0,
		float4 projectionCoord		: TEXCOORD1,
		float3 eyeDir				: TEXCOORD2,
		float3 normal				: TEXCOORD3,
		
		out float4 col		: COLOR,
		
		uniform float4 tintColour,
		uniform float noiseScale, 
		uniform float fresnelBias,
		uniform float fresnelScale,
		uniform float fresnelPower,
		uniform sampler2D noiseMap : register(s0),
		uniform sampler2D reflectMap : register(s1),
		uniform sampler2D refractMap : register(s2)
		)
{
	// Do the tex projection manually so we can distort _after_
	float2 final = projectionCoord.xy / projectionCoord.w;

	// Noise
	float3 noiseNormal = (tex2D(noiseMap, (noiseCoord.xy / 5)).rgb - 0.5).rbg * noiseScale;
	final += noiseNormal.xz;

	// Fresnel
	//normal = normalize(normal + noiseNormal.xz);
	float fresnel = fresnelBias + fresnelScale * pow(1 + dot(eyeDir, normal), fresnelPower);

	// Reflection / refraction
	float4 reflectionColour = tex2D(reflectMap, final);
	float4 refractionColour = tex2D(refractMap, final) + tintColour;

	// Final colour
	col = lerp(refractionColour, reflectionColour, fresnel);

}

// Old version to match ATI PS 1.3 implementation
void main_vp_old(
		float4 pos			: POSITION,
		float4 normal		: NORMAL,
		float2 tex			: TEXCOORD0,
		
		out float4 oPos		: POSITION,
		out float fresnel   : COLOR,
		out float3 noiseCoord : TEXCOORD0,
		out float4 projectionCoord : TEXCOORD1,

		uniform float4x4 worldViewProjMatrix,
		uniform float3 eyePosition, // object space
		uniform float fresnelBias,
		uniform float fresnelScale,
		uniform float fresnelPower,
		uniform float timeVal,
		uniform float scale,  // the amount to scale the noise texture by
		uniform float scroll, // the amount by which to scroll the noise
		uniform float noise  // the noise perturb as a factor of the  time
		)
{
	oPos = mul(worldViewProjMatrix, pos);
	// Projective texture coordinates, adjust for mapping
	float4x4 scalemat = float4x4(0.5,   0,   0, 0.5, 
	                               0,-0.5,   0, 0.5,
								   0,   0, 0.5, 0.5,
								   0,   0,   0,   1);
	projectionCoord = mul(scalemat, oPos);
	// Noise map coords
	noiseCoord.xy = (tex + (timeVal * scroll)) * scale;
	noiseCoord.z = noise * timeVal;

	// calc fresnel factor (reflection coefficient)
	float3 eyeDir = normalize(pos.xyz - eyePosition);
	fresnel = fresnelBias + fresnelScale * pow(1 + dot(eyeDir, normal), fresnelPower);
	
}


Example_FresnelFp.glsles



#version 100

precision highp float;
precision highp int;
precision lowp sampler2D;
precision lowp samplerCube;

uniform vec4 tintColour;
uniform float noiseScale;
uniform float fresnelBias;
uniform float fresnelScale;
uniform float fresnelPower;
uniform sampler2D noiseMap;
uniform sampler2D reflectMap;
uniform sampler2D refractMap;

varying vec3 noiseCoord;
varying vec4 projectionCoord;
varying vec3 eyeDir;
varying vec3 normal;

// Fragment program for distorting a texture using a 3D noise texture
void main()
{
	// Do the tex projection manually so we can distort _after_
	vec2 final = projectionCoord.xy / projectionCoord.w;

	// Noise
	vec3 noiseNormal = (texture2D(noiseMap, (noiseCoord.xy / 5.0)).rgb - 0.5).rbg * noiseScale;
	final += noiseNormal.xz;

	// Fresnel
	//normal = normalize(normal + noiseNormal.xz);
	float fresnel = fresnelBias + fresnelScale * pow(1.0 + dot(eyeDir, normal), fresnelPower);

	// Reflection / refraction
	vec4 reflectionColour = texture2D(reflectMap, final);
	vec4 refractionColour = texture2D(refractMap, final) + tintColour;

	// Final colour
	gl_FragColor = mix(refractionColour, reflectionColour, fresnel);
}


Example_FresnelVp.glsles



#version 100

precision highp float;
precision highp int;
precision lowp sampler2D;
precision lowp samplerCube;

attribute vec4 uv0;
attribute vec4 vertex;

uniform mat4 worldViewProjMatrix;
uniform vec3 eyePosition; // object space
uniform float timeVal;
uniform float scale;  // the amount to scale the noise texture by
uniform float scroll; // the amount by which to scroll the noise
uniform float noise;  // the noise perturb as a factor of the  time

varying vec3 noiseCoord;
varying vec4 projectionCoord;
varying vec3 eyeDir;
varying vec3 normal;

// Vertex program for fresnel reflections / refractions
void main()
{
	gl_Position = worldViewProjMatrix * vertex;
	// Projective texture coordinates, adjust for mapping
	mat4 scalemat = mat4(0.5, 0.0, 0.0, 0.5, 
                         0.0, -0.5, 0.0, 0.5,
                         0.0, 0.0, 0.5, 0.5,
                         0.0, 0.0, 0.0, 1.0);
	projectionCoord = scalemat * gl_Position;

	// Noise map coords
	noiseCoord.xy = (uv0.xy + (timeVal * scroll)) * scale;
	noiseCoord.z = noise * timeVal;

	eyeDir = normalize(vertex.xyz - eyePosition); 
}



Example_FresnelPS.asm



ps.1.4
  // conversion from Cg generated ARB_fragment_program to ps.1.4 by NFZ
  // command line args: -profile arbfp1 -entry main_fp
  // program main_fp
  // c0 : distortionRange
  // c1 : tintColour
  // testure 0 : noiseMap
  // texture 1 : reflectMap
  // texture 2 : refractMap
  // v0.x : fresnel 
  // t0.xyz : noiseCoord
  // t1.xyw : projectionCoord 

def c2, 2, 1, 0, 0

  // Cg:	distort.x = tex3D(noiseMap, noiseCoord).x;
  // arbfp1:	TEX R0.x, fragment.texcoord[0], texture[0], 3D;
  // sample noise map using noiseCoord in TEX unit 0 

texld r0, t0.xyz

  // get projected texture coordinates from TEX coord 1
  // will be used in phase 2

texcrd r1.xy, t1_dw.xyw
mov r1.z, c2.y

  // Cg:	distort.y = tex3D(noiseMap, noiseCoord + yoffset).x;
  // arbfp1:	ADD R1.xyz, fragment.texcoord[0], c1;
  // arbfp1:	TEX R1.x, R1, texture[0], 3D;
  // arbfp1:	MOV R0.y, R1.x;

  // Cg:	distort = (distort * 2 - 1) * distortionRange;
  // arbfp1:	MAD R0.xy, R0, c0.x, -c0.y;
  // arbfp1:	MUL R0.xy, R0, u0.x;
  // (distort * 2 - 1) same as 2*(distort -.5) so use _bx2

  // Cg:	final = projectionCoord.xy / projectionCoord.w;
  // Cg:	final += distort;
  // arbfp1:	RCP R0.w, fragment.texcoord[1].w;
  // arbfp1:	MAD R0.xy, fragment.texcoord[1], R0.w, R0;
  // 	final = (distort *  projectionCoord.w) + projectionCoord.xy
  // for ps.1.4 have to re-arrange things a bit to perturb projected texture coordinates

mad r0.xyz, r0_bx2, c0.x, r1

phase

  // do dependant texture reads
  // Cg:	reflectionColour = tex2D(reflectMap, final);
  // arbfp1:	TEX R0, R0, texture[1], 2D;
  // sampe reflectMap using dependant read : texunit 1 

texld r1, r0.xyz

  // Cg:	refractionColour = tex2D(refractMap, final) + tintColour;
  // arbfp1:	TEX R1, R0, texture[2], 2D;
  // sample refractMap : texunit 2 

texld r2, r0.xyz

  // adding tintColour that is in global c1
  // arbfp1:	ADD R1, R1, u1;

add r2, r2, c1

  // Cg:	col = lerp(refractionColour, reflectionColour, fresnel);
  // arbfp1:	ADD R0, R0, -R1;
  // arbfp1:	MAD result.color, fragment.color.primary.x, R0, R1;

lrp r0, v0.x, r1, r2




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: