diff --git a/Assets/Editor/ApplyCartoonFireShader.cs b/Assets/Editor/ApplyCartoonFireShader.cs new file mode 100644 index 0000000..01e3b0f --- /dev/null +++ b/Assets/Editor/ApplyCartoonFireShader.cs @@ -0,0 +1,42 @@ +using UnityEngine; +using UnityEditor; + +public static class ApplyCartoonFireShader +{ + [MenuItem("Tools/Apply Cartoon Fire Shader")] + public static void Apply() + { + string materialPath = "Assets/Materials/Fire_Material.mat"; + Material mat = AssetDatabase.LoadAssetAtPath(materialPath); + if (mat == null) + { + Debug.LogError($"Material not found at {materialPath}"); + return; + } + + Shader cartoonShader = Shader.Find("Custom/CartoonFire"); + if (cartoonShader == null) + { + Debug.LogError("Shader Custom/CartoonFire not found! Make sure it compiled successfully."); + return; + } + + Undo.RecordObject(mat, "Apply Cartoon Fire Shader"); + mat.shader = cartoonShader; + + // Set properties + mat.SetColor("_ColorOuter", new Color(1.5f, 0.2f, 0.1f, 1.0f)); + mat.SetColor("_ColorMid", new Color(1.8f, 0.55f, 0.0f, 1.0f)); + mat.SetColor("_ColorInner", new Color(2.2f, 0.95f, 0.15f, 1.0f)); + mat.SetVector("_Speed", new Vector4(0.0f, -1.8f, 0.0f, 0.0f)); + mat.SetFloat("_DistortStrength", 0.08f); + mat.SetFloat("_ThresholdOuter", 0.15f); + mat.SetFloat("_ThresholdMid", 0.38f); + mat.SetFloat("_ThresholdInner", 0.58f); + mat.SetFloat("_NoiseScale", 15.0f); + + EditorUtility.SetDirty(mat); + AssetDatabase.SaveAssets(); + Debug.Log("Successfully applied CartoonFire shader to Fire_Material.mat and set default values!"); + } +} diff --git a/Assets/Editor/ApplyCartoonFireShader.cs.meta b/Assets/Editor/ApplyCartoonFireShader.cs.meta new file mode 100644 index 0000000..c0fea0e --- /dev/null +++ b/Assets/Editor/ApplyCartoonFireShader.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: ccc774ec6a36cbd41af560b342b39471 \ No newline at end of file diff --git a/Assets/Materials/Fire_Material.mat b/Assets/Materials/Fire_Material.mat index 1cd4d0b..f1edd50 100644 --- a/Assets/Materials/Fire_Material.mat +++ b/Assets/Materials/Fire_Material.mat @@ -8,7 +8,7 @@ Material: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: Fire_Material - m_Shader: {fileID: -6465566751694194690, guid: ec072c5cefc89e045946ddcbed457f8a, type: 3} + m_Shader: {fileID: 4800000, guid: 8b5db5774fae5da4e8d1096b76b05ba6, type: 3} m_Parent: {fileID: 0} m_ModifiedSerializedProperties: 0 m_ValidKeywords: [] @@ -45,11 +45,19 @@ Material: m_Offset: {x: 0, y: 0} m_Ints: [] m_Floats: + - _DistortStrength: 0.08 - _Fade: 0.4 - _FireCellsCount: 5 + - _NoiseScale: 15 + - _ThresholdInner: 0.58 + - _ThresholdMid: 0.38 + - _ThresholdOuter: 0.15 m_Colors: - _Color: {r: 2, g: 2, b: 2, a: 1} - - _Speed: {r: 0, g: -0.5, b: 0, a: 0} + - _ColorInner: {r: 2.2, g: 0.95, b: 0.15, a: 1} + - _ColorMid: {r: 1.8, g: 0.55, b: 0, a: 1} + - _ColorOuter: {r: 1.5, g: 0.2, b: 0.1, a: 1} + - _Speed: {r: 0, g: -1.8, b: 0, a: 0} m_BuildTextureStacks: [] m_AllowLocking: 1 --- !u!114 &3751385830976373873 diff --git a/Assets/Scenes/Levels/1-1.unity b/Assets/Scenes/Levels/1-1.unity index e7c7cb4..f95692f 100644 --- a/Assets/Scenes/Levels/1-1.unity +++ b/Assets/Scenes/Levels/1-1.unity @@ -511322,9 +511322,9 @@ Transform: m_GameObject: {fileID: 1960185702} serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 359.75, y: -8.25, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 + m_LocalPosition: {x: 350.75, y: -7.25, z: 0} + m_LocalScale: {x: 0.35, y: 0.35, z: 0.35} + m_ConstrainProportionsScale: 1 m_Children: - {fileID: 2060491968} m_Father: {fileID: 215445643} @@ -511378,7 +511378,7 @@ SpriteRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_MaskInteraction: 0 - m_Sprite: {fileID: -6229913347053766037, guid: 1b1114bc71f1d3f429880f34c5fd8246, type: 3} + m_Sprite: {fileID: 8051134168378353487, guid: c25aa87244f398143b580fa4102b0db1, type: 3} m_Color: {r: 1, g: 1, b: 1, a: 1} m_FlipX: 0 m_FlipY: 0 @@ -516711,7 +516711,7 @@ ParticleSystem: m_PostInfinity: 2 m_RotationOrder: 4 cycleCount: 1 - repeatInterval: 0.0001 + repeatInterval: 0.01 probability: 1 SizeModule: enabled: 0 diff --git a/Assets/Shaders/CartoonFire.shader b/Assets/Shaders/CartoonFire.shader new file mode 100644 index 0000000..ed3355d --- /dev/null +++ b/Assets/Shaders/CartoonFire.shader @@ -0,0 +1,172 @@ +Shader "Custom/CartoonFire" +{ + Properties + { + [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} + _Color ("Main Color (Multiplier)", Color) = (1,1,1,1) + + [HDR] _ColorOuter ("Outer Color (Red)", Color) = (1.5, 0.2, 0.1, 1) + [HDR] _ColorMid ("Mid Color (Orange)", Color) = (1.8, 0.55, 0.0, 1) + [HDR] _ColorInner ("Inner Color (Yellow)", Color) = (2.2, 0.95, 0.15, 1) + + _Speed ("Scroll Speed (XY)", Vector) = (0.0, -1.8, 0.0, 0.0) + _DistortStrength ("Distort Strength", Range(0, 0.5)) = 0.08 + + _ThresholdOuter ("Threshold Outer", Range(0, 1)) = 0.15 + _ThresholdMid ("Threshold Mid", Range(0, 1)) = 0.38 + _ThresholdInner ("Threshold Inner", Range(0, 1)) = 0.58 + + _NoiseScale ("Noise Scale", Range(1, 50)) = 15.0 + } + + SubShader + { + Tags + { + "Queue" = "Transparent" + "IgnoreProjector" = "True" + "RenderType" = "Transparent" + "PreviewType" = "Plane" + "CanUseSpriteAtlas" = "True" + "RenderPipeline" = "UniversalPipeline" + } + + Cull Off + Lighting Off + ZWrite Off + Blend SrcAlpha OneMinusSrcAlpha + + Pass + { + Name "SpriteUnlit" + HLSLPROGRAM + #pragma vertex vert + #pragma fragment frag + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + + struct Attributes + { + float4 positionOS : POSITION; + float4 color : COLOR; + float2 uv : TEXCOORD0; + }; + + struct Varyings + { + float4 positionCS : SV_POSITION; + float4 color : COLOR; + float2 uv : TEXCOORD0; + }; + + TEXTURE2D(_MainTex); + SAMPLER(sampler_MainTex); + + CBUFFER_START(UnityPerMaterial) + float4 _MainTex_ST; + float4 _Color; + float4 _ColorOuter; + float4 _ColorMid; + float4 _ColorInner; + float4 _Speed; + float _DistortStrength; + float _ThresholdOuter; + float _ThresholdMid; + float _ThresholdInner; + float _NoiseScale; + CBUFFER_END + + // Procedural noise functions + float hash(float2 p) + { + p = frac(p * float2(123.34, 456.21)); + p += dot(p, p + 45.32); + return frac(p.x * p.y); + } + + float noise(float2 p) + { + float2 i = floor(p); + float2 f = frac(p); + float2 u = f * f * (3.0 - 2.0 * f); + + return lerp(lerp(hash(i + float2(0.0,0.0)), hash(i + float2(1.0,0.0)), u.x), + lerp(hash(i + float2(0.0,1.0)), hash(i + float2(1.0,1.0)), u.x), u.y); + } + + float fbm(float2 p) + { + float v = 0.0; + float a = 0.5; + float2 shift = float2(100.0, 100.0); + float2x2 rot = float2x2(0.8, 0.6, -0.6, 0.8); + for (int i = 0; i < 4; ++i) { + v += a * noise(p); + p = mul(rot, p) * 2.0 + shift; + a *= 0.5; + } + return v; + } + + Varyings vert(Attributes input) + { + Varyings output; + output.positionCS = TransformObjectToHClip(input.positionOS.xyz); + output.uv = input.uv; + output.color = input.color; + return output; + } + + float4 frag(Varyings input) : SV_Target + { + // Calculate moving noise coordinates + float2 noiseUV = input.uv * _NoiseScale + _Speed.xy * _Time.y; + float n = fbm(noiseUV); + + // Distort the UV coordinates + float2 distortedUV = input.uv + float2(n - 0.5, n - 0.5) * _DistortStrength; + + // Sample the main sprite texture + float4 mainTex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, distortedUV); + + // Base value is derived from texture transparency and color + float value = mainTex.a; + + // Fade out at the top of the sprite (vertical gradient) + value *= saturate(1.15 - input.uv.y); + + // Combine with noise value + value = saturate(value * 0.3 + value * n * 0.7); + + // Toon stepping (thresholds) + float stepOuter = step(_ThresholdOuter, value); + float stepMid = step(_ThresholdMid, value); + float stepInner = step(_ThresholdInner, value); + + // Select color based on steps + float4 fireColor = float4(0, 0, 0, 0); + + if (stepInner > 0.5) + { + fireColor = _ColorInner; + } + else if (stepMid > 0.5) + { + fireColor = _ColorMid; + } + else if (stepOuter > 0.5) + { + fireColor = _ColorOuter; + } + + // Final alpha is gated by the outer step + fireColor.a *= stepOuter; + + // Modulate by sprite / particle vertex color + fireColor *= input.color * _Color; + + return fireColor; + } + ENDHLSL + } + } +} diff --git a/Assets/Shaders/CartoonFire.shader.meta b/Assets/Shaders/CartoonFire.shader.meta new file mode 100644 index 0000000..50db873 --- /dev/null +++ b/Assets/Shaders/CartoonFire.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 8b5db5774fae5da4e8d1096b76b05ba6 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: