#if !(defined(VFX_VARYING_PS_INPUTS) && defined(VFX_VARYING_POSCS)) #error VFX_VARYING_PS_INPUTS and VFX_VARYING_POSCS must be defined. #endif ${VFXPerPassInclude} ${VFXGeneratedBlockFunction} struct vs_input { VFX_DECLARE_INSTANCE_ID }; #pragma vertex vert float4 ClipOnNearPlane(float4 pos, float4 other) { if (pos.w >= _ProjectionParams.y || other.w < _ProjectionParams.y) return pos; // Project on near plane float ratio = (_ProjectionParams.y - pos.w) / (other.w - pos.w); return pos + (other - pos) * ratio; } VFX_VARYING_PS_INPUTS vert(uint id : SV_VertexID, vs_input i) { VFX_VARYING_PS_INPUTS o = (VFX_VARYING_PS_INPUTS)0; UNITY_SETUP_INSTANCE_ID(i); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); uint index = (id >> 2) + VFX_GET_INSTANCE_ID(i) * 2048; ${VFXInitInstancing} ${VFXLoadGraphValues} ${VFXLoadContextData} uint systemSeed = contextData.systemSeed; uint nbMax = contextData.maxParticleCount; ${VFXLoadAttributesOrCull} ${VFXProcessBlocks} if (!attributes.alive) return o; #if TARGET_FROM_ATTRIBUTES ${VFXLoadSize} float4x4 elementToVFX = GetElementToVFXMatrix( attributes.axisX, attributes.axisY, attributes.axisZ, float3(attributes.angleX,attributes.angleY,attributes.angleZ), float3(attributes.pivotX,attributes.pivotY,attributes.pivotZ), size3, attributes.position); attributes.position = mul(elementToVFX,float4(0,0,0,1)).xyz; ${VFXLoadParameter:{targetOffset}} attributes.targetPosition = mul(elementToVFX,float4(targetOffset,1)).xyz; #endif float4 pos0 = TransformPositionVFXToClip(attributes.position); float4 pos1 = TransformPositionVFXToClip(attributes.targetPosition); pos0 = ClipOnNearPlane(pos0, pos1); pos1 = ClipOnNearPlane(pos1, pos0); float2 ndcPos0 = pos0.xy / pos0.w; float2 ndcPos1 = pos1.xy / pos1.w; float2 dir = ndcPos0 - ndcPos1; float2 normal = normalize(dir.yx * float2(-1,abs(UNITY_MATRIX_P[1][1]) / UNITY_MATRIX_P[0][0])); #if IS_OPAQUE_PARTICLE const float thicknessMul = 1.0f; // pixel perfect #else const float thicknessMul = 2.0f; // for AA #endif normal *= thicknessMul / _ScreenParams.xy; float4 dPos0 = float4(normal * pos0.w, 0.0f, 0.0f); float4 dPos1 = float4(normal * pos1.w, 0.0f, 0.0f); float4 vPosArray[4] = { pos0 + dPos0, pos0 - dPos0, pos1 + dPos1, pos1 - dPos1}; #ifdef VFX_VARYING_PIXELOFFSET o.VFX_VARYING_PIXELOFFSET = (id & 1) ? -1.0f : 1.0f; #endif // If ever used we need the position in vfx space (we dont take into account the pixel offset) float3 vPos = ((id >> 1) & 1) ? attributes.targetPosition : attributes.position; o.VFX_VARYING_POSCS = vPosArray[id & 3]; ${VFXVertexComputeCurrentAndPreviousClipPos} ${VFXVertexCommonProcess} ${VFXVertexAdditionalProcess} return o; }