qdp

HLSL Example

qdp
Mar 2nd, 2023 (edited)
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 104.04 KB | Gaming | 0 0
  1. This code is provided for educational purposes only!
  2.  
  3. // Copyright Epic Games, Inc. All Rights Reserved.
  4.  
  5. /**
  6.  * MaterialTemplate.usf: Filled in by FHLSLMaterialTranslator::GetMaterialShaderCode for each material being compiled.
  7.  */
  8.  
  9. #include "/Engine/Private/SceneTexturesCommon.ush"
  10. #include "/Engine/Private/EyeAdaptationCommon.ush"
  11. #include "/Engine/Private/Random.ush"
  12. #include "/Engine/Private/SobolRandom.ush"
  13. #include "/Engine/Private/MonteCarlo.ush"
  14. #include "/Engine/Generated/UniformBuffers/Material.ush"
  15. #include "/Engine/Private/DepthOfFieldCommon.ush"
  16. #include "/Engine/Private/CircleDOFCommon.ush"
  17. #include "/Engine/Private/GlobalDistanceFieldShared.ush"
  18. #include "/Engine/Private/PhysicsFieldSampler.ush"
  19. #include "/Engine/Private/SceneData.ush"
  20. #include "/Engine/Private/HairShadingCommon.ush"
  21. #include "/Engine/Private/HairStrands/HairCardsAttributeCommon.ush"
  22. #include "/Engine/Private/HairStrands/HairStrandsAttributeCommon.ush"
  23.  
  24. #if USES_SPEEDTREE
  25.     #include "/Engine/Private/SpeedTreeCommon.ush"
  26. #endif
  27.  
  28. //////////////////////////////////////////////////////////////////////////
  29. //! Must match ESceneTextureId
  30.  
  31. #define PPI_SceneColor 0
  32. #define PPI_SceneDepth 1
  33. #define PPI_DiffuseColor 2
  34. #define PPI_SpecularColor 3
  35. #define PPI_SubsurfaceColor 4
  36. #define PPI_BaseColor 5
  37. #define PPI_Specular 6
  38. #define PPI_Metallic 7
  39. #define PPI_WorldNormal 8
  40. #define PPI_SeparateTranslucency 9
  41. #define PPI_Opacity 10
  42. #define PPI_Roughness 11
  43. #define PPI_MaterialAO 12
  44. #define PPI_CustomDepth 13
  45. #define PPI_PostProcessInput0 14
  46. #define PPI_PostProcessInput1 15
  47. #define PPI_PostProcessInput2 16
  48. #define PPI_PostProcessInput3 17
  49. #define PPI_PostProcessInput4 18
  50. #define PPI_PostProcessInput5 19 // (UNUSED)
  51. #define PPI_PostProcessInput6 20 // (UNUSED)
  52. #define PPI_DecalMask 21
  53. #define PPI_ShadingModelColor 22
  54. #define PPI_ShadingModelID 23
  55. #define PPI_AmbientOcclusion 24
  56. #define PPI_CustomStencil 25
  57. #define PPI_StoredBaseColor 26
  58. #define PPI_StoredSpecular 27
  59. #define PPI_Velocity 28
  60. #define PPI_WorldTangent 29
  61. #define PPI_Anisotropy 30
  62.  
  63. //////////////////////////////////////////////////////////////////////////
  64.  
  65. #define NUM_MATERIAL_TEXCOORDS_VERTEX 1
  66. #define NUM_MATERIAL_TEXCOORDS 1
  67. #define NUM_CUSTOM_VERTEX_INTERPOLATORS 0
  68. #define NUM_TEX_COORD_INTERPOLATORS 1
  69.  
  70. // Vertex interpolators offsets definition
  71.  
  72.  
  73. #if NUM_VIRTUALTEXTURE_SAMPLES || LIGHTMAP_VT_ENABLED
  74.     #include "/Engine/Private/VirtualTextureCommon.ush"
  75. #endif
  76.  
  77. #ifdef MIN_MATERIAL_TEXCOORDS
  78.     #include "/Engine/Private/MinMaterialTexCoords.ush"
  79. #endif
  80.  
  81. #if MATERIAL_ATMOSPHERIC_FOG
  82.     #include "/Engine/Private/AtmosphereCommon.ush"
  83. #endif
  84.  
  85. #if MATERIAL_SKY_ATMOSPHERE && PROJECT_SUPPORT_SKY_ATMOSPHERE
  86.     #include "/Engine/Private/SkyAtmosphereCommon.ush"
  87. #endif
  88.  
  89. #if MATERIAL_SHADINGMODEL_SINGLELAYERWATER
  90.     #include "/Engine/Private/SingleLayerWaterCommon.ush"
  91. #endif
  92.  
  93. #include "/Engine/Private/PaniniProjection.ush"
  94.  
  95. #ifndef USE_DITHERED_LOD_TRANSITION
  96.     #if USE_INSTANCING
  97.         #ifndef USE_DITHERED_LOD_TRANSITION_FOR_INSTANCED
  98.             #error "USE_DITHERED_LOD_TRANSITION_FOR_INSTANCED should have been defined"
  99.         #endif
  100.         #define USE_DITHERED_LOD_TRANSITION USE_DITHERED_LOD_TRANSITION_FOR_INSTANCED
  101.     #else
  102.         #ifndef USE_DITHERED_LOD_TRANSITION_FROM_MATERIAL
  103.             #error "USE_DITHERED_LOD_TRANSITION_FROM_MATERIAL should have been defined"
  104.         #endif
  105.         #define USE_DITHERED_LOD_TRANSITION USE_DITHERED_LOD_TRANSITION_FROM_MATERIAL
  106.     #endif
  107. #endif
  108.  
  109. #ifndef USE_STENCIL_LOD_DITHER
  110.     #define USE_STENCIL_LOD_DITHER    USE_STENCIL_LOD_DITHER_DEFAULT
  111. #endif
  112.  
  113. //Platforms that don't run the editor shouldn't need editor features in the shaders.
  114. #ifndef PLATFORM_SUPPORTS_EDITOR_SHADERS
  115. #define PLATFORM_SUPPORTS_EDITOR_SHADERS 1
  116. #endif
  117.  
  118. //Tie Editor features to platform support and the COMPILE_SHADERS_FOR_DEVELOPMENT which is set via CVAR.
  119. #define USE_EDITOR_SHADERS (PLATFORM_SUPPORTS_EDITOR_SHADERS && USE_DEVELOPMENT_SHADERS)
  120.  
  121. //Materials also have to opt in to these features.
  122. #define USE_EDITOR_COMPOSITING (USE_EDITOR_SHADERS && EDITOR_PRIMITIVE_MATERIAL)
  123.  
  124. #define MATERIALBLENDING_ANY_TRANSLUCENT (MATERIALBLENDING_TRANSLUCENT || MATERIALBLENDING_ADDITIVE || MATERIALBLENDING_MODULATE)
  125.  
  126. #define IS_MESHPARTICLE_FACTORY (PARTICLE_MESH_FACTORY || NIAGARA_MESH_FACTORY)
  127.  
  128. #define IS_HAIR_FACTORY (HAIR_STRAND_MESH_FACTORY || HAIR_CARD_MESH_FACTORY)
  129.  
  130. /**
  131.  * Parameters used by vertex and pixel shaders to access particle properties.
  132.  */
  133. struct FMaterialParticleParameters
  134. {
  135.     /** Relative time [0-1]. */
  136.     half RelativeTime;
  137.     /** Fade amount due to motion blur. */
  138.     half MotionBlurFade;
  139.     /** Random value per particle [0-1]. */
  140.     half Random;
  141.     /** XYZ: Direction, W: Speed. */
  142.     half4 Velocity;
  143.     /** Per-particle color. */
  144.     half4 Color;
  145.     /** Particle translated world space position and size(radius). */
  146.     float4 TranslatedWorldPositionAndSize;
  147.     /** Macro UV scale and bias. */
  148.     half4 MacroUV;
  149.  
  150.     /** Dynamic parameters used by particle systems. */
  151. #if NIAGARA_PARTICLE_FACTORY && (DYNAMIC_PARAMETERS_MASK != 0)
  152.     uint DynamicParameterValidMask;
  153. #endif
  154.     half4 DynamicParameter;
  155.  
  156. #if( DYNAMIC_PARAMETERS_MASK & 2)
  157.     half4 DynamicParameter1;
  158. #endif
  159.  
  160. #if (DYNAMIC_PARAMETERS_MASK & 4)
  161.     half4 DynamicParameter2;
  162. #endif
  163.  
  164. #if (DYNAMIC_PARAMETERS_MASK & 8)
  165.     half4 DynamicParameter3;
  166. #endif
  167.  
  168.     /** mesh particle transform */
  169.     float4x4 ParticleToWorld;
  170.  
  171.     /** Inverse mesh particle transform */
  172.     float4x4 WorldToParticle;
  173.  
  174. #if USE_PARTICLE_SUBUVS
  175.     /** SubUV texture coordinates*/
  176.     MaterialFloat2 SubUVCoords[2];
  177.     /** SubUV interpolation value*/
  178.     MaterialFloat SubUVLerp;
  179. #endif
  180.  
  181.     /** The size of the particle. */
  182.     float2 Size;
  183. };
  184.  
  185. float4 GetDynamicParameter(FMaterialParticleParameters Parameters, float4 Default, int ParameterIndex=0)
  186. {
  187. #if (NIAGARA_PARTICLE_FACTORY)
  188.     switch ( ParameterIndex)
  189.     {
  190.     #if (DYNAMIC_PARAMETERS_MASK & 1)
  191.         case 0:    return (Parameters.DynamicParameterValidMask & 1) != 0 ? Parameters.DynamicParameter : Default;
  192.     #endif
  193.     #if (DYNAMIC_PARAMETERS_MASK & 2)
  194.         case 1:    return (Parameters.DynamicParameterValidMask & 2) != 0 ? Parameters.DynamicParameter1 : Default;
  195.     #endif
  196.     #if (DYNAMIC_PARAMETERS_MASK & 4)
  197.         case 2:    return (Parameters.DynamicParameterValidMask & 4) != 0 ? Parameters.DynamicParameter2 : Default;
  198.     #endif    
  199.     #if (DYNAMIC_PARAMETERS_MASK & 8)
  200.         case 3:    return (Parameters.DynamicParameterValidMask & 8) != 0 ? Parameters.DynamicParameter3 : Default;
  201.     #endif
  202.         default: return Default;
  203.     }
  204. #elif (PARTICLE_FACTORY)
  205.     if ( ParameterIndex == 0 )
  206.     {
  207.         return Parameters.DynamicParameter;
  208.     }
  209. #endif
  210.     return Default;
  211.  
  212. }
  213.  
  214. struct FMaterialAttributes
  215. {
  216.     float3 BaseColor;
  217.     float Metallic;
  218.     float Specular;
  219.     float Roughness;
  220.     float Anisotropy;
  221.     float3 EmissiveColor;
  222.     float Opacity;
  223.     float OpacityMask;
  224.     float3 Normal;
  225.     float3 Tangent;
  226.     float3 WorldPositionOffset;
  227.     float3 WorldDisplacement;
  228.     float TessellationMultiplier;
  229.     float3 SubsurfaceColor;
  230.     float ClearCoat;
  231.     float ClearCoatRoughness;
  232.     float AmbientOcclusion;
  233.     float2 Refraction;
  234.     float PixelDepthOffset;
  235.     uint ShadingModel;
  236.     float2 CustomizedUV0;
  237.     float2 CustomizedUV1;
  238.     float2 CustomizedUV2;
  239.     float2 CustomizedUV3;
  240.     float2 CustomizedUV4;
  241.     float2 CustomizedUV5;
  242.     float2 CustomizedUV6;
  243.     float2 CustomizedUV7;
  244.     float3 BentNormal;
  245.     float3 ClearCoatBottomNormal;
  246.     float3 CustomEyeTangent;
  247.  
  248. };
  249.  
  250. /**
  251.  * Parameters calculated from the pixel material inputs.
  252.  */
  253. struct FPixelMaterialInputs
  254. {
  255.     MaterialFloat3 EmissiveColor;
  256.     MaterialFloat Opacity;
  257.     MaterialFloat OpacityMask;
  258.     MaterialFloat3 BaseColor;
  259.     MaterialFloat Metallic;
  260.     MaterialFloat Specular;
  261.     MaterialFloat Roughness;
  262.     MaterialFloat Anisotropy;
  263.     MaterialFloat3 Normal;
  264.     MaterialFloat3 Tangent;
  265.     MaterialFloat4 Subsurface;
  266.     MaterialFloat AmbientOcclusion;
  267.     MaterialFloat2 Refraction;
  268.     MaterialFloat PixelDepthOffset;
  269.     uint ShadingModel;
  270.  
  271. };
  272.  
  273. /**
  274.  * Parameters needed by pixel shader material inputs, related to Geometry.
  275.  * These are independent of vertex factory.
  276.  */
  277. struct FMaterialPixelParameters
  278. {
  279. #if NUM_TEX_COORD_INTERPOLATORS
  280.     float2 TexCoords[NUM_TEX_COORD_INTERPOLATORS];
  281. #endif
  282.  
  283.     /** Interpolated vertex color, in linear color space. */
  284.     half4 VertexColor;
  285.  
  286.     /** Normalized world space normal. */
  287.     half3 WorldNormal;
  288.    
  289.     /** Normalized world space tangent. */
  290.     half3 WorldTangent;
  291.  
  292.     /** Normalized world space reflected camera vector. */
  293.     half3 ReflectionVector;
  294.  
  295.     /** Normalized world space camera vector, which is the vector from the point being shaded to the camera position. */
  296.     half3 CameraVector;
  297.  
  298.     /** World space light vector, only valid when rendering a light function. */
  299.     half3 LightVector;
  300.  
  301.     /**
  302.      * Like SV_Position (.xy is pixel position at pixel center, z:DeviceZ, .w:SceneDepth)
  303.      * using shader generated value SV_POSITION
  304.      * Note: this is not relative to the current viewport.  RelativePixelPosition = MaterialParameters.SvPosition.xy - View.ViewRectMin.xy;
  305.      */
  306.     float4 SvPosition;
  307.        
  308.     /** Post projection position reconstructed from SvPosition, before the divide by W. left..top -1..1, bottom..top -1..1  within the viewport, W is the SceneDepth */
  309.     float4 ScreenPosition;
  310.  
  311.     half UnMirrored;
  312.  
  313.     half TwoSidedSign;
  314.  
  315.     /**
  316.      * Orthonormal rotation-only transform from tangent space to world space
  317.      * The transpose(TangentToWorld) is WorldToTangent, and TangentToWorld[2] is WorldVertexNormal
  318.      */
  319.     half3x3 TangentToWorld;
  320.  
  321. #if USE_WORLDVERTEXNORMAL_CENTER_INTERPOLATION
  322.     /** World vertex normal interpolated at the pixel center that is safe to use for derivatives. */
  323.     half3 WorldVertexNormal_Center;
  324. #endif
  325.  
  326.     /**
  327.      * Interpolated worldspace position of this pixel
  328.      * todo: Make this TranslatedWorldPosition and also rename the VS/DS/HS WorldPosition to be TranslatedWorldPosition
  329.      */
  330.     float3 AbsoluteWorldPosition;
  331.  
  332.     /**
  333.      * Interpolated worldspace position of this pixel, centered around the camera
  334.      */
  335.     float3 WorldPosition_CamRelative;
  336.  
  337.     /**
  338.      * Interpolated worldspace position of this pixel, not including any world position offset or displacement.
  339.      * Only valid if shader is compiled with NEEDS_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS, otherwise just contains 0
  340.      */
  341.     float3 WorldPosition_NoOffsets;
  342.  
  343.     /**
  344.      * Interpolated worldspace position of this pixel, not including any world position offset or displacement.
  345.      * Only valid if shader is compiled with NEEDS_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS, otherwise just contains 0
  346.      */
  347.     float3 WorldPosition_NoOffsets_CamRelative;
  348.  
  349.     /** Offset applied to the lighting position for translucency, used to break up aliasing artifacts. */
  350.     half3 LightingPositionOffset;
  351.  
  352.     float AOMaterialMask;
  353.  
  354. #if LIGHTMAP_UV_ACCESS
  355.     float2    LightmapUVs;
  356. #endif
  357.  
  358. #if USE_INSTANCING
  359.     half4 PerInstanceParams;
  360. #endif
  361.  
  362.     // Index into View.PrimitiveSceneData
  363.     uint PrimitiveId;
  364.  
  365.     // Actual primitive Id
  366. #if IS_HAIR_FACTORY
  367.     uint    HairPrimitiveId;    // Control point ID
  368.     float2    HairPrimitiveUV;    // U: parametric distance between the two surrounding control point. V: parametric distance along hair width
  369. #endif
  370.  
  371.     /** Per-particle properties. Only valid for particle vertex factories. */
  372.     FMaterialParticleParameters Particle;
  373.  
  374. #if ES3_1_PROFILE
  375.     float4 LayerWeights;
  376. #endif
  377.  
  378. #if TEX_COORD_SCALE_ANALYSIS
  379.     /** Parameters used by the MaterialTexCoordScales shader. */
  380.     FTexCoordScalesParams TexCoordScalesParams;
  381. #endif
  382.  
  383. #if POST_PROCESS_MATERIAL && (FEATURE_LEVEL <= FEATURE_LEVEL_ES3_1)
  384.     /** Used in mobile custom pp material to preserve original SceneColor Alpha */
  385.     half BackupSceneColorAlpha;
  386. #endif
  387.  
  388. #if COMPILER_HLSL
  389.     // Workaround for "error X3067: 'GetObjectWorldPosition': ambiguous function call"
  390.     // Which happens when FMaterialPixelParameters and FMaterialVertexParameters have the same number of floats with the HLSL compiler ver 9.29.952.3111
  391.     // Function overload resolution appears to identify types based on how many floats / ints / etc they contain
  392.     uint Dummy;
  393. #endif
  394.  
  395. #if NUM_VIRTUALTEXTURE_SAMPLES || LIGHTMAP_VT_ENABLED
  396.     FVirtualTextureFeedbackParams VirtualTextureFeedback;
  397. #endif
  398.  
  399. #if WATER_MESH_FACTORY
  400.     uint WaterWaveParamIndex;
  401. #endif
  402.  
  403. #if CLOUD_LAYER_PIXEL_SHADER
  404.     float CloudSampleAltitude;
  405.     float CloudSampleAltitudeInLayer;
  406.     float CloudSampleNormAltitudeInLayer;
  407.     float3 VolumeSampleConservativeDensity;
  408.     float ShadowSampleDistance;
  409. #endif
  410. };
  411.  
  412. /**
  413.  * Compile out calls to StoreTexCoordScale if we're not doing texcoord scale analysis
  414.  */
  415. #if TEX_COORD_SCALE_ANALYSIS
  416. #define MaterialStoreTexCoordScale(Parameters, UV, TextureReferenceIndex) StoreTexCoordScale(Parameters.TexCoordScalesParams, UV, TextureReferenceIndex)
  417. #define MaterialStoreTexSample(Parameters, UV, TextureReferenceIndex) StoreTexSample(Parameters.TexCoordScalesParams, UV, TextureReferenceIndex)
  418. #else
  419. #define MaterialStoreTexCoordScale(Parameters, UV, TextureReferenceIndex) 1.0f
  420. #define MaterialStoreTexSample(Parameters, UV, TextureReferenceIndex) 1.0f
  421. #endif
  422.  
  423. // @todo compat hack
  424. FMaterialPixelParameters MakeInitializedMaterialPixelParameters()
  425. {
  426.     FMaterialPixelParameters MPP;
  427.     MPP = (FMaterialPixelParameters)0;
  428.     MPP.TangentToWorld = float3x3(1,0,0,0,1,0,0,0,1);
  429.     return MPP;
  430. }
  431.  
  432. /**
  433.  * Parameters needed by domain shader material inputs.
  434.  * These are independent of vertex factory.
  435.  */
  436. struct FMaterialTessellationParameters
  437. {
  438.     // Note: Customized UVs are only evaluated in the vertex shader, which is not really what you want with tessellation, but keeps the code simpler
  439.     // (tessellation texcoords are the same as pixels shader texcoords)
  440. #if NUM_TEX_COORD_INTERPOLATORS
  441.     float2 TexCoords[NUM_TEX_COORD_INTERPOLATORS];
  442. #endif
  443.     float4 VertexColor;
  444.     // TODO: Non translated world position
  445.     float3 WorldPosition;
  446.     float3 TangentToWorldPreScale;
  447.  
  448.     // TangentToWorld[2] is WorldVertexNormal, [0] and [1] are binormal and tangent
  449.     float3x3 TangentToWorld;
  450.  
  451.     // Index into View.PrimitiveSceneData
  452.     uint PrimitiveId;
  453. };
  454.  
  455. /**
  456.  * Parameters needed by vertex shader material inputs.
  457.  * These are independent of vertex factory.
  458.  */
  459. struct FMaterialVertexParameters
  460. {
  461.     // Position in the translated world (VertexFactoryGetWorldPosition).
  462.     // Previous position in the translated world (VertexFactoryGetPreviousWorldPosition) if
  463.     //    computing material's output for previous frame (See {BasePassVertex,Velocity}Shader.usf).
  464.     float3 WorldPosition;
  465.     // TangentToWorld[2] is WorldVertexNormal
  466.     half3x3 TangentToWorld;
  467. #if USE_INSTANCING
  468.     /** Per-instance properties. */
  469.     float4x4 InstanceLocalToWorld;
  470.     float3 InstanceLocalPosition;
  471.     float4 PerInstanceParams;
  472.     uint InstanceId;
  473.     uint InstanceOffset;
  474.  
  475. #elif IS_MESHPARTICLE_FACTORY
  476.     /** Per-particle properties. */
  477.     float4x4 InstanceLocalToWorld;
  478. #endif
  479.     // If either USE_INSTANCING or (IS_MESHPARTICLE_FACTORY && FEATURE_LEVEL >= FEATURE_LEVEL_SM4)
  480.     // is true, PrevFrameLocalToWorld is a per-instance transform
  481.     float4x4 PrevFrameLocalToWorld;
  482.  
  483.     float3 PreSkinnedPosition;
  484.     float3 PreSkinnedNormal;
  485.  
  486. #if GPU_SKINNED_MESH_FACTORY
  487.     float3 PreSkinOffset;
  488.     float3 PostSkinOffset;
  489. #endif
  490.  
  491.     half4 VertexColor;
  492. #if NUM_MATERIAL_TEXCOORDS_VERTEX
  493.     float2 TexCoords[NUM_MATERIAL_TEXCOORDS_VERTEX];
  494.     #if ES3_1_PROFILE
  495.     float2 TexCoordOffset; // Offset for UV localization for large UV values
  496.     #endif
  497. #endif
  498.  
  499.     /** Per-particle properties. Only valid for particle vertex factories. */
  500.     FMaterialParticleParameters Particle;
  501.  
  502.     // Index into View.PrimitiveSceneData
  503.     uint PrimitiveId;
  504.  
  505. #if WATER_MESH_FACTORY
  506.     uint WaterWaveParamIndex;
  507. #endif
  508. };
  509.  
  510. /**
  511.  * Returns the upper 3x3 portion of the LocalToWorld matrix.
  512.  */
  513. MaterialFloat3x3 GetLocalToWorld3x3(uint PrimitiveId)
  514. {
  515.     return (MaterialFloat3x3)GetPrimitiveData(PrimitiveId).LocalToWorld;
  516. }
  517.  
  518. MaterialFloat3x3 GetLocalToWorld3x3()
  519. {
  520.     return (MaterialFloat3x3)Primitive.LocalToWorld;
  521. }
  522.  
  523. float3 GetTranslatedWorldPosition(FMaterialVertexParameters Parameters)
  524. {
  525.     return Parameters.WorldPosition;
  526. }
  527.  
  528. float3 GetPrevTranslatedWorldPosition(FMaterialVertexParameters Parameters)
  529. {
  530.     // Previous world position and current world position are sharing the
  531.     // same attribute in Parameters, because in BasePassVertexShader.usf
  532.     // and in VelocityShader.usf, we are regenerating a Parameters from
  533.     // VertexFactoryGetPreviousWorldPosition() instead of
  534.     // VertexFactoryGetWorldPosition().
  535.     return GetTranslatedWorldPosition(Parameters);
  536. }
  537.  
  538. float3 GetWorldPosition(FMaterialVertexParameters Parameters)
  539. {
  540.     return GetTranslatedWorldPosition(Parameters) - ResolvedView.PreViewTranslation;
  541. }
  542.  
  543. float3 GetPrevWorldPosition(FMaterialVertexParameters Parameters)
  544. {
  545.     return GetPrevTranslatedWorldPosition(Parameters) - ResolvedView.PrevPreViewTranslation;
  546. }
  547.  
  548. //TODO(bug UE-17131): We should compute world displacement for the previous frame
  549. float3 GetWorldPosition(FMaterialTessellationParameters Parameters)
  550. {
  551.     return Parameters.WorldPosition;
  552. }
  553.  
  554. float3 GetTranslatedWorldPosition(FMaterialTessellationParameters Parameters)
  555. {
  556.     return Parameters.WorldPosition + ResolvedView.PreViewTranslation;
  557. }
  558.  
  559. float3 GetWorldPosition(FMaterialPixelParameters Parameters)
  560. {
  561.     return Parameters.AbsoluteWorldPosition;
  562. }
  563.  
  564. float3 GetWorldPosition_NoMaterialOffsets(FMaterialPixelParameters Parameters)
  565. {
  566.     return Parameters.WorldPosition_NoOffsets;
  567. }
  568.  
  569. float3 GetTranslatedWorldPosition(FMaterialPixelParameters Parameters)
  570. {
  571.     return Parameters.WorldPosition_CamRelative;
  572. }
  573.  
  574. float3 GetTranslatedWorldPosition_NoMaterialOffsets(FMaterialPixelParameters Parameters)
  575. {
  576.     return Parameters.WorldPosition_NoOffsets_CamRelative;
  577. }
  578.  
  579. float4 GetScreenPosition(FMaterialVertexParameters Parameters)
  580. {
  581.     return mul(float4(Parameters.WorldPosition, 1.0f), ResolvedView.TranslatedWorldToClip);
  582. }
  583.  
  584. float4 GetScreenPosition(FMaterialPixelParameters Parameters)
  585. {
  586.     return Parameters.ScreenPosition;
  587. }
  588.  
  589. // Returns the pixel's depth, in world units. Works for both orthographic and perspective projections:
  590. float GetPixelDepth(FMaterialVertexParameters Parameters)
  591. {
  592.     FLATTEN
  593.     if (View.ViewToClip[3][3] < 1.0f)
  594.     {
  595.         // Perspective
  596.         return GetScreenPosition(Parameters).w;
  597.     }
  598.     else
  599.     {
  600.         // Ortho
  601.         return ConvertFromDeviceZ(GetScreenPosition(Parameters).z);
  602.     }
  603. }
  604.  
  605. float GetPixelDepth(FMaterialPixelParameters Parameters)
  606. {
  607.     FLATTEN
  608.     if (View.ViewToClip[3][3] < 1.0f)
  609.     {
  610.         // Perspective
  611.         return GetScreenPosition(Parameters).w;
  612.     }
  613.     else
  614.     {
  615.         // Ortho
  616.         return ConvertFromDeviceZ(GetScreenPosition(Parameters).z);
  617.     }
  618. }
  619.  
  620. float2 GetSceneTextureUV(FMaterialVertexParameters Parameters)
  621. {
  622.     return ScreenAlignedPosition(GetScreenPosition(Parameters));
  623. }
  624.  
  625. float2 GetSceneTextureUV(FMaterialPixelParameters Parameters)
  626. {
  627.     return SvPositionToBufferUV(Parameters.SvPosition);
  628. }
  629.  
  630. float2 GetViewportUV(FMaterialVertexParameters Parameters)
  631. {
  632. #if POST_PROCESS_MATERIAL
  633.     return Parameters.WorldPosition.xy;
  634. #else
  635.     return BufferUVToViewportUV(GetSceneTextureUV(Parameters));
  636. #endif
  637. }
  638.  
  639. float2 GetPixelPosition(FMaterialVertexParameters Parameters)
  640. {
  641.     return GetViewportUV(Parameters) * View.ViewSizeAndInvSize.xy;
  642. }
  643.  
  644.  
  645. #if POST_PROCESS_MATERIAL
  646.  
  647. float2 GetPixelPosition(FMaterialPixelParameters Parameters)
  648. {
  649.     return Parameters.SvPosition.xy - float2(PostProcessOutput_ViewportMin);
  650. }
  651.  
  652. float2 GetViewportUV(FMaterialPixelParameters Parameters)
  653. {
  654.     return GetPixelPosition(Parameters) * PostProcessOutput_ViewportSizeInverse;
  655. }
  656.  
  657. #else
  658.  
  659. float2 GetPixelPosition(FMaterialPixelParameters Parameters)
  660. {
  661.     return Parameters.SvPosition.xy - float2(View.ViewRectMin.xy);
  662. }
  663.  
  664. float2 GetViewportUV(FMaterialPixelParameters Parameters)
  665. {
  666.     return SvPositionToViewportUV(Parameters.SvPosition);
  667. }
  668.  
  669. #endif
  670.  
  671. float GetWaterWaveParamIndex(FMaterialPixelParameters Parameters)
  672. {
  673. #if WATER_MESH_FACTORY
  674.     return (float)Parameters.WaterWaveParamIndex;
  675. #else
  676.     return 0.0f;
  677. #endif
  678. }
  679.  
  680. float GetWaterWaveParamIndex(FMaterialVertexParameters Parameters)
  681. {
  682. #if WATER_MESH_FACTORY
  683.     return (float)Parameters.WaterWaveParamIndex;
  684. #else
  685.     return 0.0f;
  686. #endif
  687. }
  688.  
  689. // Returns whether a scene texture id is a for a post process input or not.
  690. bool IsPostProcessInputSceneTexture(const uint SceneTextureId)
  691. {
  692.     return (SceneTextureId >= PPI_PostProcessInput0 && SceneTextureId <= PPI_PostProcessInput6);
  693. }
  694.  
  695. // Returns the view size and texel size in a given scene texture.
  696. float4 GetSceneTextureViewSize(const uint SceneTextureId)
  697. {
  698.     #if POST_PROCESS_MATERIAL
  699.     if (IsPostProcessInputSceneTexture(SceneTextureId))
  700.     {
  701.         switch (SceneTextureId)
  702.         {
  703.         case PPI_PostProcessInput0:
  704.             return float4(PostProcessInput_0_ViewportSize, PostProcessInput_0_ViewportSizeInverse);
  705.         case PPI_PostProcessInput1:
  706.             return float4(PostProcessInput_1_ViewportSize, PostProcessInput_1_ViewportSizeInverse);
  707.         case PPI_PostProcessInput2:
  708.             return float4(PostProcessInput_2_ViewportSize, PostProcessInput_2_ViewportSizeInverse);
  709.         case PPI_PostProcessInput3:
  710.             return float4(PostProcessInput_3_ViewportSize, PostProcessInput_3_ViewportSizeInverse);
  711.         case PPI_PostProcessInput4:
  712.             return float4(PostProcessInput_4_ViewportSize, PostProcessInput_4_ViewportSizeInverse);
  713.         default:
  714.             return float4(0, 0, 0, 0);
  715.         }
  716.     }
  717.     #endif
  718.     return ResolvedView.ViewSizeAndInvSize;
  719. }
  720.  
  721. // Return the buffer UV min and max for a given scene texture id.
  722. float4 GetSceneTextureUVMinMax(const uint SceneTextureId)
  723. {
  724.     #if POST_PROCESS_MATERIAL
  725.     if (IsPostProcessInputSceneTexture(SceneTextureId))
  726.     {
  727.         switch (SceneTextureId)
  728.     {
  729.         case PPI_PostProcessInput0:
  730.             return float4(PostProcessInput_0_UVViewportBilinearMin, PostProcessInput_0_UVViewportBilinearMax);
  731.         case PPI_PostProcessInput1:
  732.             return float4(PostProcessInput_1_UVViewportBilinearMin, PostProcessInput_1_UVViewportBilinearMax);
  733.         case PPI_PostProcessInput2:
  734.             return float4(PostProcessInput_2_UVViewportBilinearMin, PostProcessInput_2_UVViewportBilinearMax);
  735.         case PPI_PostProcessInput3:
  736.             return float4(PostProcessInput_3_UVViewportBilinearMin, PostProcessInput_3_UVViewportBilinearMax);
  737.         case PPI_PostProcessInput4:
  738.             return float4(PostProcessInput_4_UVViewportBilinearMin, PostProcessInput_4_UVViewportBilinearMax);
  739.         default:
  740.             return float4(0, 0, 1, 1);
  741.         }
  742.     }
  743.     #endif
  744.  
  745.     return View.BufferBilinearUVMinMax;
  746. }
  747.  
  748. // Transforms viewport UV to scene texture's UV.
  749. MaterialFloat2 ViewportUVToSceneTextureUV(MaterialFloat2 ViewportUV, const uint SceneTextureId)
  750. {
  751.     #if POST_PROCESS_MATERIAL
  752.     if (IsPostProcessInputSceneTexture(SceneTextureId))
  753.     {
  754.         switch (SceneTextureId)
  755.         {
  756.         case PPI_PostProcessInput0:
  757.             return ViewportUV * PostProcessInput_0_UVViewportSize + PostProcessInput_0_UVViewportMin;
  758.         case PPI_PostProcessInput1:
  759.             return ViewportUV * PostProcessInput_1_UVViewportSize + PostProcessInput_1_UVViewportMin;
  760.         case PPI_PostProcessInput2:
  761.             return ViewportUV * PostProcessInput_2_UVViewportSize + PostProcessInput_2_UVViewportMin;
  762.         case PPI_PostProcessInput3:
  763.             return ViewportUV * PostProcessInput_3_UVViewportSize + PostProcessInput_3_UVViewportMin;
  764.         case PPI_PostProcessInput4:
  765.             return ViewportUV * PostProcessInput_4_UVViewportSize + PostProcessInput_4_UVViewportMin;
  766.         default:
  767.             return ViewportUV;
  768.         }
  769.     }
  770.     #endif
  771.  
  772.     return ViewportUVToBufferUV(ViewportUV);
  773. }
  774.  
  775. // Manually clamp scene texture UV as if using a clamp sampler.
  776. MaterialFloat2 ClampSceneTextureUV(MaterialFloat2 BufferUV, const uint SceneTextureId)
  777. {
  778.     float4 MinMax = GetSceneTextureUVMinMax(SceneTextureId);
  779.  
  780.     return clamp(BufferUV, MinMax.xy, MinMax.zw);
  781. }
  782.  
  783. // Get default scene texture's UV.
  784. MaterialFloat2 GetDefaultSceneTextureUV(FMaterialVertexParameters Parameters, const uint SceneTextureId)
  785. {
  786.     return GetSceneTextureUV(Parameters);
  787. }
  788.  
  789. // Get default scene texture's UV.
  790. MaterialFloat2 GetDefaultSceneTextureUV(FMaterialPixelParameters Parameters, const uint SceneTextureId)
  791. {
  792.     #if POST_PROCESS_MATERIAL
  793.         return ViewportUVToSceneTextureUV(GetViewportUV(Parameters), SceneTextureId);
  794.     #else
  795.         return GetSceneTextureUV(Parameters);
  796.     #endif
  797. }
  798.  
  799.  
  800. #if DECAL_PRIMITIVE && NUM_MATERIAL_TEXCOORDS
  801.     /*
  802.      * Material node DecalMipmapLevel's code designed to avoid the 2x2 pixels artefacts on the edges around where the decal
  803.      * is projected to. The technique is fetched from (http://www.humus.name/index.php?page=3D&ID=84).
  804.      *
  805.      * The problem around edges of the meshes, is that the hardware computes the mipmap level according to ddx(uv) and ddy(uv),
  806.      * but since the pixel shader are invocated by group of 2x2 pixels, then on edges some pixel might be getting the
  807.      * current depth of an differet mesh that the other pixel of the same groups. If this mesh is very far from the other
  808.      * mesh of the same group of pixel, then one of the delta might be very big, leading to choosing a low mipmap level for this
  809.      * group of 4 pixels, causing the artefacts.
  810.      */
  811.     float2 ComputeDecalUVFromSvPosition(float4 SvPosition)
  812.     {
  813.         half DeviceZ = LookupDeviceZ(SvPositionToBufferUV(SvPosition));
  814.  
  815.         SvPosition.z = DeviceZ;
  816.  
  817.         float4 DecalVector = mul(float4(SvPosition.xyz,1), SvPositionToDecal);
  818.         DecalVector.xyz /= DecalVector.w;
  819.         DecalVector = DecalVector * 0.5f + 0.5f;
  820.         DecalVector.xyz = DecalVector.zyx;
  821.         return DecalVector.xy;
  822.     }
  823.  
  824.     float2 ComputeDecalDDX(FMaterialPixelParameters Parameters)
  825.     {
  826.         /*
  827.          * Assuming where in a pixel shader invocation, then we compute manualy compute two d(uv)/d(x)
  828.          * with the pixels's left and right neighbours.
  829.          */
  830.         float4 ScreenDeltaX = float4(1, 0, 0, 0);
  831.         float2 UvDiffX0 = Parameters.TexCoords[0] - ComputeDecalUVFromSvPosition(Parameters.SvPosition - ScreenDeltaX);
  832.         float2 UvDiffX1 = ComputeDecalUVFromSvPosition(Parameters.SvPosition + ScreenDeltaX) - Parameters.TexCoords[0];
  833.  
  834.         /*
  835.          * So we have two diff on the X axis, we want the one that has the smallest length
  836.          * to avoid the 2x2 pixels mipmap artefacts on the edges.
  837.          */
  838.         return dot(UvDiffX0, UvDiffX0) < dot(UvDiffX1, UvDiffX1) ? UvDiffX0 : UvDiffX1;
  839.     }
  840.  
  841.     float2 ComputeDecalDDY(FMaterialPixelParameters Parameters)
  842.     {
  843.         // do same for the Y axis
  844.         float4 ScreenDeltaY = float4(0, 1, 0, 0);
  845.         float2 UvDiffY0 = Parameters.TexCoords[0] - ComputeDecalUVFromSvPosition(Parameters.SvPosition - ScreenDeltaY);
  846.         float2 UvDiffY1 = ComputeDecalUVFromSvPosition(Parameters.SvPosition + ScreenDeltaY) - Parameters.TexCoords[0];
  847.  
  848.         return dot(UvDiffY0, UvDiffY0) < dot(UvDiffY1, UvDiffY1) ? UvDiffY0 : UvDiffY1;
  849.     }
  850.  
  851.     float ComputeDecalMipmapLevel(FMaterialPixelParameters Parameters, float2 TextureSize)
  852.     {
  853.         float2 UvPixelDiffX = ComputeDecalDDX(Parameters) * TextureSize;
  854.         float2 UvPixelDiffY = ComputeDecalDDY(Parameters) * TextureSize;
  855.  
  856.         // Computes the mipmap level
  857.         float MaxDiff = max(dot(UvPixelDiffX, UvPixelDiffX), dot(UvPixelDiffY, UvPixelDiffY));
  858.         return 0.5 * log2(MaxDiff);
  859.     }
  860. #else // DECAL_PRIMITIVE && NUM_MATERIAL_TEXCOORDS
  861.     float2 ComputeDecalDDX(FMaterialPixelParameters Parameters)
  862.     {
  863.         return 0.0f;
  864.     }
  865.    
  866.     float2 ComputeDecalDDY(FMaterialPixelParameters Parameters)
  867.     {
  868.         return 0.0f;
  869.     }
  870.  
  871.     float ComputeDecalMipmapLevel(FMaterialPixelParameters Parameters, float2 TextureSize)
  872.     {
  873.         return 0.0f;
  874.     }
  875. #endif // DECAL_PRIMITIVE && NUM_MATERIAL_TEXCOORDS
  876.  
  877. #if DECAL_PRIMITIVE
  878.     /*
  879.      * Deferred decal don't have a Primitive uniform buffer, because we don't know on which primitive the decal
  880.      * is being projected to. But the user may still need to get the decal's actor world position.
  881.      * So instead of setting up a primitive buffer that may cost to much CPU effort to be almost never used,
  882.      * we directly fetch this value from the DeferredDecal.usf specific uniform variable DecalToWorld.
  883.      */
  884.     float3 GetActorWorldPosition(uint PrimitiveId)
  885.     {
  886.         return DecalToWorld[3].xyz;
  887.     }
  888.    
  889.     float3 GetObjectOrientation(uint PrimitiveId)
  890.     {
  891.         return DecalOrientation.xyz;
  892.     }
  893. #else
  894.     float3 GetActorWorldPosition(uint PrimitiveId)
  895.     {
  896.         return GetPrimitiveData(PrimitiveId).ActorWorldPosition;
  897.     }
  898.    
  899.     float3 GetObjectOrientation(uint PrimitiveId)
  900.     {
  901.         return GetPrimitiveData(PrimitiveId).ObjectOrientation.xyz;
  902.     }
  903. #endif // DECAL_PRIMITIVE
  904.  
  905. #if DECAL_PRIMITIVE
  906.     float DecalLifetimeOpacity()
  907.     {
  908.         return DecalParams.y;
  909.     }
  910. #else
  911.     float DecalLifetimeOpacity()
  912.     {
  913.         return 0.0f;
  914.     }
  915. #endif // DECAL_PRIMITIVE
  916.  
  917. // Per Instance Custom Data Getter (Vertex Shader Only)
  918. /** Get the per-instance custom data when instancing */
  919. float GetPerInstanceCustomData(FMaterialVertexParameters Parameters, int Index, float DefaultValue)
  920. {
  921. #if USE_INSTANCING && USES_PER_INSTANCE_CUSTOM_DATA
  922.     if(InstanceVF.NumCustomDataFloats > 0)
  923.     {
  924.         int BufferStartIndex = (Parameters.InstanceId + Parameters.InstanceOffset) * InstanceVF.NumCustomDataFloats;
  925.         int FloatIndex = clamp(Index, 0, InstanceVF.NumCustomDataFloats - 1);
  926.         return InstanceVF.InstanceCustomDataBuffer[BufferStartIndex + FloatIndex];
  927.     }
  928.     else
  929.     {
  930.         return DefaultValue;
  931.     }
  932. #else
  933.     return DefaultValue;
  934. #endif
  935. }
  936.  
  937. /** Transforms a vector from tangent space to world space, prescaling by an amount calculated previously */
  938. MaterialFloat3 TransformTangentVectorToWorld_PreScaled(FMaterialTessellationParameters Parameters, MaterialFloat3 InTangentVector)
  939. {
  940. #if FEATURE_LEVEL >= FEATURE_LEVEL_SM5
  941.     // used optionally to scale up the vector prior to conversion
  942.     InTangentVector *= abs( Parameters.TangentToWorldPreScale );    
  943.  
  944.     // Transform directly to world space
  945.     // The vector transform is optimized for this case, only one vector-matrix multiply is needed
  946.     return mul(InTangentVector, Parameters.TangentToWorld);
  947. #else
  948.     return TransformTangentVectorToWorld(Parameters.TangentToWorld, InTangentVector);
  949. #endif // #if FEATURE_LEVEL_SM5
  950. }
  951.  
  952. /** Transforms a vector from tangent space to view space */
  953. MaterialFloat3 TransformTangentVectorToView(FMaterialPixelParameters Parameters, MaterialFloat3 InTangentVector)
  954. {
  955.     // Transform from tangent to world, and then to view space
  956.     return mul(mul(InTangentVector, Parameters.TangentToWorld), (MaterialFloat3x3)ResolvedView.TranslatedWorldToView);
  957. }
  958.  
  959. /** Transforms a vector from local space to world space (VS version) */
  960. MaterialFloat3 TransformLocalVectorToWorld(FMaterialVertexParameters Parameters,MaterialFloat3 InLocalVector)
  961. {
  962.     #if USE_INSTANCING || IS_MESHPARTICLE_FACTORY
  963.         return mul(InLocalVector, (MaterialFloat3x3)Parameters.InstanceLocalToWorld);
  964.     #else
  965.         return mul(InLocalVector, GetLocalToWorld3x3(Parameters.PrimitiveId));
  966.     #endif
  967. }
  968.  
  969. /** Transforms a vector from local space to world space (PS version) */
  970. MaterialFloat3 TransformLocalVectorToWorld(FMaterialPixelParameters Parameters,MaterialFloat3 InLocalVector)
  971. {
  972.     return mul(InLocalVector, GetLocalToWorld3x3(Parameters.PrimitiveId));
  973. }
  974.  
  975. /** Transforms a vector from local space to previous frame world space (VS version) */
  976. MaterialFloat3 TransformLocalVectorToPrevWorld(FMaterialVertexParameters Parameters,MaterialFloat3 InLocalVector)
  977. {
  978.     return mul(InLocalVector, (MaterialFloat3x3)Parameters.PrevFrameLocalToWorld);
  979. }
  980.  
  981. #if HAS_PRIMITIVE_UNIFORM_BUFFER
  982.  
  983. /** Transforms a position from local space to absolute world space */
  984. float3 TransformLocalPositionToWorld(FMaterialPixelParameters Parameters,float3 InLocalPosition)
  985. {
  986.     return mul(float4(InLocalPosition, 1), GetPrimitiveData(Parameters.PrimitiveId).LocalToWorld).xyz;
  987. }
  988.  
  989. /** Transforms a position from local space to absolute world space */
  990. float3 TransformLocalPositionToWorld(FMaterialVertexParameters Parameters,float3 InLocalPosition)
  991. {
  992.     #if USE_INSTANCING || IS_MESHPARTICLE_FACTORY
  993.         return mul(float4(InLocalPosition, 1), Parameters.InstanceLocalToWorld).xyz;
  994.     #else
  995.         return mul(float4(InLocalPosition, 1), GetPrimitiveData(Parameters.PrimitiveId).LocalToWorld).xyz;
  996.     #endif
  997. }
  998.  
  999. /** Transforms a position from local space to previous frame absolute world space */
  1000. float3 TransformLocalPositionToPrevWorld(FMaterialVertexParameters Parameters,float3 InLocalPosition)
  1001. {
  1002.     return mul(float4(InLocalPosition, 1), Parameters.PrevFrameLocalToWorld).xyz;
  1003. }
  1004.  
  1005. #endif
  1006.  
  1007. #if HAS_PRIMITIVE_UNIFORM_BUFFER
  1008.  
  1009. /** Return the object's position in world space */
  1010. float3 GetObjectWorldPosition(FMaterialPixelParameters Parameters)
  1011. {
  1012.     return GetPrimitiveData(Parameters.PrimitiveId).ObjectWorldPositionAndRadius.xyz;
  1013. }
  1014.  
  1015. float3 GetObjectWorldPosition(FMaterialTessellationParameters Parameters)
  1016. {
  1017.     return GetPrimitiveData(Parameters.PrimitiveId).ObjectWorldPositionAndRadius.xyz;
  1018. }
  1019.  
  1020. /** Return the object's position in world space. For instanced meshes, this returns the instance position. */
  1021. float3 GetObjectWorldPosition(FMaterialVertexParameters Parameters)
  1022. {
  1023.     #if USE_INSTANCING || IS_MESHPARTICLE_FACTORY
  1024.         return Parameters.InstanceLocalToWorld[3].xyz;
  1025.     #else
  1026.         return GetPrimitiveData(Parameters.PrimitiveId).ObjectWorldPositionAndRadius.xyz;
  1027.     #endif
  1028. }
  1029.  
  1030. #endif
  1031.  
  1032. /** Get the per-instance random value when instancing */
  1033. float GetPerInstanceRandom(FMaterialVertexParameters Parameters)
  1034. {
  1035. #if USE_INSTANCING
  1036.     return Parameters.PerInstanceParams.x;
  1037. #else
  1038.     return 0.0;
  1039. #endif
  1040. }
  1041.  
  1042. /** Get the per-instance random value when instancing */
  1043. float GetPerInstanceRandom(FMaterialPixelParameters Parameters)
  1044. {
  1045. #if USE_INSTANCING
  1046.     return Parameters.PerInstanceParams.x;
  1047. #else
  1048.     return 0.0;
  1049. #endif
  1050. }
  1051.  
  1052. /** Get the per-instance fade-out amount when instancing */
  1053. float GetPerInstanceFadeAmount(FMaterialPixelParameters Parameters)
  1054. {
  1055. #if USE_INSTANCING
  1056.     return float(Parameters.PerInstanceParams.y);
  1057. #else
  1058.     return float(1.0);
  1059. #endif
  1060. }
  1061.  
  1062. /** Get the per-instance fade-out amount when instancing */
  1063. float GetPerInstanceFadeAmount(FMaterialVertexParameters Parameters)
  1064. {
  1065. #if USE_INSTANCING
  1066.     return float(Parameters.PerInstanceParams.y);
  1067. #else
  1068.     return float(1.0);
  1069. #endif
  1070. }
  1071.  
  1072. MaterialFloat GetDistanceCullFade()
  1073. {
  1074. #if PIXELSHADER
  1075.     return saturate(ResolvedView.RealTime * PrimitiveFade.FadeTimeScaleBias.x + PrimitiveFade.FadeTimeScaleBias.y);
  1076. #else
  1077.     return 1.0f;
  1078. #endif
  1079. }
  1080.  
  1081. /** Rotates Position about the given axis by the given angle, in radians, and returns the offset to Position. */
  1082. float3 RotateAboutAxis(float4 NormalizedRotationAxisAndAngle, float3 PositionOnAxis, float3 Position)
  1083. {
  1084.     // Project Position onto the rotation axis and find the closest point on the axis to Position
  1085.     float3 ClosestPointOnAxis = PositionOnAxis + NormalizedRotationAxisAndAngle.xyz * dot(NormalizedRotationAxisAndAngle.xyz, Position - PositionOnAxis);
  1086.     // Construct orthogonal axes in the plane of the rotation
  1087.     float3 UAxis = Position - ClosestPointOnAxis;
  1088.     float3 VAxis = cross(NormalizedRotationAxisAndAngle.xyz, UAxis);
  1089.     float CosAngle;
  1090.     float SinAngle;
  1091.     sincos(NormalizedRotationAxisAndAngle.w, SinAngle, CosAngle);
  1092.     // Rotate using the orthogonal axes
  1093.     float3 R = UAxis * CosAngle + VAxis * SinAngle;
  1094.     // Reconstruct the rotated world space position
  1095.     float3 RotatedPosition = ClosestPointOnAxis + R;
  1096.     // Convert from position to a position offset
  1097.     return RotatedPosition - Position;
  1098. }
  1099.  
  1100. // Material Expression function
  1101. float MaterialExpressionDepthOfFieldFunction(float SceneDepth, int FunctionValueIndex)
  1102. {
  1103.     // tryed switch() but seems that doesn't work
  1104.  
  1105.     if(FunctionValueIndex == 0) // TDOF_NearAndFarMask
  1106.     {
  1107.         return CalcUnfocusedPercentCustomBound(SceneDepth, 1, 1);
  1108.     }
  1109.     else if(FunctionValueIndex == 1) // TDOF_Near
  1110.     {
  1111.         return CalcUnfocusedPercentCustomBound(SceneDepth, 1, 0);
  1112.     }
  1113.     else if(FunctionValueIndex == 2) // TDOF_Far
  1114.     {
  1115.         return CalcUnfocusedPercentCustomBound(SceneDepth, 0, 1);
  1116.     }
  1117.     else if(FunctionValueIndex == 3) // TDOF_CircleOfConfusionRadius
  1118.     {
  1119.         // * 2 to compensate for half res
  1120.         return DepthToCoc(SceneDepth) * 2.0f;
  1121.     }
  1122.     return 0;
  1123. }
  1124.  
  1125. // TODO convert to LUT
  1126. float3 MaterialExpressionBlackBody( float Temp )
  1127. {
  1128.     float u = ( 0.860117757f + 1.54118254e-4f * Temp + 1.28641212e-7f * Temp*Temp ) / ( 1.0f + 8.42420235e-4f * Temp + 7.08145163e-7f * Temp*Temp );
  1129.     float v = ( 0.317398726f + 4.22806245e-5f * Temp + 4.20481691e-8f * Temp*Temp ) / ( 1.0f - 2.89741816e-5f * Temp + 1.61456053e-7f * Temp*Temp );
  1130.  
  1131.     float x = 3*u / ( 2*u - 8*v + 4 );
  1132.     float y = 2*v / ( 2*u - 8*v + 4 );
  1133.     float z = 1 - x - y;
  1134.  
  1135.     float Y = 1;
  1136.     float X = Y/y * x;
  1137.     float Z = Y/y * z;
  1138.  
  1139.     float3x3 XYZtoRGB =
  1140.     {
  1141.          3.2404542, -1.5371385, -0.4985314,
  1142.         -0.9692660,  1.8760108,  0.0415560,
  1143.          0.0556434, -0.2040259,  1.0572252,
  1144.     };
  1145.  
  1146.     return mul( XYZtoRGB, float3( X, Y, Z ) ) * pow( 0.0004 * Temp, 4 );
  1147. }
  1148.  
  1149. float2 MaterialExpressionGetHairRootUV(FMaterialPixelParameters Parameters)
  1150. {
  1151. #if IS_HAIR_FACTORY
  1152.     return GetHairStrandsRootUV(Parameters.HairPrimitiveId, Parameters.HairPrimitiveUV);
  1153. #else
  1154.     return float2(0, 0);
  1155. #endif
  1156. }
  1157.  
  1158. float2 MaterialExpressionGetHairUV(FMaterialPixelParameters Parameters)
  1159. {    
  1160. #if IS_HAIR_FACTORY
  1161.     return GetHairStrandsUV(Parameters.HairPrimitiveId, Parameters.HairPrimitiveUV);
  1162. #else
  1163.     return float2(0,0);
  1164. #endif
  1165. }
  1166.  
  1167. float2 MaterialExpressionGetHairDimensions(FMaterialPixelParameters Parameters)
  1168. {
  1169. #if IS_HAIR_FACTORY
  1170.     return GetHairStrandsDimensions(Parameters.HairPrimitiveId, Parameters.HairPrimitiveUV);
  1171. #else
  1172.     return float2(0, 0);
  1173. #endif
  1174. }
  1175.  
  1176. float MaterialExpressionGetHairSeed(FMaterialPixelParameters Parameters)
  1177. {
  1178. #if IS_HAIR_FACTORY
  1179.     return GetHairStrandsSeed(Parameters.HairPrimitiveId, Parameters.HairPrimitiveUV);
  1180. #else
  1181.     return 0;
  1182. #endif
  1183. }
  1184.  
  1185. float3 MaterialExpressionGetHairBaseColor(FMaterialPixelParameters Parameters)
  1186. {
  1187. #if IS_HAIR_FACTORY
  1188.     return GetHairStrandsBaseColor(Parameters.HairPrimitiveId, Parameters.HairPrimitiveUV);
  1189. #else
  1190.     return float3(0,0,0);
  1191. #endif
  1192. }
  1193.  
  1194. float MaterialExpressionGetHairRoughness(FMaterialPixelParameters Parameters)
  1195. {
  1196. #if IS_HAIR_FACTORY
  1197.     return GetHairStrandsRoughness(Parameters.HairPrimitiveId, Parameters.HairPrimitiveUV);
  1198. #else
  1199.     return 0;
  1200. #endif
  1201. }
  1202.  
  1203. float MaterialExpressionGetHairDepth(FMaterialVertexParameters Parameters)
  1204. {
  1205.     return 0;
  1206. }
  1207.  
  1208. float MaterialExpressionGetHairDepth(FMaterialPixelParameters Parameters)
  1209. {
  1210. #if IS_HAIR_FACTORY
  1211.     return GetHairStrandsDepth(Parameters.HairPrimitiveId, Parameters.HairPrimitiveUV, Parameters.SvPosition.z);
  1212. #else
  1213.     return 0;
  1214. #endif
  1215. }
  1216.  
  1217. float MaterialExpressionGetHairCoverage(FMaterialPixelParameters Parameters)
  1218. {
  1219. #if IS_HAIR_FACTORY
  1220.     return GetHairStrandsCoverage(Parameters.HairPrimitiveId, Parameters.HairPrimitiveUV);
  1221. #else
  1222.     return 0;
  1223. #endif
  1224. }
  1225.  
  1226. float3 MaterialExpressionGetHairTangent(FMaterialPixelParameters Parameters, bool bUseTangentSpace)
  1227. {
  1228. #if HAIR_STRAND_MESH_FACTORY
  1229.     return bUseTangentSpace ? float3(0,1,0) : Parameters.TangentToWorld[2];
  1230. #elif HAIR_CARD_MESH_FACTORY
  1231.     return GetHairStrandsTangent(Parameters.HairPrimitiveId, Parameters.HairPrimitiveUV, Parameters.TangentToWorld, bUseTangentSpace);
  1232. #else
  1233.     return 0;
  1234. #endif    
  1235. }
  1236.  
  1237. float2 MaterialExpressionGetAtlasUVs(FMaterialPixelParameters Parameters)
  1238. {
  1239. #if HAIR_STRAND_MESH_FACTORY
  1240.     return float2(0,0);
  1241. #elif HAIR_CARD_MESH_FACTORY
  1242.     return Parameters.HairPrimitiveUV;
  1243. #else
  1244.     return 0;
  1245. #endif
  1246.  
  1247. }
  1248.  
  1249. float4 MaterialExpressionGetHairAuxilaryData(FMaterialPixelParameters Parameters)
  1250. {
  1251. #if HAIR_CARD_MESH_FACTORY
  1252.     return GetHairStrandsAuxilaryData(Parameters.HairPrimitiveId, Parameters.HairPrimitiveUV);
  1253. #else
  1254.     return 0;
  1255. #endif
  1256. }
  1257.  
  1258. float3 MaterialExpressionGetHairColorFromMelanin(float Melanin, float Redness, float3 DyeColor)
  1259. {
  1260.     return GetHairColorFromMelanin(Melanin, Redness, DyeColor);
  1261. }
  1262.  
  1263. float4 MaterialExpressionAtmosphericFog(FMaterialPixelParameters Parameters, float3 AbsoluteWorldPosition)
  1264. {
  1265. #if MATERIAL_ATMOSPHERIC_FOG
  1266.     // WorldPosition default value is Parameters.AbsoluteWorldPosition if not overridden by the user
  1267.     float3 ViewVector = AbsoluteWorldPosition - ResolvedView.WorldCameraOrigin;
  1268.     float SceneDepth = length(ViewVector);
  1269.     return GetAtmosphericFog(ResolvedView.WorldCameraOrigin, ViewVector, SceneDepth, float3(0.f, 0.f, 0.f));
  1270. #else
  1271.     return float4(0.f, 0.f, 0.f, 0.f);
  1272. #endif
  1273. }
  1274.  
  1275. float3 MaterialExpressionAtmosphericLightVector(FMaterialPixelParameters Parameters)
  1276. {
  1277. #if MATERIAL_ATMOSPHERIC_FOG
  1278.     return ResolvedView.AtmosphereLightDirection[0].xyz;
  1279. #else
  1280.     return float3(0.f, 0.f, 0.f);
  1281. #endif
  1282. }
  1283.  
  1284. float3 MaterialExpressionAtmosphericLightColor(FMaterialPixelParameters Parameters)
  1285. {
  1286. #if MATERIAL_ATMOSPHERIC_FOG
  1287.     return ResolvedView.AtmosphereLightColor[0].rgb;
  1288. #else
  1289.     return float3(0.f, 0.f, 0.f);
  1290. #endif
  1291. }
  1292.  
  1293. float3 MaterialExpressionSkyAtmosphereLightIlluminance(FMaterialPixelParameters Parameters, float3 WorldPosition, uint LightIndex)
  1294. {
  1295. #if MATERIAL_SKY_ATMOSPHERE && PROJECT_SUPPORT_SKY_ATMOSPHERE
  1296.     const float3 PlanetCenterToWorldPos = (WorldPosition - ResolvedView.SkyPlanetCenterAndViewHeight.xyz) * CM_TO_SKY_UNIT;
  1297.  
  1298.     // GetAtmosphereTransmittance does a shadow test against the virtual planet.
  1299.     const float3 TransmittanceToLight = GetAtmosphereTransmittance(
  1300.         PlanetCenterToWorldPos, ResolvedView.AtmosphereLightDirection[LightIndex].xyz, ResolvedView.SkyAtmosphereBottomRadiusKm, ResolvedView.SkyAtmosphereTopRadiusKm,
  1301.         View.TransmittanceLutTexture, View.TransmittanceLutTextureSampler);
  1302.  
  1303.     return ResolvedView.AtmosphereLightColor[LightIndex].rgb * TransmittanceToLight;
  1304. #else
  1305.     return float3(0.0f, 0.0f, 0.0f);
  1306. #endif
  1307. }
  1308.  
  1309. #if MATERIAL_SKY_ATMOSPHERE && PROJECT_SUPPORT_SKY_ATMOSPHERE
  1310.     #define DEFINE_SKYATMLIGHTDIRECTION(MaterialParamType) float3 MaterialExpressionSkyAtmosphereLightDirection(MaterialParamType Parameters, uint LightIndex) {return ResolvedView.AtmosphereLightDirection[LightIndex].xyz;}
  1311. #else
  1312.     #define DEFINE_SKYATMLIGHTDIRECTION(MaterialParamType) float3 MaterialExpressionSkyAtmosphereLightDirection(MaterialParamType Parameters, uint LightIndex) {return float3(0.0f, 0.0f, 0.0f);}
  1313. #endif
  1314. DEFINE_SKYATMLIGHTDIRECTION(FMaterialPixelParameters)
  1315. DEFINE_SKYATMLIGHTDIRECTION(FMaterialVertexParameters)
  1316.  
  1317. float3 MaterialExpressionSkyAtmosphereLightDiskLuminance(FMaterialPixelParameters Parameters, uint LightIndex)
  1318. {
  1319.     float3 LightDiskLuminance = float3(0.0f, 0.0f, 0.0f);
  1320. #if MATERIAL_SKY_ATMOSPHERE && PROJECT_SUPPORT_SKY_ATMOSPHERE
  1321.     if (ResolvedView.RenderingReflectionCaptureMask == 0.0f) // Do not render light disk when in reflection capture in order to avoid double specular. The sun contribution is already computed analyticaly.
  1322.     {
  1323.         const float3 PlanetCenterToWorldCameraPos = (ResolvedView.SkyWorldCameraOrigin - ResolvedView.SkyPlanetCenterAndViewHeight.xyz) * CM_TO_SKY_UNIT;
  1324.         const float ViewHeight = ResolvedView.SkyPlanetCenterAndViewHeight.w * CM_TO_SKY_UNIT;
  1325.         const float3 ViewDir = -Parameters.CameraVector;
  1326.  
  1327.         // GetLightDiskLuminance does a test against the virtual planet but SkyWorldCameraOrigin is always put safely setup above it (to never have the camera into the virtual planet with a black screen)
  1328.         LightDiskLuminance =  GetLightDiskLuminance(PlanetCenterToWorldCameraPos, ViewDir, ResolvedView.SkyAtmosphereBottomRadiusKm, ResolvedView.SkyAtmosphereTopRadiusKm,
  1329.             View.TransmittanceLutTexture, View.TransmittanceLutTextureSampler,
  1330.             ResolvedView.AtmosphereLightDirection[LightIndex].xyz, ResolvedView.AtmosphereLightDiscCosHalfApexAngle[LightIndex].x, ResolvedView.AtmosphereLightDiscLuminance[LightIndex].xyz);
  1331.     }
  1332. #endif
  1333.     return LightDiskLuminance;
  1334. }
  1335.  
  1336. float3 MaterialExpressionSkyAtmosphereViewLuminance(FMaterialPixelParameters Parameters)
  1337. {
  1338. #if MATERIAL_SKY_ATMOSPHERE && PROJECT_SUPPORT_SKY_ATMOSPHERE
  1339.     const float3 PlanetCenterToWorldCameraPos = (ResolvedView.SkyWorldCameraOrigin - ResolvedView.SkyPlanetCenterAndViewHeight.xyz) * CM_TO_SKY_UNIT;
  1340.     const float ViewHeight = ResolvedView.SkyPlanetCenterAndViewHeight.w * CM_TO_SKY_UNIT;
  1341.     const float3 ViewDir = -Parameters.CameraVector;
  1342.  
  1343.     // The referencial used to build the Sky View lut
  1344.     float3x3 LocalReferencial = GetSkyViewLutReferential(ResolvedView.SkyViewLutReferential);
  1345.     // Compute inputs in this referential
  1346.     float3 WorldPosLocal = float3(0.0, 0.0, ViewHeight);
  1347.     float3 UpVectorLocal = float3(0.0, 0.0, 1.0);
  1348.     float3 WorldDirLocal = mul(LocalReferencial, ViewDir);
  1349.     float ViewZenithCosAngle = dot(WorldDirLocal, UpVectorLocal);
  1350.  
  1351.     float2 Sol = RayIntersectSphere(WorldPosLocal, WorldDirLocal, float4(0.0f, 0.0f, 0.0f, ResolvedView.SkyAtmosphereBottomRadiusKm));
  1352.     const bool IntersectGround = any(Sol > 0.0f);
  1353.  
  1354.     float2 SkyViewLutUv;
  1355.     SkyViewLutParamsToUv(IntersectGround, ViewZenithCosAngle, WorldDirLocal, ViewHeight, ResolvedView.SkyAtmosphereBottomRadiusKm, ResolvedView.SkyViewLutSizeAndInvSize, SkyViewLutUv);
  1356.     float3 SkyAtmosphereViewLuminance = Texture2DSampleLevel(View.SkyViewLutTexture, View.SkyViewLutTextureSampler, SkyViewLutUv, 0.0f).rgb;
  1357.     SkyAtmosphereViewLuminance *= ResolvedView.SkyAtmosphereSkyLuminanceFactor;
  1358. #if USE_PREEXPOSURE
  1359.     SkyAtmosphereViewLuminance *= ResolvedView.OneOverPreExposure;
  1360. #endif
  1361.     return SkyAtmosphereViewLuminance;
  1362. #else
  1363.     return float3(0.0f, 0.0f, 0.0f);
  1364. #endif
  1365. }
  1366.  
  1367. float4 MaterialExpressionSkyAtmosphereAerialPerspective(FMaterialPixelParameters Parameters, float3 WorldPosition)
  1368. {
  1369. #if MATERIAL_SKY_ATMOSPHERE && PROJECT_SUPPORT_SKY_ATMOSPHERE
  1370.     const float OneOverPreExposure = USE_PREEXPOSURE ? ResolvedView.OneOverPreExposure : 1.0f;
  1371.  
  1372.     const float3 WorldPos = WorldPosition * CM_TO_SKY_UNIT;
  1373.     const float3 CameraPos = ResolvedView.SkyWorldCameraOrigin.xyz*CM_TO_SKY_UNIT;
  1374.  
  1375.     // NDCPosition is not computed using WorldPosition because it could result in position outside the frustum,
  1376.     // distorted uvs and bad visuals with artefact. Only the distance computation can actually be benefit from the surface position specified here.
  1377.     float4 NDCPosition = mul(float4(Parameters.AbsoluteWorldPosition.xyz, 1), ResolvedView.WorldToClip);
  1378.  
  1379.     float4 AerialPerspective = GetAerialPerspectiveLuminanceTransmittance(
  1380.         ResolvedView.RealTimeReflectionCapture, ResolvedView.SkyAtmosphereCameraAerialPerspectiveVolumeSizeAndInvSize,
  1381.         NDCPosition, WorldPos, CameraPos,
  1382.         View.CameraAerialPerspectiveVolume, View.CameraAerialPerspectiveVolumeSampler,
  1383.         ResolvedView.SkyAtmosphereCameraAerialPerspectiveVolumeDepthResolutionInv,
  1384.         ResolvedView.SkyAtmosphereCameraAerialPerspectiveVolumeDepthResolution,
  1385.         ResolvedView.SkyAtmosphereAerialPerspectiveStartDepthKm,
  1386.         ResolvedView.SkyAtmosphereCameraAerialPerspectiveVolumeDepthSliceLengthKm,
  1387.         ResolvedView.SkyAtmosphereCameraAerialPerspectiveVolumeDepthSliceLengthKmInv,
  1388.         OneOverPreExposure);
  1389.     return AerialPerspective;
  1390. #else
  1391.     return float4(0.0f, 0.0f, 0.0f, 1.0f); // RGB= null scattering, A= null transmittance
  1392. #endif
  1393. }
  1394.  
  1395. float3 MaterialExpressionSkyAtmosphereDistantLightScatteredLuminance(FMaterialPixelParameters Parameters)
  1396. {
  1397. #if MATERIAL_SKY_ATMOSPHERE && PROJECT_SUPPORT_SKY_ATMOSPHERE
  1398.     // TODO load on platforms supporting it
  1399.     return Texture2DSampleLevel(View.DistantSkyLightLutTexture, View.DistantSkyLightLutTextureSampler, float2(0.5f, 0.5f), 0.0f).rgb;
  1400. #else
  1401.     return float3(0.0f, 0.0f, 0.0f);
  1402. #endif
  1403. }
  1404.  
  1405. /**
  1406.     Get the scene depth from the scene below the single layer water surface. This is only valid in the single layer water rendering pass.
  1407.     Returns the chosen fallback depth if the material doesn't support reading back the correct depth.
  1408. */
  1409. float MaterialExpressionSceneDepthWithoutWater(float2 ViewportUV, float FallbackDepth)
  1410. {
  1411. #if MATERIAL_SHADINGMODEL_SINGLELAYERWATER && !SCENE_TEXTURES_DISABLED && (!SIMPLE_SINGLE_LAYER_WATER || SINGLE_LAYER_WATER_SIMPLE_FORWARD)
  1412.  
  1413.     const float2 ClampedViewportUV = clamp(ViewportUV, OpaqueBasePass.SceneWithoutSingleLayerWaterMinMaxUV.xy, OpaqueBasePass.SceneWithoutSingleLayerWaterMinMaxUV.zw);
  1414.  
  1415.     return OpaqueBasePass.SceneDepthWithoutSingleLayerWaterTexture.SampleLevel(SingleLayerWaterSceneDepthSampler, ClampedViewportUV, 0).x * SINGLE_LAYER_WATER_DEPTH_SCALE;
  1416. #else
  1417.     return FallbackDepth;
  1418. #endif
  1419. }
  1420.  
  1421. float MaterialExpressionCloudSampleAltitude(FMaterialPixelParameters Parameters)
  1422. {
  1423. #if CLOUD_LAYER_PIXEL_SHADER
  1424.     return Parameters.CloudSampleAltitude;
  1425. #else
  1426.     return 0.0f;
  1427. #endif
  1428. }
  1429.  
  1430. float MaterialExpressionCloudSampleAltitudeInLayer(FMaterialPixelParameters Parameters)
  1431. {
  1432. #if CLOUD_LAYER_PIXEL_SHADER
  1433.     return Parameters.CloudSampleAltitudeInLayer;
  1434. #else
  1435.     return 0.0f;
  1436. #endif
  1437. }
  1438.  
  1439. float MaterialExpressionCloudSampleNormAltitudeInLayer(FMaterialPixelParameters Parameters)
  1440. {
  1441. #if CLOUD_LAYER_PIXEL_SHADER
  1442.     return Parameters.CloudSampleNormAltitudeInLayer;
  1443. #else
  1444.     return 0.0f;
  1445. #endif
  1446. }
  1447.  
  1448. float3 MaterialExpressionVolumeSampleConservativeDensity(FMaterialPixelParameters Parameters)
  1449. {
  1450. #if CLOUD_LAYER_PIXEL_SHADER
  1451.     return Parameters.VolumeSampleConservativeDensity;
  1452. #else
  1453.     return float3(0.0f, 0.0f, 0.0f);
  1454. #endif
  1455. }
  1456.  
  1457. float MaterialExpressionVolumeSampleShadowSampleDistance(FMaterialPixelParameters Parameters)
  1458. {
  1459. #if CLOUD_LAYER_PIXEL_SHADER
  1460.     return Parameters.ShadowSampleDistance;
  1461. #else
  1462.     return 0.0f;
  1463. #endif
  1464. }
  1465.  
  1466. float3 MaterialExpressionPreSkinOffset(FMaterialVertexParameters Parameters)
  1467. {
  1468. #if GPU_SKINNED_MESH_FACTORY
  1469.     return Parameters.PreSkinOffset;
  1470. #else
  1471.     return 0;
  1472. #endif
  1473. }
  1474.  
  1475. float3 MaterialExpressionPostSkinOffset(FMaterialVertexParameters Parameters)
  1476. {
  1477. #if GPU_SKINNED_MESH_FACTORY
  1478.     return Parameters.PostSkinOffset;
  1479. #else
  1480.     return 0;
  1481. #endif
  1482. }
  1483.  
  1484. /**
  1485.  * Utility function to unmirror one coordinate value to the other side
  1486.  * UnMirrored == 1 if normal
  1487.  * UnMirrored == -1 if mirrored
  1488.  *
  1489.  * Used by most of parameter functions generated via code in this file
  1490.  */
  1491. MaterialFloat UnMirror( MaterialFloat Coordinate, FMaterialPixelParameters Parameters )
  1492. {
  1493.     return ((Coordinate)*(Parameters.UnMirrored)*0.5+0.5);
  1494. }
  1495.  
  1496. /**
  1497.  * UnMirror only U
  1498.  */
  1499. MaterialFloat2 UnMirrorU( MaterialFloat2 UV, FMaterialPixelParameters Parameters )
  1500. {
  1501.     return MaterialFloat2(UnMirror(UV.x, Parameters), UV.y);
  1502. }
  1503.  
  1504. /**
  1505.  * UnMirror only V
  1506.  */
  1507. MaterialFloat2 UnMirrorV( MaterialFloat2 UV, FMaterialPixelParameters Parameters )
  1508. {
  1509.     return MaterialFloat2(UV.x, UnMirror(UV.y, Parameters));
  1510. }
  1511.  
  1512. /**
  1513.  * UnMirror only UV
  1514.  */
  1515. MaterialFloat2 UnMirrorUV( MaterialFloat2 UV, FMaterialPixelParameters Parameters )
  1516. {
  1517.     return MaterialFloat2(UnMirror(UV.x, Parameters), UnMirror(UV.y, Parameters));
  1518. }
  1519.  
  1520. /**
  1521.  * Transforms screen space positions into UVs with [.5, .5] centered on ObjectPostProjectionPosition,
  1522.  * And [1, 1] at ObjectPostProjectionPosition + (ObjectRadius, ObjectRadius).
  1523.  */
  1524. MaterialFloat2 GetParticleMacroUV(FMaterialPixelParameters Parameters)
  1525. {
  1526.     return (Parameters.ScreenPosition.xy / Parameters.ScreenPosition.w - Parameters.Particle.MacroUV.xy) * Parameters.Particle.MacroUV.zw + MaterialFloat2(.5, .5);
  1527. }
  1528.  
  1529. MaterialFloat4 ProcessMaterialColorTextureLookup(MaterialFloat4 TextureValue)
  1530. {
  1531.     return TextureValue;
  1532. }
  1533.  
  1534. MaterialFloat4 ProcessMaterialVirtualColorTextureLookup(MaterialFloat4 TextureValue)
  1535. {
  1536.     TextureValue = ProcessMaterialColorTextureLookup(TextureValue);
  1537. #if FEATURE_LEVEL == FEATURE_LEVEL_ES3_1
  1538.     // on mobile all VT physical spaces use linear color formats, do sRGB to Linear conversion in the shader
  1539.     TextureValue = MaterialFloat4(TextureValue.rgb*TextureValue.rgb, TextureValue.a);
  1540. #endif
  1541.     return TextureValue;
  1542. }
  1543.  
  1544. MaterialFloat4 ProcessMaterialExternalTextureLookup(MaterialFloat4 TextureValue)
  1545. {
  1546. #if COMPILER_GLSL_ES3_1
  1547.     return MaterialFloat4(pow(TextureValue.rgb, 2.2f), TextureValue.a);
  1548. #else
  1549.     return ProcessMaterialColorTextureLookup(TextureValue);
  1550. #endif
  1551. }
  1552.  
  1553. MaterialFloat4 ProcessMaterialLinearColorTextureLookup(MaterialFloat4 TextureValue)
  1554. {
  1555.     return TextureValue;
  1556. }
  1557.  
  1558. MaterialFloat ProcessMaterialGreyscaleTextureLookup(MaterialFloat TextureValue)
  1559. {
  1560. #if (COMPILER_GLSL_ES3_1 || VULKAN_PROFILE) // OpenGLES3.1, Vulkan3.1 do not support sRGB sampling from R8
  1561.     #if MOBILE_EMULATION
  1562.     if( ResolvedView.MobilePreviewMode > 0.5f )
  1563.     {
  1564.         // undo HW srgb->lin
  1565.         TextureValue = pow(TextureValue, 1.0f/2.2f); // TODO: replace with a more accurate lin -> sRGB conversion.
  1566.     }
  1567.     #endif
  1568.     // sRGB read approximation (in highp if possible)
  1569.     float LinValue = TextureValue;
  1570.     LinValue *= LinValue;
  1571.     return MaterialFloat(LinValue);
  1572. #endif
  1573.     return TextureValue;
  1574. }
  1575.  
  1576. MaterialFloat ProcessMaterialLinearGreyscaleTextureLookup(MaterialFloat TextureValue)
  1577. {
  1578.     return TextureValue;
  1579. }
  1580.  
  1581. /** Accesses a shared material sampler or falls back if independent samplers are not supported. */
  1582. SamplerState GetMaterialSharedSampler(SamplerState TextureSampler, SamplerState SharedSampler)
  1583. {
  1584. #if SUPPORTS_INDEPENDENT_SAMPLERS
  1585.     return SharedSampler;
  1586. #else
  1587.     // Note: to match behavior on platforms that don't support SUPPORTS_INDEPENDENT_SAMPLERS,
  1588.     // TextureSampler should have been set to the same sampler.  This is not currently done.
  1589.     return TextureSampler;
  1590. #endif
  1591. }
  1592.  
  1593. /** Calculate a reflection vector about the specified world space normal. Optionally normalize this normal **/
  1594. MaterialFloat3 ReflectionAboutCustomWorldNormal(FMaterialPixelParameters Parameters, MaterialFloat3 WorldNormal, bool bNormalizeInputNormal)
  1595. {
  1596.     if (bNormalizeInputNormal)
  1597.     {
  1598.         WorldNormal = normalize(WorldNormal);
  1599.     }
  1600.  
  1601.     return -Parameters.CameraVector + WorldNormal * dot(WorldNormal, Parameters.CameraVector) * 2.0;
  1602. }
  1603.  
  1604. #ifndef SPHERICAL_OPACITY_FOR_SHADOW_DEPTHS
  1605. #define SPHERICAL_OPACITY_FOR_SHADOW_DEPTHS 0
  1606. #endif
  1607.  
  1608. /**
  1609.  * Calculates opacity for a billboard particle as if it were a sphere.
  1610.  * Note: Calling this function requires the vertex factory to have been compiled with SPHERICAL_PARTICLE_OPACITY set to 1
  1611.  */
  1612. float GetSphericalParticleOpacity(FMaterialPixelParameters Parameters, float Density)
  1613. {
  1614.     float Opacity = 0;
  1615.  
  1616. #if PARTICLE_FACTORY || HAS_PRIMITIVE_UNIFORM_BUFFER
  1617.  
  1618. #if PARTICLE_FACTORY
  1619.  
  1620.     float3 ParticleTranslatedWorldPosition = Parameters.Particle.TranslatedWorldPositionAndSize.xyz;
  1621.     float ParticleRadius = max(0.000001f, Parameters.Particle.TranslatedWorldPositionAndSize.w);
  1622.  
  1623. #elif HAS_PRIMITIVE_UNIFORM_BUFFER
  1624.  
  1625.     // Substitute object attributes if the mesh is not a particle
  1626.     // This is mostly useful for previewing materials using spherical opacity in the material editor
  1627.     float3 ParticleTranslatedWorldPosition = GetPrimitiveData(Parameters.PrimitiveId).ObjectWorldPositionAndRadius.xyz + ResolvedView.PreViewTranslation.xyz;
  1628.     float ParticleRadius = max(0.000001f, GetPrimitiveData(Parameters.PrimitiveId).ObjectWorldPositionAndRadius.w);
  1629.  
  1630. #endif
  1631.  
  1632.     // Rescale density to make the final opacity independent of the particle radius
  1633.     float RescaledDensity = Density / ParticleRadius;
  1634.  
  1635.     // Distance from point being shaded to particle center
  1636.     float DistanceToParticle = length(Parameters.WorldPosition_NoOffsets_CamRelative - ParticleTranslatedWorldPosition);
  1637.  
  1638.     FLATTEN
  1639.     if (DistanceToParticle < ParticleRadius)
  1640.     {
  1641.         // Distance from point being shaded to the point on the sphere along the view direction
  1642.         float HemisphericalDistance = sqrt(ParticleRadius * ParticleRadius - DistanceToParticle * DistanceToParticle);
  1643.  
  1644. #if SPHERICAL_OPACITY_FOR_SHADOW_DEPTHS
  1645.         // When rendering shadow depths we can't use scene depth or the near plane, just use the distance through the whole sphere
  1646.         float DistanceThroughSphere = HemisphericalDistance * 2;
  1647. #else
  1648.         // Initialize near and far sphere intersection distances
  1649.         float NearDistance = Parameters.ScreenPosition.w - HemisphericalDistance;
  1650.         float FarDistance = Parameters.ScreenPosition.w + HemisphericalDistance;
  1651.  
  1652.         float SceneDepth = CalcSceneDepth(SvPositionToBufferUV(Parameters.SvPosition));
  1653.         FarDistance = min(SceneDepth, FarDistance);
  1654.  
  1655.         // Take into account opaque objects intersecting the sphere
  1656.         float DistanceThroughSphere = FarDistance - NearDistance;
  1657. #endif
  1658.  
  1659.         // Use the approximation for the extinction line integral from "Spherical Billboards and their Application to Rendering Explosions"
  1660.         Opacity = saturate(1 - exp2(-RescaledDensity * (1 - DistanceToParticle / ParticleRadius) * DistanceThroughSphere));
  1661.  
  1662. #if !SPHERICAL_OPACITY_FOR_SHADOW_DEPTHS
  1663.         // Fade out as the particle approaches the near plane
  1664.         Opacity = lerp(0, Opacity, saturate((Parameters.ScreenPosition.w - ParticleRadius - ResolvedView.NearPlane) / ParticleRadius));
  1665. #endif
  1666.     }
  1667.  
  1668. #endif
  1669.  
  1670.     return Opacity;
  1671. }
  1672.  
  1673. float2 RotateScaleOffsetTexCoords(float2 InTexCoords, float4 InRotationScale, float2 InOffset)
  1674. {
  1675.     return float2(dot(InTexCoords, InRotationScale.xy), dot(InTexCoords, InRotationScale.zw)) + InOffset;
  1676. }
  1677.  
  1678. #if USES_SPEEDTREE
  1679.  
  1680. /** Vertex offset for SpeedTree wind and LOD */
  1681. float3 GetSpeedTreeVertexOffsetInner(FMaterialVertexParameters Parameters, int GeometryType, int WindType, int LODType, float BillboardThreshold, bool bExtraBend, float3 ExtraBend, FSpeedTreeData STData)
  1682. {
  1683.     #if (NUM_MATERIAL_TEXCOORDS_VERTEX < 6) || IS_MESHPARTICLE_FACTORY
  1684.         return float4(0,0,0);
  1685.     #endif
  1686.  
  1687.     #if USE_INSTANCING
  1688.         float3x3 LocalToWorld = (float3x3)Parameters.InstanceLocalToWorld;
  1689.         float3 LocalPosition = Parameters.InstanceLocalPosition;
  1690.  
  1691.         // skip if this instance is hidden
  1692.         if (Parameters.PerInstanceParams.z < 1.f)
  1693.         {
  1694.             return float3(0,0,0);
  1695.         }
  1696.     #else
  1697.         float3x3 LocalToWorld = (float3x3)GetPrimitiveData(Parameters.PrimitiveId).LocalToWorld;
  1698.         float3 LocalPosition = mul(float4(GetWorldPosition(Parameters), 1), GetPrimitiveData(Parameters.PrimitiveId).WorldToLocal).xyz;
  1699.     #endif
  1700.  
  1701.     float3 TreePos = GetObjectWorldPosition(Parameters);
  1702.  
  1703.     // compute LOD by finding screen space size
  1704.     float LodInterp = 1.0;
  1705. #if !USE_INSTANCING || !USE_DITHERED_LOD_TRANSITION
  1706.     if (LODType == SPEEDTREE_LOD_TYPE_SMOOTH)
  1707.     {
  1708.         const float Dist = length(TreePos - ResolvedView.WorldCameraOrigin);
  1709.         const float ScreenMultiple = 0.5 * max(ResolvedView.ViewToClip[0][0], ResolvedView.ViewToClip[1][1]);
  1710.         const float ScreenRadius = 2.0 * ScreenMultiple * GetPrimitiveData(Parameters.PrimitiveId).ObjectWorldPositionAndRadius.w / max(1.0, Dist);
  1711.         LodInterp = saturate((ScreenRadius - SpeedTreeLODInfo.x) / SpeedTreeLODInfo.z);
  1712.     }
  1713. #endif
  1714.     TreePos *= 0.001; // The only other use of the tree position is as an offset into trig functions, but big numbers don't play nice there
  1715.  
  1716.     // SpeedTrees should only be uniformly scaled, but if necessary, it takes a few more instructions
  1717.     float TreeScale = length(mul(float3(0,0,1), LocalToWorld));
  1718.                     //float3(length((float3)LocalToWorld[0]),
  1719.                     //        length((float3)LocalToWorld[1]),
  1720.                     //        length((float3)LocalToWorld[2]));
  1721.  
  1722.  
  1723.     // @todo There is probably a more optimal way to get the rotated (but not translated or scaled) vertex position needed for correct wind
  1724.     float3 OriginalPosition = LocalPosition;
  1725.     OriginalPosition = mul(OriginalPosition, LocalToWorld) / TreeScale;
  1726.  
  1727.     float3 FinalPosition = OriginalPosition;
  1728.    
  1729.     if (GeometryType == SPEEDTREE_GEOMETRY_TYPE_BILLBOARD)
  1730.     {
  1731.         if (BillboardThreshold < 1.0)
  1732.         {
  1733.             // billboard meshes can have triangles drop out if they aren't facing the camera
  1734.             // this rotates the view direction around so we ignore the local Z component
  1735.             float3 LocalView2D = normalize(float3(ResolvedView.ViewForward.xy, 0));
  1736.             float3 LocalNormal2D = normalize(float3(Parameters.TangentToWorld[2].xy, 0));
  1737.             if (dot(LocalView2D, LocalNormal2D) > (-1.0 + BillboardThreshold * 0.25))
  1738.             {
  1739.                 FinalPosition = float3(0,0,0);
  1740.             }
  1741.         }
  1742.     }
  1743.     else
  1744.     {
  1745.         // rotated normal needed in a few places
  1746.         float3 Normal = Parameters.TangentToWorld[2];
  1747.  
  1748.         // branches and fronds
  1749.         if (GeometryType == SPEEDTREE_GEOMETRY_TYPE_BRANCH || GeometryType == SPEEDTREE_GEOMETRY_TYPE_FROND)
  1750.         {
  1751.             // smooth LOD
  1752.             #if !USE_INSTANCING
  1753.                 if (LODType == SPEEDTREE_LOD_TYPE_SMOOTH)
  1754.                 {
  1755.                     float3 LODPos = float3(Parameters.TexCoords[3].x, Parameters.TexCoords[3].y, Parameters.TexCoords[4].x);
  1756.                     LODPos = mul(LODPos, LocalToWorld) / TreeScale;
  1757.                     FinalPosition = lerp(LODPos, FinalPosition, LodInterp);
  1758.                 }
  1759.             #endif
  1760.  
  1761.             // frond wind, if needed
  1762.             if (GeometryType == SPEEDTREE_GEOMETRY_TYPE_FROND && WindType == SPEEDTREE_WIND_TYPE_PALM)
  1763.             {
  1764.                 float2 TexCoords = Parameters.TexCoords[0];
  1765.                 float4 WindExtra = float4(Parameters.TexCoords[5].x, Parameters.TexCoords[5].y, Parameters.TexCoords[6].x, 0.0);
  1766.                 FinalPosition = RippleFrond(STData, FinalPosition, Normal, TexCoords.x, TexCoords.y, WindExtra.x, WindExtra.y, WindExtra.z);
  1767.             }
  1768.         }
  1769.  
  1770.         // leaves and facing leaves
  1771.         if (GeometryType == SPEEDTREE_GEOMETRY_TYPE_FACINGLEAF ||
  1772.                 (GeometryType == SPEEDTREE_GEOMETRY_TYPE_LEAF &&
  1773.                 (LODType == SPEEDTREE_LOD_TYPE_SMOOTH || (WindType > SPEEDTREE_WIND_TYPE_FASTEST && WindType != SPEEDTREE_WIND_TYPE_PALM))))
  1774.         {
  1775.             // remove anchor pos from vertex position
  1776.             float3 Anchor = float3(Parameters.TexCoords[4].y, Parameters.TexCoords[5].x, Parameters.TexCoords[5].y);
  1777.  
  1778.             // face camera-facing leaves to the camera, if needed
  1779.             if (GeometryType == SPEEDTREE_GEOMETRY_TYPE_FACINGLEAF)
  1780.             {
  1781.                 // have to rotate the view into local space
  1782.                 FinalPosition = LocalPosition - Anchor;
  1783.                 FinalPosition = FinalPosition.x * ResolvedView.ViewRight +
  1784.                                 FinalPosition.y * ResolvedView.ViewUp +
  1785.                                 FinalPosition.z * ResolvedView.ViewForward;
  1786.             }
  1787.            
  1788.             Anchor = (mul(Anchor, LocalToWorld)) / TreeScale;
  1789.            
  1790.             if (GeometryType == SPEEDTREE_GEOMETRY_TYPE_LEAF)
  1791.             {
  1792.                 FinalPosition -= Anchor;
  1793.             }
  1794.  
  1795.             // smooth LOD
  1796.             #if !USE_INSTANCING
  1797.                 if (LODType == SPEEDTREE_LOD_TYPE_SMOOTH)
  1798.                 {
  1799.                     if (GeometryType == SPEEDTREE_GEOMETRY_TYPE_LEAF)
  1800.                     {
  1801.                         float3 LODPos = float3(Parameters.TexCoords[3].x, Parameters.TexCoords[3].y, Parameters.TexCoords[4].x);
  1802.                         LODPos = mul(LODPos, LocalToWorld) / TreeScale - Anchor;
  1803.                         FinalPosition = lerp(LODPos, FinalPosition, LodInterp);
  1804.                     }
  1805.                     else
  1806.                     {
  1807.                         float LODScalar = Parameters.TexCoords[3].x;
  1808.                         FinalPosition *= lerp(LODScalar, 1.0, LodInterp);
  1809.                     }
  1810.                 }
  1811.             #endif
  1812.  
  1813.             // leaf wind
  1814.             if (WindType > SPEEDTREE_WIND_TYPE_FASTEST && WindType != SPEEDTREE_WIND_TYPE_PALM)
  1815.             {
  1816.                 float4 WindExtra = float4(Parameters.TexCoords[6].x, Parameters.TexCoords[6].y, Parameters.TexCoords[7].x, Parameters.TexCoords[7].y);
  1817.                 float LeafWindTrigOffset = Anchor.x + Anchor.y;
  1818.                 FinalPosition = LeafWind(STData, WindExtra.w > 0.0, FinalPosition, Normal, WindExtra.x, float3(0,0,0), WindExtra.y, WindExtra.z, LeafWindTrigOffset, WindType);
  1819.             }
  1820.                
  1821.             // move leaf back to anchor
  1822.             FinalPosition += Anchor;
  1823.         }
  1824.  
  1825.         if (WindType > SPEEDTREE_WIND_TYPE_FAST)
  1826.         {
  1827.             // branch wind (applies to all geometry)
  1828.             float2 VertBranchWind = Parameters.TexCoords[2];
  1829.             FinalPosition = BranchWind(STData, FinalPosition, TreePos, float4(VertBranchWind, 0, 0), WindType);
  1830.         }    
  1831.     }
  1832.  
  1833.     // global wind can apply to the whole tree, even billboards
  1834.     bool bHasGlobal = (WindType != SPEEDTREE_WIND_TYPE_NONE);
  1835.     if (bExtraBend || bHasGlobal)
  1836.     {
  1837.         FinalPosition = GlobalWind(STData, FinalPosition, TreePos, true, bHasGlobal, bExtraBend, ExtraBend);
  1838.     }
  1839.  
  1840.     // convert into a world space offset
  1841.     return (FinalPosition - OriginalPosition) * TreeScale;
  1842. }
  1843.  
  1844. /** Vertex offset for SpeedTree wind and LOD */
  1845. float3 GetSpeedTreeVertexOffset(FMaterialVertexParameters Parameters, int GeometryType, int WindType, int LODType, float BillboardThreshold, bool bUsePreviousFrame, bool bExtraBend, float3 ExtraBend)
  1846. {
  1847. #if VF_SUPPORTS_SPEEDTREE_WIND
  1848.     if (bUsePreviousFrame)
  1849.     {
  1850.         return GetSpeedTreeVertexOffsetInner(Parameters, GeometryType, WindType, LODType, BillboardThreshold, bExtraBend, ExtraBend, GetPreviousSpeedTreeData());
  1851.     }
  1852.     return GetSpeedTreeVertexOffsetInner(Parameters, GeometryType, WindType, LODType, BillboardThreshold, bExtraBend, ExtraBend, GetCurrentSpeedTreeData());
  1853. #else
  1854.     return 0;
  1855. #endif
  1856. }
  1857.  
  1858. #endif
  1859.  
  1860. MaterialFloat2 GetLightmapUVs(FMaterialPixelParameters Parameters)
  1861. {
  1862. #if LIGHTMAP_UV_ACCESS
  1863.     return Parameters.LightmapUVs;
  1864. #else
  1865.     return MaterialFloat2(0,0);
  1866. #endif
  1867. }
  1868.  
  1869. //The post-process material needs to decode the scene color since it's encoded at PreTonemapMSAA if MSAA enabled on MetalMobilePlatorm
  1870. //The POST_PROCESS_MATERIAL_BEFORE_TONEMAP is 1 for both BL_BeforeTranslucency and BL_BeforeTonemapping post-process materials
  1871. #if FEATURE_LEVEL <= FEATURE_LEVEL_ES3_1 && POST_PROCESS_MATERIAL && POST_PROCESS_MATERIAL_BEFORE_TONEMAP && METAL_PROFILE
  1872. uint bMetalMSAAHDRDecode;
  1873. #endif
  1874.  
  1875. #if NEEDS_SCENE_TEXTURES
  1876.  
  1877. #if SHADING_PATH_MOBILE
  1878.  
  1879. MaterialFloat4 MobileSceneTextureLookup(inout FMaterialPixelParameters Parameters, int SceneTextureId, float2 UV)
  1880. {
  1881. #if (FEATURE_LEVEL <= FEATURE_LEVEL_ES3_1)
  1882.  
  1883.     if (SceneTextureId == PPI_SceneDepth)
  1884.     {
  1885.         #if MOBILE_DEFERRED_SHADING
  1886.             MaterialFloat Depth = ConvertFromDeviceZ(Texture2DSample(MobileSceneTextures.SceneDepthTexture, MobileSceneTextures.SceneDepthTextureSampler, UV).r);
  1887.         #else
  1888.             MaterialFloat Depth = ConvertFromDeviceZ(Texture2DSample(MobileSceneTextures.SceneColorTexture, MobileSceneTextures.SceneColorTextureSampler, UV).a);
  1889.         #endif
  1890.         return MaterialFloat4(Depth.rrr, 0.f);
  1891.     }
  1892.     else if (SceneTextureId == PPI_CustomDepth)
  1893.     {
  1894.         MaterialFloat Depth = ConvertFromDeviceZ(Texture2DSample(MobileSceneTextures.CustomDepthTexture, MobileSceneTextures.CustomDepthTextureSampler, UV).r);
  1895.         return MaterialFloat4(Depth.rrr, 0.f);
  1896.     }
  1897.     else if (SceneTextureId == PPI_PostProcessInput0)
  1898.     {
  1899. #if POST_PROCESS_MATERIAL
  1900.         MaterialFloat4 Input0 = Texture2DSample(PostProcessInput_0_Texture, PostProcessInput_0_SharedSampler, UV);
  1901.         #if POST_PROCESS_MATERIAL_BEFORE_TONEMAP
  1902.             #if METAL_PROFILE
  1903.                 // Decode the input color since the color is encoded for MSAA
  1904.                 // The decode instructions might be able to skip with dynamic branch
  1905.                 if (bMetalMSAAHDRDecode)
  1906.                 {
  1907.                     Input0.rgb = Input0.rgb * rcp(Input0.r*(-0.299) + Input0.g*(-0.587) + Input0.b*(-0.114) + 1.0);
  1908.                 }
  1909.             #endif
  1910.         #endif
  1911.         // We need to preserve original SceneColor Alpha as it's used by tonemapper on mobile
  1912.         Parameters.BackupSceneColorAlpha = Input0.a;
  1913.         return Input0;
  1914. #endif// POST_PROCESS_MATERIAL
  1915.     }
  1916.     else if (SceneTextureId == PPI_CustomStencil)
  1917.     {
  1918.         MaterialFloat Stencil = Texture2DSample(MobileSceneTextures.MobileCustomStencilTexture, MobileSceneTextures.MobileCustomStencilTextureSampler, UV).r*255.0;
  1919.         Stencil = floor(Stencil + 0.5);
  1920.         return MaterialFloat4(Stencil.rrr, 0.f);
  1921.     }
  1922. #endif// FEATURE_LEVEL
  1923.  
  1924.     return MaterialFloat4(0.0f, 0.0f, 0.0f, 0.0f);
  1925. }
  1926.  
  1927. #endif // SHADING_PATH_MOBILE
  1928.  
  1929. #if SHADING_PATH_DEFERRED
  1930.  
  1931. #include "/Engine/Private/DeferredShadingCommon.ush"        // GetGBufferData()
  1932.  
  1933.  
  1934. #if POST_PROCESS_MATERIAL
  1935. /** Samples the screen-space velocity for the specified UV coordinates. */
  1936. float2 PostProcessVelocityLookup(float Depth, float2 UV)
  1937. {
  1938. #if GBUFFER_HAS_VELOCITY
  1939.     float4 EncodedVelocity = Texture2DSampleLevel(SceneTexturesStruct.GBufferVelocityTexture, SceneTexturesStruct_GBufferVelocityTextureSampler, UV, 0);
  1940. #else
  1941.     float4 EncodedVelocity = Texture2DSample(PostProcessInput_4_Texture, PostProcessInput_4_SharedSampler, UV);
  1942. #endif
  1943.  
  1944.     float2 Velocity;
  1945.     if( EncodedVelocity.x > 0.0 )
  1946.     {
  1947.         Velocity = DecodeVelocityFromTexture(EncodedVelocity).xy;
  1948.     }
  1949.     else
  1950.     {
  1951.         float4 ThisClip = float4( UV, Depth, 1 );
  1952.         float4 PrevClip = mul( ThisClip, View.ClipToPrevClip );
  1953.         float2 PrevScreen = PrevClip.xy / PrevClip.w;
  1954.         Velocity = UV - PrevScreen;
  1955.     }
  1956.  
  1957.     return Velocity;
  1958. }
  1959. #endif
  1960.  
  1961. /** Applies an offset to the scene texture lookup and decodes the HDR linear space color. */
  1962. float4 SceneTextureLookup(float2 UV, int SceneTextureIndex, bool bFiltered)
  1963. {
  1964. #if SCENE_TEXTURES_DISABLED
  1965.  
  1966.     // When scene textures are disabled, the output is matched to the dummy scene texture defaults.
  1967.     switch(SceneTextureIndex)
  1968.     {
  1969.     case PPI_SceneDepth:
  1970.     case PPI_CustomDepth:
  1971.         return ConvertFromDeviceZ(0.0f);
  1972.     case PPI_MaterialAO:
  1973.     case PPI_CustomStencil:
  1974.         return 1.0f;
  1975.     default:
  1976.         return 0.0f;
  1977.     }
  1978.  
  1979. #else // !SCENE_TEXTURES_DISABLED
  1980.  
  1981.     FScreenSpaceData ScreenSpaceData = GetScreenSpaceData(UV, false);
  1982.     switch(SceneTextureIndex)
  1983.     {
  1984.         // order needs to match to ESceneTextureId
  1985.  
  1986.         case PPI_SceneColor:
  1987.             return float4(CalcSceneColor(UV), 0);
  1988.         case PPI_SceneDepth:
  1989.             return ScreenSpaceData.GBuffer.Depth;
  1990.         case PPI_DiffuseColor:
  1991.             return float4(ScreenSpaceData.GBuffer.DiffuseColor, 0);
  1992.         case PPI_SpecularColor:
  1993.             return float4(ScreenSpaceData.GBuffer.SpecularColor, 0);
  1994.         case PPI_SubsurfaceColor:
  1995.             return IsSubsurfaceModel(ScreenSpaceData.GBuffer.ShadingModelID) ? float4( ExtractSubsurfaceColor(ScreenSpaceData.GBuffer), ScreenSpaceData.GBuffer.CustomData.a ) : ScreenSpaceData.GBuffer.CustomData;
  1996.         case PPI_BaseColor:
  1997.             return float4(ScreenSpaceData.GBuffer.BaseColor, 0);
  1998.         case PPI_Specular:
  1999.             return ScreenSpaceData.GBuffer.Specular;
  2000.         case PPI_Metallic:
  2001.             return ScreenSpaceData.GBuffer.Metallic;
  2002.         case PPI_WorldNormal:
  2003.             return float4(ScreenSpaceData.GBuffer.WorldNormal, 0);
  2004.         case PPI_SeparateTranslucency:
  2005.             return float4(1, 1, 1, 1);    // todo
  2006.         case PPI_Opacity:
  2007.             return ScreenSpaceData.GBuffer.CustomData.a;
  2008.         case PPI_Roughness:
  2009.             return ScreenSpaceData.GBuffer.Roughness;
  2010.         case PPI_MaterialAO:
  2011.             return ScreenSpaceData.GBuffer.GBufferAO;
  2012.         case PPI_CustomDepth:
  2013.             return ScreenSpaceData.GBuffer.CustomDepth;
  2014. #if POST_PROCESS_MATERIAL
  2015.         case PPI_PostProcessInput0:
  2016.             return Texture2DSample(PostProcessInput_0_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_0_SharedSampler, UV);
  2017.         case PPI_PostProcessInput1:
  2018.             return Texture2DSample(PostProcessInput_1_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_1_SharedSampler, UV);
  2019.         case PPI_PostProcessInput2:
  2020.             return Texture2DSample(PostProcessInput_2_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_2_SharedSampler, UV);
  2021.         case PPI_PostProcessInput3:
  2022.             return Texture2DSample(PostProcessInput_3_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_3_SharedSampler, UV);
  2023.         case PPI_PostProcessInput4:
  2024.             return Texture2DSample(PostProcessInput_4_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_4_SharedSampler, UV);
  2025. #endif // __POST_PROCESS_COMMON__
  2026.         case PPI_DecalMask:
  2027.             return 0;  // material compiler will return an error
  2028.         case PPI_ShadingModelColor:
  2029.             return float4(GetShadingModelColor(ScreenSpaceData.GBuffer.ShadingModelID), 1);
  2030.         case PPI_ShadingModelID:
  2031.             return float4(ScreenSpaceData.GBuffer.ShadingModelID, 0, 0, 0);
  2032.         case PPI_AmbientOcclusion:
  2033.             return ScreenSpaceData.AmbientOcclusion;
  2034.         case PPI_CustomStencil:
  2035.             return ScreenSpaceData.GBuffer.CustomStencil;
  2036.         case PPI_StoredBaseColor:
  2037.             return float4(ScreenSpaceData.GBuffer.StoredBaseColor, 0);
  2038.         case PPI_StoredSpecular:
  2039.             return float4(ScreenSpaceData.GBuffer.StoredSpecular.rrr, 0);
  2040. #if POST_PROCESS_MATERIAL
  2041.         case PPI_Velocity:
  2042.             return float4(PostProcessVelocityLookup(ConvertToDeviceZ(ScreenSpaceData.GBuffer.Depth), UV), 0, 0);
  2043. #endif
  2044.         case PPI_WorldTangent:
  2045.             return float4(ScreenSpaceData.GBuffer.WorldTangent, 0);
  2046.         case PPI_Anisotropy:
  2047.             return ScreenSpaceData.GBuffer.Anisotropy;
  2048.         default:
  2049.             return float4(0, 0, 0, 0);
  2050.     }
  2051. #endif // SCENE_TEXTURES_DISABLED
  2052. }
  2053.  
  2054. #endif // SHADING_PATH_DEFERRED
  2055. #endif // NEEDS_SCENE_TEXTURES
  2056.  
  2057. #if SHADING_PATH_DEFERRED
  2058.  
  2059. /** Applies an offset to the scene texture lookup and decodes the HDR linear space color. */
  2060. float3 DecodeSceneColorForMaterialNode(float2 ScreenUV)
  2061. {
  2062. #if !defined(SceneColorCopyTexture)
  2063.     // Hit proxies rendering pass doesn't have access to valid render buffers
  2064.     return float3(0.0f, 0.0f, 0.0f);
  2065. #else
  2066.     float4 EncodedSceneColor = Texture2DSample(SceneColorCopyTexture, SceneColorCopySampler, ScreenUV);
  2067.  
  2068.     // Undo the function in EncodeSceneColorForMaterialNode
  2069.     float3 SampledColor = pow(EncodedSceneColor.rgb, 4) * 10;
  2070.  
  2071. #if USE_PREEXPOSURE
  2072.     SampledColor *= View.OneOverPreExposure.xxx;
  2073. #endif
  2074.  
  2075.     return SampledColor;
  2076. #endif
  2077. }
  2078.  
  2079. #endif // SHADING_PATH_DEFERRED
  2080.  
  2081. // Uniform material expressions.
  2082.  
  2083.  
  2084. // can return in tangent space or world space (use MATERIAL_TANGENTSPACENORMAL)
  2085. half3 GetMaterialNormalRaw(FPixelMaterialInputs PixelMaterialInputs)
  2086. {
  2087.     return PixelMaterialInputs.Normal;
  2088. }
  2089.  
  2090. half3 GetMaterialNormal(FMaterialPixelParameters Parameters, FPixelMaterialInputs PixelMaterialInputs)
  2091. {
  2092.     half3 RetNormal;
  2093.  
  2094.     RetNormal = GetMaterialNormalRaw(PixelMaterialInputs);
  2095.        
  2096.     #if (USE_EDITOR_SHADERS && !ES3_1_PROFILE) || MOBILE_EMULATION
  2097.     {
  2098.         // this feature is only needed for development/editor - we can compile it out for a shipping build (see r.CompileShadersForDevelopment cvar help)
  2099.         half3 OverrideNormal = ResolvedView.NormalOverrideParameter.xyz;
  2100.  
  2101.         #if !MATERIAL_TANGENTSPACENORMAL
  2102.             OverrideNormal = Parameters.TangentToWorld[2] * (1 - ResolvedView.NormalOverrideParameter.w);
  2103.         #endif
  2104.  
  2105.         RetNormal = RetNormal * ResolvedView.NormalOverrideParameter.w + OverrideNormal;
  2106.     }
  2107.     #endif
  2108.  
  2109.     return RetNormal;
  2110. }
  2111.  
  2112. half3 GetMaterialTangentRaw(FPixelMaterialInputs PixelMaterialInputs)
  2113. {
  2114.     return PixelMaterialInputs.Tangent;
  2115. }
  2116.  
  2117. half3 GetMaterialTangent(FPixelMaterialInputs PixelMaterialInputs)
  2118. {
  2119.     return GetMaterialTangentRaw(PixelMaterialInputs);
  2120. }
  2121.  
  2122. half3 GetMaterialEmissiveRaw(FPixelMaterialInputs PixelMaterialInputs)
  2123. {
  2124.     return PixelMaterialInputs.EmissiveColor;
  2125. }
  2126.  
  2127. half3 GetMaterialEmissive(FPixelMaterialInputs PixelMaterialInputs)
  2128. {
  2129.     half3 EmissiveColor = GetMaterialEmissiveRaw(PixelMaterialInputs);
  2130. #if !MATERIAL_ALLOW_NEGATIVE_EMISSIVECOLOR
  2131.     EmissiveColor = max(EmissiveColor, 0.0f);
  2132. #endif
  2133.     return EmissiveColor;
  2134. }
  2135.  
  2136. half3 GetMaterialEmissiveForCS(FMaterialPixelParameters Parameters)
  2137. {
  2138. return 0;
  2139. }
  2140.  
  2141. // Shading Model is an uint and represents a SHADINGMODELID_* in ShadingCommon.ush
  2142. uint GetMaterialShadingModel(FPixelMaterialInputs PixelMaterialInputs)
  2143. {
  2144.     return PixelMaterialInputs.ShadingModel;
  2145. }
  2146.  
  2147. half3 GetMaterialBaseColorRaw(FPixelMaterialInputs PixelMaterialInputs)
  2148. {
  2149.     return PixelMaterialInputs.BaseColor;
  2150. }
  2151.  
  2152. half3 GetMaterialBaseColor(FPixelMaterialInputs PixelMaterialInputs)
  2153. {
  2154.     return saturate(GetMaterialBaseColorRaw(PixelMaterialInputs));
  2155. }
  2156.  
  2157. half GetMaterialMetallicRaw(FPixelMaterialInputs PixelMaterialInputs)
  2158. {
  2159.     return PixelMaterialInputs.Metallic;
  2160. }
  2161.  
  2162. half GetMaterialMetallic(FPixelMaterialInputs PixelMaterialInputs)
  2163. {
  2164.     return saturate(GetMaterialMetallicRaw(PixelMaterialInputs));
  2165. }
  2166.  
  2167. half GetMaterialSpecularRaw(FPixelMaterialInputs PixelMaterialInputs)
  2168. {
  2169.     return PixelMaterialInputs.Specular;
  2170. }
  2171.  
  2172. half GetMaterialSpecular(FPixelMaterialInputs PixelMaterialInputs)
  2173. {
  2174.     return saturate(GetMaterialSpecularRaw(PixelMaterialInputs));
  2175. }
  2176.  
  2177. half GetMaterialRoughnessRaw(FPixelMaterialInputs PixelMaterialInputs)
  2178. {
  2179.     return PixelMaterialInputs.Roughness;
  2180. }
  2181.  
  2182. half GetMaterialRoughness(FPixelMaterialInputs PixelMaterialInputs)
  2183. {
  2184. #if MATERIAL_FULLY_ROUGH
  2185.     return 1;
  2186. #endif
  2187.     half Roughness = saturate(GetMaterialRoughnessRaw(PixelMaterialInputs));
  2188.    
  2189.     #if (USE_EDITOR_SHADERS && !ES3_1_PROFILE) || MOBILE_EMULATION
  2190.     {
  2191.         // this feature is only needed for development/editor - we can compile it out for a shipping build (see r.CompileShadersForDevelopment cvar help)
  2192.         Roughness = Roughness * ResolvedView.RoughnessOverrideParameter.y + ResolvedView.RoughnessOverrideParameter.x;
  2193.     }
  2194.     #endif
  2195.    
  2196.     return Roughness;
  2197. }
  2198.  
  2199. half GetMaterialAnisotropyRaw(FPixelMaterialInputs PixelMaterialInputs)
  2200. {
  2201.     return PixelMaterialInputs.Anisotropy;
  2202. }
  2203.  
  2204. half GetMaterialAnisotropy(FPixelMaterialInputs PixelMaterialInputs)
  2205. {
  2206.     return clamp(GetMaterialAnisotropyRaw(PixelMaterialInputs), -1.0f, 1.0f);
  2207. }
  2208.  
  2209. half GetMaterialTranslucencyDirectionalLightingIntensity()
  2210. {
  2211. return 1.00000;
  2212. }
  2213.  
  2214. half GetMaterialTranslucentShadowDensityScale()
  2215. {
  2216. return 0.50000;
  2217. }
  2218.  
  2219. half GetMaterialTranslucentSelfShadowDensityScale()
  2220. {
  2221. return 2.00000;
  2222. }
  2223.  
  2224. half GetMaterialTranslucentSelfShadowSecondDensityScale()
  2225. {
  2226. return 10.00000;
  2227. }
  2228.  
  2229. half GetMaterialTranslucentSelfShadowSecondOpacity()
  2230. {
  2231. return 0.00000;
  2232. }
  2233.  
  2234. half GetMaterialTranslucentBackscatteringExponent()
  2235. {
  2236. return 30.00000;
  2237. }
  2238.  
  2239. half3 GetMaterialTranslucentMultipleScatteringExtinction()
  2240. {
  2241. return MaterialFloat3(1.00000, 0.83300, 0.58800);
  2242. }
  2243.  
  2244. // This is the clip value constant that is defined in the material (range 0..1)
  2245. // Use GetMaterialMask() to get the Material Mask combined with this.
  2246. half GetMaterialOpacityMaskClipValue()
  2247. {
  2248. return 0.33330;
  2249. }
  2250.  
  2251. // Should only be used by GetMaterialOpacity(), returns the unmodified value generated from the shader expressions of the opacity input.
  2252. // To compute the opacity depending on the material blending GetMaterialOpacity() should be called instead.
  2253. half GetMaterialOpacityRaw(FPixelMaterialInputs PixelMaterialInputs)
  2254. {
  2255.     return PixelMaterialInputs.Opacity;
  2256. }
  2257.  
  2258. #if MATERIALBLENDING_MASKED || (DECAL_BLEND_MODE == DECALBLENDMODEID_VOLUMETRIC)
  2259. // Returns the material mask value generated from the material expressions.
  2260. // Use GetMaterialMask() to get the value altered depending on the material blend mode.
  2261. half GetMaterialMaskInputRaw(FPixelMaterialInputs PixelMaterialInputs)
  2262. {
  2263.     return PixelMaterialInputs.OpacityMask;
  2264. }
  2265.  
  2266. // Returns the material mask value generated from the material expressions minus the used defined
  2267. // MaskClip value constant. If this value is <=0 the pixel should be killed.
  2268. half GetMaterialMask(FPixelMaterialInputs PixelMaterialInputs)
  2269. {
  2270.     return GetMaterialMaskInputRaw(PixelMaterialInputs) - GetMaterialOpacityMaskClipValue();
  2271. }
  2272. #endif
  2273.  
  2274. // Returns the material opacity depending on the material blend mode.
  2275. half GetMaterialOpacity(FPixelMaterialInputs PixelMaterialInputs)
  2276. {
  2277.     // Clamp to valid range to prevent negative colors from lerping
  2278.     return saturate(GetMaterialOpacityRaw(PixelMaterialInputs));
  2279. }
  2280.  
  2281. #if TRANSLUCENT_SHADOW_WITH_MASKED_OPACITY
  2282. half GetMaterialMaskedOpacity(FPixelMaterialInputs PixelMaterialInputs)
  2283. {
  2284.     return GetMaterialOpacity(PixelMaterialInputs) - GetMaterialOpacityMaskClipValue();
  2285. }
  2286. #endif
  2287.  
  2288. float3 GetMaterialWorldPositionOffset(FMaterialVertexParameters Parameters)
  2289. {
  2290.     #if USE_INSTANCING
  2291.         // skip if this instance is hidden
  2292.         if (Parameters.PerInstanceParams.z < 1.f)
  2293.         {
  2294.             return float3(0,0,0);
  2295.         }
  2296.     #endif
  2297.     return MaterialFloat3(0.00000000,0.00000000,0.00000000);;
  2298. }
  2299.  
  2300. float3 GetMaterialPreviousWorldPositionOffset(FMaterialVertexParameters Parameters)
  2301. {
  2302.     #if USE_INSTANCING
  2303.         // skip if this instance is hidden
  2304.         if (Parameters.PerInstanceParams.z < 1.f)
  2305.         {
  2306.             return float3(0,0,0);
  2307.         }
  2308.     #endif
  2309.     return MaterialFloat3(0.00000000,0.00000000,0.00000000);;
  2310. }
  2311.  
  2312. half3 GetMaterialWorldDisplacement(FMaterialTessellationParameters Parameters)
  2313. {
  2314.     return MaterialFloat3(0.00000000,0.00000000,0.00000000);;
  2315. }
  2316.  
  2317. half GetMaterialMaxDisplacement()
  2318. {
  2319. return 0.00000;
  2320. }
  2321.  
  2322. half GetMaterialTessellationMultiplier(FMaterialTessellationParameters Parameters)
  2323. {
  2324.     return 1.00000000;;
  2325. }
  2326.  
  2327. // .rgb:SubsurfaceColor, .a:SSProfileId in 0..1 range
  2328. half4 GetMaterialSubsurfaceDataRaw(FPixelMaterialInputs PixelMaterialInputs)
  2329. {
  2330.     return PixelMaterialInputs.Subsurface;
  2331. }
  2332.  
  2333. half4 GetMaterialSubsurfaceData(FPixelMaterialInputs PixelMaterialInputs)
  2334. {
  2335.     half4 OutSubsurface = GetMaterialSubsurfaceDataRaw(PixelMaterialInputs);
  2336.     OutSubsurface.rgb = saturate(OutSubsurface.rgb);
  2337.     return OutSubsurface;
  2338. }
  2339.  
  2340. half GetMaterialCustomData0(FMaterialPixelParameters Parameters)
  2341. {
  2342.     return 1.00000000;;
  2343. }
  2344.  
  2345. half GetMaterialCustomData1(FMaterialPixelParameters Parameters)
  2346. {
  2347.     return 0.10000000;;
  2348. }
  2349.  
  2350. half GetMaterialAmbientOcclusionRaw(FPixelMaterialInputs PixelMaterialInputs)
  2351. {
  2352.     return PixelMaterialInputs.AmbientOcclusion;
  2353. }
  2354.  
  2355. half GetMaterialAmbientOcclusion(FPixelMaterialInputs PixelMaterialInputs)
  2356. {
  2357.     return saturate(GetMaterialAmbientOcclusionRaw(PixelMaterialInputs));
  2358. }
  2359.  
  2360. half2 GetMaterialRefraction(FPixelMaterialInputs PixelMaterialInputs)
  2361. {
  2362.     return PixelMaterialInputs.Refraction;
  2363. }
  2364.  
  2365. #if NUM_TEX_COORD_INTERPOLATORS
  2366. void GetMaterialCustomizedUVs(FMaterialVertexParameters Parameters, inout float2 OutTexCoords[NUM_TEX_COORD_INTERPOLATORS])
  2367. {
  2368.     OutTexCoords[0] = Parameters.TexCoords[0].xy;
  2369.  
  2370. }
  2371.  
  2372. void GetCustomInterpolators(FMaterialVertexParameters Parameters, inout float2 OutTexCoords[NUM_TEX_COORD_INTERPOLATORS])
  2373. {
  2374.  
  2375. }
  2376. #endif
  2377.  
  2378. float GetMaterialPixelDepthOffset(FPixelMaterialInputs PixelMaterialInputs)
  2379. {
  2380.     return PixelMaterialInputs.PixelDepthOffset;
  2381. }
  2382.  
  2383. #if DECAL_PRIMITIVE
  2384.  
  2385. float3 TransformTangentNormalToWorld(MaterialFloat3x3 TangentToWorld, float3 TangentNormal)
  2386. {
  2387.     // To transform the normals use tranpose(Inverse(DecalToWorld)) = transpose(WorldToDecal)
  2388.     // But we want to only rotate the normals (we don't want to non-uniformaly scale them).
  2389.     // We assume the matrix is only a scale and rotation, and we remove non-uniform scale:
  2390.     float3 lengthSqr = { length2(DecalToWorld._m00_m01_m02),
  2391.                             length2(DecalToWorld._m10_m11_m12),
  2392.                             length2(DecalToWorld._m20_m21_m22) };
  2393.  
  2394.     float3 scale = rsqrt(lengthSqr);
  2395.                
  2396.     // Pre-multiply by the inverse of the non-uniform scale in DecalToWorld
  2397.     float4 ScaledNormal = float4(-TangentNormal.z * scale.x, TangentNormal.y * scale.y, TangentNormal.x * scale.z, 0.f);
  2398.  
  2399.     // Compute the normal
  2400.     return normalize(mul(ScaledNormal, DecalToWorld).xyz);
  2401. }
  2402.  
  2403. #else //DECAL_PRIMITIVE
  2404.  
  2405. float3 TransformTangentNormalToWorld(MaterialFloat3x3 TangentToWorld, float3 TangentNormal)
  2406. {
  2407.     return normalize(float3(TransformTangentVectorToWorld(TangentToWorld, TangentNormal)));
  2408. }
  2409.  
  2410. #endif //DECAL_PRIMITIVE
  2411.  
  2412. float3 CalculateAnisotropyTangent(FMaterialPixelParameters Parameters, FPixelMaterialInputs PixelMaterialInputs)
  2413. {
  2414.     float3 Normal = Parameters.WorldNormal;
  2415.  
  2416. #if CLEAR_COAT_BOTTOM_NORMAL && (NUM_MATERIAL_OUTPUTS_CLEARCOATBOTTOMNORMAL > 0)
  2417.     Normal =  ClearCoatBottomNormal0(Parameters);
  2418.     #if MATERIAL_TANGENTSPACENORMAL
  2419.         Normal = TransformTangentVectorToWorld(Parameters.TangentToWorld, Normal);
  2420.     #endif
  2421. #endif
  2422.  
  2423.     float3 Tangent = GetMaterialTangent(PixelMaterialInputs);
  2424.  
  2425. #if MATERIAL_TANGENTSPACENORMAL
  2426.     #if SIMPLE_FORWARD_SHADING
  2427.         Tangent = float3(1, 0, 0);
  2428.     #endif
  2429.  
  2430.     Tangent = TransformTangentNormalToWorld(Parameters.TangentToWorld, Tangent);
  2431. #endif
  2432.  
  2433.     float3 BiTangent = cross(Normal, Tangent);
  2434.     Tangent = normalize(cross(BiTangent, Normal));
  2435.  
  2436.     return Tangent;
  2437. }
  2438.  
  2439. void CalcPixelMaterialInputs(in out FMaterialPixelParameters Parameters, in out FPixelMaterialInputs PixelMaterialInputs)
  2440. {
  2441.     // Initial calculations (required for Normal)
  2442.     MaterialFloat2 Local0 = (Parameters.TexCoords[0].xy * Material.ScalarExpressions[0].x);
  2443.     MaterialFloat Local1 = MaterialStoreTexCoordScale(Parameters, Local0, 1);
  2444.     MaterialFloat4 Local2 = UnpackNormalMap(Texture2DSampleBias(Material.Texture2D_0, Material.Texture2D_0Sampler,Local0,View.MaterialTextureMipBias));
  2445.     MaterialFloat Local3 = MaterialStoreTexSample(Parameters, Local2, 1);
  2446.     MaterialFloat3 Local4 = lerp(Local2.rgb,MaterialFloat3(0.00000000,0.00000000,1.00000000),MaterialFloat(Material.ScalarExpressions[0].y));
  2447.  
  2448.     // The Normal is a special case as it might have its own expressions and also be used to calculate other inputs, so perform the assignment here
  2449.     PixelMaterialInputs.Normal = Local4;
  2450.  
  2451.  
  2452.     // Note that here MaterialNormal can be in world space or tangent space
  2453.     float3 MaterialNormal = GetMaterialNormal(Parameters, PixelMaterialInputs);
  2454.  
  2455. #if MATERIAL_TANGENTSPACENORMAL
  2456. #if SIMPLE_FORWARD_SHADING
  2457.     Parameters.WorldNormal = float3(0, 0, 1);
  2458. #endif
  2459.  
  2460. #if FEATURE_LEVEL >= FEATURE_LEVEL_SM4
  2461.     // Mobile will rely on only the final normalize for performance
  2462.     MaterialNormal = normalize(MaterialNormal);
  2463. #endif
  2464.  
  2465.     // normalizing after the tangent space to world space conversion improves quality with sheared bases (UV layout to WS causes shrearing)
  2466.     // use full precision normalize to avoid overflows
  2467.     Parameters.WorldNormal = TransformTangentNormalToWorld(Parameters.TangentToWorld, MaterialNormal);
  2468.  
  2469. #else //MATERIAL_TANGENTSPACENORMAL
  2470.  
  2471.     Parameters.WorldNormal = normalize(MaterialNormal);
  2472.  
  2473. #endif //MATERIAL_TANGENTSPACENORMAL
  2474.  
  2475. #if MATERIAL_TANGENTSPACENORMAL
  2476.     // flip the normal for backfaces being rendered with a two-sided material
  2477.     Parameters.WorldNormal *= Parameters.TwoSidedSign;
  2478. #endif
  2479.  
  2480.     Parameters.ReflectionVector = ReflectionAboutCustomWorldNormal(Parameters, Parameters.WorldNormal, false);
  2481.  
  2482. #if !PARTICLE_SPRITE_FACTORY
  2483.     Parameters.Particle.MotionBlurFade = 1.0f;
  2484. #endif // !PARTICLE_SPRITE_FACTORY
  2485.  
  2486.     // Now the rest of the inputs
  2487.     MaterialFloat3 Local5 = lerp(MaterialFloat3(0.00000000,0.00000000,0.00000000),Material.VectorExpressions[1].rgb,MaterialFloat(Material.ScalarExpressions[0].z));
  2488.     MaterialFloat Local6 = MaterialStoreTexCoordScale(Parameters, Local0, 0);
  2489.     MaterialFloat4 Local7 = ProcessMaterialColorTextureLookup(Texture2DSampleBias(Material.Texture2D_1, Material.Texture2D_1Sampler,Local0,View.MaterialTextureMipBias));
  2490.     MaterialFloat Local8 = MaterialStoreTexSample(Parameters, Local7, 0);
  2491.     MaterialFloat3 Local9 = (Local7.rgb + Material.ScalarExpressions[0].w);
  2492.     MaterialFloat3 Local10 = (Local9 * Material.VectorExpressions[3].rgb);
  2493.     MaterialFloat4 Local11 = ProcessMaterialColorTextureLookup(Texture2DSampleBias(Material.Texture2D_2, Material.Texture2D_2Sampler,Local0,View.MaterialTextureMipBias));
  2494.     MaterialFloat Local12 = MaterialStoreTexSample(Parameters, Local11, 0);
  2495.  
  2496.     PixelMaterialInputs.EmissiveColor = Local5;
  2497.     PixelMaterialInputs.Opacity = 1.00000000;
  2498.     PixelMaterialInputs.OpacityMask = 1.00000000;
  2499.     PixelMaterialInputs.BaseColor = Local10;
  2500.     PixelMaterialInputs.Metallic = Local13.b;
  2501.     PixelMaterialInputs.Specular = 0.50000000;
  2502.     PixelMaterialInputs.Roughness = Local13.g;
  2503.     PixelMaterialInputs.Anisotropy = 0.00000000;
  2504.     PixelMaterialInputs.Tangent = MaterialFloat3(1.00000000,0.00000000,0.00000000);
  2505.     PixelMaterialInputs.Subsurface = 0;
  2506.     PixelMaterialInputs.AmbientOcclusion = Local13.r;
  2507.     PixelMaterialInputs.Refraction = 0;
  2508.     PixelMaterialInputs.PixelDepthOffset = 0.00000000;
  2509.     PixelMaterialInputs.ShadingModel = 1;
  2510.  
  2511.  
  2512. #if MATERIAL_USES_ANISOTROPY
  2513.     Parameters.WorldTangent = CalculateAnisotropyTangent(Parameters, PixelMaterialInputs);
  2514. #else
  2515.     Parameters.WorldTangent = 0;
  2516. #endif
  2517. }
  2518.  
  2519. // Programmatically set the line number after all the material inputs which have a variable number of line endings
  2520. // This allows shader error line numbers after this point to be the same regardless of which material is being compiled
  2521. #line 2445
  2522.  
  2523. void ClipLODTransition(float2 SvPosition, float DitherFactor)
  2524. {
  2525.     if (abs(DitherFactor) > .001)
  2526.     {
  2527.         float ArgCos = dot(floor(SvPosition.xy), float2(347.83451793, 3343.28371963));
  2528. #if FEATURE_LEVEL <= FEATURE_LEVEL_ES3_1
  2529.         // Temporary workaround for precision issues on mobile when the argument is bigger than 10k
  2530.         ArgCos = fmod(ArgCos, 10000);
  2531. #endif
  2532.         float RandCos = cos(ArgCos);
  2533.         float RandomVal = frac(RandCos * 1000.0);
  2534.         half RetVal = (DitherFactor < 0.0) ?
  2535.             (DitherFactor + 1.0 > RandomVal) :
  2536.             (DitherFactor < RandomVal);
  2537.         clip(RetVal - .001);
  2538.     }
  2539. }
  2540.  
  2541. void ClipLODTransition(FMaterialPixelParameters Parameters, float DitherFactor)
  2542. {
  2543.     ClipLODTransition(Parameters.SvPosition.xy, DitherFactor);
  2544. }
  2545.  
  2546.  
  2547. #define REQUIRES_VF_ATTRIBUTES_FOR_CLIPPING (USE_INSTANCING && USE_DITHERED_LOD_TRANSITION)
  2548.  
  2549. #if USE_INSTANCING && USE_DITHERED_LOD_TRANSITION
  2550. void ClipLODTransition(FMaterialPixelParameters Parameters)
  2551. {
  2552.     ClipLODTransition(Parameters, Parameters.PerInstanceParams.w);
  2553. }
  2554. #elif USE_DITHERED_LOD_TRANSITION && !USE_STENCIL_LOD_DITHER
  2555. void ClipLODTransition(FMaterialPixelParameters Parameters)
  2556. {
  2557.     if (PrimitiveDither.LODFactor != 0.0)
  2558.     {
  2559.         ClipLODTransition(Parameters, PrimitiveDither.LODFactor);
  2560.     }
  2561. }
  2562. void ClipLODTransition(float2 SvPosition)
  2563. {
  2564.     if (PrimitiveDither.LODFactor != 0.0)
  2565.     {
  2566.         ClipLODTransition(SvPosition, PrimitiveDither.LODFactor);
  2567.     }
  2568. }
  2569. #else
  2570. void ClipLODTransition(FMaterialPixelParameters Parameters)
  2571. {
  2572. }
  2573. void ClipLODTransition(float2 SvPosition)
  2574. {
  2575. }
  2576. #endif
  2577.  
  2578. void GetMaterialClippingShadowDepth(FMaterialPixelParameters Parameters, FPixelMaterialInputs PixelMaterialInputs)
  2579. {
  2580.     ClipLODTransition(Parameters);
  2581.     #if MATERIALBLENDING_MASKED
  2582.         clip(GetMaterialMask(PixelMaterialInputs));
  2583.     #elif TRANSLUCENT_SHADOW_WITH_MASKED_OPACITY
  2584.         clip(GetMaterialMaskedOpacity(PixelMaterialInputs));
  2585.     #elif MATERIALBLENDING_TRANSLUCENT
  2586.         clip(GetMaterialOpacity(PixelMaterialInputs) - 1.0f / 255.0f);
  2587.     #endif
  2588. }
  2589.  
  2590. void GetMaterialClippingVelocity(FMaterialPixelParameters Parameters, FPixelMaterialInputs PixelMaterialInputs)
  2591. {
  2592.     ClipLODTransition(Parameters);
  2593.     #if MATERIALBLENDING_MASKED && MATERIAL_DITHER_OPACITY_MASK
  2594.         clip(GetMaterialMaskInputRaw(PixelMaterialInputs) - 1.0f / 255.0f);
  2595.     #elif MATERIALBLENDING_MASKED
  2596.         clip(GetMaterialMask(PixelMaterialInputs));
  2597.     #elif MATERIALBLENDING_TRANSLUCENT || MATERIALBLENDING_ADDITIVE || MATERIALBLENDING_MODULATE
  2598.         clip(GetMaterialOpacity(PixelMaterialInputs) - 1.0 / 255.0 - GetMaterialOpacityMaskClipValue());
  2599.     #endif
  2600. }
  2601.  
  2602.  
  2603. void GetMaterialCoverageAndClipping(FMaterialPixelParameters Parameters, FPixelMaterialInputs PixelMaterialInputs)
  2604. {
  2605.     ClipLODTransition(Parameters);
  2606.  
  2607. #if MATERIALBLENDING_MASKED
  2608.     #if MATERIAL_DITHER_OPACITY_MASK
  2609.         /*
  2610.         5 value dither. Every value present in +
  2611.         012
  2612.         234
  2613.         401
  2614.         */
  2615.         float2 Pos = Parameters.SvPosition.xy;
  2616.        
  2617.         float2 DepthGrad = {
  2618.             ddx( Parameters.SvPosition.z ),
  2619.             ddy( Parameters.SvPosition.z )
  2620.         };
  2621.         //Pos = floor( Pos + DepthGrad * float2( 4093, 3571 ) );
  2622.  
  2623.         float Dither5 = frac( ( Pos.x + Pos.y * 2 - 1.5 + ResolvedView.TemporalAAParams.x ) / 5 );
  2624.         float Noise = frac( dot( float2( 171.0, 231.0 ) / 71, Pos.xy ) );
  2625.         float Dither = ( Dither5 * 5 + Noise ) * (1.0 / 6.0);
  2626.  
  2627.         clip( GetMaterialMask(PixelMaterialInputs) + Dither - 0.5 );
  2628.     #else
  2629.         clip(GetMaterialMask(PixelMaterialInputs));
  2630.     #endif
  2631. #endif
  2632. }
  2633.  
  2634. #define MATERIALBLENDING_MASKED_USING_COVERAGE (FORWARD_SHADING && MATERIALBLENDING_MASKED && SUPPORTS_PIXEL_COVERAGE)
  2635. #if MATERIALBLENDING_MASKED_USING_COVERAGE
  2636.  
  2637. uint GetDerivativeCoverageFromMask(float MaterialMask)
  2638. {
  2639.     uint Coverage = 0x0;
  2640.     if (MaterialMask > 0.01) Coverage = 0x8;
  2641.     if (MaterialMask > 0.25) Coverage = 0x9;
  2642.     if (MaterialMask > 0.50) Coverage = 0xD;
  2643.     if (MaterialMask > 0.75) Coverage = 0xF;
  2644.     return Coverage;
  2645. }
  2646.  
  2647. // Returns the new pixel coverage according the material's mask and the current pixel's mask.
  2648. uint DiscardMaterialWithPixelCoverage(FMaterialPixelParameters MaterialParameters, FPixelMaterialInputs PixelMaterialInputs)
  2649. {
  2650.     ClipLODTransition(MaterialParameters);
  2651.     float OriginalMask = GetMaterialMaskInputRaw(PixelMaterialInputs);
  2652.     float MaskClip = GetMaterialOpacityMaskClipValue();
  2653.  
  2654.     if (ResolvedView.NumSceneColorMSAASamples > 1)
  2655.     {
  2656.         float Mask = (OriginalMask - MaskClip) / (1.0 - MaskClip);
  2657.         uint CurrentPixelCoverage = GetDerivativeCoverageFromMask(Mask);
  2658.         // Discard pixel shader if all sample are masked to avoid computing other material inputs.
  2659.         clip(float(CurrentPixelCoverage) - 0.5);
  2660.         return CurrentPixelCoverage;
  2661.     }
  2662.     clip(OriginalMask - MaskClip);
  2663.     return 0xF;
  2664. }
  2665.  
  2666. #endif // MATERIALBLENDING_MASKED_USING_COVERAGE
  2667.  
  2668.  
  2669.     #define FrontFaceSemantic SV_IsFrontFace
  2670.     #define FIsFrontFace bool
  2671.     half GetFloatFacingSign(FIsFrontFace bIsFrontFace)
  2672.     {
  2673. #if COMPILER_DXC && COMPILER_VULKAN
  2674.         // We need to flip SV_IsFrontFace for Vulkan when compiling with DXC due to different coordinate systems.
  2675.         // HLSLcc did that by flipping SV_IsFrontFace in the high-level GLSL output.
  2676.         return bIsFrontFace ? -1 : +1;
  2677. #else
  2678.         return bIsFrontFace ? +1 : -1;
  2679. #endif
  2680. }
  2681.  
  2682. #if MATERIAL_TWOSIDED_SEPARATE_PASS
  2683.     #define OPTIONAL_IsFrontFace
  2684.     static const FIsFrontFace bIsFrontFace = 1;
  2685. #else
  2686.     #define OPTIONAL_IsFrontFace , in FIsFrontFace bIsFrontFace : FrontFaceSemantic
  2687. #endif
  2688.  
  2689. /** Initializes the subset of Parameters that was not set in GetMaterialPixelParameters. */
  2690. void CalcMaterialParametersEx(
  2691.     in out FMaterialPixelParameters Parameters,
  2692.     in out FPixelMaterialInputs PixelMaterialInputs,
  2693.     float4 SvPosition,
  2694.     float4 ScreenPosition,
  2695.     FIsFrontFace bIsFrontFace,
  2696.     float3 TranslatedWorldPosition,
  2697.     float3 TranslatedWorldPositionExcludingShaderOffsets)
  2698. {
  2699.     // Remove the pre view translation
  2700.     Parameters.WorldPosition_CamRelative = TranslatedWorldPosition.xyz;
  2701.     Parameters.AbsoluteWorldPosition = TranslatedWorldPosition.xyz - ResolvedView.PreViewTranslation.xyz;
  2702.  
  2703.     // If the material uses any non-offset world position expressions, calculate those parameters. If not,
  2704.     // the variables will have been initialised to 0 earlier.
  2705. #if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS
  2706.     Parameters.WorldPosition_NoOffsets_CamRelative = TranslatedWorldPositionExcludingShaderOffsets;
  2707.     Parameters.WorldPosition_NoOffsets = TranslatedWorldPositionExcludingShaderOffsets - ResolvedView.PreViewTranslation.xyz;
  2708. #endif
  2709.  
  2710.     Parameters.SvPosition = SvPosition;
  2711.     Parameters.ScreenPosition = ScreenPosition;
  2712.  
  2713.     #if !RAYHITGROUPSHADER
  2714.         // TranslatedWorldPosition is the world position translated to the camera position, which is just -CameraVector
  2715.         Parameters.CameraVector = normalize(-Parameters.WorldPosition_CamRelative.xyz);
  2716.     #else
  2717.         Parameters.CameraVector = -WorldRayDirection();
  2718.     #endif
  2719.  
  2720.     Parameters.LightVector = 0;
  2721.  
  2722.     Parameters.TwoSidedSign = 1.0f;
  2723.  
  2724. #if MATERIAL_TWOSIDED && HAS_PRIMITIVE_UNIFORM_BUFFER
  2725.     // #dxr: DirectX Raytracing's HitKind() intrinsic already accounts for negative scaling
  2726.     #if PIXELSHADER
  2727.         Parameters.TwoSidedSign *= ResolvedView.CullingSign * GetPrimitiveData(Parameters.PrimitiveId).InvNonUniformScaleAndDeterminantSign.w;
  2728.     #endif
  2729.  
  2730. #endif
  2731.  
  2732. #if (MATERIAL_TWOSIDED && !MATERIAL_TWOSIDED_SEPARATE_PASS) || RAYHITGROUPSHADER
  2733.     // Either we have a two-sided material that needs a sign flip, or we have a ray tracing material
  2734.     // that needs to consider rays arriving from either side
  2735.     Parameters.TwoSidedSign *= GetFloatFacingSign(bIsFrontFace);
  2736. #endif
  2737.  
  2738. #if NUM_VIRTUALTEXTURE_SAMPLES || LIGHTMAP_VT_ENABLED
  2739.     InitializeVirtualTextureFeedback(Parameters.VirtualTextureFeedback, (uint2)SvPosition.xy, View.FrameNumber);
  2740. #endif
  2741.  
  2742.     // Now that we have all the pixel-related parameters setup, calculate the Material Input/Attributes and Normal
  2743.     CalcPixelMaterialInputs(Parameters, PixelMaterialInputs);
  2744. }
  2745.  
  2746. // convenience function to setup CalcMaterialParameters assuming we don't support TranslatedWorldPositionExcludingShaderOffsets
  2747. // @param SvPosition from SV_Position when rendering the view, for other projections e.g. shadowmaps this function cannot be used and you need to call CalcMaterialParametersEx()
  2748. void CalcMaterialParameters(
  2749.     in out FMaterialPixelParameters Parameters,
  2750.     in out FPixelMaterialInputs PixelMaterialInputs,
  2751.     float4 SvPosition,
  2752.     FIsFrontFace bIsFrontFace)
  2753. {
  2754.     float4 ScreenPosition = SvPositionToResolvedScreenPosition(SvPosition);
  2755.     float3 TranslatedWorldPosition = SvPositionToResolvedTranslatedWorld(SvPosition);
  2756.  
  2757.     CalcMaterialParametersEx(Parameters, PixelMaterialInputs, SvPosition, ScreenPosition, bIsFrontFace, TranslatedWorldPosition, TranslatedWorldPosition);
  2758. }
  2759.  
  2760. void CalcMaterialParametersPost(
  2761.     in out FMaterialPixelParameters Parameters,
  2762.     in out FPixelMaterialInputs PixelMaterialInputs,
  2763.     float4 SvPosition,
  2764.     FIsFrontFace bIsFrontFace)
  2765. {
  2766.     float4 ScreenPosition = SvPositionToScreenPosition(SvPosition);
  2767.     float3 TranslatedWorldPosition = SvPositionToTranslatedWorld(SvPosition);
  2768.  
  2769.     CalcMaterialParametersEx(Parameters, PixelMaterialInputs, SvPosition, ScreenPosition, bIsFrontFace, TranslatedWorldPosition, TranslatedWorldPosition);
  2770. }
  2771.  
  2772. /** Assemble the transform from tangent space into world space */
  2773. half3x3 AssembleTangentToWorld( half3 TangentToWorld0, half4 TangentToWorld2 )
  2774. {
  2775.     // Will not be orthonormal after interpolation. This perfectly matches xNormal.
  2776.     // Any mismatch with xNormal will cause distortions for baked normal maps.
  2777.  
  2778.     // Derive the third basis vector off of the other two.
  2779.     // Flip based on the determinant sign
  2780.     half3 TangentToWorld1 = cross(TangentToWorld2.xyz,TangentToWorld0) * TangentToWorld2.w;
  2781.     // Transform from tangent space to world space
  2782.     return half3x3(TangentToWorld0, TangentToWorld1, TangentToWorld2.xyz);
  2783. }
  2784.  
  2785. // Whether the material shader should output pixel depth offset
  2786. #define OUTPUT_PIXEL_DEPTH_OFFSET (WANT_PIXEL_DEPTH_OFFSET && (MATERIALBLENDING_SOLID || MATERIALBLENDING_MASKED))
  2787.  
  2788. // Whether to use the hidden d3d11 feature that supports depth writes with ZCull by only pushing into the screen
  2789. //@todo - use for other SM5 platforms
  2790. #define SUPPORTS_CONSERVATIVE_DEPTH_WRITES ((COMPILER_HLSL && FEATURE_LEVEL >= FEATURE_LEVEL_SM5) || (PS4_PROFILE) || (COMPILER_METAL && FEATURE_LEVEL >= FEATURE_LEVEL_SM5) || SWITCH_PROFILE || SWITCH_PROFILE_FORWARD)
  2791. #define USE_CONSERVATIVE_DEPTH_WRITES (OUTPUT_PIXEL_DEPTH_OFFSET && SUPPORTS_CONSERVATIVE_DEPTH_WRITES)
  2792.  
  2793. #if USE_CONSERVATIVE_DEPTH_WRITES
  2794.  
  2795. #if COMPILER_HLSL
  2796.     // Note: for some reason using SV_DepthLessEqual without these interpolation modifiers causes a compile error in d3d
  2797.     #define INPUT_POSITION_QUALIFIERS linear noperspective centroid
  2798.     // Use conservative depth output so we still get Z Cull.  Note, this is a reversed Z depth surface.
  2799.     #define DEPTH_WRITE_SEMANTIC SV_DepthLessEqual
  2800. #elif COMPILER_METAL
  2801.     #define INPUT_POSITION_QUALIFIERS
  2802.     #define DEPTH_WRITE_SEMANTIC SV_DepthLessEqual
  2803. #elif PS4_PROFILE
  2804.     #define INPUT_POSITION_QUALIFIERS
  2805.     #define DEPTH_WRITE_SEMANTIC S_DEPTH_LE_OUTPUT
  2806. #elif SWITCH_PROFILE || SWITCH_PROFILE_FORWARD
  2807.     #define INPUT_POSITION_QUALIFIERS
  2808.     #define DEPTH_WRITE_SEMANTIC SV_DepthLessEqual
  2809. #else
  2810.     #error USE_CONSERVATIVE_DEPTH_WRITES enabled for unsupported platform
  2811. #endif
  2812.  
  2813. #else
  2814.     #define INPUT_POSITION_QUALIFIERS
  2815.     #define DEPTH_WRITE_SEMANTIC SV_DEPTH
  2816. #endif
  2817.  
  2818. #if OUTPUT_PIXEL_DEPTH_OFFSET
  2819.     #define OPTIONAL_OutDepthConservative ,out float OutDepth : DEPTH_WRITE_SEMANTIC
  2820.     #define OPTIONAL_OutDepth ,out float OutDepth : SV_DEPTH
  2821. #else
  2822.     #define OPTIONAL_OutDepthConservative
  2823.     #define OPTIONAL_OutDepth
  2824. #endif
  2825.  
  2826. float ApplyPixelDepthOffsetToMaterialParameters(inout FMaterialPixelParameters MaterialParameters, FPixelMaterialInputs PixelMaterialInputs, out float OutDepth)
  2827. {
  2828.     float PixelDepthOffset = GetMaterialPixelDepthOffset(PixelMaterialInputs);
  2829.  
  2830.     // SvPosition.z contains device depth value normally written to depth buffer
  2831.     // ScreenPosition.z is 'SvPosition.z * SvPosition.w'
  2832.     // So here we compute a new device depth value with the given pixel depth offset, but clamp the value against the regular SvPosition.z
  2833.     // This clamp is important, even if PixelDepthOffset is 0.0f, the computed DeviceDepth may end up 'slightly' larger than SvPosition.z due to floating point whatever
  2834.     // Since we are outputing depth with SV_DepthLessEqual, this ends up as undefined behavior
  2835.     // In particular, this can cause problems on PS4....PS4 enables RE_Z when using depth output along with virtual texture UAV feedback buffer writes
  2836.     // RE_Z causes the HW to perform depth test twice, once before executing pixel shader, and once after
  2837.     // The PreZ pass will write depth buffer using depth offset, then the base pass will test against this value using both modified and unmodifed depth
  2838.     // If the unmodified depth is ever slightly less than the modified depth, the initial depth test will fail, which results in z-fighting/flickering type artifacts
  2839.     float DeviceDepth = min(MaterialParameters.ScreenPosition.z / (MaterialParameters.ScreenPosition.w + PixelDepthOffset), MaterialParameters.SvPosition.z);
  2840.  
  2841.     // Once we've computed our (clamped) device depth, recompute PixelDepthOffset again to take the potential clamp into account
  2842.     PixelDepthOffset = (MaterialParameters.ScreenPosition.z - DeviceDepth * MaterialParameters.ScreenPosition.w) / DeviceDepth;
  2843.  
  2844.     // Update positions used for shading
  2845.     MaterialParameters.ScreenPosition.w += PixelDepthOffset;
  2846.     MaterialParameters.SvPosition.w = MaterialParameters.ScreenPosition.w;
  2847.     MaterialParameters.AbsoluteWorldPosition += MaterialParameters.CameraVector * PixelDepthOffset;
  2848.  
  2849.     OutDepth = INVARIANT(DeviceDepth);
  2850.  
  2851.     return PixelDepthOffset;
  2852. }
  2853.  
Advertisement
Add Comment
Please, Sign In to add comment