⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 common_vs_fxc.h

📁 hl2 source code. Do not use it illegal.
💻 H
📖 第 1 页 / 共 3 页
字号:
// This is where all common code for pixel shaders go.
#include "common_fxc.h"

#define LIGHTTYPE_NONE				0
#define LIGHTTYPE_STATIC			1
#define LIGHTTYPE_SPOT				2
#define LIGHTTYPE_POINT				3
#define LIGHTTYPE_DIRECTIONAL		4
#define LIGHTTYPE_AMBIENT			5

static const int g_StaticLightTypeArray[22] = {
	LIGHTTYPE_NONE, LIGHTTYPE_STATIC, 
	LIGHTTYPE_NONE, LIGHTTYPE_NONE, LIGHTTYPE_NONE, LIGHTTYPE_NONE, LIGHTTYPE_NONE, 
	LIGHTTYPE_NONE, LIGHTTYPE_NONE, LIGHTTYPE_NONE, LIGHTTYPE_NONE, LIGHTTYPE_NONE, 
	LIGHTTYPE_STATIC, LIGHTTYPE_STATIC, LIGHTTYPE_STATIC, LIGHTTYPE_STATIC, LIGHTTYPE_STATIC, 
	LIGHTTYPE_STATIC, LIGHTTYPE_STATIC, LIGHTTYPE_STATIC, LIGHTTYPE_STATIC, LIGHTTYPE_STATIC
};
 
static const int g_AmbientLightTypeArray[22] = {
	LIGHTTYPE_NONE, LIGHTTYPE_NONE, 
	LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, 
	LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, 
	LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, 
	LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT, LIGHTTYPE_AMBIENT
};

static const int g_LocalLightType0Array[22] = {
	LIGHTTYPE_NONE, LIGHTTYPE_NONE, 
	LIGHTTYPE_NONE, LIGHTTYPE_SPOT, LIGHTTYPE_POINT, LIGHTTYPE_DIRECTIONAL, LIGHTTYPE_SPOT, LIGHTTYPE_SPOT, 
	LIGHTTYPE_SPOT, LIGHTTYPE_POINT, LIGHTTYPE_POINT, LIGHTTYPE_DIRECTIONAL,
	LIGHTTYPE_NONE, LIGHTTYPE_SPOT, LIGHTTYPE_POINT, LIGHTTYPE_DIRECTIONAL, LIGHTTYPE_SPOT, LIGHTTYPE_SPOT, 
	LIGHTTYPE_SPOT, LIGHTTYPE_POINT, LIGHTTYPE_POINT, LIGHTTYPE_DIRECTIONAL
};

static const int g_LocalLightType1Array[22] = {
	LIGHTTYPE_NONE, LIGHTTYPE_NONE, 
	LIGHTTYPE_NONE, LIGHTTYPE_NONE, LIGHTTYPE_NONE, LIGHTTYPE_NONE, LIGHTTYPE_SPOT, LIGHTTYPE_POINT, LIGHTTYPE_DIRECTIONAL, LIGHTTYPE_POINT, LIGHTTYPE_DIRECTIONAL, LIGHTTYPE_DIRECTIONAL,
	LIGHTTYPE_NONE, LIGHTTYPE_NONE, LIGHTTYPE_NONE, LIGHTTYPE_NONE, LIGHTTYPE_SPOT, LIGHTTYPE_POINT, 
	LIGHTTYPE_DIRECTIONAL, LIGHTTYPE_POINT, LIGHTTYPE_DIRECTIONAL, LIGHTTYPE_DIRECTIONAL
};

#define FOGTYPE_RANGE				0
#define FOGTYPE_HEIGHT				1

#define COMPILE_ERROR ( 1/0; )

// -------------------------
// CONSTANTS
// -------------------------
//const float4 cConstants0				: register(c0);

#define cZero	0.0f
#define cOne	1.0f
#define cTwo	2.0f
#define cHalf	0.5f

#pragma def ( vs, c0, 0.0f, 1.0f, 2.0f, 0.5f )

const float4 cConstants1				: register(c1);
#define cOOGamma			cConstants1.x
#define cOverbright			cConstants1.y
#define cOneThird			cConstants1.z
#define cOOOverbright		cConstants1.w

const float4 cEyePosWaterZ				: register(c2);
#define cEyePos			cEyePosWaterZ.xyz

