Jump to content

Parts shaders replacement, PBR, WIP release!


Lilleman

Recommended Posts

Hi everyone!

 

This plugin, mostly intended to part modders at the moment, will replace all common KSP part shaders by customized Unity Standard shaders. It replace automatically the part's shader when a mask texture is found in the mod folder.

You will then be able to define Metallic, Smoothness, and Occlusion values:

The Red channel defines the Metallic value,

the Green channel defines the Smoothness value

and the Alpha channel define Occlusion value.

For Specular shaders, the Metallic value is not needed, so the red channel is unused.

 

The archive contains mask textures for stock parts, made with a script. This is stil a WIP and some parts looks shinier than other.
 

 

 

Current version : 0.04

Download : https://www.dropbox.com/s/qh714b3p6an1e9i/PBRShaderLoader_v0.04.zip?dl=0

Sources : https://www.dropbox.com/s/a2jeqd5a2jg8fd6/PBRShaderLoader_v0.04_src.zip?dl=0

 

License : WTFPL.

 

Known problems :

-The sky and the ground aren't reflected

-Two faces of the reflection cubemap are inverted

-The reflection probe is attached to the root part, not the center of the vessel

 

 

Original post:

Spoiler

 

With the release of 1.1 I decided to mess around with the new possibilities of Unity 5.

Obvious one is the Physic Based Rendering, so I modified some standard shaders to fit KSP requirements (from Bumped to Specular).

It works like a charm and I'm curently using a mask texture to define additional values (for instance, the diffuse shader use the red channel for Metalness, green channel for Gloss, and blue for Occlusion, no purpose for alpha yet).

It leads me to 3 questions:

-With the current method, Metalness, Gloss and Occlusion can have 256 different values. Is it precise enough?

-To get a satisfying result, the mask texture must be done by hand. Is there a proper way to do this? I'm not an artist to begin with, and the result looks amateurish.

-Is there a better way to do it?

Here is an example of what I do NOT want it to look like :

hxSO6U4m.jpg

 

Thanks in advance for any answer/suggestion.

 

 

Edited by Lilleman
update
Link to comment
Share on other sites

how did you get it to load? There's a PBR shader in PartTools legacy, but last I tried it doesn't make it past MU exporter. all other instances I see people having to use a plugin to load a shader.

Metalness/Spec; Gloss are generally modified from diffuse map, or baked from special shaders in 3d package. Occlusion is baked from 3d package. 3d texturing tools like Substance or Quixel have tools to generate all the necessary maps.

Edited by nli2work
Link to comment
Share on other sites

1.1 doesn't have reflection probes (cubemaps) yet, which are fundamental to this lighting model, so PBR is currently useless.

256 values are more than enough for metalness/gloss/occlusion. But note that texture compression is also an important factor here. RGB channels are compressed quite heavily, while Alpha channel offers the best quality. Because of that it's best to store occlusion in alpha to preserve smooth gradients. Other maps are usally fine with any RGB channel.
There's no correct way to do the masks, but there are calibration guides for various basic materials that really help get good results. For metalness generally you want either full white or black values. In-between materials are very uncommon, and you'll want mid-values only for transitions if anything, or stuff like a thin dust layer covering a metallic surface.
Unity offers two workflows for PBR materials. Specular and Metallic. I plan to use the Metallic workflow eventually.
Here are unity calibration charts for both workflows:

Metallic: http://blogs.unity3d.com/wp-content/uploads/2014/11/UnityMetallicChart.png
Specular: http://blogs.unity3d.com/wp-content/uploads/2014/11/UnitySpecularChart.png

Edited by Porkjet
Link to comment
Share on other sites

Reflection probe is for real-time reflections. there's still the main skybox, in orbit it's a cubemap, on planet it's a gradient looks like? that should still affect the PBR shader and make it look drastically different from any legacy shaders no? I tried exporting KSP Standard Bump in one of the prereleases KSP won't load the MU. 

did the updated PartTool shaders ever drop? I didn't see anything. PartTool shaders still have burn color linked instead of main color, in game main color works as expected.

Edited by nli2work
Link to comment
Share on other sites

1 hour ago, nli2work said:

how did you get it to load? There's a PBR shader in PartTools legacy, but last I tried it doesn't make it past MU exporter. all other instances I see people having to use a plugin to load a shader.

Nothing new here, it's an old hacky method I use since 0.90 or something. It does not use the asset loader or any new functionality from 1.1, and in it's current state it'll probably be incompatible with most mods. I'm using a plugin to replace a shader when a mask is available.

I'll take a look at Substance and Quixel. At the moment I'm using Paint.net and GIMP, it's a bit tedious, to say the least...

33 minutes ago, Porkjet said:

1.1 doesn't have reflection probes (cubemaps) yet, which are fundamental to this lighting model, so PBR is currently useless.

I didn't find a good way to use reflection probes in Unity's editor, it'll probably be too expensive to update reflection for each part, since none of them will provide a real reflection. Even without them, it makes a noticeable difference.

 

33 minutes ago, Porkjet said:

256 values are more than enough for metalness/gloss/occlusion. But note that texture compression is also an important factor here. RGB channels are compressed quite heavily, while Alpha channel offers the best quality. Because of that it's best to store occlusion in alpha to preserve smooth gradients. Other maps are usally fine with any RGB channel.
There's no correct way to do the masks, but there are calibration guides for various basic materials that really help get good results. For metalness generally you want either full white or black values. In-between materials are very uncommon, and you'll want mid-values only for transitions if anything, or stuff like a thin dust layer covering a metallic surface.
Unity offers two workflows for PBR materials. Specular and Metallic. I plan to use the Metallic workflow eventually.
Here are unity calibration charts for both workflows:

Metallic: http://blogs.unity3d.com/wp-content/uploads/2014/11/UnityMetallicChart.png
Specular: http://blogs.unity3d.com/wp-content/uploads/2014/11/UnitySpecularChart.png

Thank for all that. I'll switch the occlusion to the alpha channel, just in case.

edit: Forgot to mention, but if someone want to take a look at the sources, feel free to ask. (the burn color is linked to the main color too, but I can fix that easily)

Edited by Lilleman
Link to comment
Share on other sites

31 minutes ago, Lilleman said:

I didn't find a good way to use reflection probes in Unity's editor, it'll probably be too expensive to update reflection for each part, since none of them will provide a real reflection. Even without them, it makes a noticeable difference.

Not really a good difference tbh. On very shiny surfaces the specular highlight becomes very small and cubemap reflection sharper and more pronounced. Without the cubemap it just looks wrong.

In unity editor it's real simple to add a reflection probe. Just add the object, its in the lighting menu, and add the correct settings. Make sure the bounds are large enough to cover your objects and set it to realtime, play around with the settings, you'll notice when it works.

There probably are ways to mod reflection probes in too. Whatever people use to get cubemap reflections for the windowshine mod, that might actually be useful for PBR. And realtime should be no problem for any half-decent PC really, if you somehow get it working. The challenge is to make it work with the complex scene and camera setup in KSP but it looks like modders have solved that already.

Link to comment
Share on other sites

Because of the complex scene, I thought it would not work as in the editor and I didn't tried to add reflection probes to KSP... I was wrong. And it was surpringly easy...

Here's what a single probe attached to a vessel , with a resolution of 128, looks like. (The mask values aren't right, Gloss is set very high to test reflections)

v6fVWU9m.jpg

 

I think I have enough to work with for a while. I'll try to make some better masks textures and see how it turns out. Thanks again!

Edited by Lilleman
Link to comment
Share on other sites

That's looking good Lilleman! I tried a bunch of different exports with Unity and KSP Standard shaders, the only one that works partially is Unity Standard Metal. KSP Standard and Unity Standard Specular wont' even make it through PartTools... much less Light probes and Reflection probes.

Link to comment
Share on other sites

Well, it's trickier than I thought yesterday. I'm starting to run into small problems, like the navball being reflected, as well as those new IVA views.

http://imgur.com/a/9Ptv5

 

On 26/04/2016 at 4:16 PM, nli2work said:

I tried a bunch of different exports with Unity and KSP Standard shaders, the only one that works partially is Unity Standard Metal. KSP Standard and Unity Standard Specular wont' even make it through PartTools... much less Light probes and Reflection probes.

 

