You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
336 lines
11 KiB
336 lines
11 KiB
struct VaryingsToPS
|
|
{
|
|
VaryingsMeshToPS vmesh;
|
|
#ifdef VARYINGS_NEED_PASS
|
|
VaryingsPassToPS vpass;
|
|
#endif
|
|
};
|
|
|
|
struct PackedVaryingsToPS
|
|
{
|
|
#ifdef VARYINGS_NEED_PASS
|
|
PackedVaryingsPassToPS vpass;
|
|
#endif
|
|
|
|
PackedVaryingsMeshToPS vmesh;
|
|
|
|
// SGVs must be packed after all non-SGVs have been packed.
|
|
// If there are several SGVs, they are packed in the order of HLSL declaration.
|
|
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
|
|
#if defined(PLATFORM_SUPPORTS_PRIMITIVE_ID_IN_PIXEL_SHADER) && SHADER_STAGE_FRAGMENT
|
|
#if (defined(VARYINGS_NEED_PRIMITIVEID) || (SHADERPASS == SHADERPASS_FULL_SCREEN_DEBUG))
|
|
uint primitiveID : SV_PrimitiveID;
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(VARYINGS_NEED_CULLFACE) && SHADER_STAGE_FRAGMENT
|
|
FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;
|
|
#endif
|
|
};
|
|
|
|
PackedVaryingsToPS PackVaryingsToPS(VaryingsToPS input)
|
|
{
|
|
PackedVaryingsToPS output;
|
|
output.vmesh = PackVaryingsMeshToPS(input.vmesh);
|
|
#ifdef VARYINGS_NEED_PASS
|
|
output.vpass = PackVaryingsPassToPS(input.vpass);
|
|
#endif
|
|
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
|
return output;
|
|
}
|
|
|
|
FragInputs UnpackVaryingsToFragInputs(PackedVaryingsToPS packedInput)
|
|
{
|
|
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
|
|
|
|
#if defined(PLATFORM_SUPPORTS_PRIMITIVE_ID_IN_PIXEL_SHADER) && SHADER_STAGE_FRAGMENT
|
|
#if (defined(VARYINGS_NEED_PRIMITIVEID) || (SHADERPASS == SHADERPASS_FULL_SCREEN_DEBUG))
|
|
input.primitiveID = packedInput.primitiveID;
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(VARYINGS_NEED_CULLFACE) && SHADER_STAGE_FRAGMENT
|
|
input.isFrontFace = IS_FRONT_VFACE(packedInput.cullFace, true, false);
|
|
#endif
|
|
|
|
return input;
|
|
}
|
|
|
|
#ifdef TESSELLATION_ON
|
|
|
|
|
|
struct VaryingsToDS
|
|
{
|
|
VaryingsMeshToDS vmesh;
|
|
#ifdef VARYINGS_NEED_PASS
|
|
VaryingsPassToDS vpass;
|
|
#endif
|
|
};
|
|
|
|
struct PackedVaryingsToDS
|
|
{
|
|
PackedVaryingsMeshToDS vmesh;
|
|
#ifdef VARYINGS_NEED_PASS
|
|
PackedVaryingsPassToDS vpass;
|
|
#endif
|
|
};
|
|
|
|
PackedVaryingsToDS PackVaryingsToDS(VaryingsToDS input)
|
|
{
|
|
PackedVaryingsToDS output;
|
|
output.vmesh = PackVaryingsMeshToDS(input.vmesh);
|
|
#ifdef VARYINGS_NEED_PASS
|
|
output.vpass = PackVaryingsPassToDS(input.vpass);
|
|
#endif
|
|
|
|
return output;
|
|
}
|
|
|
|
VaryingsToDS UnpackVaryingsToDS(PackedVaryingsToDS input)
|
|
{
|
|
VaryingsToDS output;
|
|
output.vmesh = UnpackVaryingsMeshToDS(input.vmesh);
|
|
#ifdef VARYINGS_NEED_PASS
|
|
output.vpass = UnpackVaryingsPassToDS(input.vpass);
|
|
#endif
|
|
|
|
return output;
|
|
}
|
|
|
|
VaryingsToDS InterpolateWithBaryCoordsToDS(VaryingsToDS input0, VaryingsToDS input1, VaryingsToDS input2, float3 baryCoords)
|
|
{
|
|
VaryingsToDS output;
|
|
|
|
output.vmesh = InterpolateWithBaryCoordsMeshToDS(input0.vmesh, input1.vmesh, input2.vmesh, baryCoords);
|
|
#ifdef VARYINGS_NEED_PASS
|
|
output.vpass = InterpolateWithBaryCoordsPassToDS(input0.vpass, input1.vpass, input2.vpass, baryCoords);
|
|
#endif
|
|
|
|
return output;
|
|
}
|
|
|
|
#endif // TESSELLATION_ON
|
|
|
|
#ifdef TESSELLATION_ON
|
|
#define VaryingsType VaryingsToDS
|
|
#define VaryingsMeshType VaryingsMeshToDS
|
|
#define PackedVaryingsType PackedVaryingsToDS
|
|
#define PackVaryingsType PackVaryingsToDS
|
|
#else
|
|
#define VaryingsType VaryingsToPS
|
|
#define VaryingsMeshType VaryingsMeshToPS
|
|
#define PackedVaryingsType PackedVaryingsToPS
|
|
#define PackVaryingsType PackVaryingsToPS
|
|
#endif
|
|
|
|
#if defined(HAVE_VFX_MODIFICATION)
|
|
//compiler shows warning when using intermediate returns (see vfx culling), disable this.
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 4000)
|
|
#endif
|
|
|
|
// TODO: Here we will also have all the vertex deformation (GPU skinning, vertex animation, morph target...) or we will need to generate a compute shaders instead (better! but require work to deal with unpacking like fp16)
|
|
VaryingsMeshType VertMesh(AttributesMesh input, float3 worldSpaceOffset
|
|
#ifdef HAVE_VFX_MODIFICATION
|
|
, out AttributesElement element
|
|
#endif
|
|
)
|
|
{
|
|
VaryingsMeshType output;
|
|
#if defined(USE_CUSTOMINTERP_SUBSTRUCT) || defined(HAVE_VFX_MODIFICATION)
|
|
ZERO_INITIALIZE(VaryingsMeshType, output); // Only required with custom interpolator to quiet the shader compiler about not fully initialized struct
|
|
#endif
|
|
|
|
// Deduce the actual instance ID of the current instance (it is then stored in unity_InstanceID)
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
// Transfer the unprocessed instance ID to the next stage
|
|
UNITY_TRANSFER_INSTANCE_ID(input, output);
|
|
|
|
#ifdef HAVE_VFX_MODIFICATION
|
|
ZERO_INITIALIZE(AttributesElement, element);
|
|
|
|
if(!GetMeshAndElementIndex(input, element))
|
|
return output; // Culled index.
|
|
|
|
#if UNITY_ANY_INSTANCING_ENABLED
|
|
output.instanceID = input.instanceID; //Transfer again because we modify it in GetMeshAndElementIndex
|
|
#endif
|
|
|
|
if(!GetInterpolatorAndElementData(input, output, element))
|
|
return output; // Dead particle.
|
|
|
|
SetupVFXMatrices(element, output);
|
|
#endif
|
|
|
|
#ifdef HAVE_MESH_MODIFICATION
|
|
input = ApplyMeshModification(input, _TimeParameters.xyz
|
|
#ifdef USE_CUSTOMINTERP_SUBSTRUCT
|
|
// If custom interpolators are in use, we need to write them to the shader graph generated VaryingsMesh
|
|
, output
|
|
#endif
|
|
#ifdef HAVE_VFX_MODIFICATION
|
|
, element
|
|
#endif
|
|
);
|
|
#endif
|
|
|
|
// This return the camera relative position (if enable)
|
|
float3 positionRWS = TransformObjectToWorld(input.positionOS) + worldSpaceOffset;
|
|
#ifdef ATTRIBUTES_NEED_NORMAL
|
|
float3 normalWS = TransformObjectToWorldNormal(input.normalOS);
|
|
#else
|
|
float3 normalWS = float3(0.0, 0.0, 0.0); // We need this case to be able to compile ApplyVertexModification that doesn't use normal.
|
|
#endif
|
|
|
|
#ifdef ATTRIBUTES_NEED_TANGENT
|
|
float4 tangentWS = float4(TransformObjectToWorldDir(input.tangentOS.xyz), input.tangentOS.w);
|
|
#endif
|
|
|
|
// Do vertex modification in camera relative space (if enable)
|
|
#if defined(HAVE_VERTEX_MODIFICATION)
|
|
ApplyVertexModification(input, normalWS, positionRWS, _TimeParameters.xyz);
|
|
#endif
|
|
|
|
#ifdef TESSELLATION_ON
|
|
output.positionRWS = positionRWS;
|
|
#ifdef VARYINGS_NEED_POSITIONPREDISPLACEMENT_WS
|
|
output.positionPredisplacementRWS = positionRWS;
|
|
#endif
|
|
// For tessellation we evaluate the tessellation factor from vertex shader then interpolate it in Hull Shader
|
|
// Note: For unknown reason evaluating the tessellationFactor directly in Hull shader cause internal compiler issue for both Metal and Vulkan (Unity issue) when use with shadergraph
|
|
// so we prefer this version to be compatible with all platforms, have same code for non shader graph and shader graph version and also it should be faster.
|
|
output.tessellationFactor = GetTessellationFactor(input);
|
|
output.normalWS = normalWS;
|
|
#if defined(VARYINGS_NEED_TANGENT_TO_WORLD) || defined(VARYINGS_DS_NEED_TANGENT)
|
|
output.tangentWS = tangentWS;
|
|
#endif
|
|
#else // TESSELLATION_ON
|
|
#ifdef VARYINGS_NEED_POSITION_WS
|
|
output.positionRWS = positionRWS;
|
|
#endif
|
|
#ifdef VARYINGS_NEED_POSITIONPREDISPLACEMENT_WS
|
|
output.positionPredisplacementRWS = positionRWS;
|
|
#endif
|
|
|
|
output.positionCS = TransformWorldToHClip(positionRWS);
|
|
#ifdef VARYINGS_NEED_TANGENT_TO_WORLD
|
|
output.normalWS = normalWS;
|
|
output.tangentWS = tangentWS;
|
|
#endif
|
|
#if !defined(SHADER_API_METAL) && defined(SHADERPASS) && (SHADERPASS == SHADERPASS_FULL_SCREEN_DEBUG)
|
|
if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_VERTEX_DENSITY)
|
|
IncrementVertexDensityCounter(output.positionCS);
|
|
#endif
|
|
#endif // TESSELLATION_ON
|
|
|
|
#if defined(VARYINGS_NEED_TEXCOORD0) || defined(VARYINGS_DS_NEED_TEXCOORD0)
|
|
output.texCoord0 = input.uv0;
|
|
#endif
|
|
#if defined(VARYINGS_NEED_TEXCOORD1) || defined(VARYINGS_DS_NEED_TEXCOORD1)
|
|
output.texCoord1 = input.uv1;
|
|
#endif
|
|
#if defined(VARYINGS_NEED_TEXCOORD2) || defined(VARYINGS_DS_NEED_TEXCOORD2)
|
|
output.texCoord2 = input.uv2;
|
|
#endif
|
|
#if defined(VARYINGS_NEED_TEXCOORD3) || defined(VARYINGS_DS_NEED_TEXCOORD3)
|
|
output.texCoord3 = input.uv3;
|
|
#endif
|
|
#if defined(VARYINGS_NEED_COLOR) || defined(VARYINGS_DS_NEED_COLOR)
|
|
output.color = input.color;
|
|
#endif
|
|
#if (defined(VARYINGS_NEED_INSTANCEID) || defined(VARYINGS_DS_NEED_INSTANCEID)) && !UNITY_ANY_INSTANCING_ENABLED
|
|
output.instanceID = input.instanceID;
|
|
#endif
|
|
|
|
#if defined(VARYINGS_NEED_SIX_WAY_DIFFUSE_GI_DATA)
|
|
GatherDiffuseGIData(normalWS, tangentWS, positionRWS, output.diffuseGIData0, output.diffuseGIData1, output.diffuseGIData2);
|
|
#endif
|
|
return output;
|
|
}
|
|
|
|
#if defined(HAVE_VFX_MODIFICATION)
|
|
#pragma warning(pop)
|
|
#endif
|
|
|
|
VaryingsMeshType VertMesh(AttributesMesh input)
|
|
{
|
|
#ifdef HAVE_VFX_MODIFICATION
|
|
AttributesElement element;
|
|
return VertMesh(input, 0.0f, element);
|
|
#else
|
|
return VertMesh(input, 0.0f);
|
|
#endif
|
|
}
|
|
|
|
#ifdef HAVE_VFX_MODIFICATION
|
|
VaryingsMeshType VertMesh(AttributesMesh input, out AttributesElement element)
|
|
{
|
|
return VertMesh(input, 0.0f, element);
|
|
}
|
|
#endif
|
|
|
|
#ifdef TESSELLATION_ON
|
|
|
|
VaryingsMeshToPS VertMeshTesselation(VaryingsMeshToDS input)
|
|
{
|
|
VaryingsMeshToPS output;
|
|
|
|
// Deduce the actual instance ID of the current instance (it is then stored in unity_InstanceID)
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
// Transfer the unprocessed instance ID to the next stage
|
|
UNITY_TRANSFER_INSTANCE_ID(input, output);
|
|
|
|
output.positionCS = TransformWorldToHClip(input.positionRWS);
|
|
|
|
#if !defined(SHADER_API_METAL) && defined(SHADERPASS) && (SHADERPASS == SHADERPASS_FULL_SCREEN_DEBUG)
|
|
if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_VERTEX_DENSITY)
|
|
IncrementVertexDensityCounter(output.positionCS);
|
|
#endif
|
|
|
|
#ifdef VARYINGS_NEED_POSITION_WS
|
|
output.positionRWS = input.positionRWS;
|
|
#endif
|
|
#ifdef VARYINGS_NEED_POSITIONPREDISPLACEMENT_WS
|
|
output.positionPredisplacementRWS = input.positionPredisplacementRWS;
|
|
#endif
|
|
|
|
#ifdef VARYINGS_NEED_TANGENT_TO_WORLD
|
|
output.normalWS = input.normalWS;
|
|
output.tangentWS = input.tangentWS;
|
|
#endif
|
|
|
|
#ifdef VARYINGS_NEED_TEXCOORD0
|
|
output.texCoord0 = input.texCoord0;
|
|
#endif
|
|
#ifdef VARYINGS_NEED_TEXCOORD1
|
|
output.texCoord1 = input.texCoord1;
|
|
#endif
|
|
#ifdef VARYINGS_NEED_TEXCOORD2
|
|
output.texCoord2 = input.texCoord2;
|
|
#endif
|
|
#ifdef VARYINGS_NEED_TEXCOORD3
|
|
output.texCoord3 = input.texCoord3;
|
|
#endif
|
|
#ifdef VARYINGS_NEED_COLOR
|
|
output.color = input.color;
|
|
#endif
|
|
#if defined(VARYINGS_NEED_INSTANCEID) && !UNITY_ANY_INSTANCING_ENABLED
|
|
output.instanceID = input.instanceID;
|
|
#endif
|
|
|
|
#if defined(VARYINGS_NEED_SIX_WAY_DIFFUSE_GI_DATA)
|
|
GatherDiffuseGIData(input.normalWS, input.tangentWS, input.positionRWS, output.diffuseGIData0, output.diffuseGIData1, output.diffuseGIData2);
|
|
#endif
|
|
// Call is last to deal with 'not completely initialize warning'. We don't want to ZeroInitialize the output struct to be able to detect issue.
|
|
#ifdef USE_CUSTOMINTERP_SUBSTRUCT
|
|
// If custom interpolators are in use, we need to write them to the shader graph generated VaryingsMesh
|
|
VertMeshTesselationCustomInterpolation(input, output);
|
|
#endif
|
|
|
|
return output;
|
|
}
|
|
|
|
#endif // TESSELLATION_ON
|