Jump to content

Recommended Posts

Update on the project: I've solved the Oren-Nayar equation in terms of vector calculus. Was fun refreshng my math skills :D Maybe even more simplification possible:



And then I've got an idea: the fur is rendered only when it comes into render distance and then left alone. If it's possible to delay the effect of the ambient blue-alpha correlation method, it will be possible to render the fur with full density with me being able to get the alpha as low as I want to. What I need is a way to get the time.

  • Respect! 1
Link to comment

I think this topic is complicated enough and received enough work by now that it deserves its own topic. What's the problem we work on?

1. Bug Explanation


The game comes with a pretty much widely unused fur shader based on FurGle using the Shells and Fins alpha method (more on that later).
The issue is following bug:

On 4/23/2022 at 10:54 PM, idbeholdME said:

One thing about the new fur on boars/bears etc.

I don't really know the technical terms for it, but it is not obscured by for example fog or when a corpse goes under water. All other things become slightly obscured by the fog when they are too far. But the fur retains 100% clarity at any distance/under any conditions.

Screenshot of a distant bear:


Notice how the ground/bushes/trees, everything except the fur on the bear is slightly obscured the further it is. But the fur always stays the same.


Here is a screenshot of a dead boar under water:


Yes, the body is under the water, but it has zero graphical effect on the fur. Like the fur is set to always have 100% opacity and nothing can change that. Only the fur that the PFP adds behaves like this, so it must have something to do with that. Although not in the screenshot, the head/tusks/any part of the body that does not have fur on it becomes properly obscured by the water.

Or could it because I'm using the vanilla s2render.dll file? Does it look like this with the patched one?

Can we do something about it? The answer is yes. This right here:

On 5/16/2022 at 8:12 PM, Lindor said:

I think this is why Fog/Water has no effect on the fur: If you take a close look, it actually affects the underlying skin (which uses the same shader), e.g. the head of the boars, only the fur itself remains unaffected because of the (hardcoded) isotropic lighting used. There's nothing I can do in the shader file to fix this, I'm sorry.

Was wrong, the lambertian lighting model is not the cause of that issue and it's also not hardcoded. I managed to disable/enable it, in fact I have complete control over the lighting model used. With pure anisotropic lighting, the fur kinda looks like an oil painting (see image below).

The issue sits at the code level; the fog rendering can be enabled within the shader file but the prolem with the water is that it's not part of the shader lighting, it's processed as a completely separate function. And the bug is that this specific function has no effect on the fur because the alpha channel (which controls transparency) is an important part of the FurGle Fins alpha method, therefore alpha rendering is completely disabled and gets only controlled by the shader.

2. How does fur generation work? FurGle Shells + Fins method explained.


So why did I say then that we can do something here? Well, first let us understand how the Shells+Fins alpha method works. Imges say more than 1000 words I guess:

Img 1.1: Shells

Each layer you see on the right is called a "shell". Unfortunately, the Ellipses are 2d meaning they're infinitely thin and therefore not rendered from the side. This is where The fins come into play:
Img 1.2: Fins

You can read more on that here: https://www.researchgate.net/publication/277296247_Real-Time_Rendering_of_Fur_i

You can now see why the alpha channel plays such a big role. The different Ellipses overlap and have different colors, fins overlap with shells in front and behind and last but not least, wether or not the fin is rendered is dependent on the alpha value of the shell through a formula. Messing with that will yield totally messed up results, like thinning out, striping effects etc.

3. Examples for fur with different lighting models


This is how it looks with completely anisotrpic lighting if you set the fins completely transparent:
Img 2.1: Shells only, lambertian lighting disabled, anisotropic lighting added

And this is with only fins and disabled shells:

Img 2.2: Fins only, lambertian lighting disabled, anisotropic lighting added

The oil painting effect comes from the anisotropic lighting used, it's pretty cool imho.

4. The solution: The ambient blue-alpha correlation method (or ABAC-method) and Future Plans
(note: it turned out to not work well because it depends on surrounding light level)


So why do I say then we can do something about it? Well, the trick is setting the lighting's alpha channel at the shader level based on the amount of environmental blue color a pixel is receiving, and doinhg it just the right amount so that the fur is not thinned out too much but at the same time the underwater fur transparency is at an acceptable level. Of course you have to do it for both the fur.shader (which is controlling the shells) and fins.shader (which is controlling the fins, obviously). This is the current stage of the project:

Img 3.1: ambient blue alpha correlation method seen from far

Img 3.2: ambient blue alpha correlation method seen close up

Img 3.3: ambient blue alpha correlation method seen underwater

I think it looks okay-ish for now.

Future plans of this project are a package of all kinds of different combinations of following fur/fin shader properties

  • Diffuse Lighting
    • Lambertian lighting
    • Anisotroopic Lighting
    • Oren Nayar lighting
  • Alpha Channel
    • ambient blue-alpha correlation method
    • Only Shells
    • Only Fins
    • Standard

Which will be a total of 12 different shell/fin shader pairs

Additional Future plans:

  • Find out how to manipulate Weight and Thickness
  • Find the optimal parameter setting for the ambient blue-alpha correlation method to make the fur as dense and transparent as possible
  • If possible, find another way to determine wether the surface is underwater other than the amount blue ambient lighting (@dimitrius154help pls :D)
  • Test other speculars than standard Blinn-Phong

The final shader package will be uploaded to the download section and not be posted as code.


Edited by Lindor
Link to comment

The project is finished. Feel free to use it for your mods or to look at the files and see what I did. If there are any questions, I would be glad to answer them.

@gogoblender can we merge this thread with the download's discussion thread?



On 5/23/2022 at 1:55 AM, Lindor said:

And then I've got an idea: the fur is rendered only when it comes into render distance and then left alone. If it's possible to delay the effect of the ambient blue-alpha correlation method, it will be possible to render the fur with full density with me being able to get the alpha as low as I want to. What I need is a way to get the time.

That doesn't work. I know how to get the time:

add uniform float 4 system_data to your Pixel Shader pixdata / vertex shader appdata.
float time = system_data.x gives you the time at which the shader is called.

add uniform float sc_time to your Pixel Shader pixdata / vertex shader appdata.
sc_time gives you the time at which you started the game session.

both times are in seconds.

It's impossible to store a value between shader calls though, so it's impossible to store the time at which the object first comes into render distance and send it to the next shader call (the shader is called every frame). Even if you managed to deepcopy, this deepcopy would get applied every shader call. Therefore it's impossible to get the time at how long the object has been in render distance, therefore it's impossible to delay any effects by a set amount of time. But I can now animate things.

Btw the best way to get the ingame time is not via system time, but via the brightnes of light_col_diff (float sun_brightness = sqrt(dot(light_col_diff .xyz, light_col_diff .xyz))) in the pixel shader. Way better to differentiate between night/day.

  • Like! 1
Link to comment
  • The title was changed to Sacred 2 Downl0ads - Fur shader Pack (20 different fur.shader + fins.shader pairs)

Uhmm... Forum bug:

I tried to edit this post to fix the broken link which broke due to the merge: http://darkmatters.org/forums/index.php?/topic/72326-fur-shader-pack-20-different-furshader-finsshader-pairs/#comment-7137560


But when I clicked "edit", it edited the leading post instead: http://darkmatters.org/forums/index.php?/topic/72326-fur-shader-pack-20-different-furshader-finsshader-pairs/#comment-7137517


Which had the shells + fins explanation and many screenshots in it. That's really really bad, I hope I can restore it somehow.:lindor:



EDIT: I managed to restore it. Not from memory, my memory is good but not that good, I had it open in another tabwhere it didn't update the edit yet. Got really lucky here, it would be really bad if all this was getting lost.:sweating:

Edited by Lindor
  • Thanks! 1
Link to comment
On 5/23/2022 at 7:56 PM, Lindor said:

I have finished implementing the first version of Oren-Nayar a minute ago, this is what it looks like

Interesting, is there any GPU usage variation(vanilla vs. current test version)? 

Link to comment
10 hours ago, dimitrius154 said:

Interesting, is there any GPU usage variation(vanilla vs. current test version)? 

Not on average value, but on peak value. Average GPU load with 7 boars was 77% for both Vanilla and Oren-Nayar, peak value for Vanilla was 81%, peak value for the most computational expensive version of Oren-Nayar was 93%. But why don't you just download it and test it yourself?


Water rendering seems to be very computational expensive, 50%load in town get boosted up to 70% near a river/ocean (which is the base value you can compare above numbers with). Compared to that the new fur shader is next to nothing.

Link to comment

I tried the ambient blue-alpha correlation method/shells + fins/oren-nayar + specular and while the fur does look differently, I can't seem to achieve the obscured effect under water as you'd shown in the screenshots. Same as before, the water has no effect on the fur. Did I pick a wrong combination or is there some other problem?

I did clear the shader cache.

Edited by idbeholdME
Link to comment
1 hour ago, idbeholdME said:

I tried the ambient blue-alpha correlation method/shells + fins/oren-nayar + specular and while the fur does look differently, I can't seem to achieve the obscured effect under water as you'd shown in the screenshots. Same as before, the water has no effect on the fur. Did I pick a wrong combination or is there some other problem?

I did clear the shader cache.

No you didn't do anything wrong!

There is another problem. It works differently good during different ingame times. The ambient lighting is suuuuper sensitive, it has taken me extremely much time to find a sweetspot formula. The sweetspot changes with the ingame lighting over time and with different areas. At times it even had the fur going completely invisible during night time, though I hope I have this problem fixed.