I can give you the shaders I made if you want to test some things. But since it's still a WIP, it's probably not a good idea to base your work on it (I'm not sure if specular is working correctly, and the burn color is still linked to the main color).

Edited by Lilleman
Link to comment
Share on other sites

'Got a first "proof of concept" release to make. It's very basic, but you can already have an idea of what it will look like, and mess with it.

I'm not sure about the license for the compiled version : it use some masks made from Squad's textures, can I redistribute them with the current license (WTFPL)?

They are made from a script, so at the moment they are not looking as nice as they should. Most of them are looking somehow similar to the stock game.

As mentioned earlier: the red channel set the "Metallic" value, green is "Smoothness", alpha is "Occlusion". Red channel isn't necessary for Specular shaders.

 

Anyway, some parts still don't have a new shader (like the OscarB fuel tank): it seems they use the "KSP/ScreenSpaceMask" one. As it wasn't in the 1.1 parttools package, I'm not sure how it should behave.

Here's the compiled version : https://www.dropbox.com/s/0l70289yyipkoym/PBRShaderLoader.zip?dl=0

Sources : https://www.dropbox.com/s/isc2yjsgs4l1rpe/PBRShaderLoader_src.zip?dl=0

This is an extreme case. Do not try this at home

2BzlA8em.jpg

 

Edit : forgot to mention : Expect some glitches. It does not look as nice in movement...

Edited by Lilleman
Link to comment
Share on other sites

Yep. For now it can replace KSP/Alpha/Cutoff, KSP/Alpha/Cutoff Bumped, KSP/Alpha/Translucent, KSP/Bumped, KSP/Bumped Specular, KSP/Diffuse, KSP/Emissive/Bumped Specular, KSP/Emissive/Diffuse, KSP/Emissive/Specular and KSP/Specular. It should cover most parts.

Shader's sources are in the archive, you can check in Unity's editor if they work as you want.

The shader will be replaced only if a mask texture is available. They are stored in the mod folder, I wanted to keep them separated for convenience.

 

Also, it add a reflection probe component to each part. You can set basic properties for it in a config file.

Edited by Lilleman
Link to comment
Share on other sites

Nobody tried it yet? I'm counting on feedbacks to improve this.

Maybe it'll get more visibility in the "Add-on development" section?

 

I'm having a small problem with probes: at the moment they are assigned automatically by Unity: the closest probe to a mesh's face is used.

It can lead to some weirdness, so I need to use the "anchor override" MeshRenderer's option. The problem is: reflection probes are added to parts prefabs, when the MeshRenderer component is not yet initialized. Is there a way to assign the anchor override on a prefab?

Edited by Lilleman
Link to comment
Share on other sites

A reflection probe for each part is a bit expensive, would be better if you spanwed one per vessel at the camera anchor or CoM and increase it's bounds to cover the whole thing. Might be easier for you too.

Link to comment
Share on other sites

Is reflection probes absolutely necessary? It's really meant only for real-time reflections on limited meshes in limited range, and not for general lighting on every thing on large scales. Lighting effects from skybox (the environment) is already calculated into the Standard shader without adding reflection probes. The Flight scenes are not very similar to typical levels you'd build in a game. the VAB/SPH are closer to what typical levels are like. It's hard to test anything without knowing how KSP scenes, lighting, and render settings are. If the skybox in Flight scenes is always the star map, then you would have to use real-time reflection to get some decent looking ambient light effect. 

also would be hard to use hex or xxx,xxx,xxx,xxx for color settings in the config?

there're two new parameters in deployable solar panel (and radiator) planetLayerMask and defaultLayerMask, may be provisions for future implementation of reflection on these parts.

KSP has layers for ScaledScenery, Planets and terrain I think, on layer 10; and Local Scenery, static meshes like VAB and Anamolies I think, on 15; maybe some performance can be gained by setting reflection probe culling mask to these layers. It would mean no Part-to-Part reflection as most if not all part meshes are on default layer.

Edited by nli2work
Link to comment
Share on other sites

I was trying to get the most accurate reflections possible, but a probe per part is definitely too much. Unity handles it, though, it just refresh them very slowly. Still, I need to use something else.

I tried that because there's no way to set the probe's culling mask to ignore parts, and it leads to some weird reflections (IVA view is reflected, for instance). I don't think I can change the parts rendering layers to fit my needs.

As for the skybox, I was thinking of making my own (make a cubemap from a camera). I'm not sure how it will turn out.

1 hour ago, nli2work said:

also would be hard to use hex or xxx,xxx,xxx,xxx for color settings in the config?

No problem.

 

Link to comment
Share on other sites

It's still not working exactly as it should, but it looks a bit better.

 

v0.02 Changelog:

-Fixed the Alpha Cutoff shaders, to get rid of a somehow good-looking glitch http://imgur.com/OMxXrir

-Use a single reflection probe per vessel.

-The backgound color in the config file is now an hex value

-The "reflection probe size" value now does nothing (the reflection probe should be scaled from the ship's size)

 

That's about it. I'm still trying to figure out how to hide a vessel's meshrenderers before updating the cubemap. Also, whatever I try, the probe seems to be located in the root part, I can't find a way to attach it to the ship bounds center...

 

Download : https://www.dropbox.com/s/6f36nv5iaxvqvjh/PBRShaderLoader_v0.02.zip?dl=0

Sources : https://www.dropbox.com/s/mrj2znkt8atj0p8/PBRShaderLoader_v0.02_src.zip?dl=0

 

uPC8pUHm.jpg

Edited by Lilleman
Link to comment
Share on other sites

On 4/30/2016 at 11:40 AM, Lilleman said:

I was trying to get the most accurate reflections possible, but a probe per part is definitely too much. Unity handles it, though, it just refresh them very slowly. Still, I need to use something else.

yeah there're 3 different ways Unity updates reflection cube map. either updating only on Awake, update each face sequentially over a several frames, or update all faces at once. All at once gives most accurate reflection relative to time, but most resource intensive. 

Have you looked at light probes? that's intended more for the effect you're after, though that might require some changes (likely big) on Squad's side. As for reflection probe bounds... maybe referencing the part's drag cube could help? or perhaps checking out FAR's voxelization process to estimate the bounds of full vessel on load?

Edited by nli2work
Link to comment
Share on other sites

36 minutes ago, nli2work said:

Have you looked at light probes? that's intended more for the effect you're after, though that might require some changes (likely big) on Squad's side. As for reflection probe bounds... maybe referencing the part's drag cube could help? or perhaps checking out FAR's voxelization process to estimate the bounds of full vessel on load?

If it was just for the ambient lighting, Planetshine is doing just fine. But PBR shaders are not looking as good without reflections. 

7WNtT07l.jpg

Jool's reflection on Kerbal X.

Plus, I never used light probes. I just took a quick look on Unity's documentation, and I don't really see how it could be applied to KSP. I'll learn a bit about it.

FAR's solution to calculate bounds  seems overly complicated for my needs, I've got a function to do that (wich is just testing parts renderers bounds). I should try to attach the probe to the closest part to bounds center, instead of the root part.

Edited by Lilleman
Link to comment
Share on other sites

Yeah it's always a trade off between FPS and accuracy. Light probes also needs light maps to work, which I don't think Squad is doing at the moment. not even sure if it's possible with the way the scene scales in KSP.

how often does bounds testing happen? what happens when parts come/go like docking two vessels and boosters drop off?

Link to comment
Share on other sites

At the moment, bounds are calculated once, on vessel loading.

I planned to resize/change the position of the reflection probe each time the vessel is modified (on stage/crash/dock), and also add a low-res probe to debris (refresh rate and resolution should be defined depending on camera's distance).

For now it adds a reflection probe when OnVesselChange is called. Some changes needs to be made here.

I want to clean the code first, and check if it's compatible with other mods (I suspect my shader loader class to be incompatible with Texture Replacer).

 

Here's the function I use to find a vessel bounds. It's a bit naive, but it should do the trick for what I want to do: http://pastebin.com/m4gQQdQc

Edited by Lilleman
Link to comment
Share on other sites

this is in 1.1.1; might be shader related... the plugin breaks launch clamp, logs show these messages on vessel load, 

[LOG 17:27:48.517] Unpacking Untitled Space Craft
[ERR 17:27:48.518] Infinity or NaN floating point numbers appear when calculating the transform matrix for a Collider. Scene hierarchy path "launchClamp1/model/launchclamp/obj_ground/obj_ground_mesh"

[ERR 17:27:48.519] Infinity or NaN floating point numbers appear when calculating the transform matrix for a Collider. Scene hierarchy path "launchClamp1/model/launchclamp/obj_girdercap/obj_girder/obj_girder_mesh"

[ERR 17:27:48.519] Infinity or NaN floating point numbers appear when calculating the transform matrix for a Collider. Scene hierarchy path "launchClamp1/model/launchclamp/obj_ground/obj_ground_mesh"

[ERR 17:27:48.520] Infinity or NaN floating point numbers appear when calculating the transform matrix for a Collider. Scene hierarchy path "launchClamp1/model/launchclamp/obj_girdercap/obj_girder/obj_girder_mesh"

[ERR 17:27:48.520] Infinity or NaN floating point numbers appear when calculating the transform matrix for a Collider. Scene hierarchy path "launchClamp1/model/launchclamp/obj_ground/obj_ground_mesh"

[ERR 17:27:48.520] Infinity or NaN floating point numbers appear when calculating the transform matrix for a Collider. Scene hierarchy path "launchClamp1/model/launchclamp/obj_girdercap/obj_girder/obj_girder_mesh"

Also spams "Look rotation viewing vector is zero" on revert or switching to vessel after relaunching game.

Edited by nli2work
Link to comment
Share on other sites

Looks like the plugin tried to locate an unactive object.

It crashed the game when you switch from a vessel to a launchclamp, but not when you switch from a vessel to another... I didn't noticed that.

 

 

edit2 : found the problem, should've used Part.GetPartRendererBound(), instead of Part.gameObject.GetRendererBounds() in my previous function. I'll take a closer look at it tomorrow.

Edited by Lilleman
removed 0.021 links
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...