您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
144 行
4.7 KiB
144 行
4.7 KiB
#if SHADERPASS != SHADERPASS_VELOCITY
|
|
#error SHADERPASS_is_not_correctly_define
|
|
#endif
|
|
|
|
// Available semantic start from TEXCOORD4
|
|
struct AttributesPass
|
|
{
|
|
float3 previousPositionOS : NORMAL; // Contain previous transform position (in case of skinning for example)
|
|
|
|
// TODO: Caution - For now the tesselation doesn't displace along the normal with Velocity shader as the previous previous position
|
|
// conflict with the normal in the semantic. This need to be fix!
|
|
};
|
|
|
|
struct VaryingsPassToPS
|
|
{
|
|
// Note: Z component is not use currently
|
|
// This is the clip space position. Warning, do not confuse with the value of positionCS in PackedVarying which is SV_POSITION and store in positionSS
|
|
float4 positionCS;
|
|
float4 previousPositionCS;
|
|
};
|
|
|
|
// Available interpolator start from TEXCOORD8
|
|
struct PackedVaryingsPassToPS
|
|
{
|
|
// Note: Z component is not use
|
|
float3 interpolators0 : TEXCOORD8;
|
|
float3 interpolators1 : TEXCOORD9;
|
|
};
|
|
|
|
PackedVaryingsPassToPS PackVaryingsPassToPS(VaryingsPassToPS input)
|
|
{
|
|
PackedVaryingsPassToPS output;
|
|
output.interpolators0 = float3(input.positionCS.xyw);
|
|
output.interpolators1 = float3(input.previousPositionCS.xyw);
|
|
|
|
return output;
|
|
}
|
|
|
|
VaryingsPassToPS UnpackVaryingsPassToPS(PackedVaryingsPassToPS input)
|
|
{
|
|
VaryingsPassToPS output;
|
|
output.positionCS = float4(input.interpolators0.xy, 0.0, input.interpolators0.z);
|
|
output.previousPositionCS = float4(input.interpolators1.xy, 0.0, input.interpolators1.z);
|
|
|
|
return output;
|
|
}
|
|
|
|
#ifdef TESSELLATION_ON
|
|
|
|
// Available interpolator start from TEXCOORD4
|
|
|
|
// Same as ToPS here
|
|
#define VaryingsPassToDS VaryingsPassToPS
|
|
#define PackedVaryingsPassToDS PackedVaryingsPassToPS
|
|
#define PackVaryingsPassToDS PackVaryingsPassToPS
|
|
#define UnpackVaryingsPassToDS UnpackVaryingsPassToPS
|
|
|
|
VaryingsPassToDS InterpolateWithBaryCoordsPassToDS(VaryingsPassToDS input0, VaryingsPassToDS input1, VaryingsPassToDS input2, float3 baryCoords)
|
|
{
|
|
VaryingsPassToDS ouput;
|
|
|
|
TESSELLATION_INTERPOLATE_BARY(positionCS, baryCoords);
|
|
TESSELLATION_INTERPOLATE_BARY(previousPositionCS, baryCoords);
|
|
|
|
return ouput;
|
|
}
|
|
|
|
#endif // TESSELLATION_ON
|
|
|
|
#ifdef TESSELLATION_ON
|
|
#define VaryingsPassType VaryingsPassToDS
|
|
#else
|
|
#define VaryingsPassType VaryingsPassToPS
|
|
#endif
|
|
|
|
// We will use custom attributes for this pass
|
|
#define VARYINGS_NEED_PASS
|
|
#include "VertMesh.hlsl"
|
|
|
|
PackedVaryingsType Vert(AttributesMesh inputMesh,
|
|
AttributesPass inputPass)
|
|
{
|
|
VaryingsType varyingsType;
|
|
varyingsType.vmesh = VertMesh(inputMesh);
|
|
|
|
// It is not possible to correctly generate the motion vector for tesselated geometry as tessellation parameters can change
|
|
// from one frame to another (adaptative, lod) + in Unity we only receive information for one non tesselated vertex.
|
|
// So motion vetor will be based on interpolate previous position at vertex level instead.
|
|
varyingsType.vpass.positionCS = mul(_NonJitteredViewProjMatrix, mul(unity_ObjectToWorld, float4(inputMesh.positionOS, 1.0)));
|
|
varyingsType.vpass.previousPositionCS = mul(_PrevViewProjMatrix, mul(unity_MatrixPreviousM, unity_MotionVectorsParams.x ? float4(inputPass.previousPositionOS, 1.0) : float4(inputMesh.positionOS, 1.0)));
|
|
|
|
return PackVaryingsType(varyingsType);
|
|
}
|
|
|
|
#ifdef TESSELLATION_ON
|
|
|
|
PackedVaryingsToPS VertTesselation(VaryingsToDS input)
|
|
{
|
|
VaryingsToPS output;
|
|
|
|
output.vmesh = VertMeshTesselation(input.vmesh);
|
|
|
|
output.vpass.positionCS = input.vpass.positionCS;
|
|
output.vpass.previousPositionCS = input.vpass.previousPositionCS;
|
|
|
|
return PackVaryingsToPS(output);
|
|
}
|
|
|
|
#include "TessellationShare.hlsl"
|
|
|
|
#endif // TESSELLATION_ON
|
|
|
|
float4 Frag(PackedVaryingsToPS packedInput) : SV_Target
|
|
{
|
|
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
|
|
|
|
// input.positionSS is SV_Position
|
|
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw);
|
|
UpdatePositionInput(input.positionSS.z, input.positionSS.w, input.positionWS, posInput);
|
|
|
|
#ifdef VARYINGS_NEED_POSITION_WS
|
|
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
|
|
#else
|
|
float3 V = 0; // Avoid the division by 0
|
|
#endif
|
|
|
|
// Perform alpha testing + get velocity
|
|
SurfaceData surfaceData;
|
|
BuiltinData builtinData;
|
|
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
|
|
|
|
VaryingsPassToPS inputPass = UnpackVaryingsPassToPS(packedInput.vpass);
|
|
#ifdef _DEPTHOFFSET_ON
|
|
inputPass.positionCS.w += builtinData.depthOffset;
|
|
inputPass.previousPositionCS.w += builtinData.depthOffset;
|
|
#endif
|
|
|
|
// TODO: How to allow overriden velocity vector from GetSurfaceAndBuiltinData ?
|
|
float2 velocity = CalculateVelocity(inputPass.positionCS, inputPass.previousPositionCS);
|
|
|
|
float4 outBuffer;
|
|
EncodeVelocity(velocity, outBuffer);
|
|
return outBuffer;
|
|
}
|