Untitled

 avatar
unknown
plain_text
2 months ago
21 kB
3
Indexable
// This is a copy of the source shader. Modifying this file will not affect the original shader.
#pragma kernel CSMain
#pragma only_renderers d3d11 glcore gles3 metal vulkan xboxone xboxone xboxseries playstation ps5 switch


#define NB_THREADS_PER_GROUP 64
#define HAS_VFX_ATTRIBUTES 1
#define VFX_PASSDEPTH_ACTUAL (0)
#define VFX_PASSDEPTH_MOTION_VECTOR (1)
#define VFX_PASSDEPTH_SELECTION (2)
#define VFX_PASSDEPTH_PICKING (3)
#define VFX_PASSDEPTH_SHADOW (4)
#define VFX_USE_POSITION_CURRENT 1
#define VFX_USE_SEED_CURRENT 1
#define VFX_USE_LIFETIME_CURRENT 1
#define VFX_USE_TEXINDEX_CURRENT 1
#define VFX_USE_ALIVE_CURRENT 1
#define VFX_USE_AXISX_CURRENT 1
#define VFX_USE_AXISY_CURRENT 1
#define VFX_USE_AXISZ_CURRENT 1
#define VFX_USE_ANGLEX_CURRENT 1
#define VFX_USE_ANGLEY_CURRENT 1
#define VFX_USE_ANGLEZ_CURRENT 1
#define VFX_USE_PIVOTX_CURRENT 1
#define VFX_USE_PIVOTY_CURRENT 1
#define VFX_USE_PIVOTZ_CURRENT 1
#define VFX_USE_SIZE_CURRENT 1
#define VFX_USE_SCALEX_CURRENT 1
#define VFX_USE_SCALEY_CURRENT 1
#define VFX_USE_SCALEZ_CURRENT 1
#define VFX_USE_ALPHA_CURRENT 1
#define VFX_USE_AGE_CURRENT 1
#define RAW_CAPACITY 4000u
#define HAVE_VFX_MODIFICATION 1
#define INDIRECT_BUFFER_COUNT 1
#define VFX_FEATURE_SORT 1
#define SORTING_SIGN 1
#define VFX_DISTANCE_SORT_KEY 1
#define VFX_FEATURE_FRUSTUM_CULL 1
#define VFX_WORLD_SPACE 1
#include_with_pragmas "Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXDefines.hlsl"
#define VFX_USE_GRAPH_VALUES 1
#define VFX_USE_INSTANCING 1
#define VFX_INSTANCING_FIXED_SIZE 4032
#define VFX_INSTANCING_ACTIVE_INDIRECTION 1
#define VFX_INSTANCING_BATCH_INDIRECTION 1



struct GraphValues
{
    bool _vfx_enabled_i;
    bool _vfx_enabled_j;
    float uniform_b;
    float uniform_c;
    bool _vfx_enabled_k;
    float3 Color_a;
    bool _vfx_enabled_l;
    float4 Size_a;
    float invSoftParticlesFadeDistance_a;
    float2 flipBookSize_a;
    float2 invFlipBookSize_a;
};
ByteAddressBuffer graphValuesBuffer;



Texture2D mainTexture;
SamplerState samplermainTexture;
float4 mainTexture_TexelSize;

struct VFXAttributes
{
    float3 position;
    uint seed;
    float lifetime;
    float texIndex;
    bool alive;
    float3 axisX;
    float3 axisY;
    float3 axisZ;
    float angleX;
    float angleY;
    float angleZ;
    float pivotX;
    float pivotY;
    float pivotZ;
    float size;
    float scaleX;
    float scaleY;
    float scaleZ;
    float alpha;
    float age;
};

struct VFXSourceAttributes
{
};




#if HAS_STRIPS
RWStructuredBuffer<uint> stripDataBuffer;
#endif

















// Strips tangent computation














ByteAddressBuffer attributeBuffer;

#if VFX_FEATURE_MOTION_VECTORS
RWByteAddressBuffer elementToVFXBuffer;
#endif

#if VFX_FEATURE_SORT
struct Kvp
{
	float sortKey;
	uint index;
};
#define IndirectOutputType Kvp
#else
#define IndirectOutputType uint
#endif