// This is still used by asm stuff.
const float4 cObsoleteLightIndex		: register(c3);

const float4x4 cModelViewProj			: register(c4);
const float4x4 cViewProj				: register(c8);
const float4x4 cModelView				: register(c12);

const float4 cFogParams					: register(c16);
#define cFogEndOverFogRange cFogParams.x
#define cFogOne cFogParams.y
#define cHeightClipZ cFogParams.z
#define cOOFogRange cFogParams.w

const float4x4 cViewModel				: register(c17);

const float3 cAmbientCube[6]			: register(c21);

struct LightInfo
{
	float4 color;
	float4 dir;
	float4 pos;
	float4 spotParams;
	float4 atten;
};

LightInfo cLightInfo[2]					: register(c27);

const float4 cClipParams				: register(c37);
#define cClipDirection cClipParams.x
#define cClipDirectionTimesHeightClipZ cClipParams.y

const float4 cModulationColor			: register(c38);

static const int cModel0Index = 42;
const float4x3 cModel[16]				: register(c42);

// last cmodel is c89
// c90-c95 are reserved for shader specific constants. .need to make sure that we don't
// shadow these, or we need to reserve them here.

float RangeFog( const float3 projPos )
{
	return -projPos.z * cOOFogRange + cFogEndOverFogRange;
}

float WaterFog( const float3 worldPos, const float3 projPos )
{
	float4 tmp;
	
	tmp.xy = cEyePosWaterZ.wz - worldPos.z;

	// tmp.x is the distance from the water surface to the vert
	// tmp.y is the distance from the eye position to the vert

	// if $tmp.x < 0, then set it to 0
	// This is the equivalent of moving the vert to the water surface if it's above the water surface
	
	tmp.x = max( cZero, tmp.x );

	// $tmp.w = $tmp.x / $tmp.y
	tmp.w = tmp.x / tmp.y;

	tmp.w *= projPos.z;

	// $tmp.w is now the distance that we see through water.

	return -tmp.w * cOOFogRange + cFogOne;
}

float CalcFog( const float3 worldPos, const float3 projPos, const int fogType )
{
	if( fogType == FOGTYPE_RANGE )
	{
		return RangeFog( projPos );
	}
	else
	{
		return WaterFog( worldPos, projPos );
	}
}

void SkinPosition( int numBones, const float4 modelPos, 
                   const float4 boneWeights, float4 fBoneIndices,
				   out float3 worldPos )
{
	int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices );

	if( numBones == 0 )
	{
		worldPos = mul4x3( modelPos, cModel[0] );
	}
	else if( numBones == 1 )
	{
		worldPos = mul4x3( modelPos, cModel[boneIndices[0]] );
	}
	else if( numBones == 2 )
	{
		float4x3 blendMatrix = cModel[boneIndices[0]] * boneWeights[0] +
							   cModel[boneIndices[1]] * boneWeights[1];
		worldPos = mul4x3( modelPos, blendMatrix );
	}
	else // if( numBones == 3 )
	{
		float4x3 mat1 = cModel[boneIndices[0]];
		float4x3 mat2 = cModel[boneIndices[1]];
		float4x3 mat3 = cModel[boneIndices[2]];

		float weight2 = 1.0f - boneWeights[0] - boneWeights[1];

		float4x3 blendMatrix = mat1 * boneWeights[0] + mat2 * boneWeights[1] + mat3 * weight2;
		worldPos = mul4x3( modelPos, blendMatrix );
	}
}

void SkinPositionAndNormal( int numBones, const float4 modelPos, const float3 modelNormal,
                            const float4 boneWeights, float4 fBoneIndices,
						    out float3 worldPos, out float3 worldNormal )
{
	int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices );

	if( numBones == 0 )
	{
		worldPos = mul4x3( modelPos, cModel[0] );
		worldNormal = mul3x3( modelNormal, ( const float3x3 )cModel[0] );
	}
	else if( numBones == 1 )
	{
		worldPos = mul4x3( modelPos, cModel[boneIndices[0]] );
		worldNormal = mul3x3( modelNormal, ( const float3x3 )cModel[boneIndices[0]] );
	}
	else if( numBones == 2 )
	{
		float4x3 blendMatrix = cModel[boneIndices[0]] * boneWeights[0] +
							   cModel[boneIndices[1]] * boneWeights[1];
		worldPos = mul4x3( modelPos, blendMatrix );
		worldNormal = mul3x3( modelNormal, ( float3x3 )blendMatrix );
	}
	else // if( numBones == 3 )
	{
		float4x3 mat1 = cModel[boneIndices[0]];
		float4x3 mat2 = cModel[boneIndices[1]];
		float4x3 mat3 = cModel[boneIndices[2]];

		float weight2 = 1.0f - boneWeights[0] - boneWeights[1];

		float4x3 blendMatrix = mat1 * boneWeights[0] + mat2 * boneWeights[1] + mat3 * weight2;
		worldPos = mul4x3( modelPos, blendMatrix );
		worldNormal = mul3x3( modelNormal, ( float3x3 )blendMatrix );
	}
}

