📄 common_vs_fxc.h
字号:
tmp = tmp * linear + c;
gamma = tmp * linear;
return gamma;
#else
return pow( linear, cOOGamma );
#endif
}
float3 AmbientLight( const float3 worldNormal )
{
float3 nSquared = worldNormal * worldNormal;
int3 isNegative = ( worldNormal < 0.0 );
float3 linearColor;
linearColor = nSquared.x * cAmbientCube[isNegative.x] +
nSquared.y * cAmbientCube[isNegative.y+2] +
nSquared.z * cAmbientCube[isNegative.z+4];
return linearColor;
}
float3 SpotLight( const float3 worldPos, const float3 worldNormal, int lightNum )
{
// Direct mapping of current code
float3 lightDir = cLightInfo[lightNum].pos - worldPos;
// normalize light direction, maintain temporaries for attenuation
float lightDistSquared = dot( lightDir, lightDir );
float ooLightDist = rsqrt( lightDistSquared );
lightDir *= ooLightDist;
float3 attenuationFactors;
attenuationFactors = dst( lightDistSquared, ooLightDist );
float flDistanceAttenuation = dot( attenuationFactors, cLightInfo[lightNum].atten );
flDistanceAttenuation = 1.0f / flDistanceAttenuation;
// There's an additional falloff we need to make to get the edges looking good
// and confine the light within a sphere.
float flLinearFactor = saturate( 1.0f - lightDistSquared * cLightInfo[lightNum].atten.w );
flDistanceAttenuation *= flLinearFactor;
// compute n dot l
float nDotL = dot( worldNormal, lightDir );
nDotL = max( cZero, nDotL );
// compute angular attenuation
float flCosTheta = dot( cLightInfo[lightNum].dir, -lightDir );
float flAngularAtten = (flCosTheta - cLightInfo[lightNum].spotParams.z) * cLightInfo[lightNum].spotParams.w;
flAngularAtten = max( cZero, flAngularAtten );
flAngularAtten = pow( flAngularAtten, cLightInfo[lightNum].spotParams.x );
flAngularAtten = min( cOne, flAngularAtten );
return cLightInfo[lightNum].color * flDistanceAttenuation * flAngularAtten * nDotL;
}
float3 PointLight( const float3 worldPos, const float3 worldNormal, int lightNum )
{
// Get light direction
float3 lightDir = cLightInfo[lightNum].pos - worldPos;
// Get light distance squared.
float lightDistSquared = dot( lightDir, lightDir );
// Get 1/lightDistance
float ooLightDist = rsqrt( lightDistSquared );
// Normalize light direction
lightDir *= ooLightDist;
// compute distance attenuation factors.
float3 attenuationFactors;
attenuationFactors.x = 1.0f;
attenuationFactors.y = lightDistSquared * ooLightDist;
attenuationFactors.z = lightDistSquared;
float flDistanceAtten = 1.0f / dot( cLightInfo[lightNum].atten.xyz, attenuationFactors );
// There's an additional falloff we need to make to get the edges looking good
// and confine the light within a sphere.
float flLinearFactor = saturate( 1.0f - lightDistSquared * cLightInfo[lightNum].atten.w );
flDistanceAtten *= flLinearFactor;
// Compute N dot L
float NDotL = dot( worldNormal, lightDir );
NDotL = max( cZero, NDotL );
return cLightInfo[lightNum].color * NDotL * flDistanceAtten;
}
float3 DirectionalLight( const float3 worldNormal, int lightNum )
{
// Compute N dot L
float NDotL = dot( worldNormal, -cLightInfo[lightNum].dir );
NDotL = max( cZero, NDotL );
return cLightInfo[lightNum].color * NDotL;
}
float3 DoLight( const float3 worldPos, const float3 worldNormal,
int lightNum, int lightType )
{
float3 color = 0.0f;
if( lightType == LIGHTTYPE_SPOT )
{
color = SpotLight( worldPos, worldNormal, lightNum );
}
else if( lightType == LIGHTTYPE_POINT )
{
color = PointLight( worldPos, worldNormal, lightNum );
}
else if( lightType == LIGHTTYPE_DIRECTIONAL )
{
color = DirectionalLight( worldNormal, lightNum );
}
return color;
}
float3 DoLightingLinear( const float3 worldPos, const float3 worldNormal,
const float3 staticLightingColor, const int staticLightType,
const int ambientLightType, const int localLightType0,
const int localLightType1 )
{
float3 linearColor = 0.0f;
if( staticLightType == LIGHTTYPE_STATIC )
{
// The static lighting comes in in gamma space and has also been premultiplied by $cOOOverbright
// need to get it into
// linear space so that we can do adds.
linearColor += GammaToLinear( staticLightingColor * cOverbright );
}
if( ambientLightType == LIGHTTYPE_AMBIENT )
{
linearColor += AmbientLight( worldNormal );
}
if( localLightType0 != LIGHTTYPE_NONE )
{
linearColor += DoLight( worldPos, worldNormal, 0, localLightType0 );
}
if( localLightType1 != LIGHTTYPE_NONE )
{
linearColor += DoLight( worldPos, worldNormal, 1, localLightType1 );
}
return linearColor;
}
float3 DoLighting( const float3 worldPos, const float3 worldNormal,
const float3 staticLightingColor, const int staticLightType,
const int ambientLightType, const int localLightType0,
const int localLightType1, const float modulation )
{
float3 returnColor;
// special case for no lighting
if( staticLightType == LIGHTTYPE_NONE &&
ambientLightType == LIGHTTYPE_NONE &&
localLightType0 == LIGHTTYPE_NONE &&
localLightType1 == LIGHTTYPE_NONE )
{
returnColor = float3( 0.0f, 0.0f, 0.0f );
}
else if( staticLightType == LIGHTTYPE_STATIC &&
ambientLightType == LIGHTTYPE_NONE &&
localLightType0 == LIGHTTYPE_NONE &&
localLightType1 == LIGHTTYPE_NONE )
{
// special case for static lighting only
// Don't need to bother converting to linear space in this case.
returnColor = staticLightingColor;
}
else
{
float3 linearColor = DoLightingLinear( worldPos, worldNormal, staticLightingColor,
staticLightType, ambientLightType, localLightType0, localLightType1 );
if (modulation != 1.0f)
{
linearColor *= modulation;
}
// for dx9, we don't need to scale back down to 0..1 for overbrighting.
// FIXME: But we're going to because there's some visual difference between dx8 + dx9 if we don't
// gotta look into that later.
returnColor = HuePreservingColorClamp( cOOOverbright * LinearToGamma( linearColor ) );
}
return returnColor;
}
// returns a linear HDR light value
float3 DoLightingHDR( const float3 worldPos, const float3 worldNormal,
const float3 staticLightingColor, const int staticLightType,
const int ambientLightType, const int localLightType0,
const int localLightType1, const float modulation )
{
float3 returnColor;
// special case for no lighting
if( staticLightType == LIGHTTYPE_NONE &&
ambientLightType == LIGHTTYPE_NONE &&
localLightType0 == LIGHTTYPE_NONE &&
localLightType1 == LIGHTTYPE_NONE )
{
returnColor = float3( 0.0f, 0.0f, 0.0f );
}
else if( staticLightType == LIGHTTYPE_STATIC &&
ambientLightType == LIGHTTYPE_NONE &&
localLightType0 == LIGHTTYPE_NONE &&
localLightType1 == LIGHTTYPE_NONE )
{
// special case for static lighting only
// FIXME!! Should store HDR values per vertex for static prop lighting.
returnColor = GammaToLinear( staticLightingColor * cOverbright );
}
else
{
float3 linearColor = DoLightingLinear( worldPos, worldNormal, staticLightingColor,
staticLightType, ambientLightType, localLightType0, localLightType1 );
if (modulation != 1.0f)
{
linearColor *= modulation;
}
returnColor = linearColor;
}
return returnColor;
}
void CalculateWorldBumpBasis( const float3 worldTangentS, const float3 worldTangentT,
const float3 worldNormal, out float3 worldBumpBasis1,
out float3 worldBumpBasis2, out float3 worldBumpBasis3 )
{
worldBumpBasis1.x = dot( bumpBasisTranspose[0], worldTangentS );
worldBumpBasis1.y = dot( bumpBasisTranspose[0], worldTangentT );
worldBumpBasis1.z = dot( bumpBasisTranspose[0], worldNormal );
worldBumpBasis2.x = dot( bumpBasisTranspose[1], worldTangentS );
worldBumpBasis2.y = dot( bumpBasisTranspose[1], worldTangentT );
worldBumpBasis2.z = dot( bumpBasisTranspose[1], worldNormal );
worldBumpBasis3.x = dot( bumpBasisTranspose[2], worldTangentS );
worldBumpBasis3.y = dot( bumpBasisTranspose[2], worldTangentT );
worldBumpBasis3.z = dot( bumpBasisTranspose[2], worldNormal );
}
void AddBumpedAmbientLight( const float3 worldBumpBasis1, const float3 worldBumpBasis2,
const float3 worldBumpBasis3, const float3 worldNormal,
inout float3 color1, inout float3 color2, inout float3 color3,
inout float3 normalColor )
{
float3 nSquared;
int3 isNegative;
nSquared = worldBumpBasis1 * worldBumpBasis1;
isNegative = ( worldBumpBasis1 < 0.0 );
color1 += nSquared.x * cAmbientCube[isNegative.x] +
nSquared.y * cAmbientCube[isNegative.y+2] +
nSquared.z * cAmbientCube[isNegative.z+4];
nSquared = worldBumpBasis2 * worldBumpBasis2;
isNegative = ( worldBumpBasis2 < 0.0 );
color2 += nSquared.x * cAmbientCube[isNegative.x] +
nSquared.y * cAmbientCube[isNegative.y+2] +
nSquared.z * cAmbientCube[isNegative.z+4];
nSquared = worldBumpBasis3 * worldBumpBasis3;
isNegative = ( worldBumpBasis3 < 0.0 );
color3 += nSquared.x * cAmbientCube[isNegative.x] +
nSquared.y * cAmbientCube[isNegative.y+2] +
nSquared.z * cAmbientCube[isNegative.z+4];
nSquared = worldNormal * worldNormal;
isNegative = ( worldNormal < 0.0 );
normalColor += nSquared.x * cAmbientCube[isNegative.x] +
nSquared.y * cAmbientCube[isNegative.y+2] +
nSquared.z * cAmbientCube[isNegative.z+4];
}
void AddBumpedSpotLight( const float3 worldPos, int lightNum, const float3 worldBumpBasis1,
const float3 worldBumpBasis2, const float3 worldBumpBasis3, const float3 worldNormal,
inout float3 color1, inout float3 color2, inout float3 color3,
inout float3 normalColor )
{
// Get light direction
float3 lightDir = cLightInfo[lightNum].pos - worldPos;
// Get light distance squared.
float lightDistSquared = dot( lightDir, lightDir );
// Get 1/lightDistance
float ooLightDist = rsqrt( lightDistSquared );
// Normalize light direction
lightDir *= ooLightDist;
// compute distance attenuation factors.
float3 attenuationFactors;
attenuationFactors.x = 1.0f;
attenuationFactors.y = lightDistSquared * ooLightDist;
attenuationFactors.z = lightDistSquared;
float3 distanceAtten = 1.0f / dot( cLightInfo[lightNum].atten, attenuationFactors );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -