utkutuzcu/tst / Engine /Shaders /CompilingShader-VertexFactory.usf
utkutuzcu's picture
download
raw
8.68 kB
/*=============================================================================
ParticleSpriteVertexFactory.hlsl: Particle vertex factory shader code.
Shared by standard sprite particles and SubUV sprite particles.
Copyright 1998-2008 Epic Games, Inc. All Rights Reserved.
=============================================================================*/
float4 CameraWorldPosition;
float4 CameraRight;
float4 CameraUp;
float4 ScreenAlignment;
float4x4 LocalToWorld;
// The source index is which entry in the AxisRotationVectors array is the 'source'.
float AxisRotationVectorSourceIndex;
// The code assumes:
// the right vector will be in slot 0.
// the up vector will be in slot 1.
float4 AxisRotationVectors[NUM_AXIS_ROTATION_VECTORS];
// The result scalars are used to determine which method is being used.
// The values are as follows:
// x - multiplied by the standard camera right/up values
// y - multiplied by the velocity right/up values
// z - multiplied by the axis rotation right/up values
// The multiplies are summed together to give the final right/up
float3 ParticleUpRightResultScalars;
struct FVertexFactoryInput
{
float4 Position : POSITION;
float4 OldPosition : NORMAL;
float3 Size : TANGENT;
float2 TexCoord : TEXCOORD0;
float Rotation : BLENDWEIGHT0;
#if SUBUV_PARTICLES
float2 TexCoord1 : TEXCOORD1;
float4 Interp_Sizer : TEXCOORD2;
float4 Color : TEXCOORD3;
#else //#if SUBUV_PARTICLES
float4 Color : TEXCOORD1;
#endif //#if SUBUV_PARTICLES
};
struct FVertexFactoryInterpolants
{
#if WORLD_COORDS
// xyz=normal w=determinant
float4 TangentBasisNormal : COLOR0;
float3 TangentBasisTangent : COLOR1;
#endif
float2 TexCoord : TEXCOORD0;
#if SUBUV_PARTICLES
float2 TexCoord1 : TEXCOORD1;
float4 Interp_Sizer : TEXCOORD2;
float4 Color : TEXCOORD3;
#else //#if SUBUV_PARTICLES
float4 Color : TEXCOORD1;
#endif //#if SUBUV_PARTICLES
};
FMaterialParameters GetMaterialParameters(FVertexFactoryInterpolants Interpolants)
{
FMaterialParameters Result;
#if NUM_MATERIAL_TEXCOORDS
#if SUBUV_PARTICLES
#if NUM_MATERIAL_TEXCOORDS >= 1
Result.TexCoords[0] = Interpolants.TexCoord;
#if NUM_MATERIAL_TEXCOORDS >= 2
Result.TexCoords[1] = Interpolants.TexCoord1;
#if NUM_MATERIAL_TEXCOORDS >= 3
Result.TexCoords[2] = Interpolants.Interp_Sizer.xy;
#endif // >= 3
#endif // >= 2
#endif // >= 1
#if NUM_MATERIAL_TEXCOORDS > 3
for(int CoordinateIndex = 3;CoordinateIndex < NUM_MATERIAL_TEXCOORDS;CoordinateIndex++)
Result.TexCoords[CoordinateIndex] = Interpolants.TexCoord;
#endif // > 3
#else //#if SUBUV_PARTICLES
for(int CoordinateIndex = 0;CoordinateIndex < NUM_MATERIAL_TEXCOORDS;CoordinateIndex++)
Result.TexCoords[CoordinateIndex] = Interpolants.TexCoord;
#endif //#if SUBUV_PARTICLES
#endif //#if NUM_MATERIAL_TEXCOORDS
Result.VertexColor = Interpolants.Color;
Result.TangentNormal = 0;
Result.TangentCameraVector = 0;
Result.TangentReflectionVector = 0;
Result.TangentLightVector = 0;
Result.ScreenPosition = 0;
#if WORLD_COORDS
Result.TangentBasisInverse = CalcInvTangentBasis(Interpolants.TangentBasisNormal,Interpolants.TangentBasisTangent);
#endif
return Result;
}
#if !VERTEX_LIGHTMAP // AJS: If this is an emissive+vertex light-map shader, we can save an interpolator by skipping the light-map coordinate.
float2 GetLightMapCoordinate(FVertexFactoryInterpolants Interpolants)
{
#if SUBUV_PARTICLES
return Interpolants.TexCoord[0];
#else //#if SUBUV_PARTICLES
return Interpolants.TexCoord;
#endif //#if SUBUV_PARTICLES
}
#endif //#if !VERTEX_LIGHTMAP
float3 SafeNormalize(float3 V)
{
return V / sqrt(max(dot(V,V),0.01));
}
void GetTangents(FVertexFactoryInput Input,out float4 Right,out float4 Up)
{
float4 Position = MulMatrix(LocalToWorld, Input.Position),
OldPosition = MulMatrix(LocalToWorld, Input.OldPosition);
float3 CameraDirection = SafeNormalize(CameraWorldPosition.xyz - Position.xyz),
ParticleDirection = SafeNormalize(Position.xyz - OldPosition.xyz);
float4 Right_Square = CameraRight,
Up_Square = CameraUp;
float4 Right_Rotated = (-1.0 * cos(Input.Rotation) * Up_Square) + (sin(Input.Rotation) * Right_Square),
Up_Rotated = ( sin(Input.Rotation) * Up_Square) + (cos(Input.Rotation) * Right_Square);
float4 Right_Velocity = float4(SafeNormalize(cross(CameraDirection, ParticleDirection )), 0.0),
Up_Velocity = float4(-ParticleDirection, 0.0);
// The index stored in the x component of AxisRotationVectorIndices indicates the 'source'.
// Calculate the new axis by crossing this with the CameraDirection
float4 AxisRotationResultVectors[2];
int ARVIndex = AxisRotationVectorSourceIndex;
float4 AxisSource = AxisRotationVectors[ARVIndex];
float4 Axis_Calculation = float4(SafeNormalize(cross(CameraDirection, AxisSource.xyz)), 0.0) * AxisSource.w;
// The w component of the rotation vector should 'clear' any negation that was performed.
AxisRotationResultVectors[0] = (ARVIndex != 0) ? Axis_Calculation : AxisSource;
AxisRotationResultVectors[1] = (ARVIndex == 0) ? Axis_Calculation : AxisSource;
// Clear the w component of the result
AxisRotationResultVectors[0].w = 0.0f;
AxisRotationResultVectors[1].w = 0.0f;
Right = (Right_Rotated * ParticleUpRightResultScalars.x) +
(Right_Velocity * ParticleUpRightResultScalars.y) +
(AxisRotationResultVectors[0] * ParticleUpRightResultScalars.z);
Up = (Up_Rotated * ParticleUpRightResultScalars.x) +
(Up_Velocity * ParticleUpRightResultScalars.y) +
(AxisRotationResultVectors[1] * ParticleUpRightResultScalars.z);
/***
// enum EParticleScreenAlignment
// {
// PSA_Square,
// PSA_Rectangle,
// PSA_Velocity
// };
Right = ScreenAlignment.x > 1.5f ? Right_Velocity : Right_Rotated;
Up = ScreenAlignment.x > 1.5f ? Up_Velocity : Up_Rotated;
***/
}
float4 CalcWorldPosition(FVertexFactoryInput Input)
{
float4 WorldPosition = MulMatrix(LocalToWorld,Input.Position);
float4 Right,
Up;
GetTangents(Input,Right,Up);
#if SUBUV_PARTICLES
WorldPosition += Input.Size.x * (Input.Interp_Sizer.z - 0.5) * Right;
WorldPosition += Input.Size.y * (Input.Interp_Sizer.w - 0.5) * Up;
#else //#if SUBUV_PARTICLES
WorldPosition += Input.Size.x * (Input.TexCoord.x - 0.5) * Right;
WorldPosition += Input.Size.y * (Input.TexCoord.y - 0.5) * Up;
#endif //#if SUBUV_PARTICLES
return WorldPosition;
}
/** derive basis vectors */
float3x3 CalcTangentBasis(FVertexFactoryInput Input)
{
float4 Right,
Up;
GetTangents(Input,Right,Up);
return float3x3(
Right.xyz,
Up.xyz,
normalize(cross(Right.xyz,Up.xyz))
);
}
float4 VertexFactoryGetWorldPosition(FVertexFactoryInput Input)
{
return CalcWorldPosition(Input);
}
FVertexFactoryInterpolants VertexFactoryGetInterpolants(FVertexFactoryInput Input)
{
FVertexFactoryInterpolants Interpolants;
Interpolants.TexCoord = Input.TexCoord;
Interpolants.Color = Input.Color;
#if SUBUV_PARTICLES
Interpolants.TexCoord1 = Input.TexCoord1;
Interpolants.Interp_Sizer = Input.Interp_Sizer;
#endif //SUBUV_PARTICLES
#if WORLD_COORDS
float3x3 TangentBasis = CalcTangentBasis(Input);
Interpolants.TangentBasisNormal = float4(TangentBasis[2],determinant(TangentBasis)) * 0.5 + 0.5;
Interpolants.TangentBasisTangent = TangentBasis[0] * 0.5 + 0.5;
#endif
return Interpolants;
}
float4 VertexFactoryGetPreviousWorldPosition(FVertexFactoryInput Input)
{
return VertexFactoryGetWorldPosition(Input);
}
/**
* Get the 3x3 tangent basis vectors for this vertex factory
*
* @param Input - vertex input stream structure
* @return 3x3 matrix
*/
float3x3 VertexFactoryGetTangentBasis( FVertexFactoryInput Input )
{
return CalcTangentBasis(Input);
}
/**
* Transform a vector from world space to tangent space
*
* @param Input - vertex input stream structure
* @param TangentBasis - 3x3 matrix to transform to tangent space
* @param WorldVector - vector in world space to transform
* @return vector in tangent space
*/
float3 VertexFactoryWorldToTangentSpace( FVertexFactoryInput Input, float3x3 TangentBasis, float3 WorldVector )
{
// we use a straight mul here because we are generating the matrix, so we don't worry about column major vs row major (which is what MulMatrix manages per-platform)
return mul(
TangentBasis,
WorldVector
);
}
half3 VertexFactoryGetWorldNormal(FVertexFactoryInput Input)
{
float3x3 TangentBasis = VertexFactoryGetTangentBasis(Input);
return TangentBasis[2];
}

Xet Storage Details

Size:
8.68 kB
·
Xet hash:
c07d9dd3a66358a544cd549dd35ff52ca9a5233e6bececa632eb66664b883766

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.