Untitled
unknown
plain_text
10 months ago
116 kB
4
Indexable
// This is a copy of the source shader. Modifying this file will not affect the original shader.
Shader "Hidden/VFX/SmokeTest/System/Output Particle Quad"
{
SubShader
{
Cull Off
Tags { "Queue"="Transparent+0" "IgnoreProjector"="True" "RenderType"="Transparent" }
// Strips tangent computation
Blend SrcAlpha OneMinusSrcAlpha
ZTest LEqual
ZWrite Off
Cull Off
HLSLINCLUDE
#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 VFX_USE_COLOR_CURRENT 1
#define RAW_CAPACITY 4000u
#define VFX_COLORMAPPING_DEFAULT 1
#define IS_TRANSPARENT_PARTICLE 1
#define USE_SOFT_PARTICLE 1
#define VFX_BLENDMODE_ALPHA 1
#define VFX_HAS_INDIRECT_DRAW 1
#define USE_FLIPBOOK 1
#define USE_DEAD_LIST_COUNT 1
#define VFX_PRIMITIVE_QUAD 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 4000
#pragma multi_compile_instancing
#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;
float3 color;
};
struct VFXSourceAttributes
{
};
#define VFX_NEEDS_COLOR_INTERPOLATOR (VFX_USE_COLOR_CURRENT || VFX_USE_ALPHA_CURRENT)
#if HAS_STRIPS
#define VFX_OPTIONAL_INTERPOLATION
#else
#define VFX_OPTIONAL_INTERPOLATION nointerpolation
#endif
#if VFX_USE_INSTANCING
#define VFX_VERTEX_OUTPUT_INSTANCE_INDEX nointerpolation uint2 instanceIndices : INDEX0; //instanceCurrentIndex, instanceActiveIndex
#define VFX_VARYINGS_INSTANCE_CURRENT_INDEX instanceIndices.x
#define VFX_VARYINGS_INSTANCE_ACTIVE_INDEX instanceIndices.y
#ifdef UNITY_INSTANCING_ENABLED
#define VFX_FRAG_SETUP_INSTANCE_ID(i) unity_InstanceID = i.VFX_VARYINGS_INSTANCE_CURRENT_INDEX
#else
#define VFX_FRAG_SETUP_INSTANCE_ID(i)
#endif
#else
#define VFX_VERTEX_OUTPUT_INSTANCE_INDEX
#endif
ByteAddressBuffer attributeBuffer;
#if VFX_HAS_INDIRECT_DRAW
StructuredBuffer<uint> indirectBuffer;
#endif
#if USE_DEAD_LIST_COUNT
StructuredBuffer<uint> deadListCount;
#endif
#if HAS_STRIPS
StructuredBuffer<uint> stripDataBuffer;
#endif
#if VFX_FEATURE_MOTION_VECTORS
ByteAddressBuffer elementToVFXBufferPrevious;
#if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)
#define VFX_DECLARE_MOTION_VECTORS_STORAGE(coordA, coordB)\
noperspective float4 cPosPreviousAndNonJiterred : TEXCOORD##coordA;
#define VFX_DECLARE_MOTION_VECTORS_VARYING_PREVIOUS cPosPreviousAndNonJiterred.xy
#define VFX_DECLARE_MOTION_VECTORS_VARYING_NONJITTER cPosPreviousAndNonJiterred.zw
#else
#define VFX_DECLARE_MOTION_VECTORS_STORAGE(coordA, coordB)\
float4 cPosPrevious : TEXCOORD##coordA;\
float4 cPosNonJiterred : TEXCOORD##coordB;
#define VFX_DECLARE_MOTION_VECTORS_VARYING_PREVIOUS cPosPrevious
#define VFX_DECLARE_MOTION_VECTORS_VARYING_NONJITTER cPosNonJiterred
#endif
#endif
CBUFFER_START(outputParamsConst)
float4 instancingConstants;
float3 cameraXRSettings;
CBUFFER_END
UNITY_INSTANCING_BUFFER_START(PerInstance)
UNITY_DEFINE_INSTANCED_PROP(float, _InstanceIndex)
UNITY_DEFINE_INSTANCED_PROP(float, _InstanceActiveIndex)
UNITY_INSTANCING_BUFFER_END(PerInstance)
// Helper macros to always use a valid instanceID
#if defined(UNITY_STEREO_INSTANCING_ENABLED)
#define VFX_DECLARE_INSTANCE_ID UNITY_VERTEX_INPUT_INSTANCE_ID
#define VFX_GET_INSTANCE_ID(i) unity_InstanceID
#else
#define VFX_DECLARE_INSTANCE_ID uint instanceID : SV_InstanceID;
#define VFX_GET_INSTANCE_ID(i) i.instanceID
#endif
ENDHLSL
Pass
{
Tags { "LightMode"="SceneSelectionPass" }
ZWrite On
Blend Off
HLSLPROGRAM
#define VFX_PASSDEPTH VFX_PASSDEPTH_SELECTION
#pragma target 4.5
#if SHADERGRAPH_NEEDS_NORMAL_DEPTHONLY || defined(WRITE_NORMAL_BUFFER) || FORCE_NORMAL_OUTPUT_UNLIT_VERTEX_SHADER
#define NEEDS_NORMAL 1
#endif
#if SHADERGRAPH_NEEDS_TANGENT_DEPTHONLY
#define NEEDS_TANGENT 1
#endif
struct ps_input
{
float4 pos : SV_POSITION;
#if USE_FLIPBOOK_INTERPOLATION
float4 uv : TEXCOORD0;
#else
#if USE_FLIPBOOK_ARRAY_LAYOUT
float3 uv : TEXCOORD0;
#else
float2 uv : TEXCOORD0;
#endif
#endif
#if USE_ALPHA_TEST || USE_FLIPBOOK_INTERPOLATION || VFX_USE_ALPHA_CURRENT
// x: alpha threshold
// y: frame blending factor
// z: alpha
VFX_OPTIONAL_INTERPOLATION float3 builtInInterpolants : TEXCOORD1;
#endif
#if USE_FLIPBOOK_MOTIONVECTORS
// x: motion vectors scale X
// y: motion vectors scale Y
VFX_OPTIONAL_INTERPOLATION float2 builtInInterpolants2 : TEXCOORD2;
#endif
#if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR
VFX_DECLARE_MOTION_VECTORS_STORAGE(3,4)
#endif
#if VFX_NEEDS_POSWS_INTERPOLATOR
float3 posWS : TEXCOORD5;
#endif
#if NEEDS_NORMAL
float3 normal : TEXCOORD6;
#endif
#if NEEDS_TANGENT
float4 tangent : TEXCOORD7;
#endif
UNITY_VERTEX_OUTPUT_STEREO
VFX_VERTEX_OUTPUT_INSTANCE_INDEX
};
#define VFX_VARYING_PS_INPUTS ps_input
#define VFX_VARYING_POSCS pos
#define VFX_VARYING_ALPHA builtInInterpolants.z
#define VFX_VARYING_ALPHATHRESHOLD builtInInterpolants.x
#define VFX_VARYING_FRAMEBLEND builtInInterpolants.y
#define VFX_VARYING_MOTIONVECTORSCALE builtInInterpolants2.xy
#define VFX_VARYING_UV uv
#if VFX_NEEDS_POSWS_INTERPOLATOR
#define VFX_VARYING_POSWS posWS
#endif
#if NEEDS_NORMAL
#define VFX_VARYING_NORMAL normal
#endif
#if NEEDS_TANGENT
#define VFX_VARYING_TANGENT tangent
#endif
#if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR
#define VFX_VARYING_VELOCITY_CPOS VFX_DECLARE_MOTION_VECTORS_VARYING_NONJITTER
#define VFX_VARYING_VELOCITY_CPOS_PREVIOUS VFX_DECLARE_MOTION_VECTORS_VARYING_PREVIOUS
#endif
#if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR
#define SHADERPASS SHADERPASS_MOTION_VECTORS
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_SHADOW
#define SHADERPASS SHADERPASS_SHADOWS
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_ACTUAL || VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION || VFX_PASSDEPTH == VFX_PASSDEPTH_PICKING
#if defined(WRITE_NORMAL_BUFFER)
#define SHADERPASS SHADERPASS_DEPTHNORMALSONLY
#else
#define SHADERPASS SHADERPASS_DEPTHONLY
#endif
#endif
#if !(defined(VFX_VARYING_PS_INPUTS) && defined(VFX_VARYING_POSCS))
#error VFX_VARYING_PS_INPUTS, VFX_VARYING_POSCS and VFX_VARYING_UV must be defined.
#endif
#include "Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.hlsl"
#include "Packages/com.unity.visualeffectgraph/Shaders/VFXCommon.hlsl"
#include "Packages/com.unity.visualeffectgraph/Shaders/VFXCommonOutput.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 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
struct vs_input
{
VFX_DECLARE_INSTANCE_ID
};
#if HAS_STRIPS
#define PARTICLE_IN_EDGE (id & 1)
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
#pragma vertex vert
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);
#if VFX_PRIMITIVE_TRIANGLE
uint index = id / 3;
#elif VFX_PRIMITIVE_QUAD
#if HAS_STRIPS
id += VFX_GET_INSTANCE_ID(i) * 8192;
const uint vertexPerStripCount = (PARTICLE_PER_STRIP_COUNT - 1) << 2;
uint index = id / vertexPerStripCount; // stripIndex. Needed by VFXInitInstancing
uint instanceIndex, instanceActiveIndex, instanceCurrentIndex;
index = VFXInitInstancing(index, instanceIndex, instanceActiveIndex, instanceCurrentIndex);
const StripData stripData = GetStripDataFromStripIndex(index, instanceIndex);
uint relativeIndexInStrip = ((id % vertexPerStripCount) >> 2) + (id & 1); // relative index of particle
uint maxEdgeIndex = relativeIndexInStrip - PARTICLE_IN_EDGE + 1;
if (maxEdgeIndex >= stripData.nextIndex)
return o;
index = GetParticleIndex(relativeIndexInStrip, stripData);
#else
uint index = (id >> 2) + VFX_GET_INSTANCE_ID(i) * 2048;
#endif
#elif VFX_PRIMITIVE_OCTAGON
uint index = (id >> 3) + VFX_GET_INSTANCE_ID(i) * 1024;
#endif
#if !HAS_STRIPS // With strips we need to derive the instance index prior to get the particle index
uint instanceIndex, instanceActiveIndex, instanceCurrentIndex;
index = VFXInitInstancing(index, instanceIndex, instanceActiveIndex, instanceCurrentIndex);
#endif
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));
ContextData contextData = instancingContextData[instanceActiveIndex];
uint systemSeed = contextData.systemSeed;
uint nbMax = contextData.maxParticleCount;
uint deadCount = 0;
#if USE_DEAD_LIST_COUNT
deadCount = deadListCount[instanceIndex];
#endif
#if VFX_USE_INSTANCING
if (index >= nbMax - deadCount)
#else
if (index >= asuint(nbMax) - deadCount)
#endif
{
#if USE_GEOMETRY_SHADER
return; // cull
#else
o.pos.x = VFX_NAN;
return o; // cull
#endif
}
VFXAttributes attributes = (VFXAttributes)0;
VFXSourceAttributes sourceAttributes = (VFXSourceAttributes)0;
#if VFX_HAS_INDIRECT_DRAW
index = indirectBuffer[VFXGetIndirectBufferIndex(index, instanceActiveIndex)];
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.alive = (attributeBuffer.Load(((instanceIndex * 0xEC40) + (index * 0x8 + 0x3)) << 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));
attributes.color = float3(1, 1, 1);
#else
attributes.alive = (attributeBuffer.Load(((instanceIndex * 0xEC40) + (index * 0x8 + 0x3)) << 2));
#if !HAS_STRIPS
if (!attributes.alive)
{
o.pos.x = VFX_NAN;
return o; // cull
}
#endif
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));
attributes.color = float3(1, 1, 1);
#endif
// Initialize built-in needed attributes
#if HAS_STRIPS
InitStripAttributes(index, attributes, 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);
}
#if !HAS_STRIPS
if (!attributes.alive)
return o;
#endif
#if VFX_PRIMITIVE_QUAD
#if HAS_STRIPS
#if VFX_STRIPS_UV_STRECHED
o.VFX_VARYING_UV.x = (float)(relativeIndexInStrip) / (stripData.nextIndex - 1);
#elif VFX_STRIPS_UV_PER_SEGMENT
o.VFX_VARYING_UV.x = PARTICLE_IN_EDGE;
#else
o.VFX_VARYING_UV.x = texCoord;
#endif
o.VFX_VARYING_UV.y = (id & 2) * 0.5f;
const float2 vOffsets = float2(0.0f,o.VFX_VARYING_UV.y - 0.5f);
#if VFX_STRIPS_SWAP_UV
o.VFX_VARYING_UV.xy = float2(1.0f - o.VFX_VARYING_UV.y, o.VFX_VARYING_UV.x);
#endif
#else
o.VFX_VARYING_UV.x = float(id & 1);
o.VFX_VARYING_UV.y = (id & 2) * 0.5f;
const float2 vOffsets = o.VFX_VARYING_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];
o.VFX_VARYING_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),
};
cropFactor = id & 1 ? 1.0f - cropFactor : 1.0f;
const float2 vOffsets = kUvs[id & 7] * cropFactor;
o.VFX_VARYING_UV.xy = vOffsets + 0.5f;
#endif
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
size3 += size3 < 0.0f ? -VFX_EPSILON : VFX_EPSILON; // Add an epsilon so that size is never 0 for strips
#endif
const 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);
float3 inputVertexPosition = float3(vOffsets, 0.0f);
float3 vPos = mul(elementToVFX,float4(inputVertexPosition, 1.0f)).xyz;
o.VFX_VARYING_POSCS = TransformPositionVFXToClip(vPos);
float3 vPosWS = TransformPositionVFXToWorld(vPos);
#ifdef VFX_VARYING_POSWS
o.VFX_VARYING_POSWS = vPosWS;
#endif
#if VFX_NON_UNIFORM_SCALE
float3x3 elementToVFX_N = GetElementToVFXMatrixNormal(
attributes.axisX,
attributes.axisY,
attributes.axisZ,
float3(attributes.angleX,attributes.angleY,attributes.angleZ),
size3);
#else
float3x3 elementToVFX_N = (float3x3)elementToVFX;
#endif
float3 normalWS = normalize(TransformNormalVFXToWorld((-transpose(elementToVFX_N)[2])));
#ifdef VFX_VARYING_NORMAL
float normalFlip = (size3.x * size3.y * size3.z) < 0 ? -1 : 1;
o.VFX_VARYING_NORMAL = normalFlip * normalWS;
#endif
#ifdef VFX_VARYING_TANGENT
o.VFX_VARYING_TANGENT.xyz = normalize(TransformDirectionVFXToWorld(normalize(transpose(elementToVFX)[0].xyz)));
#endif
#ifdef VFX_VARYING_BENTFACTORS
#if HAS_STRIPS
#define BENT_FACTOR_MULTIPLIER 2.0f
#else
#define BENT_FACTOR_MULTIPLIER 1.41421353816986083984375f
#endif
o.VFX_VARYING_BENTFACTORS = vOffsets * normalBendingFactor * BENT_FACTOR_MULTIPLIER;
#endif
#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
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
#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
o.VFX_VARYING_EXPOSUREWEIGHT = exposureWeight;
#endif
#if USE_SOFT_PARTICLE && defined(VFX_VARYING_INVSOFTPARTICLEFADEDISTANCE)
float invSoftParticlesFadeDistance = (float)0;
{
invSoftParticlesFadeDistance = graphValues.invSoftParticlesFadeDistance_a;
}
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)
o.VFX_VARYING_ALPHATHRESHOLD = alphaThreshold;
#endif
#if USE_UV_SCALE_BIAS
#if defined (VFX_VARYING_UV)
o.VFX_VARYING_UV.xy = o.VFX_VARYING_UV.xy * uvScale + uvBias;
#endif
#endif
#ifdef VFX_VARYING_ANGLEFADE
o.VFX_VARYING_ANGLEFADE = angleFade;
#endif
#ifdef VFX_VARYING_FADEFACTOR
o.VFX_VARYING_FADEFACTOR = fadeFactor;
#endif
#ifdef VFX_VARYING_DECALLAYER
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
#if USE_FLIPBOOK && defined(VFX_VARYING_UV)
#if USE_FLIPBOOK_ARRAY_LAYOUT
float2 flipBookSize = (float2)0;
{
flipBookSize = graphValues.flipBookSize_a;
}
VFXUVData uvData = GetUVData(flipBookSize, o.VFX_VARYING_UV.xy, attributes.texIndex);
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)
o.VFX_VARYING_MOTIONVECTORSCALE = motionVectorScale;
#endif
#endif
#else
float2 invFlipBookSize = (float2)0;
{
invFlipBookSize = graphValues.invFlipBookSize_a;
}
float2 flipBookSize = (float2)0;
{
flipBookSize = graphValues.flipBookSize_a;
}
VFXUVData uvData = GetUVData(flipBookSize, invFlipBookSize, o.VFX_VARYING_UV.xy, attributes.texIndex);
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)
o.VFX_VARYING_MOTIONVECTORSCALE = motionVectorScale * invFlipBookSize;
#endif
#endif
#endif
#endif
#if VFX_PASSDEPTH == VFX_PASSDEPTH_SHADOW
float3 posWS = TransformPositionVFXToWorld(vPos);
VFXApplyShadowBias(o.VFX_VARYING_POSCS, posWS, normalWS);
#endif
return o;
}
#define VFX_SUPPORT_MAIN_TEXTURE_SAMPLING_IN_FRAGMENT_DEPTH 1
#ifndef VFX_SUPPORT_MAIN_TEXTURE_SAMPLING_IN_FRAGMENT_DEPTH
#define VFX_SUPPORT_MAIN_TEXTURE_SAMPLING_IN_FRAGMENT_DEPTH 0
#endif
#ifdef VFX_SHADERGRAPH
#if (SHADERPASS == SHADERPASS_DEPTHNORMALSONLY)
#else
#endif
#endif
#if VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION
int _ObjectId;
int _PassValue;
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_PICKING
float4 _SelectionID;
#endif
#pragma fragment frag
void frag(ps_input i
#if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR
#ifdef WRITE_MSAA_DEPTH
// We need the depth color as SV_Target0 for alpha to coverage
, out float4 outDepthColor : SV_Target0
, out float4 outMotionVector : SV_Target1
#else
// When no MSAA, the motion vector is always the first buffer
, out float4 outMotionVector : SV_Target0
#endif
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_ACTUAL
#if defined(WRITE_MSAA_DEPTH)
#if defined(WRITE_NORMAL_BUFFER)
#error Unexpected depth setup mssa + depth normal
#endif
, out float4 outDepthColor : SV_Target0
#elif defined(WRITE_NORMAL_BUFFER)
, out float4 outNormalBuffer : SV_Target0
#else
, out float4 dummy : SV_Target0
#endif
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION || VFX_PASSDEPTH == VFX_PASSDEPTH_PICKING
, out float4 outSelection : SV_Target0
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_SHADOW
, out float4 dummy : SV_Target0
#endif
)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
VFXTransformPSInputs(i);
#ifdef VFX_VARYING_NORMAL
#if USE_DOUBLE_SIDED
const float faceMul = frontFace ? 1.0f : -1.0f;
#else
const float faceMul = 1.0f;
#endif
float3 normalWS = i.VFX_VARYING_NORMAL * faceMul;
const VFXUVData uvData = GetUVData(i);
#ifdef VFX_VARYING_TANGENT
float3 tangentWS = i.VFX_VARYING_TANGENT;
float3 bitangentWS = cross(i.VFX_VARYING_TANGENT,i.VFX_VARYING_NORMAL);
#if defined(VFX_VARYING_BENTFACTORS) && USE_NORMAL_BENDING
float3 bentFactors = float3(i.VFX_VARYING_BENTFACTORS.xy,sqrt(max(0.0f,1.0f - dot(i.VFX_VARYING_BENTFACTORS,i.VFX_VARYING_BENTFACTORS))));
normalWS = tangentWS * bentFactors.x + bitangentWS * bentFactors.y + normalWS * bentFactors.z;
tangentWS = normalize(cross(normalWS,bitangentWS));
bitangentWS = cross(tangentWS,normalWS);
tangentWS *= faceMul;
#endif
float3x3 tbn = float3x3(tangentWS,bitangentWS,normalWS);
#if USE_NORMAL_MAP
float3 n = SampleNormalMap(VFX_SAMPLER(normalMap),uvData);
float normalScale = 1.0f;
#ifdef VFX_VARYING_NORMALSCALE
normalScale = i.VFX_VARYING_NORMALSCALE;
#endif
normalWS = normalize(lerp(normalWS,mul(n,tbn),normalScale));
#endif
#endif
#endif
#ifdef VFX_SHADERGRAPH
#if (SHADERPASS == SHADERPASS_DEPTHNORMALSONLY)
#else
#endif
float alpha = OUTSG.;
#else
float alpha = VFXGetFragmentColor(i).a;
#if VFX_SUPPORT_MAIN_TEXTURE_SAMPLING_IN_FRAGMENT_DEPTH
#ifdef VFX_PROCEDURAL_UV
alpha *= VFXGetTextureColorWithProceduralUV(VFX_SAMPLER(mainTexture),i,VFX_PROCEDURAL_UV(i)).a;
#else
alpha *= VFXGetTextureColor(VFX_SAMPLER(mainTexture),i).a;
#endif
#endif
#endif
VFXClipFragmentColor(alpha,i);
#ifdef WRITE_MSAA_DEPTH
outDepthColor = i.VFX_VARYING_POSCS.z;
#if VFX_USE_ALPHA_TO_MASK
outDepthColor.a = alpha;
#endif
#endif
#ifdef WRITE_NORMAL_BUFFER
#ifdef VFX_VARYING_NORMAL
VFXComputePixelOutputToNormalBuffer(i, normalWS, GetUVData(i), outNormalBuffer);
#else
//Fallback for point and lines, render normal as if those are face camera plane
VFXComputePixelOutputToNormalBuffer(i, VFXGetWorldToViewRotMatrix()[2], GetUVData(i), outNormalBuffer);
#endif
#endif
#if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR
//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);
outMotionVector = encodedMotionVector;
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION
outSelection = float4(_ObjectId, _PassValue, 1.0, 1.0);
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_PICKING
outSelection = _SelectionID;
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_ACTUAL
#if !defined(WRITE_MSAA_DEPTH) && !defined(WRITE_NORMAL_BUFFER)
dummy = float4(i.VFX_VARYING_POSCS.z, 0,0,0);
#endif
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_SHADOW
dummy = (float4)0;
#else
#error VFX_PASSDEPTH undefined
#endif
}
ENDHLSL
}
Pass
{
Tags { "LightMode"="Picking" }
ZWrite On
Blend Off
HLSLPROGRAM
#define VFX_PASSDEPTH VFX_PASSDEPTH_PICKING
#pragma target 4.5
#if SHADERGRAPH_NEEDS_NORMAL_DEPTHONLY || defined(WRITE_NORMAL_BUFFER) || FORCE_NORMAL_OUTPUT_UNLIT_VERTEX_SHADER
#define NEEDS_NORMAL 1
#endif
#if SHADERGRAPH_NEEDS_TANGENT_DEPTHONLY
#define NEEDS_TANGENT 1
#endif
struct ps_input
{
float4 pos : SV_POSITION;
#if USE_FLIPBOOK_INTERPOLATION
float4 uv : TEXCOORD0;
#else
#if USE_FLIPBOOK_ARRAY_LAYOUT
float3 uv : TEXCOORD0;
#else
float2 uv : TEXCOORD0;
#endif
#endif
#if USE_ALPHA_TEST || USE_FLIPBOOK_INTERPOLATION || VFX_USE_ALPHA_CURRENT
// x: alpha threshold
// y: frame blending factor
// z: alpha
VFX_OPTIONAL_INTERPOLATION float3 builtInInterpolants : TEXCOORD1;
#endif
#if USE_FLIPBOOK_MOTIONVECTORS
// x: motion vectors scale X
// y: motion vectors scale Y
VFX_OPTIONAL_INTERPOLATION float2 builtInInterpolants2 : TEXCOORD2;
#endif
#if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR
VFX_DECLARE_MOTION_VECTORS_STORAGE(3,4)
#endif
#if VFX_NEEDS_POSWS_INTERPOLATOR
float3 posWS : TEXCOORD5;
#endif
#if NEEDS_NORMAL
float3 normal : TEXCOORD6;
#endif
#if NEEDS_TANGENT
float4 tangent : TEXCOORD7;
#endif
UNITY_VERTEX_OUTPUT_STEREO
VFX_VERTEX_OUTPUT_INSTANCE_INDEX
};
#define VFX_VARYING_PS_INPUTS ps_input
#define VFX_VARYING_POSCS pos
#define VFX_VARYING_ALPHA builtInInterpolants.z
#define VFX_VARYING_ALPHATHRESHOLD builtInInterpolants.x
#define VFX_VARYING_FRAMEBLEND builtInInterpolants.y
#define VFX_VARYING_MOTIONVECTORSCALE builtInInterpolants2.xy
#define VFX_VARYING_UV uv
#if VFX_NEEDS_POSWS_INTERPOLATOR
#define VFX_VARYING_POSWS posWS
#endif
#if NEEDS_NORMAL
#define VFX_VARYING_NORMAL normal
#endif
#if NEEDS_TANGENT
#define VFX_VARYING_TANGENT tangent
#endif
#if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR
#define VFX_VARYING_VELOCITY_CPOS VFX_DECLARE_MOTION_VECTORS_VARYING_NONJITTER
#define VFX_VARYING_VELOCITY_CPOS_PREVIOUS VFX_DECLARE_MOTION_VECTORS_VARYING_PREVIOUS
#endif
#if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR
#define SHADERPASS SHADERPASS_MOTION_VECTORS
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_SHADOW
#define SHADERPASS SHADERPASS_SHADOWS
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_ACTUAL || VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION || VFX_PASSDEPTH == VFX_PASSDEPTH_PICKING
#if defined(WRITE_NORMAL_BUFFER)
#define SHADERPASS SHADERPASS_DEPTHNORMALSONLY
#else
#define SHADERPASS SHADERPASS_DEPTHONLY
#endif
#endif
#if !(defined(VFX_VARYING_PS_INPUTS) && defined(VFX_VARYING_POSCS))
#error VFX_VARYING_PS_INPUTS, VFX_VARYING_POSCS and VFX_VARYING_UV must be defined.
#endif
#include "Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.hlsl"
#include "Packages/com.unity.visualeffectgraph/Shaders/VFXCommon.hlsl"
#include "Packages/com.unity.visualeffectgraph/Shaders/VFXCommonOutput.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 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
struct vs_input
{
VFX_DECLARE_INSTANCE_ID
};
#if HAS_STRIPS
#define PARTICLE_IN_EDGE (id & 1)
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
#pragma vertex vert
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);
#if VFX_PRIMITIVE_TRIANGLE
uint index = id / 3;
#elif VFX_PRIMITIVE_QUAD
#if HAS_STRIPS
id += VFX_GET_INSTANCE_ID(i) * 8192;
const uint vertexPerStripCount = (PARTICLE_PER_STRIP_COUNT - 1) << 2;
uint index = id / vertexPerStripCount; // stripIndex. Needed by VFXInitInstancing
uint instanceIndex, instanceActiveIndex, instanceCurrentIndex;
index = VFXInitInstancing(index, instanceIndex, instanceActiveIndex, instanceCurrentIndex);
const StripData stripData = GetStripDataFromStripIndex(index, instanceIndex);
uint relativeIndexInStrip = ((id % vertexPerStripCount) >> 2) + (id & 1); // relative index of particle
uint maxEdgeIndex = relativeIndexInStrip - PARTICLE_IN_EDGE + 1;
if (maxEdgeIndex >= stripData.nextIndex)
return o;
index = GetParticleIndex(relativeIndexInStrip, stripData);
#else
uint index = (id >> 2) + VFX_GET_INSTANCE_ID(i) * 2048;
#endif
#elif VFX_PRIMITIVE_OCTAGON
uint index = (id >> 3) + VFX_GET_INSTANCE_ID(i) * 1024;
#endif
#if !HAS_STRIPS // With strips we need to derive the instance index prior to get the particle index
uint instanceIndex, instanceActiveIndex, instanceCurrentIndex;
index = VFXInitInstancing(index, instanceIndex, instanceActiveIndex, instanceCurrentIndex);
#endif
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));
ContextData contextData = instancingContextData[instanceActiveIndex];
uint systemSeed = contextData.systemSeed;
uint nbMax = contextData.maxParticleCount;
uint deadCount = 0;
#if USE_DEAD_LIST_COUNT
deadCount = deadListCount[instanceIndex];
#endif
#if VFX_USE_INSTANCING
if (index >= nbMax - deadCount)
#else
if (index >= asuint(nbMax) - deadCount)
#endif
{
#if USE_GEOMETRY_SHADER
return; // cull
#else
o.pos.x = VFX_NAN;
return o; // cull
#endif
}
VFXAttributes attributes = (VFXAttributes)0;
VFXSourceAttributes sourceAttributes = (VFXSourceAttributes)0;
#if VFX_HAS_INDIRECT_DRAW
index = indirectBuffer[VFXGetIndirectBufferIndex(index, instanceActiveIndex)];
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.alive = (attributeBuffer.Load(((instanceIndex * 0xEC40) + (index * 0x8 + 0x3)) << 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));
attributes.color = float3(1, 1, 1);
#else
attributes.alive = (attributeBuffer.Load(((instanceIndex * 0xEC40) + (index * 0x8 + 0x3)) << 2));
#if !HAS_STRIPS
if (!attributes.alive)
{
o.pos.x = VFX_NAN;
return o; // cull
}
#endif
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));
attributes.color = float3(1, 1, 1);
#endif
// Initialize built-in needed attributes
#if HAS_STRIPS
InitStripAttributes(index, attributes, 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);
}
#if !HAS_STRIPS
if (!attributes.alive)
return o;
#endif
#if VFX_PRIMITIVE_QUAD
#if HAS_STRIPS
#if VFX_STRIPS_UV_STRECHED
o.VFX_VARYING_UV.x = (float)(relativeIndexInStrip) / (stripData.nextIndex - 1);
#elif VFX_STRIPS_UV_PER_SEGMENT
o.VFX_VARYING_UV.x = PARTICLE_IN_EDGE;
#else
o.VFX_VARYING_UV.x = texCoord;
#endif
o.VFX_VARYING_UV.y = (id & 2) * 0.5f;
const float2 vOffsets = float2(0.0f,o.VFX_VARYING_UV.y - 0.5f);
#if VFX_STRIPS_SWAP_UV
o.VFX_VARYING_UV.xy = float2(1.0f - o.VFX_VARYING_UV.y, o.VFX_VARYING_UV.x);
#endif
#else
o.VFX_VARYING_UV.x = float(id & 1);
o.VFX_VARYING_UV.y = (id & 2) * 0.5f;
const float2 vOffsets = o.VFX_VARYING_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];
o.VFX_VARYING_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),
};
cropFactor = id & 1 ? 1.0f - cropFactor : 1.0f;
const float2 vOffsets = kUvs[id & 7] * cropFactor;
o.VFX_VARYING_UV.xy = vOffsets + 0.5f;
#endif
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
size3 += size3 < 0.0f ? -VFX_EPSILON : VFX_EPSILON; // Add an epsilon so that size is never 0 for strips
#endif
const 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);
float3 inputVertexPosition = float3(vOffsets, 0.0f);
float3 vPos = mul(elementToVFX,float4(inputVertexPosition, 1.0f)).xyz;
o.VFX_VARYING_POSCS = TransformPositionVFXToClip(vPos);
float3 vPosWS = TransformPositionVFXToWorld(vPos);
#ifdef VFX_VARYING_POSWS
o.VFX_VARYING_POSWS = vPosWS;
#endif
#if VFX_NON_UNIFORM_SCALE
float3x3 elementToVFX_N = GetElementToVFXMatrixNormal(
attributes.axisX,
attributes.axisY,
attributes.axisZ,
float3(attributes.angleX,attributes.angleY,attributes.angleZ),
size3);
#else
float3x3 elementToVFX_N = (float3x3)elementToVFX;
#endif
float3 normalWS = normalize(TransformNormalVFXToWorld((-transpose(elementToVFX_N)[2])));
#ifdef VFX_VARYING_NORMAL
float normalFlip = (size3.x * size3.y * size3.z) < 0 ? -1 : 1;
o.VFX_VARYING_NORMAL = normalFlip * normalWS;
#endif
#ifdef VFX_VARYING_TANGENT
o.VFX_VARYING_TANGENT.xyz = normalize(TransformDirectionVFXToWorld(normalize(transpose(elementToVFX)[0].xyz)));
#endif
#ifdef VFX_VARYING_BENTFACTORS
#if HAS_STRIPS
#define BENT_FACTOR_MULTIPLIER 2.0f
#else
#define BENT_FACTOR_MULTIPLIER 1.41421353816986083984375f
#endif
o.VFX_VARYING_BENTFACTORS = vOffsets * normalBendingFactor * BENT_FACTOR_MULTIPLIER;
#endif
#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
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
#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
o.VFX_VARYING_EXPOSUREWEIGHT = exposureWeight;
#endif
#if USE_SOFT_PARTICLE && defined(VFX_VARYING_INVSOFTPARTICLEFADEDISTANCE)
float invSoftParticlesFadeDistance = (float)0;
{
invSoftParticlesFadeDistance = graphValues.invSoftParticlesFadeDistance_a;
}
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)
o.VFX_VARYING_ALPHATHRESHOLD = alphaThreshold;
#endif
#if USE_UV_SCALE_BIAS
#if defined (VFX_VARYING_UV)
o.VFX_VARYING_UV.xy = o.VFX_VARYING_UV.xy * uvScale + uvBias;
#endif
#endif
#ifdef VFX_VARYING_ANGLEFADE
o.VFX_VARYING_ANGLEFADE = angleFade;
#endif
#ifdef VFX_VARYING_FADEFACTOR
o.VFX_VARYING_FADEFACTOR = fadeFactor;
#endif
#ifdef VFX_VARYING_DECALLAYER
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
#if USE_FLIPBOOK && defined(VFX_VARYING_UV)
#if USE_FLIPBOOK_ARRAY_LAYOUT
float2 flipBookSize = (float2)0;
{
flipBookSize = graphValues.flipBookSize_a;
}
VFXUVData uvData = GetUVData(flipBookSize, o.VFX_VARYING_UV.xy, attributes.texIndex);
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)
o.VFX_VARYING_MOTIONVECTORSCALE = motionVectorScale;
#endif
#endif
#else
float2 invFlipBookSize = (float2)0;
{
invFlipBookSize = graphValues.invFlipBookSize_a;
}
float2 flipBookSize = (float2)0;
{
flipBookSize = graphValues.flipBookSize_a;
}
VFXUVData uvData = GetUVData(flipBookSize, invFlipBookSize, o.VFX_VARYING_UV.xy, attributes.texIndex);
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)
o.VFX_VARYING_MOTIONVECTORSCALE = motionVectorScale * invFlipBookSize;
#endif
#endif
#endif
#endif
#if VFX_PASSDEPTH == VFX_PASSDEPTH_SHADOW
float3 posWS = TransformPositionVFXToWorld(vPos);
VFXApplyShadowBias(o.VFX_VARYING_POSCS, posWS, normalWS);
#endif
return o;
}
#define VFX_SUPPORT_MAIN_TEXTURE_SAMPLING_IN_FRAGMENT_DEPTH 1
#ifndef VFX_SUPPORT_MAIN_TEXTURE_SAMPLING_IN_FRAGMENT_DEPTH
#define VFX_SUPPORT_MAIN_TEXTURE_SAMPLING_IN_FRAGMENT_DEPTH 0
#endif
#ifdef VFX_SHADERGRAPH
#if (SHADERPASS == SHADERPASS_DEPTHNORMALSONLY)
#else
#endif
#endif
#if VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION
int _ObjectId;
int _PassValue;
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_PICKING
float4 _SelectionID;
#endif
#pragma fragment frag
void frag(ps_input i
#if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR
#ifdef WRITE_MSAA_DEPTH
// We need the depth color as SV_Target0 for alpha to coverage
, out float4 outDepthColor : SV_Target0
, out float4 outMotionVector : SV_Target1
#else
// When no MSAA, the motion vector is always the first buffer
, out float4 outMotionVector : SV_Target0
#endif
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_ACTUAL
#if defined(WRITE_MSAA_DEPTH)
#if defined(WRITE_NORMAL_BUFFER)
#error Unexpected depth setup mssa + depth normal
#endif
, out float4 outDepthColor : SV_Target0
#elif defined(WRITE_NORMAL_BUFFER)
, out float4 outNormalBuffer : SV_Target0
#else
, out float4 dummy : SV_Target0
#endif
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION || VFX_PASSDEPTH == VFX_PASSDEPTH_PICKING
, out float4 outSelection : SV_Target0
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_SHADOW
, out float4 dummy : SV_Target0
#endif
)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
VFXTransformPSInputs(i);
#ifdef VFX_VARYING_NORMAL
#if USE_DOUBLE_SIDED
const float faceMul = frontFace ? 1.0f : -1.0f;
#else
const float faceMul = 1.0f;
#endif
float3 normalWS = i.VFX_VARYING_NORMAL * faceMul;
const VFXUVData uvData = GetUVData(i);
#ifdef VFX_VARYING_TANGENT
float3 tangentWS = i.VFX_VARYING_TANGENT;
float3 bitangentWS = cross(i.VFX_VARYING_TANGENT,i.VFX_VARYING_NORMAL);
#if defined(VFX_VARYING_BENTFACTORS) && USE_NORMAL_BENDING
float3 bentFactors = float3(i.VFX_VARYING_BENTFACTORS.xy,sqrt(max(0.0f,1.0f - dot(i.VFX_VARYING_BENTFACTORS,i.VFX_VARYING_BENTFACTORS))));
normalWS = tangentWS * bentFactors.x + bitangentWS * bentFactors.y + normalWS * bentFactors.z;
tangentWS = normalize(cross(normalWS,bitangentWS));
bitangentWS = cross(tangentWS,normalWS);
tangentWS *= faceMul;
#endif
float3x3 tbn = float3x3(tangentWS,bitangentWS,normalWS);
#if USE_NORMAL_MAP
float3 n = SampleNormalMap(VFX_SAMPLER(normalMap),uvData);
float normalScale = 1.0f;
#ifdef VFX_VARYING_NORMALSCALE
normalScale = i.VFX_VARYING_NORMALSCALE;
#endif
normalWS = normalize(lerp(normalWS,mul(n,tbn),normalScale));
#endif
#endif
#endif
#ifdef VFX_SHADERGRAPH
#if (SHADERPASS == SHADERPASS_DEPTHNORMALSONLY)
#else
#endif
float alpha = OUTSG.;
#else
float alpha = VFXGetFragmentColor(i).a;
#if VFX_SUPPORT_MAIN_TEXTURE_SAMPLING_IN_FRAGMENT_DEPTH
#ifdef VFX_PROCEDURAL_UV
alpha *= VFXGetTextureColorWithProceduralUV(VFX_SAMPLER(mainTexture),i,VFX_PROCEDURAL_UV(i)).a;
#else
alpha *= VFXGetTextureColor(VFX_SAMPLER(mainTexture),i).a;
#endif
#endif
#endif
VFXClipFragmentColor(alpha,i);
#ifdef WRITE_MSAA_DEPTH
outDepthColor = i.VFX_VARYING_POSCS.z;
#if VFX_USE_ALPHA_TO_MASK
outDepthColor.a = alpha;
#endif
#endif
#ifdef WRITE_NORMAL_BUFFER
#ifdef VFX_VARYING_NORMAL
VFXComputePixelOutputToNormalBuffer(i, normalWS, GetUVData(i), outNormalBuffer);
#else
//Fallback for point and lines, render normal as if those are face camera plane
VFXComputePixelOutputToNormalBuffer(i, VFXGetWorldToViewRotMatrix()[2], GetUVData(i), outNormalBuffer);
#endif
#endif
#if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR
//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);
outMotionVector = encodedMotionVector;
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION
outSelection = float4(_ObjectId, _PassValue, 1.0, 1.0);
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_PICKING
outSelection = _SelectionID;
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_ACTUAL
#if !defined(WRITE_MSAA_DEPTH) && !defined(WRITE_NORMAL_BUFFER)
dummy = float4(i.VFX_VARYING_POSCS.z, 0,0,0);
#endif
#elif VFX_PASSDEPTH == VFX_PASSDEPTH_SHADOW
dummy = (float4)0;
#else
#error VFX_PASSDEPTH undefined
#endif
}
ENDHLSL
}
// Forward pass
Pass
{
Tags { "LightMode"="UniversalForwardOnly" }
HLSLPROGRAM
#pragma target 4.5
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
#pragma multi_compile_fog
struct ps_input
{
float4 pos : SV_POSITION;
#if USE_FLIPBOOK_INTERPOLATION
float4 uv : TEXCOORD0;
#else
#if USE_FLIPBOOK_ARRAY_LAYOUT
float3 uv : TEXCOORD0;
#else
float2 uv : TEXCOORD0;
#endif
#endif
#if VFX_NEEDS_COLOR_INTERPOLATOR
VFX_OPTIONAL_INTERPOLATION float4 color : COLOR0;
#endif
#if USE_SOFT_PARTICLE || USE_ALPHA_TEST || USE_FLIPBOOK_INTERPOLATION || USE_EXPOSURE_WEIGHT || VFX_FEATURE_MOTION_VECTORS_FORWARD
// x: inverse soft particles fade distance
// y: alpha threshold
// z: frame blending factor
// w: exposure weight
VFX_OPTIONAL_INTERPOLATION float4 builtInInterpolants : TEXCOORD1;
#endif
#if USE_FLIPBOOK_MOTIONVECTORS
// x: motion vectors scale X
// y: motion vectors scale Y
VFX_OPTIONAL_INTERPOLATION float2 builtInInterpolants2 : TEXCOORD2;
#endif
#if VFX_NEEDS_POSWS_INTERPOLATOR
float3 posWS : TEXCOORD3;
#endif
#if VFX_FEATURE_MOTION_VECTORS_FORWARD
VFX_DECLARE_MOTION_VECTORS_STORAGE(4,5)
#endif
#if SHADERGRAPH_NEEDS_NORMAL_FORWARD || FORCE_NORMAL_OUTPUT_UNLIT_VERTEX_SHADER
float3 normal : TEXCOORD6;
#endif
#if SHADERGRAPH_NEEDS_TANGENT_FORWARD
float3 tangent : TEXCOORD7;
#endif
UNITY_VERTEX_OUTPUT_STEREO
VFX_VERTEX_OUTPUT_INSTANCE_INDEX
};
struct ps_output
{
float4 color : SV_Target0;
#if VFX_FEATURE_MOTION_VECTORS_FORWARD
float4 outMotionVector : SV_Target1;
#endif
};
#define VFX_VARYING_PS_INPUTS ps_input
#define VFX_VARYING_POSCS pos
#define VFX_VARYING_COLOR color.rgb
#define VFX_VARYING_ALPHA color.a
#define VFX_VARYING_INVSOFTPARTICLEFADEDISTANCE builtInInterpolants.x
#define VFX_VARYING_ALPHATHRESHOLD builtInInterpolants.y
#define VFX_VARYING_FRAMEBLEND builtInInterpolants.z
#define VFX_VARYING_MOTIONVECTORSCALE builtInInterpolants2.xy
#define VFX_VARYING_UV uv
#if VFX_NEEDS_POSWS_INTERPOLATOR
#define VFX_VARYING_POSWS posWS
#endif
#if USE_EXPOSURE_WEIGHT
#define VFX_VARYING_EXPOSUREWEIGHT builtInInterpolants.w
#endif
#if VFX_FEATURE_MOTION_VECTORS_FORWARD
#define VFX_VARYING_VELOCITY_CPOS VFX_DECLARE_MOTION_VECTORS_VARYING_NONJITTER
#define VFX_VARYING_VELOCITY_CPOS_PREVIOUS VFX_DECLARE_MOTION_VECTORS_VARYING_PREVIOUS
#endif
#if SHADERGRAPH_NEEDS_NORMAL_FORWARD || FORCE_NORMAL_OUTPUT_UNLIT_VERTEX_SHADER
#define VFX_VARYING_NORMAL normal
#endif
#if SHADERGRAPH_NEEDS_TANGENT_FORWARD
#define VFX_VARYING_TANGENT tangent
#endif
#if !(defined(VFX_VARYING_PS_INPUTS) && defined(VFX_VARYING_POSCS))
#error VFX_VARYING_PS_INPUTS, VFX_VARYING_POSCS and VFX_VARYING_UV must be defined.
#endif
#include "Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.hlsl"
#include "Packages/com.unity.visualeffectgraph/Shaders/VFXCommon.hlsl"
#include "Packages/com.unity.visualeffectgraph/Shaders/VFXCommonOutput.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 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
struct vs_input
{
VFX_DECLARE_INSTANCE_ID
};
#if HAS_STRIPS
#define PARTICLE_IN_EDGE (id & 1)
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
#pragma vertex vert
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);
#if VFX_PRIMITIVE_TRIANGLE
uint index = id / 3;
#elif VFX_PRIMITIVE_QUAD
#if HAS_STRIPS
id += VFX_GET_INSTANCE_ID(i) * 8192;
const uint vertexPerStripCount = (PARTICLE_PER_STRIP_COUNT - 1) << 2;
uint index = id / vertexPerStripCount; // stripIndex. Needed by VFXInitInstancing
uint instanceIndex, instanceActiveIndex, instanceCurrentIndex;
index = VFXInitInstancing(index, instanceIndex, instanceActiveIndex, instanceCurrentIndex);
const StripData stripData = GetStripDataFromStripIndex(index, instanceIndex);
uint relativeIndexInStrip = ((id % vertexPerStripCount) >> 2) + (id & 1); // relative index of particle
uint maxEdgeIndex = relativeIndexInStrip - PARTICLE_IN_EDGE + 1;
if (maxEdgeIndex >= stripData.nextIndex)
return o;
index = GetParticleIndex(relativeIndexInStrip, stripData);
#else
uint index = (id >> 2) + VFX_GET_INSTANCE_ID(i) * 2048;
#endif
#elif VFX_PRIMITIVE_OCTAGON
uint index = (id >> 3) + VFX_GET_INSTANCE_ID(i) * 1024;
#endif
#if !HAS_STRIPS // With strips we need to derive the instance index prior to get the particle index
uint instanceIndex, instanceActiveIndex, instanceCurrentIndex;
index = VFXInitInstancing(index, instanceIndex, instanceActiveIndex, instanceCurrentIndex);
#endif
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));
ContextData contextData = instancingContextData[instanceActiveIndex];
uint systemSeed = contextData.systemSeed;
uint nbMax = contextData.maxParticleCount;
uint deadCount = 0;
#if USE_DEAD_LIST_COUNT
deadCount = deadListCount[instanceIndex];
#endif
#if VFX_USE_INSTANCING
if (index >= nbMax - deadCount)
#else
if (index >= asuint(nbMax) - deadCount)
#endif
{
#if USE_GEOMETRY_SHADER
return; // cull
#else
o.pos.x = VFX_NAN;
return o; // cull
#endif
}
VFXAttributes attributes = (VFXAttributes)0;
VFXSourceAttributes sourceAttributes = (VFXSourceAttributes)0;
#if VFX_HAS_INDIRECT_DRAW
index = indirectBuffer[VFXGetIndirectBufferIndex(index, instanceActiveIndex)];
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.alive = (attributeBuffer.Load(((instanceIndex * 0xEC40) + (index * 0x8 + 0x3)) << 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));
attributes.color = float3(1, 1, 1);
#else
attributes.alive = (attributeBuffer.Load(((instanceIndex * 0xEC40) + (index * 0x8 + 0x3)) << 2));
#if !HAS_STRIPS
if (!attributes.alive)
{
o.pos.x = VFX_NAN;
return o; // cull
}
#endif
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));
attributes.color = float3(1, 1, 1);
#endif
// Initialize built-in needed attributes
#if HAS_STRIPS
InitStripAttributes(index, attributes, 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);
}
#if !HAS_STRIPS
if (!attributes.alive)
return o;
#endif
#if VFX_PRIMITIVE_QUAD
#if HAS_STRIPS
#if VFX_STRIPS_UV_STRECHED
o.VFX_VARYING_UV.x = (float)(relativeIndexInStrip) / (stripData.nextIndex - 1);
#elif VFX_STRIPS_UV_PER_SEGMENT
o.VFX_VARYING_UV.x = PARTICLE_IN_EDGE;
#else
o.VFX_VARYING_UV.x = texCoord;
#endif
o.VFX_VARYING_UV.y = (id & 2) * 0.5f;
const float2 vOffsets = float2(0.0f,o.VFX_VARYING_UV.y - 0.5f);
#if VFX_STRIPS_SWAP_UV
o.VFX_VARYING_UV.xy = float2(1.0f - o.VFX_VARYING_UV.y, o.VFX_VARYING_UV.x);
#endif
#else
o.VFX_VARYING_UV.x = float(id & 1);
o.VFX_VARYING_UV.y = (id & 2) * 0.5f;
const float2 vOffsets = o.VFX_VARYING_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];
o.VFX_VARYING_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),
};
cropFactor = id & 1 ? 1.0f - cropFactor : 1.0f;
const float2 vOffsets = kUvs[id & 7] * cropFactor;
o.VFX_VARYING_UV.xy = vOffsets + 0.5f;
#endif
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
size3 += size3 < 0.0f ? -VFX_EPSILON : VFX_EPSILON; // Add an epsilon so that size is never 0 for strips
#endif
const 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);
float3 inputVertexPosition = float3(vOffsets, 0.0f);
float3 vPos = mul(elementToVFX,float4(inputVertexPosition, 1.0f)).xyz;
o.VFX_VARYING_POSCS = TransformPositionVFXToClip(vPos);
float3 vPosWS = TransformPositionVFXToWorld(vPos);
#ifdef VFX_VARYING_POSWS
o.VFX_VARYING_POSWS = vPosWS;
#endif
#if VFX_NON_UNIFORM_SCALE
float3x3 elementToVFX_N = GetElementToVFXMatrixNormal(
attributes.axisX,
attributes.axisY,
attributes.axisZ,
float3(attributes.angleX,attributes.angleY,attributes.angleZ),
size3);
#else
float3x3 elementToVFX_N = (float3x3)elementToVFX;
#endif
float3 normalWS = normalize(TransformNormalVFXToWorld((-transpose(elementToVFX_N)[2])));
#ifdef VFX_VARYING_NORMAL
float normalFlip = (size3.x * size3.y * size3.z) < 0 ? -1 : 1;
o.VFX_VARYING_NORMAL = normalFlip * normalWS;
#endif
#ifdef VFX_VARYING_TANGENT
o.VFX_VARYING_TANGENT.xyz = normalize(TransformDirectionVFXToWorld(normalize(transpose(elementToVFX)[0].xyz)));
#endif
#ifdef VFX_VARYING_BENTFACTORS
#if HAS_STRIPS
#define BENT_FACTOR_MULTIPLIER 2.0f
#else
#define BENT_FACTOR_MULTIPLIER 1.41421353816986083984375f
#endif
o.VFX_VARYING_BENTFACTORS = vOffsets * normalBendingFactor * BENT_FACTOR_MULTIPLIER;
#endif
#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
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
#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
o.VFX_VARYING_EXPOSUREWEIGHT = exposureWeight;
#endif
#if USE_SOFT_PARTICLE && defined(VFX_VARYING_INVSOFTPARTICLEFADEDISTANCE)
float invSoftParticlesFadeDistance = (float)0;
{
invSoftParticlesFadeDistance = graphValues.invSoftParticlesFadeDistance_a;
}
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)
o.VFX_VARYING_ALPHATHRESHOLD = alphaThreshold;
#endif
#if USE_UV_SCALE_BIAS
#if defined (VFX_VARYING_UV)
o.VFX_VARYING_UV.xy = o.VFX_VARYING_UV.xy * uvScale + uvBias;
#endif
#endif
#ifdef VFX_VARYING_ANGLEFADE
o.VFX_VARYING_ANGLEFADE = angleFade;
#endif
#ifdef VFX_VARYING_FADEFACTOR
o.VFX_VARYING_FADEFACTOR = fadeFactor;
#endif
#ifdef VFX_VARYING_DECALLAYER
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
#if USE_FLIPBOOK && defined(VFX_VARYING_UV)
#if USE_FLIPBOOK_ARRAY_LAYOUT
float2 flipBookSize = (float2)0;
{
flipBookSize = graphValues.flipBookSize_a;
}
VFXUVData uvData = GetUVData(flipBookSize, o.VFX_VARYING_UV.xy, attributes.texIndex);
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)
o.VFX_VARYING_MOTIONVECTORSCALE = motionVectorScale;
#endif
#endif
#else
float2 invFlipBookSize = (float2)0;
{
invFlipBookSize = graphValues.invFlipBookSize_a;
}
float2 flipBookSize = (float2)0;
{
flipBookSize = graphValues.flipBookSize_a;
}
VFXUVData uvData = GetUVData(flipBookSize, invFlipBookSize, o.VFX_VARYING_UV.xy, attributes.texIndex);
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)
o.VFX_VARYING_MOTIONVECTORSCALE = motionVectorScale * invFlipBookSize;
#endif
#endif
#endif
#endif
return o;
}
#if VFX_SHADERGRAPH
#endif
#pragma fragment frag
ps_output frag(ps_input i,
bool frontFace : SV_IsFrontFace)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
ps_output o = (ps_output)0;
VFXTransformPSInputs(i);
#ifdef VFX_VARYING_NORMAL
#if USE_DOUBLE_SIDED
const float faceMul = frontFace ? 1.0f : -1.0f;
#else
const float faceMul = 1.0f;
#endif
float3 normalWS = i.VFX_VARYING_NORMAL * faceMul;
const VFXUVData uvData = GetUVData(i);
#ifdef VFX_VARYING_TANGENT
float3 tangentWS = i.VFX_VARYING_TANGENT;
float3 bitangentWS = cross(i.VFX_VARYING_TANGENT,i.VFX_VARYING_NORMAL);
#if defined(VFX_VARYING_BENTFACTORS) && USE_NORMAL_BENDING
float3 bentFactors = float3(i.VFX_VARYING_BENTFACTORS.xy,sqrt(max(0.0f,1.0f - dot(i.VFX_VARYING_BENTFACTORS,i.VFX_VARYING_BENTFACTORS))));
normalWS = tangentWS * bentFactors.x + bitangentWS * bentFactors.y + normalWS * bentFactors.z;
tangentWS = normalize(cross(normalWS,bitangentWS));
bitangentWS = cross(tangentWS,normalWS);
tangentWS *= faceMul;
#endif
float3x3 tbn = float3x3(tangentWS,bitangentWS,normalWS);
#if USE_NORMAL_MAP
float3 n = SampleNormalMap(VFX_SAMPLER(normalMap),uvData);
float normalScale = 1.0f;
#ifdef VFX_VARYING_NORMALSCALE
normalScale = i.VFX_VARYING_NORMALSCALE;
#endif
normalWS = normalize(lerp(normalWS,mul(n,tbn),normalScale));
#endif
#endif
#endif
#if VFX_USE_GRAPH_VALUES
uint instanceActiveIndex = i.VFX_VARYINGS_INSTANCE_ACTIVE_INDEX;
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));
#endif
#if VFX_SHADERGRAPH
#if HAS_SHADERGRAPH_PARAM_BASECOLOR
o.color.rgb = OUTSG..rgb;
o.color = VFXApplyPreExposure(o.color, i);
#endif
#if HAS_SHADERGRAPH_PARAM_EMISSION
float4 emission = float4(OUTSG..rgb, 0.0f);
emission = VFXApplyPreExposure(emission, 1.0f);
o.color.rgb += emission.rgb;
#endif
#if HAS_SHADERGRAPH_PARAM_ALPHA
o.color.a = OUTSG.;
#endif
#else
#define VFX_TEXTURE_COLOR VFXGetTextureColor(VFX_SAMPLER(mainTexture),i)
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
o.color = SampleGradient(gradient, VFX_TEXTURE_COLOR.a * color.a) * float4(color.rgb,1.0);
#endif
o.color = VFXApplyPreExposure(o.color, i);
#endif
o.color = VFXApplyAO(o.color,i);
o.color = VFXApplyFog(o.color,i);
VFXClipFragmentColor(o.color.a,i);
o.color.a = saturate(o.color.a);
o.color = VFXTransformFinalColor(o.color);
#if VFX_FEATURE_MOTION_VECTORS_FORWARD
//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);
o.outMotionVector = encodedMotionVector;
o.outMotionVector.a = o.color.a < i.VFX_VARYING_ALPHATHRESHOLD ? 0.0f : 1.0f; //Independant clipping for motion vector pass
#endif
return o;
}
ENDHLSL
}
// Forward pass
Pass
{
Tags { "LightMode"="Universal2D" }
HLSLPROGRAM
#pragma target 4.5
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
#pragma multi_compile_fog
struct ps_input
{
float4 pos : SV_POSITION;
#if USE_FLIPBOOK_INTERPOLATION
float4 uv : TEXCOORD0;
#else
#if USE_FLIPBOOK_ARRAY_LAYOUT
float3 uv : TEXCOORD0;
#else
float2 uv : TEXCOORD0;
#endif
#endif
#if VFX_NEEDS_COLOR_INTERPOLATOR
VFX_OPTIONAL_INTERPOLATION float4 color : COLOR0;
#endif
#if USE_SOFT_PARTICLE || USE_ALPHA_TEST || USE_FLIPBOOK_INTERPOLATION || USE_EXPOSURE_WEIGHT || VFX_FEATURE_MOTION_VECTORS_FORWARD
// x: inverse soft particles fade distance
// y: alpha threshold
// z: frame blending factor
// w: exposure weight
VFX_OPTIONAL_INTERPOLATION float4 builtInInterpolants : TEXCOORD1;
#endif
#if USE_FLIPBOOK_MOTIONVECTORS
// x: motion vectors scale X
// y: motion vectors scale Y
VFX_OPTIONAL_INTERPOLATION float2 builtInInterpolants2 : TEXCOORD2;
#endif
#if VFX_NEEDS_POSWS_INTERPOLATOR
float3 posWS : TEXCOORD3;
#endif
#if VFX_FEATURE_MOTION_VECTORS_FORWARD
VFX_DECLARE_MOTION_VECTORS_STORAGE(4,5)
#endif
#if SHADERGRAPH_NEEDS_NORMAL_FORWARD || FORCE_NORMAL_OUTPUT_UNLIT_VERTEX_SHADER
float3 normal : TEXCOORD6;
#endif
#if SHADERGRAPH_NEEDS_TANGENT_FORWARD
float3 tangent : TEXCOORD7;
#endif
UNITY_VERTEX_OUTPUT_STEREO
VFX_VERTEX_OUTPUT_INSTANCE_INDEX
};
struct ps_output
{
float4 color : SV_Target0;
#if VFX_FEATURE_MOTION_VECTORS_FORWARD
float4 outMotionVector : SV_Target1;
#endif
};
#define VFX_VARYING_PS_INPUTS ps_input
#define VFX_VARYING_POSCS pos
#define VFX_VARYING_COLOR color.rgb
#define VFX_VARYING_ALPHA color.a
#define VFX_VARYING_INVSOFTPARTICLEFADEDISTANCE builtInInterpolants.x
#define VFX_VARYING_ALPHATHRESHOLD builtInInterpolants.y
#define VFX_VARYING_FRAMEBLEND builtInInterpolants.z
#define VFX_VARYING_MOTIONVECTORSCALE builtInInterpolants2.xy
#define VFX_VARYING_UV uv
#if VFX_NEEDS_POSWS_INTERPOLATOR
#define VFX_VARYING_POSWS posWS
#endif
#if USE_EXPOSURE_WEIGHT
#define VFX_VARYING_EXPOSUREWEIGHT builtInInterpolants.w
#endif
#if VFX_FEATURE_MOTION_VECTORS_FORWARD
#define VFX_VARYING_VELOCITY_CPOS VFX_DECLARE_MOTION_VECTORS_VARYING_NONJITTER
#define VFX_VARYING_VELOCITY_CPOS_PREVIOUS VFX_DECLARE_MOTION_VECTORS_VARYING_PREVIOUS
#endif
#if SHADERGRAPH_NEEDS_NORMAL_FORWARD || FORCE_NORMAL_OUTPUT_UNLIT_VERTEX_SHADER
#define VFX_VARYING_NORMAL normal
#endif
#if SHADERGRAPH_NEEDS_TANGENT_FORWARD
#define VFX_VARYING_TANGENT tangent
#endif
#if !(defined(VFX_VARYING_PS_INPUTS) && defined(VFX_VARYING_POSCS))
#error VFX_VARYING_PS_INPUTS, VFX_VARYING_POSCS and VFX_VARYING_UV must be defined.
#endif
#include "Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.hlsl"
#include "Packages/com.unity.visualeffectgraph/Shaders/VFXCommon.hlsl"
#include "Packages/com.unity.visualeffectgraph/Shaders/VFXCommonOutput.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 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
struct vs_input
{
VFX_DECLARE_INSTANCE_ID
};
#if HAS_STRIPS
#define PARTICLE_IN_EDGE (id & 1)
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
#pragma vertex vert
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);
#if VFX_PRIMITIVE_TRIANGLE
uint index = id / 3;
#elif VFX_PRIMITIVE_QUAD
#if HAS_STRIPS
id += VFX_GET_INSTANCE_ID(i) * 8192;
const uint vertexPerStripCount = (PARTICLE_PER_STRIP_COUNT - 1) << 2;
uint index = id / vertexPerStripCount; // stripIndex. Needed by VFXInitInstancing
uint instanceIndex, instanceActiveIndex, instanceCurrentIndex;
index = VFXInitInstancing(index, instanceIndex, instanceActiveIndex, instanceCurrentIndex);
const StripData stripData = GetStripDataFromStripIndex(index, instanceIndex);
uint relativeIndexInStrip = ((id % vertexPerStripCount) >> 2) + (id & 1); // relative index of particle
uint maxEdgeIndex = relativeIndexInStrip - PARTICLE_IN_EDGE + 1;
if (maxEdgeIndex >= stripData.nextIndex)
return o;
index = GetParticleIndex(relativeIndexInStrip, stripData);
#else
uint index = (id >> 2) + VFX_GET_INSTANCE_ID(i) * 2048;
#endif
#elif VFX_PRIMITIVE_OCTAGON
uint index = (id >> 3) + VFX_GET_INSTANCE_ID(i) * 1024;
#endif
#if !HAS_STRIPS // With strips we need to derive the instance index prior to get the particle index
uint instanceIndex, instanceActiveIndex, instanceCurrentIndex;
index = VFXInitInstancing(index, instanceIndex, instanceActiveIndex, instanceCurrentIndex);
#endif
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));
ContextData contextData = instancingContextData[instanceActiveIndex];
uint systemSeed = contextData.systemSeed;
uint nbMax = contextData.maxParticleCount;
uint deadCount = 0;
#if USE_DEAD_LIST_COUNT
deadCount = deadListCount[instanceIndex];
#endif
#if VFX_USE_INSTANCING
if (index >= nbMax - deadCount)
#else
if (index >= asuint(nbMax) - deadCount)
#endif
{
#if USE_GEOMETRY_SHADER
return; // cull
#else
o.pos.x = VFX_NAN;
return o; // cull
#endif
}
VFXAttributes attributes = (VFXAttributes)0;
VFXSourceAttributes sourceAttributes = (VFXSourceAttributes)0;
#if VFX_HAS_INDIRECT_DRAW
index = indirectBuffer[VFXGetIndirectBufferIndex(index, instanceActiveIndex)];
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.alive = (attributeBuffer.Load(((instanceIndex * 0xEC40) + (index * 0x8 + 0x3)) << 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));
attributes.color = float3(1, 1, 1);
#else
attributes.alive = (attributeBuffer.Load(((instanceIndex * 0xEC40) + (index * 0x8 + 0x3)) << 2));
#if !HAS_STRIPS
if (!attributes.alive)
{
o.pos.x = VFX_NAN;
return o; // cull
}
#endif
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));
attributes.color = float3(1, 1, 1);
#endif
// Initialize built-in needed attributes
#if HAS_STRIPS
InitStripAttributes(index, attributes, 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);
}
#if !HAS_STRIPS
if (!attributes.alive)
return o;
#endif
#if VFX_PRIMITIVE_QUAD
#if HAS_STRIPS
#if VFX_STRIPS_UV_STRECHED
o.VFX_VARYING_UV.x = (float)(relativeIndexInStrip) / (stripData.nextIndex - 1);
#elif VFX_STRIPS_UV_PER_SEGMENT
o.VFX_VARYING_UV.x = PARTICLE_IN_EDGE;
#else
o.VFX_VARYING_UV.x = texCoord;
#endif
o.VFX_VARYING_UV.y = (id & 2) * 0.5f;
const float2 vOffsets = float2(0.0f,o.VFX_VARYING_UV.y - 0.5f);
#if VFX_STRIPS_SWAP_UV
o.VFX_VARYING_UV.xy = float2(1.0f - o.VFX_VARYING_UV.y, o.VFX_VARYING_UV.x);
#endif
#else
o.VFX_VARYING_UV.x = float(id & 1);
o.VFX_VARYING_UV.y = (id & 2) * 0.5f;
const float2 vOffsets = o.VFX_VARYING_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];
o.VFX_VARYING_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),
};
cropFactor = id & 1 ? 1.0f - cropFactor : 1.0f;
const float2 vOffsets = kUvs[id & 7] * cropFactor;
o.VFX_VARYING_UV.xy = vOffsets + 0.5f;
#endif
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
size3 += size3 < 0.0f ? -VFX_EPSILON : VFX_EPSILON; // Add an epsilon so that size is never 0 for strips
#endif
const 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);
float3 inputVertexPosition = float3(vOffsets, 0.0f);
float3 vPos = mul(elementToVFX,float4(inputVertexPosition, 1.0f)).xyz;
o.VFX_VARYING_POSCS = TransformPositionVFXToClip(vPos);
float3 vPosWS = TransformPositionVFXToWorld(vPos);
#ifdef VFX_VARYING_POSWS
o.VFX_VARYING_POSWS = vPosWS;
#endif
#if VFX_NON_UNIFORM_SCALE
float3x3 elementToVFX_N = GetElementToVFXMatrixNormal(
attributes.axisX,
attributes.axisY,
attributes.axisZ,
float3(attributes.angleX,attributes.angleY,attributes.angleZ),
size3);
#else
float3x3 elementToVFX_N = (float3x3)elementToVFX;
#endif
float3 normalWS = normalize(TransformNormalVFXToWorld((-transpose(elementToVFX_N)[2])));
#ifdef VFX_VARYING_NORMAL
float normalFlip = (size3.x * size3.y * size3.z) < 0 ? -1 : 1;
o.VFX_VARYING_NORMAL = normalFlip * normalWS;
#endif
#ifdef VFX_VARYING_TANGENT
o.VFX_VARYING_TANGENT.xyz = normalize(TransformDirectionVFXToWorld(normalize(transpose(elementToVFX)[0].xyz)));
#endif
#ifdef VFX_VARYING_BENTFACTORS
#if HAS_STRIPS
#define BENT_FACTOR_MULTIPLIER 2.0f
#else
#define BENT_FACTOR_MULTIPLIER 1.41421353816986083984375f
#endif
o.VFX_VARYING_BENTFACTORS = vOffsets * normalBendingFactor * BENT_FACTOR_MULTIPLIER;
#endif
#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
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
#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
o.VFX_VARYING_EXPOSUREWEIGHT = exposureWeight;
#endif
#if USE_SOFT_PARTICLE && defined(VFX_VARYING_INVSOFTPARTICLEFADEDISTANCE)
float invSoftParticlesFadeDistance = (float)0;
{
invSoftParticlesFadeDistance = graphValues.invSoftParticlesFadeDistance_a;
}
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)
o.VFX_VARYING_ALPHATHRESHOLD = alphaThreshold;
#endif
#if USE_UV_SCALE_BIAS
#if defined (VFX_VARYING_UV)
o.VFX_VARYING_UV.xy = o.VFX_VARYING_UV.xy * uvScale + uvBias;
#endif
#endif
#ifdef VFX_VARYING_ANGLEFADE
o.VFX_VARYING_ANGLEFADE = angleFade;
#endif
#ifdef VFX_VARYING_FADEFACTOR
o.VFX_VARYING_FADEFACTOR = fadeFactor;
#endif
#ifdef VFX_VARYING_DECALLAYER
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
#if USE_FLIPBOOK && defined(VFX_VARYING_UV)
#if USE_FLIPBOOK_ARRAY_LAYOUT
float2 flipBookSize = (float2)0;
{
flipBookSize = graphValues.flipBookSize_a;
}
VFXUVData uvData = GetUVData(flipBookSize, o.VFX_VARYING_UV.xy, attributes.texIndex);
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)
o.VFX_VARYING_MOTIONVECTORSCALE = motionVectorScale;
#endif
#endif
#else
float2 invFlipBookSize = (float2)0;
{
invFlipBookSize = graphValues.invFlipBookSize_a;
}
float2 flipBookSize = (float2)0;
{
flipBookSize = graphValues.flipBookSize_a;
}
VFXUVData uvData = GetUVData(flipBookSize, invFlipBookSize, o.VFX_VARYING_UV.xy, attributes.texIndex);
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)
o.VFX_VARYING_MOTIONVECTORSCALE = motionVectorScale * invFlipBookSize;
#endif
#endif
#endif
#endif
return o;
}
#if VFX_SHADERGRAPH
#endif
#pragma fragment frag
ps_output frag(ps_input i,
bool frontFace : SV_IsFrontFace)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
ps_output o = (ps_output)0;
VFXTransformPSInputs(i);
#ifdef VFX_VARYING_NORMAL
#if USE_DOUBLE_SIDED
const float faceMul = frontFace ? 1.0f : -1.0f;
#else
const float faceMul = 1.0f;
#endif
float3 normalWS = i.VFX_VARYING_NORMAL * faceMul;
const VFXUVData uvData = GetUVData(i);
#ifdef VFX_VARYING_TANGENT
float3 tangentWS = i.VFX_VARYING_TANGENT;
float3 bitangentWS = cross(i.VFX_VARYING_TANGENT,i.VFX_VARYING_NORMAL);
#if defined(VFX_VARYING_BENTFACTORS) && USE_NORMAL_BENDING
float3 bentFactors = float3(i.VFX_VARYING_BENTFACTORS.xy,sqrt(max(0.0f,1.0f - dot(i.VFX_VARYING_BENTFACTORS,i.VFX_VARYING_BENTFACTORS))));
normalWS = tangentWS * bentFactors.x + bitangentWS * bentFactors.y + normalWS * bentFactors.z;
tangentWS = normalize(cross(normalWS,bitangentWS));
bitangentWS = cross(tangentWS,normalWS);
tangentWS *= faceMul;
#endif
float3x3 tbn = float3x3(tangentWS,bitangentWS,normalWS);
#if USE_NORMAL_MAP
float3 n = SampleNormalMap(VFX_SAMPLER(normalMap),uvData);
float normalScale = 1.0f;
#ifdef VFX_VARYING_NORMALSCALE
normalScale = i.VFX_VARYING_NORMALSCALE;
#endif
normalWS = normalize(lerp(normalWS,mul(n,tbn),normalScale));
#endif
#endif
#endif
#if VFX_USE_GRAPH_VALUES
uint instanceActiveIndex = i.VFX_VARYINGS_INSTANCE_ACTIVE_INDEX;
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));
#endif
#if VFX_SHADERGRAPH
#if HAS_SHADERGRAPH_PARAM_BASECOLOR
o.color.rgb = OUTSG..rgb;
o.color = VFXApplyPreExposure(o.color, i);
#endif
#if HAS_SHADERGRAPH_PARAM_EMISSION
float4 emission = float4(OUTSG..rgb, 0.0f);
emission = VFXApplyPreExposure(emission, 1.0f);
o.color.rgb += emission.rgb;
#endif
#if HAS_SHADERGRAPH_PARAM_ALPHA
o.color.a = OUTSG.;
#endif
#else
#define VFX_TEXTURE_COLOR VFXGetTextureColor(VFX_SAMPLER(mainTexture),i)
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
o.color = SampleGradient(gradient, VFX_TEXTURE_COLOR.a * color.a) * float4(color.rgb,1.0);
#endif
o.color = VFXApplyPreExposure(o.color, i);
#endif
o.color = VFXApplyAO(o.color,i);
o.color = VFXApplyFog(o.color,i);
VFXClipFragmentColor(o.color.a,i);
o.color.a = saturate(o.color.a);
o.color = VFXTransformFinalColor(o.color);
#if VFX_FEATURE_MOTION_VECTORS_FORWARD
//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);
o.outMotionVector = encodedMotionVector;
o.outMotionVector.a = o.color.a < i.VFX_VARYING_ALPHATHRESHOLD ? 0.0f : 1.0f; //Independant clipping for motion vector pass
#endif
return o;
}
ENDHLSL
}
}
}
Editor is loading...
Leave a Comment