Version = 1.8.4.27161; CParticleEffect $LOCAL$/Resource { OnSpawn = "$LOCAL$/Spawner"; CustomAttributes = "$LOCAL$/_GlobalAttributes"; Autostart = true; } CCompilerSyntaxNodeExpression $LOCAL$/CCompilerSyntaxNodeExpression_D158FB1D { EditorInfosIsBlockMinimized = 0; Expression = "function void Eval() { Life = 0.2; // here, grab a random spawn location in the \'ProjSpawnVolume\' shape. // you can select that shape in the treeview and move it around in the viewport // to make lightning start at different locations Position = ProjSpawnMesh.samplePosition(); // next, reproject the start position on the mesh // (this is because otherwise the trail evolver will make a trail from the // original position to the projected position on the first frame) //Position += ProjMesh.project(Position).xyz; // random velocity on a squased sphere whose height is // 0.3 times its equatorial radius. -> move faster horizontally Velocity = vrand() * float3(1,0.3,1)*ProbeVelocity; } "; } CActionFactoryWithChilds $LOCAL$/Spawner { ChildList = { "$LOCAL$/Source", }; } CParticleFieldDeclaration $LOCAL$/CParticleFieldDeclaration_67949F4D { FieldName = "ColorCoeff"; } CParticleSamplerCurve $LOCAL$/CParticleSamplerCurve_E7219408 { SamplerName = "DisplacementWeight"; Times = { 0.0000000e+000, 5.0000000e-001, 1.0000000e+000, }; FloatValues = { 3.5361910e-001, 1.7034518e+000, 3.5361910e-001, }; FloatTangents = { 0.0000000e+000, 1.3884335e+000, 0.0000000e+000, 0.0000000e+000, -9.6360749e-001, 0.0000000e+000, }; MinLimits = float4(0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000); } CParticleEvolver_Physics $LOCAL$/CParticleEvolver_Physics_4B0C0AC6 { ConstantAcceleration = float3(0.0000000e+000, 5.0000000e+000, 0.0000000e+000); } CParticleEvolver_Script $LOCAL$/CParticleEvolver_Script_6DEC9E9F { Expression = "$LOCAL$/CCompilerSyntaxNodeExpression_E63D424E"; } CParticleAttributeList $LOCAL$/_GlobalAttributes { AttributeList = { "$LOCAL$/CParticleAttributeDeclaration_9BDD555E", "$LOCAL$/CParticleAttributeDeclaration_6085D8ED", }; } CParticleState $LOCAL$/CParticleState_37820737 { StateName = "State_0"; Evolvers = { "$LOCAL$/CParticleEvolver_Physics_4B0C0AC6", "$LOCAL$/LightningTrail", }; } CParticleDescriptor $LOCAL$/CParticleDescriptor_2830BC72 { Samplers = { "$LOCAL$/CParticleSamplerShape_23C61C9B", }; SpawnEvaluator = "$LOCAL$/CCompilerSyntaxNodeExpression_D158FB1D"; States = { "$LOCAL$/CParticleState_37820737", }; } CParticleAttributeDeclaration $LOCAL$/CParticleAttributeDeclaration_6085D8ED { AttributeName = "Flux"; AttributeDescription = "Controls the amount of strokes\\nMultiplier of the \'Source\' layer\'s spawn-rate."; DefaultValueF4 = float4(3.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000); HasMin = true; HasMax = true; MaxValueF4 = float4(3.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000); } CParticleFieldDeclaration $LOCAL$/CParticleFieldDeclaration_F6A6C829 { FieldName = "PCoords"; FieldType = int3; } CParticleEvolver_Spawner $LOCAL$/LightningTrail { SpawnInterval = 5.0000001e-002; LocalSpaceSpawn = true; Descriptor = "$LOCAL$/CParticleDescriptor_EAA4F4AE"; } CParticleState $LOCAL$/CParticleState_48BA6F7F { StateName = "State_0"; Evolvers = { "$LOCAL$/CParticleEvolver_Script_6DEC9E9F", "$LOCAL$/CParticleEvolver_Physics_815F8FC3", "$LOCAL$/CParticleEvolver_Field_11EF5012", "$LOCAL$/CParticleEvolver_Field_25CAC61C", "$LOCAL$/CParticleEvolver_Script_1CA6C021", }; } CParticleDescriptor $LOCAL$/CParticleDescriptor_EAA4F4AE { Renderer = "$LOCAL$/CParticleRenderer_List_6FEA4612"; CustomFields = { "$LOCAL$/CParticleFieldDeclaration_342360F8", "$LOCAL$/CParticleFieldDeclaration_6ACE796C", "$LOCAL$/CParticleFieldDeclaration_F6A6C829", "$LOCAL$/CParticleFieldDeclaration_7F0885A0", "$LOCAL$/CParticleFieldDeclaration_67949F4D", }; Samplers = { "$LOCAL$/CParticleSamplerShape_627F92C7", "$LOCAL$/CParticleSamplerCurve_31F983E2", "$LOCAL$/CParticleSamplerProceduralTurbulence_E0F88948", "$LOCAL$/CParticleSamplerCurve_E7219408", "$LOCAL$/CParticleSamplerShape_79C1883D", }; SpawnEvaluator = "$LOCAL$/CCompilerSyntaxNodeExpression_A9553A09"; States = { "$LOCAL$/CParticleState_48BA6F7F", }; } CParticleFieldDeclaration $LOCAL$/CParticleFieldDeclaration_7F0885A0 { FieldName = "Color"; FieldType = float4; } CCompilerSyntaxNodeExpression $LOCAL$/CCompilerSyntaxNodeExpression_A9553A09 { Expression = "function void Eval() { Life = 0.1; // grab a random lightning texture from the atlas, for the ribbon. // there are 16 sub-frames, whose IDs go from 0 to 15 TextureID = rand(0,16); // color factor that we will apply to the sampled \'Color\' in an evolve script // make particles spawned at the end of the trail\'s life dimmer, to avoid hard-ending trails. ColorCoeff = ColorCoeffLookup.sample(spawner.LifeRatio); //Position = ProjMesh.samplePosition(); // save RealPosition (see the evolvers on why we need this) RealPosition = Position; // velocity goes upwards, faster at the center of the trail (see the curve\'s shape) Velocity = float3(0,1,0) * DisplacementWeight.sample(spawner.LifeRatio); } "; } CParticleSamplerProceduralTurbulence $LOCAL$/CParticleSamplerProceduralTurbulence_E0F88948 { SamplerName = "Noise3D"; Scale = 2.5000000e-001; Strength = 2.0000000e-001; TimeScale = 1.0000000e+000; TimeBase = 2.0000000e+000; } CParticleEvolver_Field $LOCAL$/CParticleEvolver_Field_11EF5012 { Name = "Color"; Evaluator = "$LOCAL$/CParticleSamplerCurve_870B473D"; } CCompilerSyntaxNodeExpression $LOCAL$/CCompilerSyntaxNodeExpression_4DAC29C5 { Expression = "function void Eval() { // the other evolvers have computed a new Position, back it up in \'RealPosition\' // (see the comments in the first script evolver for details) RealPosition = Position; // the projection evolver filled \'PCoords\' with the meshe\'s parametric coordinates for us. // use this to grab the mesh normal where at the location we were reprojected on: float3 meshNormalAtLocation = ProjMesh.sampleNormal(PCoords); // sample the random procedural turbulent field to get a turbulent displacement: float3 turb = Noise3D.sample(RealPosition); // project this vector with the mesh normal, so that it becomes tangent to the triangle plane. // this will effectively convert it to a 2D tangent turbulence, because we don\'t want // the 3D turbulent vector to make the ribbon penetrate the mesh float3 projTurb = turb + meshNormalAtLocation * max(0,-dot(turb, meshNormalAtLocation)); // patch the Position by moving it slightly away from the mesh surface along the mesh normal, // and displace it by the turbulence vector. float distanceToMesh = 0.05; Position += meshNormalAtLocation * distanceToMesh + projTurb; // apply our color coefficient to the RGBA color sampled in the CParticleEvolver_Field that // was run before us: Color *= ColorCoeff; } "; } CParticleEvolver_Physics $LOCAL$/CParticleEvolver_Physics_815F8FC3 { } CParticleFieldDeclaration $LOCAL$/CParticleFieldDeclaration_6ACE796C { FieldName = "RealPosition"; FieldType = float3; TransformFilter = full; } CParticleSamplerCurve $LOCAL$/CParticleSamplerCurve_870B473D { ValueType = Float4; Times = { 0.0000000e+000, 1.6905037e-001, 1.0000000e+000, }; FloatValues = { 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 3.4852638e+000, 6.2353525e+000, 2.6371586e+001, 9.5917916e-001, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, }; FloatTangents = { 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 5.3765507e+000, 1.4243516e+001, 2.5521017e+001, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000, }; MinLimits = float4(0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000); } CCompilerSyntaxNodeExpression $LOCAL$/CCompilerSyntaxNodeExpression_E63D424E { Expression = "function void Eval() { // here, we have a problem: // we can\'t yet (in popcorn 1.5.4) tell the ribbon renderer to use a custom field // for position, and we want to manually shift the positions away from the mesh surface. // if we shift the positions used for reprojection, they will shift from frame to frame // and become dependent of the FPS. // Therefore, we\'ll use a trick where we will \'backup\' the simulated position into a custom // field named \'RealPosition\', then we\'ll shift the \'Position\' field to get it ready for rendering // at the start of the next frame, we\'ll restore \'Position\' to the one saved in \'RealPosition\', // so that simulation uses the correct value, not the one deformed for rendering. // here, restore the projected position saved in the previous frame Position = RealPosition; // all the next evolvers in the state will work on this restored \'Position\', // up to the last script evolver } "; } CParticleEvolver_Field $LOCAL$/CParticleEvolver_Field_25CAC61C { EditorInfosIsBlockMinimized = 0; Name = "Size"; Evaluator = "$LOCAL$/CParticleSamplerCurve_F033910F"; } CParticleSamplerCurve $LOCAL$/CParticleSamplerCurve_31F983E2 { EditorInfosIsBlockMinimized = 0; SamplerName = "ColorCoeffLookup"; Times = { 0.0000000e+000, 1.0000000e+000, }; FloatValues = { 1.0483411e+001, 1.3673043e-001, }; FloatTangents = { 0.0000000e+000, 0.0000000e+000, -1.5378418e+001, 0.0000000e+000, }; MinLimits = float4(0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000); } CParticleSamplerCurve $LOCAL$/CParticleSamplerCurve_F033910F { Times = { 0.0000000e+000, 2.6556039e-001, 1.0000000e+000, }; FloatValues = { 0.0000000e+000, 7.1906403e-002, 2.3364559e-002, }; FloatTangents = { 0.0000000e+000, 1.4652826e-001, 0.0000000e+000, 0.0000000e+000, -5.8887009e-002, 0.0000000e+000, }; MinLimits = float4(0.0000000e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000); } CParticleEvolver_Script $LOCAL$/CParticleEvolver_Script_1CA6C021 { Expression = "$LOCAL$/CCompilerSyntaxNodeExpression_4DAC29C5"; } CParticleAttributeDeclaration $LOCAL$/CParticleAttributeDeclaration_9BDD555E { AttributeName = "ProbeVelocity"; AttributeDescription = "Initial velocity of lightning strokes\\nDirectly controls the stroke length."; DefaultValueF4 = float4(3.4574502e+000, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000); HasMin = true; HasMax = true; MaxValueF4 = float4(1.0000000e+002, 0.0000000e+000, 0.0000000e+000, 0.0000000e+000); } CActionFactoryParticleSpawnerBase $LOCAL$/Source { Descriptor = "$LOCAL$/CParticleDescriptor_2830BC72"; Infinite = true; DurationInSeconds = 2.0000000e+000; SpawnCount = 8.0000000e+001; FluxFactorExpression = "Flux"; } CParticleRenderer_Ribbon $LOCAL$/CParticleRenderer_Ribbon_976AB253 { BillboardingMaterial = Additive_Soft; Diffuse = "Textures/FX/Lightning_05.dds"; AtlasDefinition = "Textures/FX/AtlasX4.pkat"; } CParticleRenderer_List $LOCAL$/CParticleRenderer_List_6FEA4612 { Renderers = { "$LOCAL$/CParticleRenderer_Ribbon_976AB253", }; } CParticleFieldDeclaration $LOCAL$/CParticleFieldDeclaration_342360F8 { FieldName = "TextureID"; } CParticleSamplerShape $LOCAL$/CParticleSamplerShape_79C1883D { EditorInfosIsBlockMinimized = 0; SamplerName = "Shape_0"; Shape = "$LOCAL$/CShapeDescriptor_1FDF7D44"; } CShapeDescriptor $LOCAL$/CShapeDescriptor_1FDF7D44 { } CParticleSamplerShape $LOCAL$/CParticleSamplerShape_627F92C7 { EditorInfosIsBlockMinimized = 0; SamplerName = "ProjMesh"; Shape = "$LOCAL$/CShapeDescriptor_1AAF32F4"; } CShapeDescriptor $LOCAL$/CShapeDescriptor_1AAF32F4 { ShapeType = SPHERE; Radius = 5.0000000e-001; MeshResource = "Meshes/VenusHigh.pkmm"; } CParticleSamplerShape $LOCAL$/CParticleSamplerShape_23C61C9B { SamplerName = "ProjSpawnMesh"; Shape = "$LOCAL$/CShapeDescriptor_E20159FA"; } CShapeDescriptor $LOCAL$/CShapeDescriptor_E20159FA { ShapeType = SPHERE; Radius = 5.0000000e-001; }