Skip to content

Instantly share code, notes, and snippets.

@SuzanneSoy
Forked from anonymous/gist:4516915
Last active December 11, 2015 00:29
Show Gist options
  • Save SuzanneSoy/4516926 to your computer and use it in GitHub Desktop.
Save SuzanneSoy/4516926 to your computer and use it in GitHub Desktop.
// Without add - 60 instructions instead of 59, and I'd swear it was 58 before I started fiddling with that stuff.
/**
* MaterialTemplate.usf: Filled in by FHLSLMaterialTranslator::GetMaterialShaderCode for each material being compiled.
* Copyright 1998-2012 Epic Games, Inc. All Rights Reserved.
*/
/*
Defined by the C++ code:
NUM_MATERIAL_TEXCOORDS
NUM_DYNAMIC_PARAMETERS
MATERIALBLENDING_SOLID
MATERIALBLENDING_MASKED
MATERIALBLENDING_TRANSLUCENT
MATERIALBLENDING_ADDITIVE
MATERIALBLENDING_MODULATE
MATERIALBLENDING_MODULATEANDADD
MATERIAL_TWOSIDED
MATERIAL_LIGHTINGMODEL_PHONG
MATERIAL_LIGHTINGMODEL_NONDIRECTIONAL
MATERIAL_LIGHTINGMODEL_UNLIT
MATERIAL_LIGHTINGMODEL_CUSTOM
MATERIAL_LIGHTINGMODEL_ANISOTROPIC
WORLD_COORDS
WORLD_POS
MATERIAL_USE_GAMMA_CORRECTION
MATERIAL_USE_SCREEN_DOOR_FADE
*/
// for give the Material function access to the DepthOfFieldFunction()
#include "DepthOfFieldCommon.usf"
#include "Random.usf"
#define NUM_MATERIAL_TEXCOORDS 1
/* transform from post-projection to world space */
float4x4 InvViewProjectionMatrix;
/* world-space camera position */
float3 CameraWorldPos;
/* MT->world-space location of owning actor */
float3 ActorWorldPos;
float4 ObjectWorldPositionAndRadius;
/** Local space up vector, in world space. */
float3 ObjectOrientation;
float3 ObjectPostProjectionPosition;
float3 ObjectNDCPosition;
float4 ObjectMacroUVScales;
float3 FoliageImpulseDirection;
float4 FoliageNormalizedRotationAxisAndAngle;
/** World space wind direction * strength in xyz, speed in w. */
float4 WindDirectionAndSpeed;
/** Global fluid detail normal texture that can be used by any material in the scene. */
sampler2D FluidDetailNormalTexture;
#if MATERIAL_DECAL
/** Distance to [near,far] plane for the decal (local or world space) */
float2 DecalNearFarPlaneDistance;
#endif
#if USE_OCCLUSION_PERCENTAGE
/** The occlusion percentage (1.0 == unoccluded, 0.0 == occluded, in between == partial occlusion) */
float OcclusionPercentage;
#endif
#if MATERIAL_USE_SCREEN_DOOR_FADE
/** Whether to enable screen-door opacity fades or not. When disabled, pixels will never be screen-door clipped. */
bool bEnableScreenDoorFade;
/** Screen door fade settings (opacity, noise scale, noise bias, noise texture scale) */
float4 ScreenDoorFadeSettings;
/** Screen door fade settings (noise texture offset) */
float4 ScreenDoorFadeSettings2;
/** 8-bit per pixel noise texture for screen door transparency */
sampler2D ScreenDoorNoiseTexture;
#endif
#if SM5_PROFILE && (MATERIALBLENDING_DITHEREDTRANSLUCENT || MATERIALBLENDING_MASKED)
#define NUM_TEXCOORD_SAMPLES NumMSAASamples
#else
#define NUM_TEXCOORD_SAMPLES 0
#endif
/**
* Parameters needed by pixel shader material inputs.
* These are independent of vertex factory.
*/
struct FMaterialPixelParameters
{
float MipBias;
#if NUM_MATERIAL_TEXCOORDS
float2 TexCoords[NUM_MATERIAL_TEXCOORDS];
#if NUM_TEXCOORD_SAMPLES
float2 SampleTexCoords[NUM_TEXCOORD_SAMPLES][NUM_MATERIAL_TEXCOORDS];
#else
float2 SampleTexCoords[1][NUM_MATERIAL_TEXCOORDS];
#endif
#endif
float4 VertexColor;
float3 TangentNormal,
TangentReflectionVector,
TangentCameraVector;
half3 TangentLightVector;
float4 ScreenPosition;
#if WORLD_COORDS
half UnMirrored;
// transpose(TangentToWorld)[2] is WorldVertexNormal
float3x3 TangentToWorld;
#endif
#if WORLD_POS
float3 WorldPosition;
#endif
#if MATERIAL_DECAL
float DecalAttenuation;
float DecalPlaneDistance;
#endif
#if USE_LENSFLARE
float LensFlareIntensity;
float LensFlareRadialDistance;
float LensFlareSourceDistance;
float LensFlareRayDistance;
#endif //USE_LENSFLARE
#if USE_DYNAMIC_PARAMETERS
float4 DynamicParameter0;
#endif //USE_DYNAMIC_PARAMETERS
#if MATERIAL_LIGHTINGMODEL_ANISOTROPIC
half3 TangentAnisotropicDirection;
#endif
#if LIGHTMAP_UV_ACCESS
float2 LightmapUVs;
#endif
#if USE_INSTANCING
float2 PerInstanceParams;
#endif
float TwoSidedSign;
};
/**
* Parameters needed by domain shader material inputs.
* These are independent of vertex factory.
*/
struct FMaterialTessellationParameters
{
#if NUM_MATERIAL_TEXCOORDS
float2 TexCoords[NUM_MATERIAL_TEXCOORDS];
#endif
float4 VertexColor;
float3 TangentReflectionVector;
float3 TangentCameraVector;
float3 WorldPosition;
float3 TangentToWorldPreScale;
// TangentToWorld[2] is WorldVertexNormal, [0] and [1] are binormal and tangent
float3x3 TangentToWorld;
};
/**
* Parameters needed by vertex shader material inputs.
* These are independent of vertex factory.
*/
struct FMaterialVertexParameters
{
float3 WorldPosition;
// transpose(TangentToWorld)[2] is WorldVertexNormal
float3x3 TangentToWorld;
#if VERTEX_FACTORY_SUPPORTS_LOCALTOWORLD && USE_INSTANCING
float4x4 InstanceLocalToWorld;
#endif
float4 VertexColor;
#if NUM_MATERIAL_TEXCOORDS && !(DECAL_FACTORY && MATERIAL_DECAL)
float2 TexCoords[NUM_MATERIAL_TEXCOORDS];
#endif
};
#if WORLD_COORDS
// Vertex and/or Pixel shader parameters used by the TransformVector material compiler node,
// And any pixel shader which needs to transform vectors out of tangent space.
float3x3 LocalToWorldMatrix;
float3x3 WorldToLocalMatrix;
float3x3 WorldToViewMatrix;
float3x3 ViewToWorldMatrix;
#if SM5_PROFILE
/** Transforms a vector from tangent space to world space, prescaling by an amount calculated previously */
float3 TransformTangentVectorToWorld_PreScaled(FMaterialTessellationParameters Parameters, float3 InTangentVector)
{
// used optionally to scale up the vector prior to conversion
InTangentVector *= abs( Parameters.TangentToWorldPreScale );
// Transform directly to world space
// The vector transform is optimized for this case, only one vector-matrix multiply is needed
return mul( Parameters.TangentToWorld, InTangentVector );
}
#endif // #if SM5_PROFILE
/** Transforms a vector from tangent space to local space */
float3 TransformTangentVectorToLocal(FMaterialPixelParameters Parameters, float3 InTangentVector)
{
// NOTE: Shouldn't use MulMatrix here, because TangentToWorld isn't passed from the CPU - it's calculated within the shader.
// Transform to world space and then to local space
return MulMatrix(WorldToLocalMatrix, mul(Parameters.TangentToWorld, InTangentVector));
}
/** Transforms a vector from tangent space to view space */
float3 TransformTangentVectorToView(FMaterialPixelParameters Parameters, float3 InTangentVector)
{
// Transform from tangent to world, and then to view space
return MulMatrix(WorldToViewMatrix, mul(Parameters.TangentToWorld, InTangentVector));
}
/** Transforms a vector from local space to tangent space */
float3 TransformLocalVectorToTangent(FMaterialPixelParameters Parameters, float3 InLocalVector)
{
// Transform from local to world space, and then to tangent space.
return mul(MulMatrix(LocalToWorldMatrix, InLocalVector), Parameters.TangentToWorld);
}
/** Transforms a vector from tangent space to local space */
float3 TransformTangentVectorToLocal(FMaterialVertexParameters Parameters, float3 InTangentVector)
{
// NOTE: Shouldn't use MulMatrix here, because TangentToWorld isn't passed from the CPU - it's calculated within the shader.
// Transform to world space and then to local space
return MulMatrix(WorldToLocalMatrix, mul(Parameters.TangentToWorld, InTangentVector));
}
/** Transforms a vector from tangent space to view space */
float3 TransformTangentVectorToView(FMaterialVertexParameters Parameters, float3 InTangentVector)
{
// Transform from tangent to world, and then to view space
return MulMatrix(WorldToViewMatrix, mul(Parameters.TangentToWorld, InTangentVector));
}
/** Transforms a vector from local space to tangent space */
float3 TransformLocalVectorToTangent(FMaterialVertexParameters Parameters, float3 InLocalVector)
{
// Transform from local to world space, and then to tangent space.
return mul(MulMatrix(LocalToWorldMatrix, InLocalVector), Parameters.TangentToWorld);
}
/** Transforms a vector from local space to world space (VS version) */
float3 TransformLocalVectorToWorld(FMaterialVertexParameters Parameters,float3 InLocalVector)
{
// We use the vertex factories LocalToWorld if it has one to save shader constants
#if VERTEX_FACTORY_SUPPORTS_LOCALTOWORLD
#if USE_INSTANCING
// unless we're instancing, in which case we use the instance LtoW.
return MulMatrix((float3x3)Parameters.InstanceLocalToWorld, InLocalVector);
#else
return MulMatrix((float3x3)LocalToWorld, InLocalVector);
#endif
#else
return MulMatrix(LocalToWorldMatrix, InLocalVector);
#endif
}
/** Transforms a vector from local space to world space (PS version) */
float3 TransformLocalVectorToWorld(FMaterialPixelParameters Parameters,float3 InLocalVector)
{
return MulMatrix(LocalToWorldMatrix, InLocalVector);
}
/** Transforms a vector from local space to view space */
float3 TransformLocalVectorToView(float3 InLocalVector)
{
return MulMatrix(WorldToViewMatrix, MulMatrix(LocalToWorldMatrix, InLocalVector));
}
/** Transforms a vector from world space to local space */
float3 TransformWorldVectorToLocal(float3 InWorldVector)
{
return MulMatrix(WorldToLocalMatrix, InWorldVector);
}
/** Transforms a vector from world space to view space */
float3 TransformWorldVectorToView(float3 InWorldVector)
{
return MulMatrix(WorldToViewMatrix, InWorldVector);
}
/** Transforms a vector from view space to world space */
float3 TransformViewVectorToWorld(float3 InViewVector)
{
return MulMatrix(ViewToWorldMatrix, InViewVector);
}
/** Transforms a vector from view space to local space */
float3 TransformViewVectorToLocal(float3 InViewVector)
{
return MulMatrix(WorldToLocalMatrix, MulMatrix(ViewToWorldMatrix, InViewVector));
}
/** Transforms a position from local space to world space */
float4 TransformLocalPositionToWorld(FMaterialVertexParameters Parameters, float4 InLocalPosition)
{
// If the vertex factory does not support local to world this will produce incorrect results.
// However, we do not want to block compilation of the material if one vertex factory does not support it
#if VERTEX_FACTORY_SUPPORTS_LOCALTOWORLD
#if USE_INSTANCING
// InstanceLocalToWorld does not have PreViewTranslation applied.
return MulMatrix(Parameters.InstanceLocalToWorld, InLocalPosition);
#else
return MulMatrix(LocalToWorld, InLocalPosition) - PreViewTranslation;
#endif
#else
return InLocalPosition;
#endif
}
#endif //#if WORLD_COORDS
/**
* Transforms post projection (effectively view space) positions into UVs with [.5, .5] centered on ObjectPostProjectionPosition,
* And [1, 1] at ObjectPostProjectionPosition + (ObjectRadius, ObjectRadius).
*/
float2 GetViewSpaceMacroUVs(FMaterialPixelParameters Parameters)
{
return (Parameters.ScreenPosition.xy - ObjectPostProjectionPosition.xy) * ObjectMacroUVScales.xy + float2(.5, .5);
}
/**
* Transforms screen space positions into UVs with [.5, .5] centered on ObjectPostProjectionPosition,
* And [1, 1] at ObjectPostProjectionPosition + (ObjectRadius, ObjectRadius).
*/
float2 GetScreenSpaceMacroUVs(FMaterialPixelParameters Parameters)
{
return (Parameters.ScreenPosition.xy / Parameters.ScreenPosition.w - ObjectNDCPosition.xy) * ObjectMacroUVScales.zw + float2(.5, .5);
}
/** Rotates Position about the given axis by the given angle, in radians, and returns the offset to Position. */
float3 RotateAboutAxis(float4 NormalizedRotationAxisAndAngle, float3 PositionOnAxis, float3 Position)
{
// Project Position onto the rotation axis and find the closest point on the axis to Position
float3 ClosestPointOnAxis = PositionOnAxis + NormalizedRotationAxisAndAngle.xyz * dot(NormalizedRotationAxisAndAngle.xyz, Position - PositionOnAxis);
// Construct orthogonal axes in the plane of the rotation
float3 UAxis = Position - ClosestPointOnAxis;
float3 VAxis = cross(NormalizedRotationAxisAndAngle.xyz, UAxis);
float CosAngle;
float SinAngle;
sincos(NormalizedRotationAxisAndAngle.w, SinAngle, CosAngle);
// Rotate using the orthogonal axes
float3 R = UAxis * CosAngle + VAxis * SinAngle;
// Reconstruct the rotated world space position
float3 RotatedPosition = ClosestPointOnAxis + R;
// Convert from position to a position offset
return RotatedPosition - Position;
}
float DepthBiasedAlpha( FMaterialPixelParameters Parameters, float InAlpha, float InBias, float InBiasScale )
{
float Result;
half SceneDepth = PreviousDepth(Parameters.ScreenPosition);
float DepthBias = (1.0 - InBias) * InBiasScale;
float BlendAmt = saturate((SceneDepth - Parameters.ScreenPosition.w) / max(DepthBias,0.001));
Result = InAlpha * BlendAmt;
return Result;
}
float3 DepthBiasedBlend( FMaterialPixelParameters Parameters, float3 InColor, float InBias, float InBiasScale )
{
float3 Result;
float3 SceneColor = PreviousLighting(Parameters.ScreenPosition).rgb;
half SceneDepth = PreviousDepth(Parameters.ScreenPosition);
float DepthBias = (1.0 - InBias) * InBiasScale;
float BlendAmt = saturate((SceneDepth - Parameters.ScreenPosition.w) / max(DepthBias,0.001));
Result = lerp( SceneColor, InColor * 1.000001, BlendAmt );
return Result;
}
/**
* Utility function to unmirror one coordinate value to the other side
* UnMirrored == 1 if normal
* UnMirrored == -1 if mirrored
*
* Used by most of parameter functions generated via code in this file
*/
half UnMirror( half Coordinate, FMaterialPixelParameters Parameters )
{
#if WORLD_COORDS
return ((Coordinate)*(Parameters.UnMirrored)*0.5+0.5);
#else
return Coordinate;
#endif
}
/**
* UnMirror only U
*/
half2 UnMirrorU( half2 UV, FMaterialPixelParameters Parameters )
{
return half2(UnMirror(UV.x, Parameters), UV.y);
}
/**
* UnMirror only V
*/
half2 UnMirrorV( half2 UV, FMaterialPixelParameters Parameters )
{
return half2(UV.x, UnMirror(UV.y, Parameters));
}
/**
* UnMirror only UV
*/
half2 UnMirrorUV( half2 UV, FMaterialPixelParameters Parameters )
{
return half2(UnMirror(UV.x, Parameters), UnMirror(UV.y, Parameters));
}
/** Get the lens flare intensity */
float GetLensFlareIntensity(FMaterialPixelParameters Parameters)
{
#if USE_LENSFLARE
return Parameters.LensFlareIntensity;
#else //USE_LENSFLARE
return 1.0f;
#endif //USE_LENSFLARE
}
/** Get the lens flare occlusion */
float GetLensFlareOcclusion(FMaterialPixelParameters Parameters)
{
#if USE_LENSFLARE && USE_OCCLUSION_PERCENTAGE
return OcclusionPercentage;
#else //USE_LENSFLARE
return 1.0f;
#endif //USE_LENSFLARE
}
/** Get the lens flare radial distance */
float GetLensFlareRadialDistance(FMaterialPixelParameters Parameters)
{
#if USE_LENSFLARE
return Parameters.LensFlareRadialDistance;
#else //USE_LENSFLARE
return 0.0f;
#endif //USE_LENSFLARE
}
/** Get the lens flare ray distance */
float GetLensFlareRayDistance(FMaterialPixelParameters Parameters)
{
#if USE_LENSFLARE
return Parameters.LensFlareRayDistance;
#else //USE_LENSFLARE
return 0.0f;
#endif //USE_LENSFLARE
}
/** Get the lens flare source distance */
float GetLensFlareSourceDistance(FMaterialPixelParameters Parameters)
{
#if USE_LENSFLARE
return Parameters.LensFlareSourceDistance;
#else //USE_LENSFLARE
return 0.0f;
#endif //USE_LENSFLARE
}
/** Retrieve the given emitter parameter */
float4 GetDynamicParameter(FMaterialPixelParameters Parameters)
{
#if USE_DYNAMIC_PARAMETERS
return Parameters.DynamicParameter0;
#else //USE_DYNAMIC_PARAMETERS
return float4(1.0f, 1.0f, 1.0f, 1.0f);
#endif //USE_DYNAMIC_PARAMETERS
}
/** Get the occlusion percentage */
float GetOcclusionPercentage()
{
#if USE_OCCLUSION_PERCENTAGE
return OcclusionPercentage;
#else
return 1.0f;
#endif
}
float2 GetLightmapUVs(FMaterialPixelParameters Parameters)
{
#if LIGHTMAP_UV_ACCESS
return Parameters.LightmapUVs;
#else
return float2(0,0);
#endif
}
float2 GetMaterialTexCoord(FMaterialPixelParameters Parameters, int CoordIdx)
{
#if NUM_MATERIAL_TEXCOORDS
#if MATERIAL_DECAL
return Parameters.TexCoords[0].xy;
#else
return Parameters.TexCoords[CoordIdx].xy;
#endif
#else
return float2(0,0);
#endif
}
float GetPerInstanceRandom(FMaterialPixelParameters Parameters)
{
#if USE_INSTANCING
return Parameters.PerInstanceParams.x;
#else
return 0.f;
#endif
}
float3 GetPerInstanceSelectionMask(FMaterialPixelParameters Parameters)
{
#if USE_INSTANCING
return float3(Parameters.PerInstanceParams.y,Parameters.PerInstanceParams.y,Parameters.PerInstanceParams.y);
#else
return float3(1.f,1.f,1.f);
#endif
}
// Uniform material expressions.
float4 UniformPixelVector_0;
half3 GetMaterialNormal(FMaterialPixelParameters Parameters)
{
return float3(0.00000000,0.00000000,1.00000000);
}
half3 GetMaterialEmissive(FMaterialPixelParameters Parameters)
{
float3 Local1 = (UniformPixelVector_0.rgb * GetPerInstanceSelectionMask(Parameters));
float3 Local2 = (float3(0.00000000,0.00000000,0.00000000) + Local1);
return Local2;
}
half3 GetMaterialDiffuseColorRaw(FMaterialPixelParameters Parameters)
{
float3 Local3 = (UniformPixelVector_0.rgb * GetPerInstanceSelectionMask(Parameters));
float3 Local4 = ((1.00000000) - Local3);
float2 Local5 = Parameters.TexCoords[0].xy;
float2 Local6 = ((1.00000000) * Local5);
float2 Local7 = ((-0.50000000) + Local6);
float2 Local8 = ((4.00000000) * Local7);
float2 Local9 = abs(Local8);
float Local10 = (Local8.r - (0.00000000));
float Local11 = (Local10 * ((1.00000000) / (1.00000000)));
float Local12 = ((0.50000000) + Local11);
float Local13 = (Local12 * (6.28318548));
float Local14 = cos(Local13);
float Local15 = ((1.00000000) + Local14);
float Local16 = (Local15 * (0.50000000));
float Local17 = (Local8.g * (-1.00000000));
float Local18 = (Local16 - Local17);
float Local19 = abs(Local18);
float Local20 = ((Local19 >= (0.04000000)) ? (Local19 > (0.04000000) ? (1.00000000) : (0.00000000)) : (0.00000000));
float2 Local21 = (Local20 * Local9);
float3 Local22 = (float3(Local21,0) * Local4);
return Local22;
}
half3 GetMaterialDiffuseColor(FMaterialPixelParameters Parameters)
{
return GetMaterialDiffuseColorRaw(Parameters) * DiffuseOverrideParameter.w + DiffuseOverrideParameter.xyz;
}
half GetMaterialDiffusePower(FMaterialPixelParameters Parameters)
{
return (1.00000000);
}
half3 GetMaterialDiffuseColorNormalized(float3 DiffuseColor, FMaterialPixelParameters Parameters)
{
// Normalizes the diffuse color to reflect the same amount of light regardless of diffuse power.
return DiffuseColor *
((1 + GetMaterialDiffusePower(Parameters)) / 2);
}
half3 GetMaterialSpecularColorRaw(FMaterialPixelParameters Parameters)
{
return float3(0.00000000,0.00000000,0.00000000);
}
half3 GetMaterialSpecularColor(FMaterialPixelParameters Parameters)
{
return GetMaterialSpecularColorRaw(Parameters) * SpecularOverrideParameter.w + SpecularOverrideParameter.xyz;
}
half GetMaterialSpecularPower(FMaterialPixelParameters Parameters)
{
return (15.00000000);
}
// This is the clip value constant that is defined in the material (range 0..1)
// Use GetMaterialMask() to get the Material Mask combined with this.
half GetMaterialOpacityMaskClipValue()
{
return 0.33330;
}
// Should only be used by GetMaterialOpacity(), returns the unmodified value generated from the shader expressions of the opacity input.
// To compute the opacity depending on the material blending GetMaterialOpacity() should be called instead.
half GetMaterialOpacityRaw(FMaterialPixelParameters Parameters)
{
return (1.00000000);
}
#if MATERIALBLENDING_MASKED || MATERIAL_CAST_LIT_TRANSLUCENCY_SHADOW_AS_MASKED || MATERIALBLENDING_SOFTMASKED
// Returns the material mask value generated from the material expressions.
// Use GetMaterialMask() to get the value altered depending on the material blend mode.
float GetMaterialMaskInputRaw(FMaterialPixelParameters Parameters)
{
return (1.00000000);
}
// Returns the material mask value generated from the material expressions minus the used defined
// MaskClip value constant. If this value is <=0 the pixel should be killed.
float GetMaterialMask(FMaterialPixelParameters Parameters)
{
return GetMaterialMaskInputRaw(Parameters) - GetMaterialOpacityMaskClipValue();
}
#endif
// Returns the material opacity depending on the material blend mode.
half GetMaterialOpacity(FMaterialPixelParameters Parameters)
{
#if MATERIALBLENDING_SOFTMASKED
// Take the mask value generated from the material expressions (material mask input)
// and scale the value that the opacity is at the maximum where clip() kills the pixel.
// This bahavior is similar to the material blending Masked and makes it simple to change
// materials using Masked material blending (simply change to SoftMasked and tweak the OpacityMaskClip value).
half MaskInput = GetMaterialMaskInputRaw(Parameters);
half Mask = GetMaterialOpacityMaskClipValue();
// max() to be division by 0 safe
// The division and the max() is optimized away as the the mask value is compiled in as a literal.
return saturate(MaskInput / max(Mask, 0.0001f));
#else
// Take the unaltered value generated from the material expressions (opacity input).
return GetMaterialOpacityRaw(Parameters);
#endif
}
float2 GetMaterialDistortion(FMaterialPixelParameters Parameters)
{
return float2(0.00000000,0.00000000);
}
float3 GetMaterialTwoSidedLightingMask(FMaterialPixelParameters Parameters)
{
return ((0.00000000) * float3(1.00000000,1.00000000,1.00000000));
}
#if MATERIAL_LIGHTINGMODEL_CUSTOM
float3 GetMaterialCustomLightingRaw(FMaterialPixelParameters Parameters)
{
return float3(0.00000000,0.00000000,0.00000000);
}
float3 GetMaterialCustomLighting(FMaterialPixelParameters Parameters)
{
return GetMaterialCustomLightingRaw(Parameters) * DiffuseOverrideParameter.w
+ DiffuseOverrideParameter.xyz * max(dot(GetMaterialNormal(Parameters), Parameters.TangentLightVector), 0);
}
float3 GetMaterialCustomLightingDiffuseRaw(FMaterialPixelParameters Parameters)
{
return float3(0.00000000,0.00000000,0.00000000);
}
float3 GetMaterialCustomLightingDiffuse(FMaterialPixelParameters Parameters)
{
return GetMaterialCustomLightingDiffuseRaw(Parameters) * DiffuseOverrideParameter.w + DiffuseOverrideParameter.xyz;
}
#endif
#if MATERIAL_LIGHTINGMODEL_ANISOTROPIC
float3 GetMaterialAnisotropicDirection(FMaterialPixelParameters Parameters)
{
return float3(0.00000000,1.00000000,0.00000000);
}
#endif
float3 GetMaterialWorldPositionOffset(FMaterialVertexParameters Parameters)
{
return float3(0.00000000,0.00000000,0.00000000);
}
#if SM5_PROFILE
float3 GetMaterialWorldDisplacement(FMaterialTessellationParameters Parameters)
{
return float3(0.00000000,0.00000000,0.00000000);
}
float GetMaterialTessellationMultiplier(FMaterialTessellationParameters Parameters)
{
return (1.00000000);
}
#endif // #if SM5_PROFILE
#if MATERIAL_ENABLE_SUBSURFACE_SCATTERING
float3 GetMaterialSubsurfaceInscatteringColor(FMaterialPixelParameters Parameters)
{
return float3(1.00000000,1.00000000,1.00000000);
}
float3 GetMaterialSubsurfaceAbsorptionColor(FMaterialPixelParameters Parameters)
{
return float3(0.79691654,0.58597296,0.58597296);
}
float GetMaterialSubsurfaceScatteringRadius(FMaterialPixelParameters Parameters)
{
return (0.00000000);
}
#endif
// Programmatically set the line number after all the material inputs which have a variable number of line endings
// This allows shader error line numbers after this point to be the same regardless of which material is being compiled
#line 721
float3 GetMaterialPointLightTransfer(float3 DiffuseColor,float3 SpecularColor,FMaterialPixelParameters Parameters,half FalloffExponent,half3 ShadowFactor)
{
float3 TwoSidedLightingMask = GetMaterialTwoSidedLightingMask(Parameters);
float3 Lighting = 0;
#if MATERIAL_LIGHTINGMODEL_NONDIRECTIONAL
Lighting = DiffuseColor * ShadowFactor;
#elif MATERIAL_LIGHTINGMODEL_PHONG
Lighting = PointLightPhong(
GetMaterialDiffuseColorNormalized(DiffuseColor, Parameters),
GetMaterialDiffusePower(Parameters),
TwoSidedLightingMask,
SpecularColor,
GetMaterialSpecularPower(Parameters),
Parameters.TangentLightVector,
Parameters.TangentCameraVector,
Parameters.TangentNormal,
Parameters.TangentReflectionVector
) *
ShadowFactor;
#elif MATERIAL_LIGHTINGMODEL_CUSTOM
Lighting = GetMaterialCustomLighting(Parameters) * ShadowFactor;
#elif MATERIAL_LIGHTINGMODEL_ANISOTROPIC
Lighting = PointLightAnisotropic(
DiffuseColor,
TwoSidedLightingMask,
SpecularColor,
GetMaterialSpecularPower(Parameters),
Parameters.TangentLightVector,
Parameters.TangentCameraVector,
Parameters.TangentNormal,
Parameters.TangentReflectionVector,
Parameters.TangentAnisotropicDirection
) *
ShadowFactor;
#endif
return Lighting;
}
float3 GetMaterialHemisphereLightTransferFull(float3 DiffuseColor,float3 CustomLightingDiffuse,FMaterialPixelParameters Parameters,float3 SkyVector, float3 UpperColor, float3 LowerColor)
{
float3 TwoSidedLighting = 0;
float3 TwoSidedLightingMask = 0;
TwoSidedLightingMask = GetMaterialTwoSidedLightingMask(Parameters);
TwoSidedLighting = TwoSidedLightingMask * DiffuseColor;
float3 UpperLighting = 0;
float3 LowerLighting = 0;
#if MATERIAL_LIGHTINGMODEL_NONDIRECTIONAL
UpperLighting = DiffuseColor;
LowerLighting = DiffuseColor;
#elif (MATERIAL_LIGHTINGMODEL_PHONG || MATERIAL_LIGHTINGMODEL_CUSTOM || MATERIAL_LIGHTINGMODEL_ANISOTROPIC)
float NormalContribution = dot(SkyVector,Parameters.TangentNormal);
float2 ContributionWeightsSqrt = float2(0.5, 0.5f) + float2(0.5f, -0.5f) * NormalContribution;
float2 ContributionWeights = ContributionWeightsSqrt * ContributionWeightsSqrt;
#if MATERIAL_LIGHTINGMODEL_PHONG || MATERIAL_LIGHTINGMODEL_ANISOTROPIC
UpperLighting = DiffuseColor * ContributionWeights[0];
LowerLighting = DiffuseColor * ContributionWeights[1];
#elif MATERIAL_LIGHTINGMODEL_CUSTOM
UpperLighting = CustomLightingDiffuse * ContributionWeights[0];
LowerLighting = CustomLightingDiffuse * ContributionWeights[1];
#endif
#endif
return lerp(UpperLighting,TwoSidedLighting,TwoSidedLightingMask) * UpperColor +
lerp(LowerLighting,TwoSidedLighting,TwoSidedLightingMask) * LowerColor;
}
#if MATERIAL_USE_SCREEN_DOOR_FADE
/** Applies screen door fade and clip pixels that fail screen door opacity test */
void ApplyScreenDoorFadeMask( float2 ScreenPos )
{
// Screen door fade work in progress
if( bEnableScreenDoorFade )
{
// Fade opacity is passed in as a constant for the entire primitive
float FadeOpacity = ScreenDoorFadeSettings.x;
// Texture based noise
const float NoiseScale = ScreenDoorFadeSettings.y;
const float NoiseBias = ScreenDoorFadeSettings.z;
const float2 NoiseTextureOffset = ScreenDoorFadeSettings2.xy;
const float2 NoiseTextureScale = ScreenDoorFadeSettings2.zw;
half3 Noise = tex2D( ScreenDoorNoiseTexture, NoiseTextureOffset + ScreenPos.xy * NoiseTextureScale ).xyz;
float ScreenFactor = NoiseBias + NoiseScale * Noise.x;
// // Simple distance-based stipple pattern
// float ScreenFactor = min( frac( ScreenPos.x * 400.0f ), frac( ScreenPos.y * 200.0f ) );
float ScreenDoorFadeMask = ScreenFactor - ( 1 - FadeOpacity );
clip( ScreenDoorFadeMask );
}
}
#endif
#if MATERIAL_DECAL
float4 GetMaterialClippingDecal(FMaterialPixelParameters Parameters)
{
float4 DecalClip = 1;
#if NUM_MATERIAL_TEXCOORDS > 0
// clip if projected tex coords < 0 or > 1
DecalClip.xy = Parameters.TexCoords[0].xy * (1 - Parameters.TexCoords[0].xy);
// clip if outside of the decal frustum near plane
DecalClip.z = (Parameters.DecalPlaneDistance - DecalNearFarPlaneDistance.x) + 0.001;
// clip if outside of the decal frustum far plane
DecalClip.w = (DecalNearFarPlaneDistance.y - Parameters.DecalPlaneDistance) + 0.001;
#if PS3
clip(DecalClip.x);
clip(DecalClip.y);
clip(DecalClip.z);
clip(DecalClip.w);
#else
clip(DecalClip);
#endif
#endif
return DecalClip;
}
float GetMaterialAttenuationDecal(FMaterialPixelParameters Parameters)
{
float DecalAttenuation = Parameters.DecalAttenuation;
// The near and far planes are always equal distance from the center decal plane,
// so we only need to calculate against one plane in abs positive space, and the
// FarPlane, as calculated, is always positive. The scale by 5.0 here causes the
// decal attenuation to start fading out 8037547760f the way to the near or far plane.
const float PositivePlaneDistance = DecalNearFarPlaneDistance.y;
const float PositivePixelDistance = abs(Parameters.DecalPlaneDistance);
const float DistanceDeltaScaled = 5.0 * (PositivePlaneDistance - PositivePixelDistance);
DecalAttenuation *= saturate(DistanceDeltaScaled / PositivePlaneDistance);
return DecalAttenuation;
}
#else
#define GetMaterialClippingDecal(Parameters)
#define GetMaterialAttenuationDecal(Parameters) 1.0
#endif
void GetMaterialClippingShadowDepth(FMaterialPixelParameters Parameters, float2 ScreenPos)
{
GetMaterialClippingDecal(Parameters);
#if MATERIAL_CAST_LIT_TRANSLUCENCY_SHADOW_AS_MASKED || MATERIALBLENDING_MASKED || MATERIALBLENDING_SOFTMASKED
clip(GetMaterialMask(Parameters));
#elif MATERIALBLENDING_DITHEREDTRANSLUCENT || MATERIALBLENDING_TRANSLUCENT
clip(GetMaterialOpacity(Parameters) - 1.0f / 255.0f);
#endif
#if MATERIAL_USE_SCREEN_DOOR_FADE
// Apply screen door fade clip mask
ApplyScreenDoorFadeMask( ScreenPos );
#endif
}
#if MATERIALBLENDING_MASKED || MATERIALBLENDING_SOFTMASKED
#if SM5_PROFILE
#define OPTIONAL_PixelShaderCoverageInputOutput \
in uint InCoverage : SV_Coverage, \
out uint OutCoverage : SV_Coverage,
void GetMaterialCoverageAndClipping(FMaterialPixelParameters Parameters,float2 PixelCoordinates,in uint InCoverage,out uint OutCoverage)
{
OutCoverage = InCoverage;
GetMaterialClippingDecal(Parameters);
#if MATERIAL_USE_SCREEN_DOOR_FADE
// Apply screen door fade clip mask
ApplyScreenDoorFadeMask( PixelCoordinates );
#endif
#if MASKED_ANTIALIASING
// Choose a sharper mip to account for sampling it at a higher frequency.
Parameters.MipBias = -log2(NUM_TEXCOORD_SAMPLES) / 2;
uint MaskedCoverage = 0;
UNROLL
for(uint SampleIndex = 0;SampleIndex < NUM_TEXCOORD_SAMPLES;++SampleIndex)
{
// Set the texture coordinates for this sample.
#if NUM_MATERIAL_TEXCOORDS
Parameters.TexCoords = Parameters.SampleTexCoords[SampleIndex];
#endif
// If the sample is masked out, don't set that bit in the output coverage.
MaskedCoverage |= (GetMaterialMask(Parameters) < 0.0f) ? (1 << SampleIndex) : 0;
}
OutCoverage = InCoverage & ~MaskedCoverage;
#else // MASKED_ANTIALIASING
clip(GetMaterialMask(Parameters));
#endif //MASKED_ANTIALIASING
}
#else
#define OPTIONAL_PixelShaderCoverageInputOutput
static uint InCoverage;
static uint OutCoverage;
void GetMaterialCoverageAndClipping(FMaterialPixelParameters Parameters,float2 PixelCoordinates,uint Unused1,uint Unused2)
{
GetMaterialClippingDecal(Parameters);
clip(GetMaterialMask(Parameters));
#if MATERIAL_USE_SCREEN_DOOR_FADE
// Apply screen door fade clip mask
ApplyScreenDoorFadeMask( PixelCoordinates );
#endif
}
#endif
#elif MATERIALBLENDING_DITHEREDTRANSLUCENT
sampler2D AlphaSampleTexture;
#if SM5_PROFILE
#define OPTIONAL_PixelShaderCoverageInputOutput \
in uint InCoverage : SV_Coverage, \
out uint OutCoverage : SV_Coverage,
float GetOpacityThreshold(float4 ScreenPosition,uint SampleIndex)
{
return tex2D(AlphaSampleTexture,float2(
(float)SampleIndex / (float)NUM_TEXCOORD_SAMPLES,
PseudoRandom(ScreenPosition.xy)
)).r;
}
void GetMaterialCoverageAndClipping(FMaterialPixelParameters Parameters,float2 PixelCoordinates,in uint InCoverage,out uint OutCoverage)
{
GetMaterialClippingDecal(Parameters);
#if MATERIAL_USE_SCREEN_DOOR_FADE
// Apply screen door fade clip mask
ApplyScreenDoorFadeMask(PixelCoordinates );
#endif
uint MaskedCoverage = 0;
UNROLL
for(uint SampleIndex = 0;SampleIndex < NUM_TEXCOORD_SAMPLES;++SampleIndex)
{
// Set the texture coordinates for this sample.
#if NUM_MATERIAL_TEXCOORDS
Parameters.TexCoords = Parameters.SampleTexCoords[SampleIndex];
#endif
// If the sample is masked out, don't set that bit in the output coverage.
float Opacity = GetMaterialOpacity(Parameters);
float OpacityThreshold = GetOpacityThreshold(Parameters.ScreenPosition,SampleIndex);
MaskedCoverage |= (Opacity < OpacityThreshold) ? (1 << SampleIndex) : 0;
}
OutCoverage = InCoverage & ~MaskedCoverage;
}
#else
#define OPTIONAL_PixelShaderCoverageInputOutput
static uint InCoverage;
static uint OutCoverage;
float GetOpacityThreshold(float4 ScreenPosition)
{
return tex2D(AlphaSampleTexture,float2(
0,
PseudoRandom(ScreenPosition.xy + float2(0,ScreenPosition.w)))
).r;
}
void GetMaterialCoverageAndClipping(FMaterialPixelParameters Parameters,float2 PixelCoordinates,uint Unused1,uint Unused2)
{
GetMaterialClippingDecal(Parameters);
float Opacity = GetMaterialOpacity(Parameters);
float OpacityThreshold = GetOpacityThreshold(Parameters.ScreenPosition);
clip(Opacity - OpacityThreshold);
#if MATERIAL_USE_SCREEN_DOOR_FADE
// Apply screen door fade clip mask
ApplyScreenDoorFadeMask( PixelCoordinates );
#endif
}
#endif
#else
#define OPTIONAL_PixelShaderCoverageInputOutput
static uint InCoverage;
static uint OutCoverage;
void GetMaterialCoverageAndClipping(FMaterialPixelParameters Parameters,float2 PixelCoordinates,uint Unused1,uint Unused2)
{
GetMaterialClippingDecal(Parameters);
#if MATERIAL_USE_SCREEN_DOOR_FADE
// Apply screen door fade clip mask
ApplyScreenDoorFadeMask( PixelCoordinates );
#endif
}
#endif
#if MATERIAL_LIT_TRANSLUCENCY_PREPASS
void GetMaterialClippingLitTranslucencyDepthOnly(FMaterialPixelParameters Parameters)
{
clip( GetMaterialOpacity(Parameters) - 1.f );
}
#endif
#if MATERIAL_LIT_TRANSLUCENCY_DEPTH_POSTPASS
void GetMaterialClippingLitTranslucencyDepthPostPass(FMaterialPixelParameters Parameters)
{
clip( GetMaterialOpacity(Parameters) - 1.f/255.f );
}
#endif
#if MATERIAL_TWOSIDED_SEPARATE_PASS
#define OPTIONAL_FacingSign
static const float FacingSign = 1.0f;
#else
#define OPTIONAL_FacingSign in float FacingSign : VFACE,
#endif
#if MATERIAL_USE_SCREEN_DOOR_FADE
#if SM5_PROFILE
// SM5 requires SV_Position to be declared as xyzw
#define OPTIONAL_PixelShaderScreenPosition in float4 PixelShaderScreenPosition : SV_Position,
#else
// SM3 requires VPOS to be declared as xy
#define OPTIONAL_PixelShaderScreenPosition in float2 PixelShaderScreenPosition : VPOS,
#endif
#else
#define OPTIONAL_PixelShaderScreenPosition
static const float2 PixelShaderScreenPosition = float2( 0.0f, 0.0f );
#endif
/**
* Flip vectors for lighting with 2 sided materials
*/
void TwoSidedFlipVector(in out FMaterialPixelParameters Parameters)
{
// flip the normal for backfaces being rendered with a two-sided material
Parameters.TangentNormal *= Parameters.TwoSidedSign;
#if MATERIAL_LIGHTINGMODEL_ANISOTROPIC
Parameters.TangentAnisotropicDirection *= Parameters.TwoSidedSign;
#endif
}
/** Initializes the subset of Parameters that was not set in GetMaterialPixelParameters. */
void CalcMaterialParameters(
in out FMaterialPixelParameters Parameters,
float FacingSign,
float4 CameraVectorOrVertexColor,
float4 PixelPosition,
half3 LightVector = half3(0,0,1),
uniform bool bAllowTwoSidedFlip = true)
{
Parameters.MipBias = 0;
#if NUM_MATERIAL_TEXCOORDS && !NUM_TEXCOORD_SAMPLES
UNROLL for(uint CoordinateIndex = 0;CoordinateIndex < NUM_MATERIAL_TEXCOORDS;++CoordinateIndex)
{
Parameters.SampleTexCoords[0][CoordinateIndex] = 0;
}
#endif
#if WORLD_POS
Parameters.WorldPosition = PixelPosition.xyz + CameraWorldPos;
Parameters.ScreenPosition = MulMatrix(ViewProjectionMatrix,PixelPosition);
#else
Parameters.ScreenPosition = PixelPosition;
#endif
#if PER_PIXEL_CAMERA_VECTOR
// When per-pixel camera vector is enabled, we store vertex color in the interpolator that
// is usually used for camera vector so that we can use vertex color and environment maps
// simultaneously in the base pass. This is needed due to a low number of available interpolators.
Parameters.VertexColor = CameraVectorOrVertexColor;
// Compute the world space camera -> pixel vector
// NOTE: Actually, we've already computed this! (-PixelPosition.xyz)
// float3 WorldCameraVector = normalize( CameraWorldPos.xyz - Parameters.WorldPosition.xyz );
float3 WorldCameraVector = normalize( -PixelPosition.xyz );
// Transform camera vector from world space to tangent space. Sadly the vector's direction may
// be changed by this as the tangent->world matrix has been passed through interpolators.
Parameters.TangentCameraVector = TransformWorldVectorToTangent(Parameters.TangentToWorld, WorldCameraVector);
// Parameters.TangentCameraVector = transpose(Parameters.TangentToWorld)[0];
#else
// When using per-vertex camera vectors, the value passed in will always be a camera vector
// and vertex color will be stored in a separate interpolator.
float3 CameraVector = CameraVectorOrVertexColor.xyz;
// Per-vertex camera vector
Parameters.TangentCameraVector = normalize(CameraVector);
#endif
Parameters.TangentLightVector = normalize((half3)LightVector);
Parameters.TangentNormal = normalize(GetMaterialNormal(Parameters));
Parameters.TwoSidedSign = 1.0f;
#if MATERIAL_LIGHTINGMODEL_ANISOTROPIC
Parameters.TangentAnisotropicDirection = normalize(GetMaterialAnisotropicDirection(Parameters));
#if MATERIAL_DEFINED_NORMALMAP
// Graham-Schmidt Orthonormalization, from http://ati.amd.com/developer/shaderx/ShaderX_PerPixelAniso.pdf
Parameters.TangentAnisotropicDirection = Parameters.TangentAnisotropicDirection - (dot(Parameters.TangentNormal,Parameters.TangentAnisotropicDirection) * Parameters.TangentNormal);
// Renormalize the vector, with bias to prevent NaN.
Parameters.TangentAnisotropicDirection = Parameters.TangentAnisotropicDirection / sqrt(max(dot(Parameters.TangentAnisotropicDirection,Parameters.TangentAnisotropicDirection), 0.01));
#endif
#endif
#if MATERIAL_TWOSIDED
Parameters.TwoSidedSign *= TwoSidedSign;
#if !MATERIAL_TWOSIDED_SEPARATE_PASS
// D3D requires that VFACE be used by a conditional instruction rather than used as a signed float directly.
float FacingSignFloat = FacingSign >= 0 ? +1 : -1;
#if PS3 || XBOX || SM5_PROFILE
Parameters.TwoSidedSign *= FacingSignFloat;
#else
// in SM3 VFACE is actually negative for frontfaces since frontfacing polys in U8E3 are CM_CW instead of CM_CCW
Parameters.TwoSidedSign *= -FacingSignFloat;
#endif
#endif
#endif
// allow individual shaders to override the flip
if (bAllowTwoSidedFlip)
{
TwoSidedFlipVector(Parameters);
}
Parameters.TangentReflectionVector = -Parameters.TangentCameraVector + Parameters.TangentNormal * dot(Parameters.TangentNormal,Parameters.TangentCameraVector) * 2.0;
}
#if SM5_PROFILE
/**
* Initializes the subset of Parameters that was not set in GetMaterialTessellationParameters (in vertex factory code).
* Assumes that Parameters.WorldPosition and Parameters.TangentToWorld have been set
*/
void CalcMaterialTessellationParameters( in out FMaterialTessellationParameters Parameters )
{
// Since we don't have access to normal map, our tangent space normal is always 0,0,1
float3 TangentNormal = float3(0,0,1);
Parameters.TangentReflectionVector = -Parameters.TangentCameraVector + TangentNormal * dot(TangentNormal,Parameters.TangentCameraVector) * 2.0;
}
#endif
/** Assemble the transform from tangent space into world space */
float3x3 CalcTangentToWorld( float3 TangentToWorld0, float4 TangentToWorld2 )
{
// Renormalize basis vectors as they are no longer unit length due to linear interpolation
float3 TangentToWorld2N = normalize(TangentToWorld2.xyz);
float3 TangentToWorld0N = normalize(TangentToWorld0);
// Derive the third basis vector off of the other two, guaranteed to be unit length as the other two are an orthonormal set.
// Flip based on the determinant sign
float3 TangentToWorld1N = cross(TangentToWorld2N,TangentToWorld0N) * TangentToWorld2.w;
// Transform from tangent space to world space
return float3x3(TangentToWorld0N, TangentToWorld1N, TangentToWorld2N);
}
/** Temporal AA jitter offset in xy, whether the object should be jittered in z. */
float3 TemporalAAParameters;
/** Applies the temporal AA jitter to a screen-space position. */
float4 ApplyTemporalAAJitter(float4 ScreenPosition)
{
float2 Offset = TemporalAAParameters.xy;
return float4(
ScreenPosition.xy + TemporalAAParameters.z * ScreenPosition.w * Offset,
ScreenPosition.zw
);
}
#if MATERIAL_USE_GAMMA_CORRECTION
/** optional gamma correction to be applied to materials. Inverse gamma */
half MatInverseGamma;
/**
* Apply linear to gamma correction. This is needed when rendering materials to a render target with gamma != 1.0
* @param Color - color in linear space
* @return color in gamma space
*/
half4 MaterialGammaCorrect( half4 Color )
{
return float4( pow( Color.xyz, MatInverseGamma ), Color.w );
}
#else
/** stub when not compiling with gamma correction */
#define MaterialGammaCorrect( Color ) ( Color )
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment