Jump to content

[Tutorial] How to load and use custom shaders within KSP


Recommended Posts

I wanted to share a easy way to use your homegrown shaders within KSP.

0. install unity 5.4.0p4 and the KSP parttools (and the parttools bugfix )

1. put your own shaders into a folder (Shaders)

Pxw08FF.png

 

2. tag your shaders as a seperate AssetBundle (or create a new one)

b9gZY02.png

3. start the KSP asset compiler

Chb052n.png

 

4, check if the files are in the bundle

ryPU8XA.png

 

5. press show all, if OK

. n2gnUCv.png

 

6.press the build button

Zaup4Qi.png

 

6. you will find the shader.ksp file in the AssetBundles folder of the folder you put your unity project.

  rkJF1jH.png

 

7. rename the file as you wish and place it in the KSP GameData folder.

 

Now we have the shader compiled and ready to be used within KSP. Next we need find a way to access the shader, because the Shader.find(shadername) function will not find it.

using System.Collections.Generic;
using UnityEngine;

	// only start once at the MainMenu
    [KSPAddon(KSPAddon.Startup.MainMenu, true)]
    public class KSPShader : MonoBehaviour
    {

        private Dictionary<string, Shader> allShaders = new Dictionary<string, Shader>();


        /// <summary>
        /// Initial Unity Awake call
        /// </summary>
        public void Awake()
        {
            LoadShaders();

            var myshader = GetShader("ShaderNG/TypeC");

            if (myshader == null)
            {
                Debug.Log("Shader ShaderNG/TypeC was not loaded");
            } else
            {
                Debug.Log("Shader found");
            }

        }

        internal void LoadShaders()
        {
		// here we force unity to load all shaders, even those that are not used by any material, so we can find ours.
		Shader.WarmupAllShaders();
            foreach (var shader in Resources.FindObjectsOfTypeAll<Shader>())
            {
                if (!allShaders.ContainsKey(shader.name))
                {
                    allShaders.Add(shader.name, shader);
                }
            }
        }

      	// replacement function for Shader.find(). will return any valid shader in the System.
        internal Shader GetShader(string name)
        {
            if (allShaders.ContainsKey(name))
            {
                return allShaders[name];
            } else
            {
                return null;
            }
        }
    }
}

The earliest time to access the shaders is the Awake() function at the MainMenue.

 

Edited by Ger_space
now with the proper use of asset bundles
Link to comment
Share on other sites

On 6/9/2017 at 4:26 AM, Ger_space said:

 

Now we have the shader compiled and ready to be used within KSP. Next we need find a way to access the shader, because the Shader.find(shadername) function will not find it.


using System.Collections.Generic;
using UnityEngine;

	// only start once at the MainMenu
    [KSPAddon(KSPAddon.Startup.MainMenu, true)]
    public class KSPShader : MonoBehaviour
    {

        private Dictionary<string, Shader> allShaders = new Dictionary<string, Shader>();


        /// <summary>
        /// Initial Unity Awake call
        /// </summary>
        public void Awake()
        {
            LoadShaders();

            var myshader = GetShader("ShaderNG/TypeC");

            if (myshader == null)
            {
                Debug.Log("Shader ShaderNG/TypeC was not loaded");
            } else
            {
                Debug.Log("Shader found");
            }

        }

        internal void LoadShaders()
        {
		// here we force unity to load all shaders, even those that are not used by any material, so we can find ours.
		Shader.WarmupAllShaders();
            foreach (var shader in Resources.FindObjectsOfTypeAll<Shader>())
            {
                if (!allShaders.ContainsKey(shader.name))
                {
                    allShaders.Add(shader.name, shader);
                }
            }
        }

      	// replacement function for Shader.find(). will return any valid shader in the System.
        internal Shader GetShader(string name)
        {
            if (allShaders.ContainsKey(name))
            {
                return allShaders[name];
            } else
            {
                return null;
            }
        }
    }
}

The earliest time to access the shaders is the Awake() function at the MainMenue.

 

you should make the GetShader a public static, so it can be accessed from anywhere, would also need to make the allShaders a static

Link to comment
Share on other sites

37 minutes ago, linuxgurugamer said:

you should make the GetShader a public static, so it can be accessed from anywhere, would also need to make the allShaders a static

the allSahders can stay private, because nobody sould access that directly, except the functions LoadShaders() and GetShader() and  internal is OK, for a mod as long as you stay within one dll. 

Link to comment
Share on other sites

2 hours ago, Ger_space said:

the allSahders can stay private, because nobody sould access that directly, except the functions LoadShaders() and GetShader() and  internal is OK, for a mod as long as you stay within one dll. 

I didn't say make the allShaders public, I said it had to be static.

To make it more general, so that it can be used in multiple mods, GetShader() should be public and static

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...