The fromula I have rn is alpha * y where y = x^(2^(100*(0.9-x))) where x = 1 if a<0, 0 if a>1 and 1-a if 0<a<1 where a is 2b-r-g where r, g and b is red, blue and green component of the normalized ambient lighting vector. btw the formula for y is not exactly as given, it's in increments of steps of 0.1n for x because you should only do exponentiation with integer exponents.

I tested the sweetspot by clipping the fur for clip(x-k), started with k=2^-1 and then de/increased it in steps 2^-n depending on wether the fur would get clipped on street and on water. So I did 2^-1 +/- 2^-2 +/- 2^-3 +/- ... +/- 2^-n until I had something that would clip the fur underwater but not on land. the variance of the sweetspot zone is then 2^-(n+1).

The sweetspot for x during night time is 0.89375 +- 2^-8 while during daytime 0.9something (don't have the exact value anymore) +-2^-10. You see the sweetspot zone shifts too much to get a reliable formula for every ingame time because the sweetspot zones don't overlap.

I also tried bringing the diffuse vector into play to get the ingame time, but that doesn't work either because of the different lighting in different regions.

The formula given rn is just what works "best" without making the fur transparent during normal play. Not perfect, but still better than nothing.



What also works is just hard-setting the fur transparency to smth between 0.2-0.5, but imho it looks too bad and doesn't justify, hence why I didn't grant those. But I can if wished, it's not very difficult to do (in fact it's super easy).


This is the formula used, x =2b-r-g and y is the value the alpha gets multiplies with. blue curve is the actual calculation while red is what it would look like if it was a smooth function.


This is what it would look like if you just hard multiplied the alpha by 0.4:


Right is what happens if you hover over the obhect with the mouse: the undelying texture gets brighter which is why the fur is barely visible. As if the fur wasn't just barely visible even on the left... drastic loss fur such a small underwater effect:


You see, this problem is incredibly difficult. I've spent more than 100 hrs to solve it by now, and the best I've got is the formula given above. And the worst thing is - it still makes the fur invisible at night at certain areas.


The only thing which might work reliable is some sort of ray tracing. But first of all, I don't know how to get the color of rendered texels, second of all, it would explode the computational cost. Never the less I'm still working on it.

Edited by Lindor
Link to comment
18 minutes ago, dimitrius154 said:

Still busy with the Martyr. Finishing the Psyker cultivation:MG_18:

Haha guess I'm just too proud of it, I want everyone to download it and try it out :D

Link to comment

I've been learning about the concept of shader layers. I think based on that it will be possible to revive SURFACE_FLAG_VARIABLE_FUR, so that it will be possible to have two differently looking fur shaders be active at the same time. Well, technically it's the same shader, just looking differently depending on the flag you use in surface.txt. It's not guaranteed though, there's the small possibility that the devs haven't linked the flag to the layer bit yet.

Link to comment

I don't think the underwater bug has to do smth with the alpha-based shells+fins generation method the game uses anymore. Fur is technically VFX, and no VFX have the underwater effect. Look at the seraphim's Endijan T-Wings e.g., there's a passage right north-eastern of Sloeford where the boar hunter camp is where you can go underwater and observe the body disappear but the T-Wings stay as is. I know now that ray tracing calculation is impossible to do, the function you'd need, GrabPass(""), is not part of the OpenGL's shader language version Sacred 2 uses yet, the game's simply too old. I don't have any more ideas left, the abac-method was the best I could do. I'll stop working  on it and concentrate on more other amazing things I'll do with shaders, like the layer thing I posted above. @idbeholdME

  • Like! 1
Link to comment
  • 1 month later...


@gogoblender @Schot

Due to the topic merge, the first post in this topic which contained the shells+fins explanation got changed into the download file description when I uploaded the first version of the fur shader. The first time I could restore it because luckily I had this topic opened in another tab, unupdated, when I uploaded shader pack.

This time I uploaded a new version and the leading post got updated again, but I don't have backupdata to restore.

Can you please restore the leading post to the old explanation? Maybe from a forums backup? It was quite important information, for new modders and myself.

Link to comment
1 hour ago, Schot said:

Yikes!  That's very unfortunate Lindor.  Merged content is tricky business.  Especially in the case of merging into a Downloads page.  It's a bit of a paradox it seems!  I've not dabbled with retrieving overwritten data very much and the general response from our forum software creators is that it isn't possible.  Restoring from a site backup is a somewhat big ask but before we even go digging too much further...  Is this what you are looking for?

Google cache of this page:

Sometimes looking at the cached version of a Google indexed page can get us out of a sticky situation.   :)


strong work!

and so early in the morning!





Link to comment
Just now, Flix said:

My advice in this case is to not use the lead post for custom info, use the second post instead.

The lead post will always be overwritten by the stock standard file info each time you update the download.

ahhh, good tip , thanks Ben



Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...
Please Sign In or Sign Up