${VFXBegin:VFXVertexCommonProcess} #if VFX_USE_COLOR_CURRENT && defined(VFX_VARYING_COLOR) o.VFX_VARYING_COLOR = attributes.color; #endif #if VFX_USE_ALPHA_CURRENT && defined(VFX_VARYING_ALPHA) o.VFX_VARYING_ALPHA = attributes.alpha; #endif #ifdef VFX_VARYING_EXPOSUREWEIGHT ${VFXLoadParameter:{exposureWeight}} o.VFX_VARYING_EXPOSUREWEIGHT = exposureWeight; #endif #if USE_SOFT_PARTICLE && defined(VFX_VARYING_INVSOFTPARTICLEFADEDISTANCE) ${VFXLoadParameter:{invSoftParticlesFadeDistance}} o.VFX_VARYING_INVSOFTPARTICLEFADEDISTANCE = invSoftParticlesFadeDistance; #endif #if (USE_ALPHA_TEST || VFX_FEATURE_MOTION_VECTORS_FORWARD) && (!VFX_SHADERGRAPH || !HAS_SHADERGRAPH_PARAM_ALPHACLIPTHRESHOLD) && defined(VFX_VARYING_ALPHATHRESHOLD) ${VFXLoadParameter:{alphaThreshold}} o.VFX_VARYING_ALPHATHRESHOLD = alphaThreshold; #endif #if USE_UV_SCALE_BIAS ${VFXLoadParameter:{uvScale}} ${VFXLoadParameter:{uvBias}} #if defined (VFX_VARYING_UV) o.VFX_VARYING_UV.xy = o.VFX_VARYING_UV.xy * uvScale + uvBias; #endif #endif #ifdef VFX_VARYING_ANGLEFADE ${VFXLoadParameter:{angleFade}} o.VFX_VARYING_ANGLEFADE = angleFade; #endif #ifdef VFX_VARYING_FADEFACTOR ${VFXLoadParameter:{fadeFactor}} o.VFX_VARYING_FADEFACTOR = fadeFactor; #endif #ifdef VFX_VARYING_DECALLAYER ${VFXLoadParameter:{decalLayerMask}} o.VFX_VARYING_DECALLAYER = decalLayerMask; #endif #if defined(VFX_VARYING_POSWS) o.VFX_VARYING_POSWS = TransformPositionVFXToWorld(vPos); #endif #if VFX_USE_INSTANCING #ifdef UNITY_INSTANCING_ENABLED o.VFX_VARYINGS_INSTANCE_CURRENT_INDEX = unity_InstanceID; #endif o.VFX_VARYINGS_INSTANCE_ACTIVE_INDEX = instanceActiveIndex; #endif ${VFXEnd} ${VFXBegin:VFXGetRTScalingFactor} float3 rtScale = float3(1,1,1); #if VFX_USE_RT_CUSTOM_SCALE ${VFXLoadParameter:{rayTracedScaling}} rtScale = float3(rayTracedScaling, 1.0f); #else #ifdef VFX_RT_DEFAULT_SCALE rtScale = VFX_RT_DEFAULT_SCALE; #endif #endif ${VFXEnd} ${VFXBegin:VFXLoadSize} float3 size3 = float3(attributes.size,attributes.size,attributes.size); #if VFX_USE_SCALEX_CURRENT size3.x *= attributes.scaleX; #endif #if VFX_USE_SCALEY_CURRENT size3.y *= attributes.scaleY; #endif #if VFX_USE_SCALEZ_CURRENT size3.z *= attributes.scaleZ; #endif ${VFXEnd} ${VFXBegin:VFXLoadSizeRT} float3 size3 = float3(attributes.size,attributes.size,attributes.size); ${VFXGetRTScalingFactor} size3 *= rtScale; #if VFX_USE_SCALEX_CURRENT size3.x *= attributes.scaleX; #endif #if VFX_USE_SCALEY_CURRENT size3.y *= attributes.scaleY; #endif #if VFX_USE_SCALEZ_CURRENT size3.z *= attributes.scaleZ; #endif ${VFXEnd} ${VFXBegin:VFXVertexSetFlipbooksInterpolants} #if USE_FLIPBOOK && defined(VFX_VARYING_UV) #if USE_FLIPBOOK_ARRAY_LAYOUT ${VFXLoadParameter:{flipBookSize}} #if USE_FLIPBOOK_INTERPOLATION VFXUVData uvData = GetUVData(flipBookSize, o.VFX_VARYING_UV.xy, attributes.texIndex, attributes.texIndexBlend); #else VFXUVData uvData = GetUVData(flipBookSize, o.VFX_VARYING_UV.xy, attributes.texIndex); #endif o.VFX_VARYING_UV.xyz = uvData.uvs.xyz; #if USE_FLIPBOOK_INTERPOLATION && defined(VFX_VARYING_UV) && defined (VFX_VARYING_FRAMEBLEND) o.VFX_VARYING_UV.w = uvData.uvs.w; o.VFX_VARYING_FRAMEBLEND = uvData.blend; #if USE_FLIPBOOK_MOTIONVECTORS && defined(VFX_VARYING_MOTIONVECTORSCALE) ${VFXLoadParameter:{motionVectorScale}} o.VFX_VARYING_MOTIONVECTORSCALE = motionVectorScale; #endif #endif #else ${VFXLoadParameter:{invFlipBookSize}} ${VFXLoadParameter:{flipBookSize}} #if USE_FLIPBOOK_INTERPOLATION VFXUVData uvData = GetUVData(flipBookSize, invFlipBookSize, o.VFX_VARYING_UV.xy, attributes.texIndex, attributes.texIndexBlend); #else VFXUVData uvData = GetUVData(flipBookSize, invFlipBookSize, o.VFX_VARYING_UV.xy, attributes.texIndex); #endif o.VFX_VARYING_UV.xy = uvData.uvs.xy; #if USE_FLIPBOOK_INTERPOLATION && defined(VFX_VARYING_UV) && defined (VFX_VARYING_FRAMEBLEND) o.VFX_VARYING_UV.zw = uvData.uvs.zw; o.VFX_VARYING_FRAMEBLEND = uvData.blend; #if USE_FLIPBOOK_MOTIONVECTORS && defined(VFX_VARYING_MOTIONVECTORSCALE) ${VFXLoadParameter:{motionVectorScale}} o.VFX_VARYING_MOTIONVECTORSCALE = motionVectorScale * invFlipBookSize; #endif #endif #endif #endif ${VFXEnd} ${VFXBegin:VFXLoadAttributesOrCull} #if HAS_STRIPS && !VFX_HAS_INDIRECT_DRAW // We render one particle less for each strip in this case nbMax -= STRIP_COUNT; #endif uint deadCount = 0; #if USE_DEAD_LIST_COUNT deadCount = deadList[instanceIndex]; #endif #if VFX_USE_INSTANCING if (index >= nbMax - deadCount) #else if (index >= asuint(nbMax) - deadCount) #endif { CULL_VERTEX(o); } VFXAttributes attributes = (VFXAttributes)0; VFXSourceAttributes sourceAttributes = (VFXSourceAttributes)0; #if VFX_HAS_INDIRECT_DRAW if (index >= indirectBuffer[instanceActiveIndex]) { CULL_VERTEX(o); } index = indirectBuffer[VFXGetIndirectBufferIndex(index, instanceActiveIndex)]; #endif #if HAS_STRIPS_DATA StripData stripData; uint relativeIndexInStrip = 0; uint primitiveID = 0; #if HAS_STRIPS primitiveID = id; #endif if (!FindIndexInStrip(index, primitiveID, instanceIndex, relativeIndexInStrip, stripData)) { CULL_VERTEX(o); } #endif ${VFXLoadAttributes} #if !VFX_HAS_INDIRECT_DRAW && !HAS_STRIPS if (!attributes.alive) { CULL_VERTEX(o); } #endif // Initialize built-in needed attributes #if HAS_STRIPS_DATA InitStripAttributes(index, attributes, stripData); #endif ${VFXEnd} ${VFXBegin:VFXVertexComputeCurrentAndPreviousClipPos} #if VFX_FEATURE_MOTION_VECTORS && defined(VFX_VARYING_VELOCITY_CPOS_PREVIOUS) && defined(VFX_VARYING_VELOCITY_CPOS) #ifdef VFX_FEATURE_MOTION_VECTORS_VERTS o.VFX_VARYING_VELOCITY_CPOS_PREVIOUS = o.VFX_VARYING_VELOCITY_CPOS = (float2)0.0f; #else o.VFX_VARYING_VELOCITY_CPOS_PREVIOUS = o.VFX_VARYING_VELOCITY_CPOS = float4(0.0f, 0.0f, 0.0f, 1.0f); #endif ${VFXLoadParameter:{currentFrameIndex}} uint elementToVFXBaseIndex; if (TryGetElementToVFXBaseIndex(index, instanceIndex, elementToVFXBaseIndex, currentFrameIndex)) { float4 cPos = TransformPositionVFXToNonJitteredClip(vPos); #ifdef VFX_FEATURE_MOTION_VECTORS_VERTS o.VFX_VARYING_VELOCITY_CPOS_PREVIOUS = VFXGetPreviousClipPosition(elementToVFXBaseIndex, id).xy; o.VFX_VARYING_VELOCITY_CPOS = cPos.xy / cPos.w; #else float4x4 previousElementToVFX = VFXGetPreviousElementToVFX(elementToVFXBaseIndex); float3 oldvPos = mul(previousElementToVFX, float4(inputVertexPosition, 1.0f)).xyz; o.VFX_VARYING_VELOCITY_CPOS_PREVIOUS = TransformPositionVFXToPreviousClip(oldvPos); o.VFX_VARYING_VELOCITY_CPOS = cPos; #endif } #endif ${VFXEnd} ${VFXBegin:VFXVertexComputeDisplacement} float displacement = 0.0; #if VFX_FEATURE_MOTION_VECTORS uint elementToVFXBaseIndex; float3 previousWS; ${VFXLoadParameter:{currentFrameIndex}} if (TryGetElementToVFXBaseIndex(index, instanceIndex, elementToVFXBaseIndex, currentFrameIndex)) { float4x4 previousElementToVFX = VFXGetPreviousElementToVFX(elementToVFXBaseIndex); previousWS = TransformPreviousVFXPositionToWorld(mul(previousElementToVFX, float4(inputVertexPosition, 1.0f)).xyz); displacement = length(currentWS - previousWS); } #endif ${VFXEnd} ${VFXBegin:VFXComputeOutputMotionVector} //No w division with fast path of motion vectors #ifdef VFX_FEATURE_MOTION_VECTORS_VERTS float2 velocity = i.VFX_VARYING_VELOCITY_CPOS - i.VFX_VARYING_VELOCITY_CPOS_PREVIOUS; #else float2 velocity = (i.VFX_VARYING_VELOCITY_CPOS.xy/i.VFX_VARYING_VELOCITY_CPOS.w) - (i.VFX_VARYING_VELOCITY_CPOS_PREVIOUS.xy/i.VFX_VARYING_VELOCITY_CPOS_PREVIOUS.w); #endif #if UNITY_UV_STARTS_AT_TOP velocity.y = -velocity.y; #endif float4 encodedMotionVector = 0.0f; VFXEncodeMotionVector(velocity * 0.5f, encodedMotionVector); ${VFXEnd} ${VFXBegin:VFXApplyColor} float4 color = VFXGetFragmentColor(i); #ifndef VFX_TEXTURE_COLOR #define VFX_TEXTURE_COLOR float4(1.0,1.0,1.0,1.0) #endif #if VFX_COLORMAPPING_DEFAULT o.color = color * VFX_TEXTURE_COLOR; #endif #if VFX_COLORMAPPING_GRADIENTMAPPED ${VFXLoadParameter:{gradient}} o.color = SampleGradient(gradient, VFX_TEXTURE_COLOR.a * color.a) * float4(color.rgb,1.0); #endif ${VFXEnd} ${VFXBegin:VFXDeclareGetStripTangent} // Strips tangent computation float3 GetParticlePosition(uint index, uint instanceIndex) { VFXAttributes attributes = (VFXAttributes)0; ${VFXLoadAttributes:{position}} return attributes.position; } float3 GetStripTangent(float3 currentPos, uint instanceIndex, uint relativeIndex, const StripData stripData) { float3 prevTangent = (float3)0.0f; if (relativeIndex > 0) { uint prevIndex = GetParticleIndex(relativeIndex - 1,stripData); float3 tangent = currentPos - GetParticlePosition(prevIndex,instanceIndex); float sqrLength = dot(tangent, tangent); if (sqrLength > VFX_EPSILON * VFX_EPSILON) prevTangent = tangent * rsqrt(sqrLength); } float3 nextTangent = (float3)0.0f; if (relativeIndex + 1 < stripData.nextIndex) { uint nextIndex = GetParticleIndex(relativeIndex + 1,stripData); float3 tangent = GetParticlePosition(nextIndex, instanceIndex) - currentPos; float sqrLength = dot(tangent, tangent); if (sqrLength > VFX_EPSILON * VFX_EPSILON) nextTangent = tangent * rsqrt(sqrLength); } return normalize(prevTangent + nextTangent); } ${VFXEnd} ${VFXBegin:VFXInitInstancing} uint instanceIndex, instanceActiveIndex, instanceCurrentIndex; index = VFXInitInstancing(index, instanceIndex, instanceActiveIndex, instanceCurrentIndex); ${VFXEnd} ${VFXBegin:VFXInitInstancingCompute} uint instanceIndex, instanceActiveIndex, instanceCurrentIndex; #if defined(VFX_INSTANCING_FIXED_SIZE) uint index = GetThreadId(groupId, 0, dispatchWidth); index = VFXInitInstancing(index, instanceIndex, instanceActiveIndex, instanceCurrentIndex); index += groupThreadId.x; #else uint index = VFXInitInstancing(id, instanceIndex, instanceActiveIndex, instanceCurrentIndex); #endif ${VFXEnd} ${VFXBegin:VFXInstancingConstants} float4 instancingConstants; uint2 instancingBufferOffsets; ${VFXEnd} ${VFXBegin:VFXFeedSortingKeys} Kvp output; #if VFX_CUSTOM_SORT_KEY ${VFXLoadParameter:{sortKey}} output.sortKey = -1.0f * sortKey; //Lowest values are rendered first #elif VFX_DISTANCE_SORT_KEY #if VFX_LOCAL_SPACE float3 posRWS = TransformObjectToWorld(attributes.position); #else float3 posRWS = GetCameraRelativePositionWS(attributes.position); #endif float3 camToPos = posRWS - GetCurrentViewPosition(); output.sortKey = dot(camToPos,camToPos); // sqr distance to the camera #elif VFX_DEPTH_SORT_KEY #if VFX_LOCAL_SPACE float3 posRWS = TransformObjectToWorld(attributes.position); #else float3 posRWS = GetCameraRelativePositionWS(attributes.position); #endif float3 zAxisCam = -GetWorldToViewMatrix()[2].xyz; float depth = dot(posRWS, zAxisCam); output.sortKey = depth; #elif VFX_YOUNGEST_SORT_KEY ${VFXLoadAttributes:{age}} output.sortKey = attributes.age; #endif //VFX_[CRITERION]_SORT_KEY output.index = index; output.sortKey *= SORTING_SIGN; ${VFXEnd} ${VFXBegin:VFXGetIndexFromRTPrimitiveIndex} #ifdef VFX_RT_DECIMATION_FACTOR int rayTracingDecimationFactor = VFX_RT_DECIMATION_FACTOR; #else int rayTracingDecimationFactor = 1; #endif uint index = PrimitiveIndex() * rayTracingDecimationFactor; uint instanceIndex = asuint(_InstanceIndex); uint instanceActiveIndex = asuint(_InstanceActiveIndex); VFXGetInstanceCurrentIndex(index); ${VFXEnd} ${VFXBegin:VFXDeclareAppendOutputIndirectBuffer} void AppendOutputBuffer(RWStructuredBuffer outputBuffer, IndirectOutputType output, uint instanceActiveIndex, uint increment = 1) { uint indirectIndex; #if VFX_FEATURE_SORT InterlockedAdd(outputBuffer[instanceActiveIndex].index, increment, indirectIndex); #else InterlockedAdd(outputBuffer[instanceActiveIndex], increment, indirectIndex); #endif indirectIndex /= increment; indirectIndex += instancingBatchSize + instanceActiveIndex * RAW_CAPACITY; outputBuffer[indirectIndex] = output; } ${VFXEnd}