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.
224 lines
7.4 KiB
224 lines
7.4 KiB
// Output Type: Planar Primitive (Triangle, Quad, Octagon)
|
|
|
|
#if defined(HAS_STRIPS) && !defined(VFX_PRIMITIVE_QUAD)
|
|
#error VFX_PRIMITIVE_QUAD must be defined when HAS_STRIPS is.
|
|
#endif
|
|
|
|
#define VFX_NON_UNIFORM_SCALE VFX_LOCAL_SPACE
|
|
|
|
#define HAVE_VFX_PLANAR_PRIMITIVE
|
|
|
|
bool GetMeshAndElementIndex(inout VFX_SRP_ATTRIBUTES input, inout AttributesElement element)
|
|
{
|
|
uint id = input.vertexID;
|
|
|
|
// Index Setup
|
|
uint index = 0;
|
|
#if VFX_PRIMITIVE_TRIANGLE
|
|
index = id / 3;
|
|
#elif VFX_PRIMITIVE_QUAD
|
|
index = (id >> 2) + VFX_GET_INSTANCE_ID(i) * 2048;
|
|
#elif VFX_PRIMITIVE_OCTAGON
|
|
index = (id >> 3) + VFX_GET_INSTANCE_ID(i) * 1024;
|
|
#endif
|
|
|
|
$splice(VFXInitInstancing)
|
|
#ifdef UNITY_INSTANCING_ENABLED
|
|
input.instanceID = unity_InstanceID;
|
|
#endif
|
|
|
|
$splice(VFXLoadContextData)
|
|
uint systemSeed = contextData.systemSeed;
|
|
uint nbMax = contextData.maxParticleCount;
|
|
|
|
if (ShouldCullElement(index, instanceIndex, nbMax))
|
|
return false;
|
|
|
|
#if VFX_HAS_INDIRECT_DRAW
|
|
index = indirectBuffer[VFXGetIndirectBufferIndex(index, instanceActiveIndex)];
|
|
#endif
|
|
|
|
#if HAS_STRIPS
|
|
StripData stripData;
|
|
uint relativeIndexInStrip = 0;
|
|
if (!FindIndexInStrip(index, id, instanceIndex, relativeIndexInStrip, stripData))
|
|
return false;
|
|
|
|
element.relativeIndexInStrip = relativeIndexInStrip;
|
|
element.stripData = stripData;
|
|
#endif
|
|
|
|
element.index = index;
|
|
element.instanceIndex = instanceIndex;
|
|
element.instanceActiveIndex = instanceActiveIndex;
|
|
|
|
// Configure planar Primitive
|
|
float4 uv = 0;
|
|
|
|
#if VFX_PRIMITIVE_QUAD
|
|
#if HAS_STRIPS
|
|
#if VFX_STRIPS_UV_STRECHED
|
|
uv.x = (float)(relativeIndexInStrip) / (stripData.nextIndex - 1);
|
|
#elif VFX_STRIPS_UV_PER_SEGMENT
|
|
uv.x = STRIP_PARTICLE_IN_EDGE;
|
|
#else
|
|
GetElementData(element);
|
|
const InternalAttributesElement attributes = element.attributes;
|
|
$splice(VFXLoadGraphValues)
|
|
$splice(VFXLoadTexcoordParameter)
|
|
uv.x = texCoord;
|
|
#endif
|
|
|
|
uv.y = (id & 2) * 0.5f;
|
|
const float2 vOffsets = float2(0.0f, uv.y - 0.5f);
|
|
|
|
#if VFX_STRIPS_SWAP_UV
|
|
uv.xy = float2(1.0f - uv.y, uv.x);
|
|
#endif
|
|
|
|
#else
|
|
uv.x = float(id & 1);
|
|
uv.y = (id & 2) * 0.5f;
|
|
const float2 vOffsets = uv.xy - 0.5f;
|
|
#endif
|
|
#elif VFX_PRIMITIVE_TRIANGLE
|
|
const float2 kOffsets[] = {
|
|
float2(-0.5f, -0.288675129413604736328125f),
|
|
float2(0.0f, 0.57735025882720947265625f),
|
|
float2(0.5f, -0.288675129413604736328125f),
|
|
};
|
|
|
|
const float kUVScale = 0.866025388240814208984375f;
|
|
|
|
const float2 vOffsets = kOffsets[id % 3];
|
|
uv.xy = (vOffsets * kUVScale) + 0.5f;
|
|
#elif VFX_PRIMITIVE_OCTAGON
|
|
const float2 kUvs[8] =
|
|
{
|
|
float2(-0.5f, 0.0f),
|
|
float2(-0.5f, 0.5f),
|
|
float2(0.0f, 0.5f),
|
|
float2(0.5f, 0.5f),
|
|
float2(0.5f, 0.0f),
|
|
float2(0.5f, -0.5f),
|
|
float2(0.0f, -0.5f),
|
|
float2(-0.5f, -0.5f),
|
|
};
|
|
|
|
GetElementData(element);
|
|
const InternalAttributesElement attributes = element.attributes;
|
|
|
|
$splice(VFXLoadGraphValues)
|
|
|
|
// Here we have to explicitly splice in the crop factor.
|
|
$splice(VFXLoadCropFactorParameter)
|
|
|
|
const float correctedCropFactor = id & 1 ? 1.0f - cropFactor : 1.0f;
|
|
const float2 vOffsets = kUvs[id & 7] * correctedCropFactor;
|
|
uv.xy = vOffsets + 0.5f;
|
|
#endif
|
|
|
|
input.positionOS = float3(vOffsets, 0.0);
|
|
#ifdef ATTRIBUTES_NEED_NORMAL
|
|
input.normalOS = float3(0, 0, -1);
|
|
#endif
|
|
#ifdef ATTRIBUTES_NEED_TANGENT
|
|
input.tangentOS = float4(1, 0, 0, 1);
|
|
#endif
|
|
#ifdef ATTRIBUTES_NEED_COLOR
|
|
input.color = float4(1, 1, 1, 1);
|
|
#endif
|
|
|
|
#ifdef ATTRIBUTES_NEED_TEXCOORD0
|
|
input.uv0 = uv;
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
#if defined(SHADER_STAGE_RAY_TRACING)
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXRayTracingCommon.hlsl"
|
|
|
|
void GetVFXInstancingIndices(out int index, out int instanceIndex, out int instanceActiveIndex)
|
|
{
|
|
#ifdef VFX_RT_DECIMATION_FACTOR
|
|
int rayTracingDecimationFactor = VFX_RT_DECIMATION_FACTOR;
|
|
#else
|
|
int rayTracingDecimationFactor = 1;
|
|
#endif
|
|
index = PrimitiveIndex() * rayTracingDecimationFactor;
|
|
instanceIndex = asuint(_InstanceIndex);
|
|
instanceActiveIndex = asuint(_InstanceActiveIndex);
|
|
VFXGetInstanceCurrentIndex(index);
|
|
}
|
|
|
|
float GetVFXVertexDisplacement(int index, float3 currentWS, float3 inputVertexPosition, uint currentFrameIndex)
|
|
{
|
|
float displacement = 0.0;
|
|
#if VFX_FEATURE_MOTION_VECTORS
|
|
uint elementToVFXBaseIndex = index * 13;
|
|
uint previousFrameIndex = elementToVFXBufferPrevious.Load(elementToVFXBaseIndex++ << 2);
|
|
if (currentFrameIndex - previousFrameIndex == 1u) //if (dot(previousElementToVFX[0], 1) != 0)
|
|
{
|
|
float4x4 previousElementToVFX = (float4x4)0;
|
|
previousElementToVFX[3] = float4(0,0,0,1);
|
|
UNITY_UNROLL
|
|
for (int itIndexMatrixRow = 0; itIndexMatrixRow < 3; ++itIndexMatrixRow)
|
|
{
|
|
uint4 read = elementToVFXBufferPrevious.Load4((elementToVFXBaseIndex + itIndexMatrixRow * 4) << 2);
|
|
previousElementToVFX[itIndexMatrixRow] = asfloat(read);
|
|
}
|
|
float3 previousWS = TransformPreviousVFXPositionToWorld(mul(previousElementToVFX, float4(inputVertexPosition, 1.0f)).xyz);
|
|
displacement = length(currentWS - previousWS);
|
|
}
|
|
#endif
|
|
return displacement;
|
|
}
|
|
|
|
void BuildFragInputsFromVFXIntersection(AttributeData attributeData, out FragInputs output, out uint outCurrentFrameIndex)
|
|
{
|
|
uint index, instanceIndex, instanceActiveIndex;
|
|
GetVFXInstancingIndices(index, instanceIndex, instanceActiveIndex);
|
|
#if VFX_USE_GRAPH_VALUES
|
|
$splice(VFXLoadGraphValues)
|
|
#endif
|
|
|
|
InternalAttributesElement attributes;
|
|
ZERO_INITIALIZE(InternalAttributesElement, attributes);
|
|
$splice(VFXLoadAttribute)
|
|
$splice(VFXProcessBlocks)
|
|
|
|
float3 size3 = GetElementSizeRT(attributes
|
|
#if VFX_USE_GRAPH_VALUES
|
|
, graphValues
|
|
#endif
|
|
);
|
|
|
|
float3 rayDirection = WorldRayDirection();
|
|
output.positionSS = float4(0.0, 0.0, 0.0, 0.0);
|
|
output.positionRWS = WorldRayOrigin() + rayDirection * RayTCurrent();
|
|
output.texCoord0 = float4(attributeData.barycentrics,0,0);
|
|
output.texCoord1 = float4(attributeData.barycentrics,0,0);
|
|
output.texCoord2 = float4(attributeData.barycentrics,0,0);
|
|
output.texCoord3 = float4(attributeData.barycentrics,0,0);
|
|
|
|
output.color = float4(attributes.color, attributes.alpha);
|
|
|
|
// Compute the world space normal
|
|
float3 normalWS = normalize(-WorldToPrimitive(attributes, size3)[2].xyz);
|
|
float3 tangentWS = normalize(WorldToPrimitive(attributes, size3)[0].xyz);
|
|
output.tangentToWorld = CreateTangentToWorld(normalWS, tangentWS, /*sign(currentVertex.tangentOS.w)*/1);
|
|
|
|
output.isFrontFace = dot(rayDirection, output.tangentToWorld[2]) < 0.0f;
|
|
|
|
$splice(VFXSetFragInputsRT)
|
|
|
|
#if VFX_FEATURE_MOTION_VECTORS
|
|
$splice(VFXLoadCurrentFrameIndexParameter)
|
|
outCurrentFrameIndex = currentFrameIndex;
|
|
#endif
|
|
}
|
|
|
|
#endif
|