// Is it worth keeping SkinPosition and SkinPositionAndNormal around since the optimizer
// gets rid of anything that isn't used?
void SkinPositionNormalAndTangentSpace( 
#ifdef USE_CONDITIONALS
						   bool bZeroBones, bool bOneBone, bool bTwoBones,
#else
						   int numBones, 
#endif
						    const float4 modelPos, const float3 modelNormal, 
							const float4 modelTangentS,
                            const float4 boneWeights, float4 fBoneIndices,
						    out float3 worldPos, out float3 worldNormal, 
							out float3 worldTangentS, out float3 worldTangentT )
{
	int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices );

#ifdef USE_CONDITIONALS
	if( bZeroBones )
#else
	if( numBones == 0 )
#endif
	{
//		worldPos = mul( float4( modelPos, 1.0f ), cModel[0] );
		worldPos = mul4x3( modelPos, cModel[0] );
		worldNormal = mul3x3( modelNormal, ( const float3x3 )cModel[0] );
		worldTangentS = mul3x3( ( float3 )modelTangentS, ( const float3x3 )cModel[0] );
	}
#ifdef USE_CONDITIONALS
	else if( bOneBone )
#else
	else if( numBones == 1 )
#endif
	{
		worldPos = mul4x3( modelPos, cModel[boneIndices[0]] );
		worldNormal = mul3x3( modelNormal, ( const float3x3 )cModel[boneIndices[0]] );
		worldTangentS = mul3x3( ( float3 )modelTangentS, ( const float3x3 )cModel[boneIndices[0]] );
	}
#ifdef USE_CONDITIONALS
	else if( bTwoBones )
#else
	else if( numBones == 2 )
#endif
	{
		float4x3 blendMatrix = cModel[boneIndices[0]] * boneWeights[0] +
							   cModel[boneIndices[1]] * boneWeights[1];
		worldPos = mul4x3( modelPos, blendMatrix );
		worldNormal = mul3x3( modelNormal, ( float3x3 )blendMatrix );
		worldTangentS = mul3x3( ( float3 )modelTangentS, ( const float3x3 )blendMatrix );
	}
	else // if( numBones == 3 )
	{
		float4x3 mat1 = cModel[boneIndices[0]];
		float4x3 mat2 = cModel[boneIndices[1]];
		float4x3 mat3 = cModel[boneIndices[2]];

		float weight2 = 1.0f - boneWeights[0] - boneWeights[1];

		float4x3 blendMatrix = mat1 * boneWeights[0] + mat2 * boneWeights[1] + mat3 * weight2;
		worldPos = mul4x3( modelPos, blendMatrix );
		worldNormal = mul3x3( modelNormal, ( float3x3 )blendMatrix );
		worldTangentS = mul3x3( ( float3 )modelTangentS, ( const float3x3 )blendMatrix );
	}
	worldTangentT = cross( worldNormal, worldTangentS ) * modelTangentS.w;
}

// FIXME: change this to half3 when ATI fixes their driver bug.
// FIXME: Try to get this to generate a lit instruction
float3 GammaToLinear( const float3 gamma )
{
#if 0
	return 0.962491f * gamma * gamma;
#else
	return pow( gamma, 1.0f / cOOGamma );
#endif
}

// FIXME: change this to half3 when ATI fixes their driver bug.
// FIXME: Try to get this to generate a lit instruction
float3 LinearToGamma( const float3 linear )
{
#if 0
	// This is a good approx.
	static const float a = 2.314217438285954f;
	static const float b = -4.377606146152142f;
	static const float c = 3.116082349104176f;

	float3 gamma, tmp;
	tmp = a * linear + b;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -