CineMut shader family - Opaque

For collaboration on developing the mod capabilities of VS; request new features, report bugs, or suggest improvements

Moderator: Mod Contributor

Post Reply
Phlogios
Confed Special Operative
Confed Special Operative
Posts: 298
Joined: Sun Jul 30, 2006 1:38 pm
Location: Sweden
Contact:

Post by Phlogios »

Why? Because every
ship has glass and has fire (engine exhaust trails), and that's stuff for the shader that is meant to do bright
things, CineMut FireGlass, so if we'll need this shader for every ship already, then might as well move
the lights to the object that has the windows and stuff; so the lights go in a separate object together with
the glassworks.
How would that work on large ships where you have hundreds of small white squares as windows?
"Enjoy the Choice" - A very wise man from Ottawa.
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Post by chuck_starchaser »

Phlogios wrote:How would that work on large ships where you have hundreds of small white squares as windows?
Actually, good point!, there'll be three ways of doing sky-scraper style windows:

1) Geometry behind; windows transparent: The geometry behind doesn't have to be individual rooms. You can have one background plane behind all the windows, and crisscrossing, intersecting strips for walls and floors. But the windows would amount to a large number of quads.

2) Same as above, but you make all the windows a single window. The frames between windows you can do by blocking transparency. CineMut FireGlass will allow you to have an "alpha" channel to give glass a tint; and you can make that tint blocking.

3) Last but not least, if you want NO transparency and NO geometry behind; --just a bit of glow--, you can do the windows the way we do them currently. What you won't be able to do is make them super-bright. Maximum brightness for glows in CineMut Opaque will be 50%. And that's plenty good enough for windows; when people make windows ultra-bright it doesn't look realistic at all.
Phlogios
Confed Special Operative
Confed Special Operative
Posts: 298
Joined: Sun Jul 30, 2006 1:38 pm
Location: Sweden
Contact:

Post by Phlogios »

No loss then.

Lamps will be different meshes?
"Enjoy the Choice" - A very wise man from Ottawa.
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Post by chuck_starchaser »

Phlogios wrote:No loss then.

Lamps will be different meshes?
Yes. Different mesh, rather. For a typical model you'd have two meshes: the main one for CineMut Opaque, and
another mesh for transparent and emissive things such as windows and lamps, using the CineMut FireGlass shader.
By the way, the main feature of CineMut FireGlass, with regards to lamps and other light sources, is that you'll be
able to encode directional focus via a texture channel. The shader will modulate brightness by (N dot Eye)^F,
where F stands for "Focus". So, you'll be able to, for instance, put transparent discs inside engine nozzles that all
they do is emmit (add light), but if you give them a high focus, their glow will hardly be visible at an angle, but will
turn brightest when you're perfectly aligned behind the ship.
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Post by klauss »

Ehm... regarding gamma-encoded glowmaps... what about custom mipmaps? You could easily create a custom downsampling program to generate the mipmaps and explicitly feed to nvcompress rather than let it generate them. Then you can use gamma-encoded glowmaps everywhere.

I bet I could write one such program in python in a few hours (I'd have to figure out libpng for python)
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Post by chuck_starchaser »

klauss wrote:Ehm... regarding gamma-encoded glowmaps... what about custom mipmaps? You could easily create a custom downsampling program to generate the mipmaps and explicitly feed to nvcompress rather than let it generate them. Then you can use gamma-encoded glowmaps everywhere.

I bet I could write one such program in python in a few hours (I'd have to figure out libpng for python)
That would be marvelous! But, AFAIK, there is no provision for feeding mipmaps to nvcompress. I recently asked that very question at the nvidia developers forum.
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Post by klauss »

That's SO weird... such a basic feature. I would have sworn it was there.
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Post by chuck_starchaser »

Indeed, you would think.

Same with ATI and CubeMapGen; you can save individual mipmaps, but you cannot edit them externally and reassemble.

And nvidia have an nvassemble, but all it does is put the 6 sides together; won't accept to be fed the mipmaps. :(

At least CubeMapGen is open source, but nvidia won't release their sources.
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Post by chuck_starchaser »

Here's the Detail Texture for CineMut Opaque:

Image

It's an un-compressed PNG, and I think it should stay that way.

It contains:
  • Fairly high frequency up to about 1/2 of the pixel frequency of noise in green channel (for speckling noise)
  • Fairly low frequency perlin in its alpha channel (for shininess modulation)
  • Fairly accurate normals in red and blue channels, computed from a medium frequency perlin
It also tiles seamlessly.

For the curious, if I take the red and blue channels and stick them in red and green, instead, and compute sqrt(1-red^2-green^2) into the blue channel, to make them look like a standard normalmap, this is what they look like:

Image

The green (speckle) channel looks like:

Image

And the alpha (shininess modulation) channel looks like:

Image
Last edited by chuck_starchaser on Sat Aug 09, 2008 7:23 pm, edited 1 time in total.
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Post by klauss »

I'll see if I can get a cinemut technique today, now that I can build VS again. (I'm working on the sound branch that was broken to the point of no-build until yesterday).

Plus I'm rebuilding my kernel. Not that it has anything to do with cinemut. :)
Curse the inventor of reiserfs. Having a good idea and then make a loussy implementation is perhaps worse than having no idea at all.
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Post by klauss »

chuck_starchaser wrote:Indeed, you would think.

Same with ATI and CubeMapGen; you can save individual mipmaps, but you cannot edit them externally and reassemble.

And nvidia have an nvassemble, but all it does is put the 6 sides together; won't accept to be fed the mipmaps. :(

At least CubeMapGen is open source, but nvidia won't release their sources.
What about ATI's compressonator? I couldn't make it work since it requires WinXP (wine doesn't cut it either last time I tried), but maybe you can.
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Post by chuck_starchaser »

Sorry, I was still "perfecting" my last post :D

Never heard of raiserf or compressonator; I will google-up the latter right away.
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Post by klauss »

BTW: it looks like you could halve the resolution on those textures without loosing much.
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Post by chuck_starchaser »

Here we go:

Image

* Reading about the compressonator *
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Post by chuck_starchaser »

Updated:

Image

Same filename AND same size (since it's uncompressed), but
this new version has the gains adjusted in the blender noodle
to utilize the full range of all the channels. Be sure to refresh
forcefully the browser cache (Ctrl-F5 in Firefox).
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Post by klauss »

I just wanted to say:
chuck_starchaser wrote:One thing I found out but forgot to mention. Format for the glow texture: For a long time I thought the right
thing to do with the glow texture was to write it with gamma (i.e. square root) then square it at run-time in the
shader. Why? Because there's only a few lights requiring full brightness. Everything else (radiosity baked
from the lights) is a lot darker, and could use a bit of brightening if only to reduce dds compression quantization.

Recently I found that the whole concept was terminally flawed, as mipmaps would be generated off the
already gammafied image, and...
(a+b+c+d)/4 != ((sqrt(a)+sqrt(b)+sqrt(c)+sqrt(d))/4)^2
where, "!=" means "NOT equal".
This last point stands. No gamma.
Don't kill the idea yet. Though not correct, it might not look bad.
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Post by chuck_starchaser »

Okay; crionic suspension applied. :)

(In the case of backgrounds, for which I was originally also considering squaring the color in the shader, a bright pixel in a group of dark pixels would darken very quickly as you step through the LOD's.)

There doesn't seem to be a way to load external mips in the compressonator. However, there's a "plug-in SDK", and one of the plugin types it allows is to do one's own mipmap generation algorithm.

I'm going to get to work on a cubemap for testing.
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Post by klauss »

Warning: the detail texture has a 1-pixel border that makes it tile badly. (wait... might be a problem in my end, but check just in case)

Another warning: I'm not sure if you tested it, but the detail blend on the bumpmap is not working right. Plastics show too much detail. It's because there's little precision in close-to-zero detail blends, I squared bump & tex detail blends and it works better (with the same textures).
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Post by chuck_starchaser »

klauss wrote:Warning: the detail texture has a 1-pixel border that makes it tile badly. (wait... might be a problem in my end, but check just in case)
I'll check it but right away I can tell you it's impossible: To make the thing tileable I started from a 512 x 512 noise which I repeated 4 times. Then I applied filters of all kinds, put it through a big noodle. But at the end I cut a 512 x 512 piece from the middle of it.
For the new, 256 version, I put a scaling node in the noodle, so the output texture was 512, from which I cut a 256 square from the middle.
Another warning: I'm not sure if you tested it, but the detail blend on the bumpmap is not working right. Plastics show too much detail. It's because there's little precision in close-to-zero detail blends, I squared bump & tex detail blends and it works better (with the same textures).
That must be a bug (I had no way to test it); plastics should have NO detail, of any kind. So, how does it look? Screenshots? :)

Here's a cubemap from the bluegreen VS background.
It's in Direct X and OpenGL formats.
http://deeplayer.com/vs/shaders/bluegreen.zip
I tried to save Individual Faces, and Cross, but I got error messages instead. Is the format in the zip okay?

EDIT:
The detail texture is okay; here it is tiled (had to kill the alpha channel to tile it; a Gimp ideosyncracy):

Image
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Post by klauss »

Screenshots.

BTW: Since I haven't worked on cubemap support and I'm not sure how soon or not soon it will be, I modified the shader to use spheremaps. Of course it won't look as good as it should (I used it with cubemaps in rendermonkey and reflections look quite a bit better).

And after fixing the no-mtl "bug" in mesher, the .obj was converted without hitch:

Code: Select all

mesher test_bike.obj test_bike.bfxm obc
mesher test_bike.bfxm test_bike.xmesh bxc
# edit test_bike.xmesh with:
#   texture ="tex_00001.png"
#   texture1="tex_10001.png"
#   texture2="tex_20001.png"
#   texture3="tex_30001.png"
#   texture4="tex_40001.png"
#   technique="cinemut_opaque"
mesher test_bike.xmesh test_bike.bfxm xbc
Changes applied to the shots you'll see include using spheremaps and squaring texture and bump detail blending factors, and I had to separate the uniforms for cloaking and damage to avoid having to edit VS source and rebuild (there's no way to specify such an uniform right now).

Anyway... cinemut technique:

Code: Select all

<?xml version="1.0"?>
<technique fallback="default">
    <!-- Full-blown shader technique, with Z-write prepass to avoid
         shading overhead for occluded fragments.
         
         This technique implements normal-mapping, specmaps with intensity-derived
         shininess modulation, variable-kernel filtered environmental reflections
         (based on shininess), specularity normalization, fading damage maps with
         specmap perturbation, and supports up to 8 lights.
         
         This is a one-pass technique, so only the first 2 lights are done 
         per-pixel, the remaining ones use per-vertex lighting.
    -->

    <!-- Z-write prepasses go at sequence 10 -->
    <pass type="shader" sequence="10" cwrite="false">
        <vertex_program src="zwrite"/>
        <fragment_program src="zwrite"/>
        <texture_unit src="decal:0" default="file:white.bmp" name="diffuseMap"/>
    </pass>
    
    <!-- first and only lighting pass -->
    <pass type="shader" sequence="15">
        <vertex_program src="highend"/>
        <fragment_program src="cinemut_opaque"/>
        
        <texture_unit src="decal:0" name="diffMap"/>
        <texture_unit src="environment" name="envMap"/>
        <texture_unit src="decal:1" name="specMap"/>
        <texture_unit src="decal:3" name="glowMap"/>
        <texture_unit src="decal:4" name="normMap"/>
        <texture_unit src="decal:2" name="damgMap"/>
        <texture_unit src="file:cm_detail.png" name="detailMap"/>
        
        <auto_param name="light_enabled" semantic="ActiveLightsArray" optional="true"/>
        <auto_param name="max_light_enabled" semantic="NumLights" optional="true"/>
        <auto_param name="ucloaking" semantic="CloakingPhase" optional="true"/>
        <auto_param name="udamage" semantic="Damage" optional="true"/>
    </pass>
