Not logged inOpenClonk Forum
Up Topic General / Help and Questions / Specularity in Material
- - By Foaly [de] Date 2016-05-29 17:41
Is there a way to make materials specular? Or do I have to do this myself in a custom shader?
Parent - - By Matthias [de] Date 2016-05-29 19:56
Meh, so I guess I have to write up my progress from a few month ago. I might even be motivated enough to fix this... ;)

Let's start at the beginning: The OC Lighting Model is just wrong. Inside the shaders, a lot is going on, but in the end, everything is multiplied into the color texture - which does not allow any highlights brighter than what is on the texture. The entire light term is something Peter cooked up himself (Some time ago, he wrote me he would try to fix that, but it didnt happen yet). It works ok for the base lighting have now (only ok because look at how ruby looks above ground), but is horrible for using real values in the .material.

I tried fixing the term once, creating a shader that takes into account at least the color values form the .material file. I used a standard shading model which included ambient, diffuse, specular and emission values. I noticed that every object turned white because they have a maximum emission value. This could be fixed by a small automated tool for the repository objects, at least, but someone would have to do it.

If we include a specular term, it's rather important to have a map to control it (and a convention how that map should work - I propose usage of the alpha channel for pointyness values, but thats for another time). You wouldn't want the skin of the clonk to be shiny, but just his belt and shoes or something. But I fear I don't know what the correct way to include new textures into every(?) shader is. There is a whole lot of #ifdef magic going on. There is a preprocessor directive for normal maps which seems to magically include the map, but there is also an example from ClonkKarl which shows including normal maps via inhertiance in the .material-file. I asked around in the IRC-Channel two month ago but noone seemed to know, so I stopped there. If we reach a consens on what should go where and how it's to be used, I could refactor my changed accordingly - note that I do not have the means to include more magic into the engine, though.

I also got caught at least 2.4mio times breaking the landscape shading because for some reason, everything in the game is rendered by the same CommonShader which also #ifdefs if it is the landscape being rendered. Thats super unhelpful. Is that really necessary?
Reply
Parent - - By Clonk-Karl [us] Date 2016-05-30 18:05
Thanks for bringing that up. I'd also much rather prefer a more traditional lighting model.

> I noticed that every object turned white because they have a maximum emission value. This could be fixed by a small automated tool for the repository objects, at least, but someone would have to do it.


Is this still the case? I see most emission values set to "0.0 0.0 0.0 1.0" in the repo, with very few objects that have non-zero values. But even then we still might need to fine-tune the ambient and diffuse components of many objects.

> But I fear I don't know what the correct way to include new textures into every(?) shader is.


At the moment that's only possible with engine changes.

> There is a preprocessor directive for normal maps which seems to magically include the map, but there is also an example from ClonkKarl which shows including normal maps via inhertiance in the .material-file. I asked around in the IRC-Channel two month ago but noone seemed to know, so I stopped there.


This would only work for mesh object shaders, i.e. not for sprites and not for the landscape. For specular highlights, that might be good enough, though. However, if we have such a map, would the specular value in the .material file still be useful?

> If we reach a consens on what should go where and how it's to be used, I could refactor my changed accordingly - note that I do not have the means to include more magic into the engine, though.


I might be able to take care of some simple engine changes.

> I also got caught at least 2.4mio times breaking the landscape shading because for some reason, everything in the game is rendered by the same CommonShader which also #ifdefs if it is the landscape being rendered. Thats super unhelpful. Is that really necessary?


It is used for the landscape upscaling. I think what it does is it computes the color values of 2 neighbouring pixels (e.g. for transitions between two materials), and then mixes those at the end. The code could possibly be refactored a bit such that it just calls a function that computes the pixel color, and then the landscape shader could call it twice.
Reply
Parent - By Foaly [de] Date 2016-05-31 07:43

> However, if we have such a map, would the specular value in the .material file still be useful?


If an object has no specular map, it will use the specular value in the .material, so it's still useful and a specular map doesn't need to be created for every existing object.
Parent - - By Matthias [de] Date 2016-05-31 08:01

> Is this still the case?


I didn't check the repository since then - But I doubt it would have been changed without any reason? I remember the clonk being pure white at least.. :)

> However, if we have such a map, would the specular value in the .material file still be useful?


Yes - apart from the reason Foaly gave, you usually can also tint existing maps with that (multiply). I doubt it's going to be used much, but basically, you could have the same specularity map and make it a little more blue or a little less strong or - especially interesting in this case - multiply it with some alpha to decrease spottiness - without touching the texture file.

> I might be able to take care of some simple engine changes.


Sounds good! We still have to decide how the shader-texture-association should work then.
For most community developers, the easiest to use a shader would possibly be to just add textures according to a naming convention into the object - something normal.png/jpg, specularity.png, emission.png/jpg. However, I assume this would fail once we think about using two materials in the same object (is that possible?). I don't know if there are other corner cases.
We could also just have them defined as named texture_units, that would be the more typical ogre way, wouldn't it? I think there was something about partially overriding texture_units from the base .material as well?
Reply
Parent - - By Clonkonaut [de] Date 2016-05-31 09:44

> using two materials in the same object (is that possible?)


Yes
Reply
Parent - By Matthias [de] Date 2016-05-31 14:40
Ok, so no magic naming convention then. Might be better anyways ;)
Reply
Parent - By Clonk-Karl [us] Date 2016-06-01 04:26
So the way I see it we are talking about two different but related things here:

1) change the current shading model to take into account all 4 light components (diffuse, ambient, emissive, specular).

2) allow some or all of these to be read from a bitmap instead that gets multiplied with the constant value from the .material script.

Obviously we cannot do 2) before doing 1), so I would suggest to start out with 1). This should be possible by just modifying the shaders we have. Note that a single mesh can consist of multiple submeshes each of which is rendered with a different material, so to a limited extent one can limit specularity to e.g. metallic parts of a mesh already with 1) alone as well. Do you want to play with the shaders to do that? If that needs some mass changing of values in material files, I could help out with that.

Once 1) is in place we can tackle 2). The simple approach that we have for the normal map would not work anymore, because one can only inherit one material, and not multiple materials (needed if we want to allow all possible combinations like "no extra map", "normal map only", "specular map only", "normal map and specular map", etc.). I'll think a bit about it.
Reply
Parent - - By PeterW [gb] Date 2016-05-31 13:30

> Let's start at the beginning: The OC Lighting Model is just wrong.


Every light model is wrong in some way. Ours is more simplified compared to what you would find in typical 3D engines. So not sure there's a "fix" that just makes everything sunshine and rainbows. The one change I have in mind might actually make things worse for highlights.

You should be able to make something brighter - the multiplier can go over 1 unless I'm very mistaken. The only thing that would be a problem is if you want the highlight to be a different colour. Or work correctly for multiple light sources at the same time, but then your problem is on the input end.

>  everything in the game is rendered by the same CommonShader which also #ifdefs if it is the landscape being rendered. Thats super unhelpful. Is that really necessary?


Not sure exactly what you're referring to, but it's a good idea that everything goes through the same shader backend so shading is consistent. After all, after all the magic has been applied the landscape is just a big surface with a normal map.
Parent - - By Matthias [de] Date 2016-05-31 14:36
Well, when I said "wrong" I actually quoted you from the private message you sent me some time ago - Back then, you also said that specularity needs to be added to the term, not multiplied into it.

> After all, after all the magic has been applied the landscape is just a big surface with a normal map.


Could the "magic" not be seperated out then, so there is an independent shader which does not even need to know if it's rendering landscape or mesh?
Reply
Parent - - By PeterW [gb] Date 2016-05-31 17:52 Edited 2016-05-31 18:06
Just providing context... After re-reading my statements: The problem actually isn't that we do "color * constant", the problem is that the constant should be "ambience + specular". What we have right now can behave like ambient shading or specular shading, and something "in the middle" - but that's not quite the same thing as the sum.

[Edit]
Btw, all of this comes directly from here, e.g. from an attempt to make a good general approximation to your shader. Not trying to shift "blame" or anything, just wanted to highlight the history here. Strictly speaking you even had the sum in there, which I promptly optimised out in the "approximated pow curve" bit :)

> Could the "magic" not be seperated out then


That was actually pretty much the idea. From what I can see, the only special case that applies to other shaders is that it needs to shade two pixels? We could remove that by mixing the pixels up-front, but that would give us worse anti-aliasing properties on the borders. I am fairly sure I tested that, and it used to be pretty noticeable.
Parent - By Matthias [de] Date 2016-05-31 20:29
Hah, ok ;) I really didn't mean to bring up the concept of "blame" in this discussion any case - It's just that after trying to make something glossy myself, and thereupon reading about general shading techniques, I feel confident enough to call the current approach "wrong" in the context that foaly tries to do the same thing. :P
Reply
Parent - - By Matthias [de] Date 2016-06-02 08:13

> it needs to shade two pixels


Can you elaborate on that a bit? I have the specularity for meshes in place, i think, but I don't know if (or with what "lightDir"-variable) I need to calculate something for the landscape case as well.
Reply
Parent - By PeterW [gb] Date 2016-06-02 17:25
Nothing too fancy - just do exactly the same shading again, for a second pixel. The reason we have to do this is because the two materials have different normals - while, say, the "rock" material might have a normal that goes towards the light, the "tunnel" material will be flat. The correct way to handle this is to shade both, then let the scaler decide which pixel (or weighted pixel combination) to use. If you get this wrong, shading will start looking uneven at material edges.
Up Topic General / Help and Questions / Specularity in Material

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill