|
| 1 | +using System; |
| 2 | +using System.Collections.Generic; |
| 3 | +using System.Linq; |
| 4 | +using UnityEngine; |
| 5 | +using System.IO; |
| 6 | +using System.Text; |
| 7 | +using System.Reflection; |
| 8 | + |
| 9 | +namespace ReflectionPlugin |
| 10 | +{ |
| 11 | + public class ReflectiveShaderModule : PartModule |
| 12 | + { |
| 13 | + [KSPField(isPersistant = false)] |
| 14 | + public int CubeMapSize = 128; |
| 15 | + [KSPField(isPersistant = false)] |
| 16 | + public float FarClipPlane = 100f; |
| 17 | + [KSPField(isPersistant = false)] |
| 18 | + public float NearClipPlane = -1f; |
| 19 | + [KSPField(isPersistant = false)] |
| 20 | + public string MeshesToChange = ""; |
| 21 | + [KSPField(isPersistant = false)] |
| 22 | + public bool OneFacePerFrame = true; |
| 23 | + [KSPField(isPersistant = false)] |
| 24 | + public float ParallaxHeight = 0.02f; |
| 25 | + [KSPField(isPersistant = false)] |
| 26 | + public float ReflectionStrength = 1.0f; |
| 27 | + [KSPField(isPersistant = false)] |
| 28 | + public Color ReflectionColor = new Color(0.5f, 0.5f, 0.5f, 0.5f); |
| 29 | + [KSPField(isPersistant = false)] |
| 30 | + public Color _Color = new Color(1.0f, 1.0f, 1.0f, 1.0f); |
| 31 | + [KSPField(isPersistant = false)] |
| 32 | + public string ShaderName = ""; |
| 33 | + [KSPField(isPersistant = false)] |
| 34 | + public float Shininess = -1f; |
| 35 | + [KSPField(isPersistant = false)] |
| 36 | + public float SpecColorA = 0.5f; |
| 37 | + [KSPField(isPersistant = false)] |
| 38 | + public float SpecColorB = 0.5f; |
| 39 | + [KSPField(isPersistant = false)] |
| 40 | + public float SpecColorG = 0.5f; |
| 41 | + [KSPField(isPersistant = false)] |
| 42 | + public float SpecColorR = -1f; |
| 43 | + [KSPField(isPersistant = false)] |
| 44 | + public float rimFalloff = 0; |
| 45 | + [KSPField(isPersistant = false)] |
| 46 | + public Color rimColor = new Color(0f, 0f, 0f, 0f); |
| 47 | + [KSPField(isPersistant = false)] |
| 48 | + public bool realTimeReflection = true; |
| 49 | + [KSPField(isPersistant = false)] |
| 50 | + public double updateRate = 60.0; |
| 51 | + [KSPField(isPersistant = false, guiActive = false, guiName = "Last Scene", guiUnits = "", guiFormat = "G")] |
| 52 | + public string lastScene = ""; |
| 53 | + [KSPField(isPersistant = false, guiActive = false, guiName = "Shader", guiUnits = "", guiFormat = "G")] |
| 54 | + public string scriptStatus = ""; |
| 55 | + |
| 56 | + |
| 57 | + |
| 58 | + private Shader _rShader; |
| 59 | + private ReflectiveScript reflectiveScript = null; |
| 60 | + |
| 61 | + public override void OnStart(PartModule.StartState state) |
| 62 | + { |
| 63 | + Debug.Log((object)"RP: Starting ReflectionPlugin .. "); |
| 64 | + if (this.ShaderName == string.Empty) |
| 65 | + { |
| 66 | + Debug.Log((object)"RP: Defaulting shader to \"Reflective/VertexLit\""); |
| 67 | + this.ShaderName = "Reflective/VertexLit"; |
| 68 | + } |
| 69 | + this._rShader = Shader.Find(this.ShaderName); |
| 70 | + Shader fallbackShader = Shader.Find("Reflective/VertexLit"); |
| 71 | + |
| 72 | + if ((UnityEngine.Object)this._rShader == (UnityEngine.Object)null) |
| 73 | + { |
| 74 | + Debug.LogWarning((object)string.Format("RP: Could not find the specified shader \"{0}\".", (object)this.ShaderName)); |
| 75 | + Debug.LogWarning((object)"RP: Simple reflective shaders:"); |
| 76 | + Debug.LogWarning((object)"RP: -\"Reflective/Diffuse\""); |
| 77 | + Debug.LogWarning((object)"RP: -\"Reflective/Specular\""); |
| 78 | + Debug.LogWarning((object)"RP: -\"Reflective/VertexLit\""); |
| 79 | + Debug.LogWarning((object)"RP: Advanced reflective shaders:"); |
| 80 | + Debug.LogWarning((object)"RP: -\"Reflective/Bumped Diffuse\""); |
| 81 | + Debug.LogWarning((object)"RP: -\"Reflective/Bumped Specular\""); |
| 82 | + Debug.LogWarning((object)"RP: -\"Reflective/Bumped Unlit\""); |
| 83 | + Debug.LogWarning((object)"RP: -\"Reflective/Bumped VertexLit\""); |
| 84 | + Debug.LogWarning((object)"RP: -\"Reflective/Parallax Diffuse\""); |
| 85 | + Debug.LogWarning((object)"RP: -\"Reflective/Parallax Specular\""); |
| 86 | + // Try to handle fallback later during material building |
| 87 | + // This is so we can try to load and deserialize missing shaders from compiled shader code. |
| 88 | + this._rShader = null; |
| 89 | + //this._rShader = Shader.Find(this.ShaderName); |
| 90 | + //if ((UnityEngine.Object)this._rShader == (UnityEngine.Object)null) |
| 91 | + //{ |
| 92 | + // Debug.LogWarning((object)"RP: Fallback shader VertexLit failed."); |
| 93 | + //} |
| 94 | + } |
| 95 | + else |
| 96 | + { |
| 97 | + Debug.LogWarning((object)string.Format("RP: Found shader \"{0}\".", (object)this._rShader.name)); |
| 98 | + } |
| 99 | + |
| 100 | + if (this.MeshesToChange == string.Empty) |
| 101 | + { |
| 102 | + Debug.Log((object)"RP: Applying changes to part .."); |
| 103 | + this.ReplaceShader(this.part.FindModelComponent<UnityEngine.Renderer>()); |
| 104 | + } |
| 105 | + else |
| 106 | + { |
| 107 | + Debug.Log((object)"RP: Applying changes to meshes .."); |
| 108 | + List<string> meshNamesList = Enumerable.ToList<string>((IEnumerable<string>)this.MeshesToChange.Split(new char[1] { ',' })); |
| 109 | + MeshFilter[] modelComponents = this.part.FindModelComponents<MeshFilter>(); |
| 110 | + if (this.MeshesToChange == "all") |
| 111 | + { |
| 112 | + foreach (MeshFilter meshFilter in modelComponents) |
| 113 | + { |
| 114 | + Debug.Log((object)("RP: Applying changes to mesh: " + meshFilter.name)); |
| 115 | + this.ReplaceShader(meshFilter.GetComponent<UnityEngine.Renderer>()); |
| 116 | + } |
| 117 | + } |
| 118 | + else |
| 119 | + { |
| 120 | + foreach (MeshFilter meshFilter in Enumerable.Where<MeshFilter>((IEnumerable<MeshFilter>)modelComponents, (Func<MeshFilter, bool>)(mesh => meshNamesList.Contains(mesh.name)))) |
| 121 | + { |
| 122 | + Debug.Log((object)("RP: Applying changes to mesh: " + meshFilter.name)); |
| 123 | + this.ReplaceShader(meshFilter.GetComponent<UnityEngine.Renderer>()); |
| 124 | + } |
| 125 | + } |
| 126 | + } |
| 127 | + Debug.Log((object)"RP: Done."); |
| 128 | + } |
| 129 | + |
| 130 | + |
| 131 | + private void ReplaceShader(UnityEngine.Renderer pRenderer) |
| 132 | + { |
| 133 | + if ((UnityEngine.Object)pRenderer != (UnityEngine.Object)null) |
| 134 | + { |
| 135 | + Debug.Log((object)string.Format("RP: Renderer found: {0}", (object)this._rShader)); |
| 136 | + Material material; |
| 137 | + if (this._rShader == null) |
| 138 | + { |
| 139 | + Debug.Log((object)("RP: null shader. Trying to retrieve ReflectionPlugin.Shaders." + this.ShaderName)); |
| 140 | + Assembly assembly = Assembly.GetExecutingAssembly(); |
| 141 | + StreamReader shaderStreamReader = new StreamReader(assembly.GetManifestResourceStream(/*"ReflectionPlugin.Shaders." + */this.ShaderName)); |
| 142 | + if (shaderStreamReader != null) |
| 143 | + { |
| 144 | + material = new Material(shaderStreamReader.ReadToEnd()) |
| 145 | + { |
| 146 | + mainTexture = pRenderer.material.mainTexture |
| 147 | + }; |
| 148 | + } |
| 149 | + else |
| 150 | + { |
| 151 | + material = new Material(Shader.Find("Reflective/VertexList")) |
| 152 | + { |
| 153 | + mainTexture = pRenderer.material.mainTexture |
| 154 | + }; |
| 155 | + } |
| 156 | + } |
| 157 | + else |
| 158 | + { |
| 159 | + material = new Material(this._rShader) |
| 160 | + { |
| 161 | + mainTexture = pRenderer.material.mainTexture |
| 162 | + }; |
| 163 | + } |
| 164 | + Texture texture1 = pRenderer.material.GetTexture("_BumpMap"); |
| 165 | + Texture texture2 = pRenderer.material.GetTexture("_Emissive"); |
| 166 | + if ((UnityEngine.Object)texture1 != (UnityEngine.Object)null) |
| 167 | + { |
| 168 | + Debug.LogWarning((object)"RP: Found bumpmap texture, applying.."); |
| 169 | + material.SetTexture("_BumpMap", texture1); |
| 170 | + material.SetTextureScale("_BumpMap", pRenderer.material.GetTextureScale("_BumpMap")); |
| 171 | + } |
| 172 | + if ((UnityEngine.Object)texture2 != (UnityEngine.Object)null) |
| 173 | + { |
| 174 | + Debug.LogWarning((object)"RP: Found heightmap texture, applying.."); |
| 175 | + material.SetTexture("_ParallaxMap", texture2); |
| 176 | + material.SetFloat("_Parallax", (double)this.ParallaxHeight < 0.00499999988824129 || (double)this.ParallaxHeight > 0.0799999982118607 ? 0.02f : this.ParallaxHeight); |
| 177 | + material.SetTextureScale("_Parallax", pRenderer.material.GetTextureScale("_Parallax")); |
| 178 | + } |
| 179 | + //try |
| 180 | + //{ |
| 181 | + print("RP: Set _Shininess"); |
| 182 | + material.SetFloat("_Shininess", (double)this.Shininess < 0.0 ? pRenderer.material.GetFloat("_Shininess") : this.Shininess); |
| 183 | + print("RP: Set _SpecColor"); |
| 184 | + material.SetColor("_SpecColor", (double)this.SpecColorR < 0.0 ? pRenderer.material.GetColor("_SpecColor") : new Color(this.SpecColorR, this.SpecColorG, this.SpecColorB, this.SpecColorA)); |
| 185 | + |
| 186 | + // -1 for ReflectionStrength will actually use ReflectionColor, Individual RGB(A???) values can be set in config. |
| 187 | + if (ReflectionStrength < 0f) |
| 188 | + { |
| 189 | + print("RP: Set _ReflectColor: " + ReflectionColor.ToString()); |
| 190 | + material.SetColor("_ReflectColor", ReflectionColor); |
| 191 | + } |
| 192 | + else |
| 193 | + { |
| 194 | + print("RP: Set _ReflectColor (ReflectionStrength: " + this.ReflectionStrength.ToString() + ")"); |
| 195 | + material.SetColor("_ReflectColor", new Color(this.ReflectionStrength, this.ReflectionStrength, this.ReflectionStrength, this.ReflectionStrength)); |
| 196 | + } |
| 197 | + |
| 198 | + print("RP: Set _Color"); |
| 199 | + material.SetColor("_Color", _Color); |
| 200 | + // rim lighting experiment. Useless for Unity reflective shaders; only the KSP versions have it. Disabled as it requires setting to KSP shaders. |
| 201 | + //material.SetFloat("_RimFalloff", rimFalloff); |
| 202 | + //material.SetColor("_RimColor", rimColor); |
| 203 | + |
| 204 | + //} |
| 205 | + //catch (Exception e) |
| 206 | + //{ |
| 207 | + // print("RP: ReplaceShader exception: " + e.ToString() + ": " + e.Message); |
| 208 | + //} |
| 209 | + // Add texture scale support |
| 210 | + material.mainTextureScale = pRenderer.material.mainTextureScale; |
| 211 | + |
| 212 | + pRenderer.material = material; |
| 213 | + ReflectiveScript reflectiveScript = this.part.gameObject.AddComponent<ReflectiveScript>(); |
| 214 | + reflectiveScript.MatRenderer = pRenderer; |
| 215 | + reflectiveScript.CubemapSize = this.CubeMapSize; |
| 216 | + reflectiveScript.FarClipPlane = this.FarClipPlane; |
| 217 | + reflectiveScript.NearClipPlane = this.NearClipPlane; |
| 218 | + reflectiveScript.OneFacePerFrame = this.OneFacePerFrame; |
| 219 | + reflectiveScript.realTimeReflection = this.realTimeReflection; |
| 220 | + reflectiveScript.updateRate = this.updateRate; |
| 221 | + reflectiveScript.dirty = 7; |
| 222 | + this.reflectiveScript = reflectiveScript; |
| 223 | + Debug.Log((object)"RP: Material, shader and texture updated."); |
| 224 | + } |
| 225 | + else |
| 226 | + Debug.LogError((object)("RP: Unable to find a Renderer component on the part. Part: " + this.part.partName)); |
| 227 | + } |
| 228 | + public void FixedUpdate() |
| 229 | + { |
| 230 | + scriptStatus = this.reflectiveScript.status; |
| 231 | + lastScene = this.reflectiveScript.lastScene; |
| 232 | + } |
| 233 | + |
| 234 | +// public override void OnUpdate() |
| 235 | +// { |
| 236 | +// base.OnUpdate(); |
| 237 | +// this.lastScene = this.reflectiveScript.lastScene; |
| 238 | +// this.lastUpdate = this.reflectiveScript.lastUpdate; |
| 239 | +// this.scriptStatus = this.reflectiveScript.status; |
| 240 | +// } |
| 241 | + } |
| 242 | +} |
0 commit comments