</technique>

And screenshots:

Image

Image

Image

Image


EDIT: Do you notice those smoothing glitches? Any idea why it could be? It looks like some polygons have inverted normals.

EDIT2: I noticed a bug: the reflection vector has to be computed from "normal_v3" instead of "vnormal_v3", it would look like this:

Image

Image

NOTE: You should consider tidying that code at some point, it's mighty hard to read ;)
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Post by chuck_starchaser »

Great! You got this working in no time at all!
The glitches you mention are not inverted normals; they are the consequence of using automatic unwrapping. It does a pessimal job. Unfortunately, the only alternative is to place seams; and placing the seams is like two days of work, minimum. I'll do so, eventually; after some intial debugging of the shader. The reflection thing was indeed a bug; thanks.
I'm looking for the bug with the detail. Can't find it yet; but there's definitely a big bug. Well, the intensity is one bug --needs to come down by like 90%; but besides that, I don't see any spleckling or shininess modulation. Somehow everything is bumped. I forgot to cut the glowmap down; that should also be knocked down 50%.
So, how I get all this to run? (Not that I'm sober enough to even think right now; but after some sleep I could try.)

This is the shot I like best, so far:

Image

Well, I think I see a bit of a different between the plastic and the painted parts there. Won't be able to tell with so much bumpiness and without a proper env map, though.
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Post by klauss »

The detail issue I think it's a materials problem. The texture used extremes for detail blending factors, the shader itself is very good I think, bugs aside. When I tried it with cubemaps in rendermonkey there was noticeable shininess variation. I believe the problem you see is that spheremaps don't filter out uniformly and so you don't see the variation in the reflection as you'd expect.

Two ideas you should consider implementing with detail maps:

One, is adding a texture channel for tiling frequency. Not every material should use the same tiling frequency, so you could read the frequency from a texture. I don't know if you have room for such a parameter, but just an idea.

The other one is controlling the amount of detailing in shininess. The plastic looks bumped because there's too much detail noise applied to its shininess. Or if it's not that, figure out why it looks bumped.

Another thing: you made a "fastnormalize" function. Mind you, there's no actual cost in a normalize call - at least for nVidia. nVidia GPUs have a builtin normalizer (at least up to the GF6) that can normalize a vector on each cycle. Such an instruction thus consumes no cycles at all. The only requirement is that it operates on half-precision vectors. I'm not sure how you specify precision in GLSL, but I wouldn't bother with fastnormalize anyway, normalization is still pretty fast.

If you want to save on instructions, replace make_signed. There's a builtin function in most shading languages (can't remember if it's there on GLSL too), expand(), that implements 2*(x-0.5). That is the "make_signed" you need, since it needs NO instructions (most arithmetic instructions have "signed" variants that automatically expand their arguments). The compiler will recognize it in both forms, as an expand() call or as 2*(x-0.5). The same happens with the converse, 0.5*x+0.5.

Another thing: you didn't normalize normal_v3. After imatmul, you have to normalize, because the matrix is linearly interpolated and will not always be orthonormal as you believe. Alternatively, you can normalize the tangent and cotangent to always obtain an orthonormal matrix, but if you don't use them other than for imatmul that's wasting instructions.

I'll upload a zip with the modified shader with the fixes I can come up with, the technique file and the bfxm for you. All you have to do to make it work is grab a techniques-capable vegastrike.exe, put the technique file in data/techniques, the shader in programs, and the bfxm in its folder in units, along with the textures as usual, set up a line in units.csv, edit data/mission/modelview.mission so that it spawns your brand-new unit (make it say type="test_bike" for instance), and fire up vegastrike.exe modelview.mission

EDIT: Reading my post I couldn't help but laugh real hard at the "all you have to do". ;)

Shout if you need help at any step.
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Post by chuck_starchaser »

klauss wrote:The detail issue I think it's a materials problem. The texture used extremes for detail blending factors,
I think you're right; I don't know what I was thinking, but I did span the whole range.
the shader itself is very good I think, bugs aside. When I tried it with cubemaps in rendermonkey there was noticeable shininess variation.
Good to hear!
I believe the problem you see is that spheremaps don't filter out uniformly and so you don't see the variation in the reflection as you'd expect.
Yeah, I wasn't expecting anything at all from spheremaps; they are totally for the birds.
Two ideas you should consider implementing with detail maps:

One, is adding a texture channel for tiling frequency. Not every material should use the same tiling frequency, so you could read the frequency from a texture. I don't know if you have room for such a parameter, but just an idea.
That is a crazy idea; in a good sense. Only problem I see is that if we use this texture channel to act as offset multiplier, we'd get tons of artifacts, from the shifts. We'd have to make sure, perhaps in LaGrande, that this channel has uniform color islands separated by bands of zeroed-out detail blend.
The other one is controlling the amount of detailing in shininess. The plastic looks bumped because there's too much detail noise applied to its shininess. Or if it's not that, figure out why it looks bumped.
I think you got the materials wrong: The blue box under the seat is plastic. The little blue block under the gauges on the handlebar is plastic. The gas tank is painted metal, and so are the guards on top of the wheels, and some of the frame tubes. The plastic is getting little or no detail, as it should.
Another thing: you made a "fastnormalize" function. Mind you, there's no actual cost in a normalize call - at least for nVidia. nVidia GPUs have a builtin normalizer (at least up to the GF6) that can normalize a vector on each cycle. Such an instruction thus consumes no cycles at all. The only requirement is that it operates on half-precision vectors. I'm not sure how you specify precision in GLSL, but I wouldn't bother with fastnormalize anyway, normalization is still pretty fast.
Good! I only ended up calling fast normalize once, I think, anyways; save a few instructions, then.
If you want to save on instructions, replace make_signed. There's a builtin function in most shading languages (can't remember if it's there on GLSL too), expand(), that implements 2*(x-0.5). That is the "make_signed" you need, since it needs NO instructions (most arithmetic instructions have "signed" variants that automatically expand their arguments). The compiler will recognize it in both forms, as an expand() call or as 2*(x-0.5). The same happens with the converse, 0.5*x+0.5.
Alrighty; I'll look it up.
Another thing: you didn't normalize normal_v3. After imatmul, you have to normalize, because the matrix is linearly interpolated and will not always be orthonormal as you believe. Alternatively, you can normalize the tangent and cotangent to always obtain an orthonormal matrix, but if you don't use them other than for imatmul that's wasting instructions.
I normalize inside imatmul itself:

Code: Select all

vec3 imatmul( in vec3 tan, in vec3 cotan, in vec3 norm, in vec3 texnorm )
{
    return normalize( texnorm.xxx*tan + texnorm.yyy*cotan + texnorm.zzz*norm );
}
I'll upload a zip with the modified shader with the fixes I can come up with, the technique file and the bfxm for you. All you have to do to make it work is grab a techniques-capable vegastrike.exe, put the technique file in data/techniques, the shader in programs, and the bfxm in its folder in units, along with the textures as usual, set up a line in units.csv, edit data/mission/modelview.mission so that it spawns your brand-new unit (make it say type="test_bike" for instance), and fire up vegastrike.exe modelview.mission
Excellent! I think my vs is the one with techniques already. I guess cubemaps are going to require another change, tho. I gotta grab a nap.

EDIT:
EDIT: Reading my post I couldn't help but laugh real hard at the "all you have to do".
Hahaha, no; it sounds okay, but at my current blood alcohol level I could not handle a fraction of it. Just took some B vitamins but I'd better grab some sleep to let them work.
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Post by klauss »

Files you need: cinemut.tgz

Notice: You're right about the normalize() and imatmul, so check the shader in the tgz since it then has useless normalize() calls ;)
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Post by chuck_starchaser »

Thanks!
Haven't gone to bed yet; I had to figure out the detail problem.
I had a bug in the LaGrande noodle: I had two RGB combiners on top of each other, somehow. Anyways, I quartered the gain on detail blend; you can try this texture if you're up to it:
http://deeplayer.com/vs/shaders//testmo ... _20001.png
Post Reply