| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // Defines | |
| // hardcoded for now | |
| #define NUM_WIND_MATRICES 3 | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // Forward declarations. | |
| half3x3 GetWorldTangentBasis(FVertexFactoryInput Input); | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // Shader constants | |
| float4x4 LocalToWorld; | |
| float4x4 PreviousLocalToWorld; | |
| float3x3 WorldToLocal; | |
| float LODAlphaAdjustment; | |
| float WindMatrixOffset; // keeps two instances of the same tree model from using the same wind matrix (range: [0,NUM_WIND_MATRICES]) | |
| float4x4 WindMatrices[NUM_WIND_MATRICES]; // houses all of the wind matrices shared by all geometry types | |
| float4x4 RotationOnlyMatrix; | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // struct FVertexFactoryInterpolants | |
| struct FVertexFactoryInterpolants | |
| { | |
| #if WORLD_COORDS | |
| float4 TangentBasisNormal : COLOR0; | |
| float3 TangentBasisTangent : COLOR1; | |
| #endif | |
| float4 VertexColor : TEXCOORD0; | |
| #if NUM_MATERIAL_TEXCOORDS | |
| float4 TexCoords[(NUM_MATERIAL_TEXCOORDS + 1) / 2] : TEXCOORD1; | |
| #endif | |
| }; | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // GetMaterialParameters | |
| FMaterialParameters GetMaterialParameters(FVertexFactoryInterpolants Interpolants) | |
| { | |
| FMaterialParameters Result; | |
| #if NUM_MATERIAL_TEXCOORDS | |
| UNROLL | |
| for(int CoordinateIndex = 0; CoordinateIndex < NUM_MATERIAL_TEXCOORDS; CoordinateIndex += 2) | |
| { | |
| Result.TexCoords[CoordinateIndex] = Interpolants.TexCoords[CoordinateIndex / 2].xy; | |
| if (CoordinateIndex + 1 < NUM_MATERIAL_TEXCOORDS) | |
| { | |
| Result.TexCoords[CoordinateIndex + 1] = Interpolants.TexCoords[CoordinateIndex / 2].wz; | |
| } | |
| } | |
| #endif | |
| Result.VertexColor = Interpolants.VertexColor; | |
| Result.TangentNormal = 0; | |
| Result.TangentCameraVector = 0; | |
| Result.TangentReflectionVector = 0; | |
| Result.ScreenPosition = 0; | |
| Result.TangentLightVector = 0; | |
| #if WORLD_COORDS | |
| Result.TangentBasisInverse = CalcInvTangentBasis(Interpolants.TangentBasisNormal, Interpolants.TangentBasisTangent); | |
| #endif | |
| return Result; | |
| } | |
| #if NEEDS_LIGHTMAP_COORDINATE | |
| float2 GetLightMapCoordinate(FVertexFactoryInterpolants Interpolants) | |
| { | |
| return 0; | |
| } | |
| #endif | |
| #if NEEDS_VERTEX_LIGHTMAP | |
| void VertexFactoryGetVertexLightMap(FVertexFactoryInput Input,out float4 LightMapA,out float4 LightMapB,out float4 LightMapC) | |
| { | |
| LightMapA = Input.LightMapA; | |
| LightMapB = Input.LightMapB; | |
| LightMapC = Input.LightMapC; | |
| } | |
| #elif NEEDS_SIMPLE_VERTEX_LIGHTMAP | |
| void VertexFactoryGetSimpleVertexLightMap(FVertexFactoryInput Input,out float4 LightMapA) | |
| { | |
| LightMapA = Input.LightMapA; | |
| } | |
| #endif | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // VertexFactoryGetWorldPositionBase | |
| void VertexFactoryGetWorldPositionBase(FVertexFactoryInput Input, out FVertexFactoryInterpolants Interpolants) | |
| { | |
| #if NUM_MATERIAL_TEXCOORDS | |
| // Ensure the unused components of the last packed texture coordinate are initialized. | |
| Interpolants.TexCoords[(NUM_MATERIAL_TEXCOORDS + 1) / 2 - 1] = 0; | |
| UNROLL | |
| for(int CoordinateIndex = 0;CoordinateIndex < NUM_MATERIAL_TEXCOORDS;CoordinateIndex += 2) | |
| { | |
| Interpolants.TexCoords[CoordinateIndex / 2].xy = Input.TexCoords[CoordinateIndex]; | |
| if(CoordinateIndex + 1 < NUM_MATERIAL_TEXCOORDS) | |
| { | |
| Interpolants.TexCoords[CoordinateIndex / 2].wz = Input.TexCoords[CoordinateIndex + 1]; | |
| } | |
| } | |
| #endif | |
| #if WORLD_COORDS | |
| half3x3 WorldTangentBasis = GetWorldTangentBasis(Input); | |
| Interpolants.TangentBasisNormal.xyz = normalize(WorldTangentBasis[2]) * 0.5 + 0.5; | |
| Interpolants.TangentBasisNormal.w = determinant(WorldTangentBasis) * 0.5 + 0.5; | |
| Interpolants.TangentBasisTangent = normalize(WorldTangentBasis[0]) * 0.5 + 0.5; | |
| #endif | |
| Interpolants.VertexColor = float4(0.0f, 0.0f, 0.0f, LODAlphaAdjustment); | |
| } | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // VertexFactoryGetWorldNormal | |
| half3 VertexFactoryGetWorldNormal(FVertexFactoryInput Input) | |
| { | |
| return GetWorldTangentBasis(Input)[2]; | |
| } | |
| /** | |
| * Get the 3x3 tangent basis vectors for this vertex factory | |
| * | |
| * @param Input - vertex input stream structure | |
| * @return 3x3 matrix | |
| */ | |
| float3x3 VertexFactoryGetTangentBasis( FVertexFactoryInput Input ) | |
| { | |
| return GetWorldTangentBasis(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 | |
| ); | |
| } | |
| /////////////////////////////////////////////////////////////////////// | |
| // Modulate_Float | |
| // | |
| // Returns x % y (some compilers generate way too many instructions when | |
| // using the native '%' operator) | |
| float Modulate_Float(float x, float y) | |
| { | |
| return x - (int(x / y) * y); | |
| } | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // WindEffect | |
| float4 WindEffect(float4 vPosition, float4 vWindInfo) | |
| { | |
| // use the random offset to make instances have slightly different wind | |
| vWindInfo.x = Modulate_Float(vWindInfo.x + WindMatrixOffset, NUM_WIND_MATRICES); | |
| vWindInfo.z = Modulate_Float(vWindInfo.z + WindMatrixOffset, NUM_WIND_MATRICES); | |
| // support for arbitrary rotations | |
| float4 vRotatedVert = MulMatrix(vPosition, RotationOnlyMatrix); | |
| // first-level wind effect - interpolate between static position and fully-blown | |
| // wind position by the wind weight value | |
| float4 vWindEffect = lerp(vRotatedVert, MulMatrix(vRotatedVert, WindMatrices[vWindInfo.x]), vWindInfo.y); | |
| // second-level wind effect - interpolate between first-level wind position and | |
| // the fully-blown wind position by the second wind weight value | |
| return lerp(vWindEffect, MulMatrix(vWindEffect, WindMatrices[vWindInfo.z]), vWindInfo.w); | |
| } | |
| /////////////////////////////////////////////////////////////////////// | |
| // RotationMatrix_zAxis | |
| // | |
| // Constructs a Z-axis rotation matrix | |
| float3x3 RotationMatrix_zAxis(float fAngle) | |
| { | |
| // compute sin/cos of fAngle | |
| float2 vSinCos; | |
| sincos(fAngle, vSinCos.x, vSinCos.y); | |
| return float3x3(vSinCos.y, -vSinCos.x, 0.0f, | |
| vSinCos.x, vSinCos.y, 0.0f, | |
| 0.0f, 0.0f, 1.0f); | |
| } | |
| /////////////////////////////////////////////////////////////////////// | |
| // Rotate_zAxis | |
| // | |
| // Returns an updated .xy value | |
| float2 Rotate_zAxis(float fAngle, float3 vPoint) | |
| { | |
| float2 vSinCos; | |
| sincos(fAngle, vSinCos.x, vSinCos.y); | |
| return float2(dot(vSinCos.yx, vPoint.xy), dot(float2(-vSinCos.x, vSinCos.y), vPoint.xy)); | |
| } | |
| /////////////////////////////////////////////////////////////////////// | |
| // RotationMatrix_yAxis | |
| // | |
| // Constructs a Y-axis rotation matrix | |
| float3x3 RotationMatrix_yAxis(float fAngle) | |
| { | |
| // compute sin/cos of fAngle | |
| float2 vSinCos; | |
| sincos(fAngle, vSinCos.x, vSinCos.y); | |
| return float3x3(vSinCos.y, 0.0f, vSinCos.x, | |
| 0.0f, 1.0f, 0.0f, | |
| -vSinCos.x, 0.0f, vSinCos.y); | |
| } | |
| /////////////////////////////////////////////////////////////////////// | |
| // Rotate_yAxis | |
| // | |
| // Returns an updated .xz value | |
| float2 Rotate_yAxis(float fAngle, float3 vPoint) | |
| { | |
| float2 vSinCos; | |
| sincos(fAngle, vSinCos.x, vSinCos.y); | |
| return float2(dot(float2(vSinCos.y, -vSinCos.x), vPoint.xz), dot(vSinCos.xy, vPoint.xz)); | |
| } | |
| /////////////////////////////////////////////////////////////////////// | |
| // RotationMatrix_xAxis | |
| // | |
| // Constructs a X-axis rotation matrix | |
| float3x3 RotationMatrix_xAxis(float fAngle) | |
| { | |
| // compute sin/cos of fAngle | |
| float2 vSinCos; | |
| sincos(fAngle, vSinCos.x, vSinCos.y); | |
| return float3x3(1.0f, 0.0f, 0.0f, | |
| 0.0f, vSinCos.y, -vSinCos.x, | |
| 0.0f, vSinCos.x, vSinCos.y); | |
| } | |
| /////////////////////////////////////////////////////////////////////// | |
| // Rotate_xAxis | |
| // | |
| // Returns an updated .yz value | |
| float2 Rotate_xAxis(float fAngle, float3 vPoint) | |
| { | |
| float2 vSinCos; | |
| sincos(fAngle, vSinCos.x, vSinCos.y); | |
| return float2(dot(vSinCos.yx, vPoint.yz), dot(float2(-vSinCos.x, vSinCos.y), vPoint.yz)); | |
| } | |
Xet Storage Details
- Size:
- 9.42 kB
- Xet hash:
- 9691dc6c5052f8bfd594c1da44ba8cbf34d1fbc6b7ef7d16a7655ff9cb80ac06
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.