#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 ${VFXPerPassInclude} ${VFXGeneratedBlockFunction} struct vs_input { float3 pos : POSITION; float2 uv : TEXCOORD0; #if VFX_SHADERGRAPH_HAS_UV1 float4 uv1 : TEXCOORD1; #endif #if VFX_SHADERGRAPH_HAS_UV2 float4 uv2 : TEXCOORD2; #endif #if VFX_SHADERGRAPH_HAS_UV3 float4 uv3 : TEXCOORD3; #endif #if VFX_SHADERGRAPH_HAS_COLOR float4 vertexColor : COLOR; #endif float3 normal : NORMAL; #if defined(VFX_VARYING_TANGENT) || SHADERGRAPH_HAS_NORMAL float4 tangent : TANGENT; #endif VFX_DECLARE_INSTANCE_ID }; #pragma vertex vert VFX_VARYING_PS_INPUTS vert(vs_input i) { VFX_VARYING_PS_INPUTS o = (VFX_VARYING_PS_INPUTS)0; UNITY_SETUP_INSTANCE_ID(i); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); uint index = VFX_GET_INSTANCE_ID(i); ${VFXInitInstancing} ${VFXLoadGraphValues} ${VFXLoadContextData} uint systemSeed = contextData.systemSeed; uint nbMax = contextData.maxParticleCount; ${VFXLoadAttributesOrCull} ${VFXProcessBlocks} if (!attributes.alive) return o; #ifdef VFX_VARYING_UV o.VFX_VARYING_UV.xy = i.uv; #endif #if VFX_SHADERGRAPH_HAS_UV1 o.uv1 = i.uv1; #endif #if VFX_SHADERGRAPH_HAS_UV2 o.uv2 = i.uv2; #endif #if VFX_SHADERGRAPH_HAS_UV3 o.uv3 = i.uv3; #endif #if VFX_SHADERGRAPH_HAS_COLOR o.vertexColor = i.vertexColor; #endif ${VFXLoadSize} float3 inputVertexPosition = i.pos; 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 vPos = mul(elementToVFX,float4(inputVertexPosition,1.0f)).xyz; float4 csPos = TransformPositionVFXToClip(vPos); o.VFX_VARYING_POSCS = csPos; // TODO This is needed only if in local space (to handle non uniform scale) or if scale attributes are stored/written (no way to know atm) float3x3 elementToVFX_N = GetElementToVFXMatrixNormal( attributes.axisX, attributes.axisY, attributes.axisZ, float3(attributes.angleX,attributes.angleY,attributes.angleZ), size3); float3 normalWS = normalize(TransformNormalVFXToWorld(mul(elementToVFX_N, i.normal))); #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 = float4(normalize(TransformDirectionVFXToWorld(mul((float3x3)elementToVFX,i.tangent.xyz))),i.tangent.w); #endif ${VFXVertexComputeCurrentAndPreviousClipPos} ${VFXVertexCommonProcess} ${VFXVertexSetFlipbooksInterpolants} ${VFXVertexAdditionalProcess} ${VFXAdditionalInterpolantsGeneration} return o; } ${VFXBegin:VFXComputeNormalWS} #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 = normalize(i.VFX_VARYING_NORMAL * faceMul); const VFXUVData uvData = GetUVData(i); #ifdef VFX_VARYING_TANGENT float3 tangentWS = normalize(i.VFX_VARYING_TANGENT.xyz); float3 bitangentWS = cross(normalWS,tangentWS) * (i.VFX_VARYING_TANGENT.w * faceMul); 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 ${VFXEnd} ${VFXBegin:VFXVertexAdditionalProcess}${VFXEnd}