#if INDIRECT_BUFFER_COUNT > 0
RWStructuredBuffer<IndirectOutputType> outputBuffer0;
#endif
#if INDIRECT_BUFFER_COUNT > 1
RWStructuredBuffer<IndirectOutputType> outputBuffer1;
#endif
#if INDIRECT_BUFFER_COUNT > 2
RWStructuredBuffer<IndirectOutputType> outputBuffer2;
#endif
#if INDIRECT_BUFFER_COUNT > 3
RWStructuredBuffer<IndirectOutputType> outputBuffer3;
#endif
#if INDIRECT_BUFFER_COUNT > 4
#error Too many indirect buffers defined.
#endif

CBUFFER_START(updateParamsConst)
    uint dispatchWidth;
    
    float4 instancingConstants;
    
    float3 cameraXRSettings;
CBUFFER_END

#include "Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.hlsl"
#include "Packages/com.unity.visualeffectgraph/Shaders/VFXCommon.hlsl"



void Orient_4(inout float3 axisX, inout float3 axisY, inout float3 axisZ) /*mode:FaceCameraPlane axes:ZY */
{
    
    float3x3 viewRot = GetVFXToViewRotMatrix();
    axisX = viewRot[0].xyz;
    axisY = viewRot[1].xyz;
    axisZ = -viewRot[2].xyz;
    #if VFX_LOCAL_SPACE // Need to remove potential scale in local transform
    axisX = normalize(axisX);
    axisY = normalize(axisY);
    axisZ = normalize(axisZ);
    #endif
    
}
void SetAttribute_CA10063D(inout float texIndex, float TexIndex) /*attribute:texIndex Composition:Overwrite Source:Slot Random:Off channels:XYZ */
{
    texIndex = TexIndex;
}
void AttributeFromCurve_48A85FDC(inout float alpha, float age, float lifetime, float3 Color) /*attribute:color Composition:Overwrite AlphaComposition:Overwrite SampleMode:OverLife Mode:PerComponent ColorMode:Alpha channels:XYZ */
{
    float t = age / lifetime;
    float4 value = 0.0f;
    value = SampleGradient(Color, t);
    alpha = value.a;
}
void AttributeFromCurve_45ABB90F(inout float size, float age, float lifetime, float4 Size) /*attribute:size Composition:Overwrite AlphaComposition:Overwrite SampleMode:OverLife Mode:PerComponent ColorMode:ColorAndAlpha channels:X */
{
    float t = age / lifetime;
    float value = 0.0f;
    value = SampleCurve(Size, t);
    size = value;
}



#if VFX_FEATURE_FRUSTUM_CULL || VFX_FEATURE_LOD
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/GeometricTools.hlsl"

bool IsSphereOutsideFrustum(float3 pos, float radius, float4 frustumPlanes[6])
{
    bool outside = false;
    [unroll]
    for (int i = 0; i < 6; ++i)
        outside = outside || DistanceFromPlane(pos, frustumPlanes[i]) < -radius;
    return outside;
}
#endif

#if HAS_STRIPS

float3 GetParticlePosition(uint index, uint instanceIndex)
{
	VFXAttributes attributes = (VFXAttributes)0;
	attributes.position = asfloat(attributeBuffer.Load3(((instanceIndex * 0xEC40) + (index * 0x8 + 0x0)) << 2));
	

	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)
			prevTangent = tangent * rsqrt(sqrLength);
	}

	float3 nextTangent = (float3)0.0f;
	if (relativeIndex < stripData.nextIndex - 1)
	{
		uint nextIndex = GetParticleIndex(relativeIndex + 1,stripData);
		float3 tangent = GetParticlePosition(nextIndex, instanceIndex) - currentPos;
		float sqrLength = dot(tangent, tangent);
		if (sqrLength > VFX_EPSILON)
			nextTangent = tangent * rsqrt(sqrLength);
	}

	return normalize(prevTangent + nextTangent);
}

#endif


void AppendOutputBuffer(RWStructuredBuffer<IndirectOutputType> outputBuffer, IndirectOutputType output, uint instanceActiveIndex)
{
    uint indirectIndex;
#if VFX_FEATURE_SORT
    InterlockedAdd(outputBuffer[instanceActiveIndex].index, 1, indirectIndex);
#else
    InterlockedAdd(outputBuffer[instanceActiveIndex], 1, indirectIndex);
#endif
    indirectIndex += instancingBatchSize + instanceActiveIndex * RAW_CAPACITY;
    outputBuffer[indirectIndex] = output;
}


[numthreads(NB_THREADS_PER_GROUP,1,1)]
void CSMain(uint3 groupId		: SV_GroupID,
			uint3 groupThreadId	: SV_GroupThreadID)
{
	uint id = GetThreadId(groupId, groupThreadId, dispatchWidth);

    
    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
    
    

    ContextData contextData = instancingContextData[instanceActiveIndex];
    uint systemSeed = contextData.systemSeed;
    uint nbMax = contextData.maxParticleCount;

	if (index < nbMax)
	{
        GraphValues graphValues;
        
        graphValues.Size_a = asfloat(graphValuesBuffer.Load4(instanceActiveIndex * 160  + 0));
        graphValues.Color_a = asfloat(graphValuesBuffer.Load3(instanceActiveIndex * 160  + 64));
        graphValues.flipBookSize_a = asfloat(graphValuesBuffer.Load2(instanceActiveIndex * 160  + 80));
        graphValues.invFlipBookSize_a = asfloat(graphValuesBuffer.Load2(instanceActiveIndex * 160  + 88));
        graphValues._vfx_enabled_i = (bool)graphValuesBuffer.Load(instanceActiveIndex * 160  + 128);
        graphValues._vfx_enabled_j = (bool)graphValuesBuffer.Load(instanceActiveIndex * 160  + 132);
        graphValues.uniform_b = asfloat(graphValuesBuffer.Load(instanceActiveIndex * 160  + 136));
        graphValues.uniform_c = asfloat(graphValuesBuffer.Load(instanceActiveIndex * 160  + 140));
        graphValues._vfx_enabled_k = (bool)graphValuesBuffer.Load(instanceActiveIndex * 160  + 144);
        graphValues._vfx_enabled_l = (bool)graphValuesBuffer.Load(instanceActiveIndex * 160  + 148);
        graphValues.invSoftParticlesFadeDistance_a = asfloat(graphValuesBuffer.Load(instanceActiveIndex * 160  + 152));
        


#if VFX_LOCAL_SPACE
        
        vfxLocalToWorld = localToWorld;

        
        vfxWorldToLocal = worldToLocal;
#else
        vfxWorldToLocal = k_identity4x4;
        vfxLocalToWorld = k_identity4x4;
#endif

		VFXAttributes attributes = (VFXAttributes)0;
		VFXSourceAttributes sourceAttributes = (VFXSourceAttributes)0;
		attributes.alive = (attributeBuffer.Load(((instanceIndex * 0xEC40) + (index * 0x8 + 0x3)) << 2));
		

		if (attributes.alive)
		{
			attributes.position = asfloat(attributeBuffer.Load3(((instanceIndex * 0xEC40) + (index * 0x8 + 0x0)) << 2));
			attributes.seed = (attributeBuffer.Load(((instanceIndex * 0xEC40) + (index * 0x1 + 0xBD00)) << 2));
			attributes.lifetime = asfloat(attributeBuffer.Load(((instanceIndex * 0xEC40) + (index * 0x1 + 0xCCC0)) << 2));
			attributes.texIndex = asfloat(attributeBuffer.Load(((instanceIndex * 0xEC40) + (index * 0x1 + 0xDC80)) << 2));
			attributes.axisX = float3(1, 0, 0);
			attributes.axisY = float3(0, 1, 0);
			attributes.axisZ = float3(0, 0, 1);
			attributes.angleX = (float)0;
			attributes.angleY = (float)0;
			attributes.angleZ = (float)0;
			attributes.pivotX = (float)0;
			attributes.pivotY = (float)0;
			attributes.pivotZ = (float)0;
			attributes.size = (float)0.100000001;
			attributes.scaleX = (float)1;
			attributes.scaleY = (float)1;
			attributes.scaleZ = (float)1;
			attributes.alpha = (float)1;
			attributes.age = asfloat(attributeBuffer.Load(((instanceIndex * 0xEC40) + (index * 0x8 + 0x4)) << 2));
			

#if HAS_STRIPS
            const StripData stripData = GetStripDataFromParticleIndex(index, instanceIndex);
            InitStripAttributes(index, attributes, stripData);
            uint relativeIndexInStrip = GetRelativeIndex(index, stripData);
#endif
			if (graphValues._vfx_enabled_i)
			{
			    Orient_4( /*inout */attributes.axisX,  /*inout */attributes.axisY,  /*inout */attributes.axisZ);
			}
			if (graphValues._vfx_enabled_j)
			{
			    float tmp_bl = Rand(attributes.seed);
			    float tmp_bm = tmp_bl * graphValues.uniform_c;
			    float tmp_bn = graphValues.uniform_b + tmp_bm;
			    SetAttribute_CA10063D( /*inout */attributes.texIndex, tmp_bn);
			}
			if (graphValues._vfx_enabled_k)
			{
			    AttributeFromCurve_48A85FDC( /*inout */attributes.alpha, attributes.age, attributes.lifetime, graphValues.Color_a);
			}
			if (graphValues._vfx_enabled_l)
			{
			    AttributeFromCurve_45ABB90F( /*inout */attributes.size, attributes.age, attributes.lifetime, graphValues.Size_a);
			}
			


            // Recheck alive as blocks can set it to false for manual culling.
            // Test will be stripped if it's not the case anyway.
            if (attributes.alive)
            {
                
                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
                
#if HAS_STRIPS
                // Add an epsilon so that size is never 0 for strips
                size3.x += size3.x < 0.0f ? -VFX_EPSILON : VFX_EPSILON;
                size3.y += size3.y < 0.0f ? -VFX_EPSILON : VFX_EPSILON;
                size3.z += size3.z < 0.0f ? -VFX_EPSILON : VFX_EPSILON;

#endif
                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);

#if VFX_FEATURE_FRUSTUM_CULL || VFX_FEATURE_LOD
#if VFX_WORLD_SPACE
	            float4x4 elementToWorld = elementToVFX;
                elementToWorld._m03_m13_m23 = GetCameraRelativePositionWS(elementToWorld._m03_m13_m23);
#else
                float4x4 elementToWorld = mul(GetObjectToWorldMatrix(),elementToVFX);
#endif

	            float xAxisSqrLength = dot(elementToWorld._m00_m10_m20, elementToWorld._m00_m10_m20);
	            float yAxisSqrLength = dot(elementToWorld._m01_m11_m21, elementToWorld._m01_m11_m21);
	            float zAxisSqrLength = dot(elementToWorld._m02_m12_m22, elementToWorld._m02_m12_m22);
                float radius = 0.5f * sqrt(xAxisSqrLength + yAxisSqrLength + zAxisSqrLength);

                float radiusScale = (float)0;
                {
                    
                    radiusScale = (float)1;
                }
                

                radius *= radiusScale;

#if VFX_FEATURE_FRUSTUM_CULL
                if (IsSphereOutsideFrustum(elementToWorld._m03_m13_m23, radius, _FrustumPlanes))
                    return;
#endif
#endif

#if INDIRECT_BUFFER_COUNT > 0
#if VFX_FEATURE_LOD
                uint outputIndex = ~0u;
#if !VFX_FEATURE_FRUSTUM_CULL
                // If particle is out of frustum and frustum culling is disabled, use the lowest LOD
                // This is useful for shadow passes for instance to avoid out of frustum particles to be culled from shadows
                if (IsSphereOutsideFrustum(elementToWorld._m03_m13_m23, radius, _FrustumPlanes))
                    outputIndex = INDIRECT_BUFFER_COUNT - 1;
                else
#endif
                {
                    float viewZ = mul(GetWorldToViewMatrix(), float4(elementToWorld._m03_m13_m23, 1)).z;
                    float4x4 centeredProjMatrix = GetViewToHClipMatrix();
                    centeredProjMatrix._13_14_23_24 = 0.0f; //Cancels the jittering and/or the eye offset when in VR
                    float4 clip = mul(centeredProjMatrix, float4(radius, radius, viewZ, 1));
                    float lodValue = max(abs(clip.x),abs(clip.y)) * rcp(max(VFX_EPSILON, clip.w));

                    

                    for (uint i = 0; i < INDIRECT_BUFFER_COUNT; ++i)
                        if (lodValue > lodValues[i])
                        {
                            outputIndex = i;
                            break;
                        }
                }
#elif INDIRECT_BUFFER_COUNT == 1
                uint outputIndex = 0;
#else
                uint outputIndex = attributes.meshIndex;
#endif
                if (outputIndex >= INDIRECT_BUFFER_COUNT)
                    return;


#if VFX_FEATURE_SORT

                Kvp output;
#if VFX_CUSTOM_SORT_KEY
                
                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
                attributes.age = asfloat(attributeBuffer.Load(((instanceIndex * 0xEC40) + (index * 0x8 + 0x4)) << 2));
                

                output.sortKey = attributes.age;

#endif //VFX_[CRITERION]_SORT_KEY
                output.index = index;
                output.sortKey *= SORTING_SIGN;

#else
                uint output = index;
#endif

                if (outputIndex == 0)
                {
                    AppendOutputBuffer(outputBuffer0, output, instanceActiveIndex);
                }
#if INDIRECT_BUFFER_COUNT > 1
                else if (outputIndex == 1)
                {
                    AppendOutputBuffer(outputBuffer1, output, instanceActiveIndex);
                }
#if INDIRECT_BUFFER_COUNT > 2
                else if (outputIndex == 2)
                {
                    AppendOutputBuffer(outputBuffer2, output, instanceActiveIndex);
                }
#if INDIRECT_BUFFER_COUNT > 3
                else if (outputIndex == 3)
                {
                    AppendOutputBuffer(outputBuffer3, output, instanceActiveIndex);
                }
#endif
#endif
#endif
#endif

#if VFX_FEATURE_MOTION_VECTORS
                uint offsetedIndex = (RAW_CAPACITY * instanceIndex) + index;
#ifdef VFX_FEATURE_MOTION_VECTORS_VERTS
                uint viewTotal = asuint(cameraXRSettings.x);
                uint viewCount = asuint(cameraXRSettings.y);
                uint viewOffset = asuint(cameraXRSettings.z);
                uint elementToVFXIndex = offsetedIndex * (VFX_FEATURE_MOTION_VECTORS_VERTS * 2 * viewTotal + 1);
#else
                uint elementToVFXIndex = offsetedIndex * 13;
#endif
                
                elementToVFXBuffer.Store(elementToVFXIndex++ << 2, attributes.alive ? asuint(currentFrameIndex) : 0u);
#ifdef VFX_FEATURE_MOTION_VECTORS_VERTS
                elementToVFXIndex += viewOffset * viewCount * VFX_FEATURE_MOTION_VECTORS_VERTS * 2;
                
                
#ifdef USING_STEREO_MATRICES
                if (viewCount == 2)
                {
                    float4 stereoOffset = float4(GetWorldStereoOffset(), 0.0f);
                    UNITY_UNROLL
                    for (int itIndexVert = 0; itIndexVert < VFX_FEATURE_MOTION_VECTORS_VERTS; ++itIndexVert)
                    {
                        float4 vertPosWorld = float4(TransformPositionVFXToWorld(verts[itIndexVert]), 1.0f);
                        vertPosWorld.xyz = VFXTransformPositionWorldToCameraRelative(vertPosWorld.xyz);
                        float4 vertPosA = mul(_XRNonJitteredViewProjMatrix[0], vertPosWorld);
                        float4 vertPosB = mul(_XRNonJitteredViewProjMatrix[1], vertPosWorld + stereoOffset);
                        elementToVFXBuffer.Store4(elementToVFXIndex << 2, asuint(float4(vertPosA.xy / vertPosA.w, vertPosB.xy / vertPosB.w)));
                        elementToVFXIndex += 4; // 1 vert * 2 floats * 2 views
                    }
                }
                else
#endif
                {
                    UNITY_UNROLL
                    for (int itIndexVert = 0; itIndexVert < VFX_FEATURE_MOTION_VECTORS_VERTS - 1; itIndexVert += 2)
                    {
                        float4 vertPosA = TransformPositionVFXToNonJitteredClip(verts[itIndexVert]);
                        float4 vertPosB = TransformPositionVFXToNonJitteredClip(verts[itIndexVert + 1]);
                        elementToVFXBuffer.Store4(elementToVFXIndex << 2, asuint(float4(vertPosA.xy / vertPosA.w, vertPosB.xy / vertPosB.w)));
                        elementToVFXIndex += 4; // 2 verts * 2 floats
                    }
                    if (VFX_FEATURE_MOTION_VECTORS_VERTS % 2 == 1)
                    {
                        int itIndexVert = VFX_FEATURE_MOTION_VECTORS_VERTS - 1;
                        float4 vertPos = TransformPositionVFXToNonJitteredClip(verts[itIndexVert]);
                        elementToVFXBuffer.Store2(elementToVFXIndex << 2, asuint(vertPos.xy / vertPos.w));
                        elementToVFXIndex += 2; // 1 verts * 2 floats
                    }
               }
#else
                UNITY_UNROLL
                for (int itIndexMatrixRow = 0; itIndexMatrixRow < 3; ++itIndexMatrixRow)
                {
                    float4 value = elementToVFX[itIndexMatrixRow] * attributes.alive;
                    elementToVFXBuffer.Store4(elementToVFXIndex << 2, asuint(value));
                    elementToVFXIndex += 4; // 1 row * 4 floats
                }
#endif
#endif
            }
		}
	}
}
Leave a Comment