Page 3 of 6

Posted: Sat Nov 01, 2008 1:16 am
by LittleBear
Have insomina! I don't really know anything about Shaders, but here a C&P from Griff's Space Bar shaders in the same format:

Code: Select all

<key>shaders</key>
<dict>
<key>griff_spacebar_mainhull.png</key>
<dict>
<key>textures</key>
<array>
<string>griff_spacebar_mainhull.png</string>
</array>
<key>vertex_shader</key>
<string>ahruman-generic.vertex</string>
<key>fragment_shader</key>
<string>griff_spacebar.fragment</string>
</dict>
</dict>   
Would adding that and then swapping the file names for your textures and shaders do it?

Posted: Sat Nov 01, 2008 1:23 am
by Simon B
Hah - partial success:
Took the shaders section, and folder, from shady cobras, turned into the following XML and got the blue glow.

No engine or laser glow. Still want the red specular.

Code: Select all

	<key>shaders</key>
		<dict>
			<key>katipo.png</key>
			<dict>
				<key>fragment_shader</key>
				 <string>ahruman_charlie_updatedships_arachnid</string>
				<key>vertex_shader</key>
				<string>ahruman_charlie_updatedships_arachnid</string>
				<key>textures</key>
				<array>
					<string>katipo-diffuse.png</string>
					<string>arachnid-effects.png</string>
				</array>
				<key>uniforms</key>
				<dict>
					<key>uTime</key>
					<string>timeElapsedSinceSpawn</string>
					<key>uEngineLevel</key>
					<string>speedFactor</string>
					<key>uLaserHeatLevel</key>
					<string>laserHeatLevel</string>
					<key>uHullHeatLevel</key>
					<string>hullHeatLevel</string>
				</dict>
			</dict>
		</dict>

Posted: Sat Nov 01, 2008 2:12 am
by Simon B
Thanks littlebear - it may have done it.

Re engines - perhaps there is a scale factor in the fragment shader?
Examining...

// Blue, intensity proportional to level.
vec4 EngineGlow(float level)

float engineAlpha = effectMap.r;
//... engineAlpha is the amount of red in the effect map.

vec4 engineEffect = engineAlpha * EngineGlow(min(uEngineLevel, 1.0));
diffuse += 0.4 * engineEffect;

*** Sanity Check:
So the engine effect will either be 1.0 or the value of uEngineLevel, which ever is less ... so it will always be less than 1.
If I put level * 40 instead of level in the EngineGlow function, that should noticeably increase the effect?

Sadly - nothing happens.

(Curiously - my flashers don't work either... <grumpy> I was using four flashers on constant to simulate the engine glow, and another one as decoration on the belly.)

Aside - for specular effects - should I use a third "specular-map.png" to become tex2 and add a

vec4 specularMap = texture2D(tex2, texCoord);

Then set a uniform specular level for the map? Then, perhaps, I get to change the specular color across the model. Good to avoid a red highlight in the blue areas...

Silly Me...

Posted: Sat Nov 01, 2008 2:24 am
by Simon B
I forgot to apply the shaders to the sub-entities didn't I?! :oops:

The engines arn't on the main model - so naturally, they didn't show up.
Now the effects are going - thank you good people.

Next to turn to the specular effect. Please?
Meantime, I'll work on updating that oxp to reflect all the feedback I've received.

Posted: Sat Nov 01, 2008 10:27 am
by Griff
here's a fragment shader that colours the specular using a third texture map to determine the colour

Image

Code: Select all

// Information from Oolite.
uniform sampler2D      tex0; // Difuse and Specular Intensity map
uniform sampler2D      tex1; // Effects & Light Illumination Map
uniform sampler2D      tex2; // Specular Colour Map

const float specExponent = 5.0;
uniform float   time;
uniform float   eng_pow;
uniform float   gun_heat;

// Information from vertex shader.
varying vec3         v_normal;      // Surface normal
varying vec3         v_pos;      // Vertex/fragment position in eye space

// cyanGlow effect
vec4 cyanGlow(float level)
{
   vec4 result;
   result.rgb = vec3(0.3, 0.6, 0.7) * level * 2.0;
   result.a = 1.0;
   
   return result;
}

// redGlow effect
vec4 redGlow(float level)
{
   vec4 result;
   result.rgb = vec3(1.9, 0.5, 0.2) * level * 2.0;
   result.a = 1.0;
   return result;
}

// WeaponGlow effect
vec4 WeaponGlow(float level)
{
   vec4 result;
   
   result.rgb = vec3(1.9, 0.5, 0.20) * level;    
   result.a = 1.0;
   
   return result;
}

#ifdef OO_REDUCED_COMPLEXITY 
#define Pulse(v, ts) ((v) * 0.95) 
#else
// Irregular flickering function.
float Pulse(float value, float timeScale)
{
   float t = time * timeScale;   

   float s0 = t;
   s0 -= floor(s0);
   float sum = abs( s0 - 0.5);
   
   float s1 = t * 0.7 - 0.05;
   s1 -= floor(s1);
   sum += abs(s1 - 0.5) - 0.25;
   
   float s2 = t * 1.3 - 0.3;
   s2 -= floor(s2);
   sum += abs(s2 - 0.5) - 0.25;
   
   float s3 = t * 5.09 - 0.6;
   s3 -= floor(s3);
   sum += abs(s3 - 0.5) - 0.25;

   return (sum * 0.1 + 0.9) * value;
}
#endif

// Calculate the contribution of a single light. Ought to be a function, but OS X's GLSlang implementation isn't sufficiently clever.
#define LIGHT(idx) \
   { \
      vec3 lightVector  = normalize(gl_LightSource[idx].position.xyz); \
      vec3 reflection   = normalize(-reflect(lightVector, v_normal)); \
      diffuse += gl_FrontMaterial.diffuse * gl_LightSource[idx].diffuse * max(dot(v_normal, lightVector), 0.0); \
      specular += gl_LightSource[idx].diffuse * pow(max(dot(reflection, eyeVector), 0.0), specExponent); \
   }

void main(void)
{
   vec4 diffuse = vec4(0.0), specular = vec4(0.0, 0.0, 0.0, 1.0);
   vec3 eyeVector = normalize(-v_pos);
  
   // Load texture data
   vec2 texCoord = gl_TexCoord[0].st;
   vec4 diffuseMap = texture2D(tex0, texCoord);
   vec4 effectsMap = texture2D(tex1, texCoord);
   vec4 specularcolour = texture2D(tex2, texCoord);
   float specIntensity = 15.0 * diffuseMap.a * diffuseMap.a; 
   
/*   Light 0 is the "showroom" light, used in the demo screen and shipyard.
   Light 0 is currently disabled, light 1 is the sun.
   */
#ifdef OO_LIGHT_0_FIX
   LIGHT(0);
#endif
   LIGHT(1);
   diffuse += gl_FrontMaterial.ambient * gl_LightModel.ambient;
   diffuse += effectsMap.a; // adds illumination to diffuse to give glowing lights effect   
   specular = mix(specular * specularcolour, specular * diffuse, 0.0); // Adds the Specular Effect
   vec4 color = diffuse * diffuseMap + specular * specIntensity;
 
   color += cyanGlow(effectsMap.r * Pulse(min(eng_pow, 1.0), 1.0)); // adds cyan exhaust glow 
   color += redGlow(effectsMap.b * Pulse(min(eng_pow, 1.0), 1.0)); // adds red 'engine heat' glow 

   color += WeaponGlow(effectsMap.g * gun_heat);


   gl_FragColor = vec4(color.rgb, 1.0);
}

the important lines are these, they set up the new texture map and use it to colour the specular highlight.

uniform sampler2D tex2; // Specular Colour Map

vec4 specularcolour = texture2D(tex2, texCoord);

specular = mix(specular * specularcolour, specular * diffuse, 0.0); // Adds the Specular Effect

Posted: Sat Nov 01, 2008 10:30 am
by Griff
if you prefer, you can just specify a RGB colour in your shader to use when colouring the specular effect, this will give the same specular colour accross the entire model and you won't need to provide a new texture map.
Image

Code: Select all

// Information from Oolite.
uniform sampler2D      tex0; // Difuse and Specular Intensity map
uniform sampler2D      tex1; // Effects & Light Illumination Map

const float specExponent = 5.0;
uniform float   time;
uniform float   eng_pow;
uniform float   gun_heat;

// Information from vertex shader.
varying vec3         v_normal;      // Surface normal
varying vec3         v_pos;      // Vertex/fragment position in eye space

// cyanGlow effect
vec4 cyanGlow(float level)
{
   vec4 result;
   result.rgb = vec3(0.3, 0.6, 0.7) * level * 2.0;
   result.a = 1.0;
   
   return result;
}

// redGlow effect
vec4 redGlow(float level)
{
   vec4 result;
   result.rgb = vec3(1.9, 0.5, 0.2) * level * 2.0;
   result.a = 1.0;
   return result;
}

// WeaponGlow effect
vec4 WeaponGlow(float level)
{
   vec4 result;
   
   result.rgb = vec3(1.9, 0.5, 0.20) * level;    
   result.a = 1.0;
   
   return result;
}

#ifdef OO_REDUCED_COMPLEXITY 
#define Pulse(v, ts) ((v) * 0.95) 
#else
// Irregular flickering function.
float Pulse(float value, float timeScale)
{
   float t = time * timeScale;   

   float s0 = t;
   s0 -= floor(s0);
   float sum = abs( s0 - 0.5);
   
   float s1 = t * 0.7 - 0.05;
   s1 -= floor(s1);
   sum += abs(s1 - 0.5) - 0.25;
   
   float s2 = t * 1.3 - 0.3;
   s2 -= floor(s2);
   sum += abs(s2 - 0.5) - 0.25;
   
   float s3 = t * 5.09 - 0.6;
   s3 -= floor(s3);
   sum += abs(s3 - 0.5) - 0.25;

   return (sum * 0.1 + 0.9) * value;
}
#endif

// Calculate the contribution of a single light. Ought to be a function, but OS X's GLSlang implementation isn't sufficiently clever.
#define LIGHT(idx) \
   { \
      vec3 lightVector  = normalize(gl_LightSource[idx].position.xyz); \
      vec3 reflection   = normalize(-reflect(lightVector, v_normal)); \
      diffuse += gl_FrontMaterial.diffuse * gl_LightSource[idx].diffuse * max(dot(v_normal, lightVector), 0.0); \
      specular += gl_LightSource[idx].diffuse * pow(max(dot(reflection, eyeVector), 0.0), specExponent); \
   }

void main(void)
{
   vec4 diffuse = vec4(0.0), specular = vec4(0.0, 0.0, 0.0, 1.0);
   vec3 eyeVector = normalize(-v_pos);
   vec4 lightColor = vec4(0.8, 0.5, 0.2, 1.0); // Sets the RGB and Alpha values for the light, in this case a nice golden orange colour
   
   // Load texture data
   vec2 texCoord = gl_TexCoord[0].st;
   vec4 diffuseMap = texture2D(tex0, texCoord);
   vec4 effectsMap = texture2D(tex1, texCoord);
   float specIntensity = 15.0 * diffuseMap.a * diffuseMap.a; 
   
/*   Light 0 is the "showroom" light, used in the demo screen and shipyard.
   Light 0 is currently disabled, light 1 is the sun.
   */
#ifdef OO_LIGHT_0_FIX
   LIGHT(0);
#endif
   LIGHT(1);
   diffuse += gl_FrontMaterial.ambient * gl_LightModel.ambient;
   diffuse += effectsMap.a; // adds illumination to diffuse to give glowing lights effect   
   specular = mix(specular * lightColor, specular * diffuse, 0.0); // Adds the Specular Effect
   vec4 color = diffuse * diffuseMap + specular * specIntensity;
 
   color += cyanGlow(effectsMap.r * Pulse(min(eng_pow, 1.0), 1.0)); // adds cyan exhaust glow 
   color += redGlow(effectsMap.b * Pulse(min(eng_pow, 1.0), 1.0)); // adds red 'engine heat' glow 

   color += WeaponGlow(effectsMap.g * gun_heat);


   gl_FragColor = vec4(color.rgb, 1.0);
}
the important lines are these two:
vec4 lightColor = vec4(0.8, 0.5, 0.2, 1.0); // Sets the RGB and Alpha values for the light, in this case a nice golden orange colour

specular = mix(specular * lightColor, specular * diffuse, 0.0); // Adds the Specular Effect

this example is a bit out of date now, Ahruman has added the ability to send vec4's to the shader using uniforms in the shipdata.plist. In this example the specular colour is hard-coded in the shader using this line:
vec4 lightColor = vec4(0.8, 0.5, 0.2, 1.0); // Sets the RGB and Alpha values for the light, in this case a nice golden orange colour

we could now specify the lightColor vec4 in the ships 'shipdata.plist' eg:

Code: Select all

uniforms = 
             { 
             SpecularRGB = { type = vector; value = "0.5 0.7 1.0";}
             }; 
so different variations of your ship could have different specular colours without having to write a different fragment shader for each one.

Posted: Sat Nov 01, 2008 10:49 am
by Griff
what can also look cool is if you use the diffuse map to color the specular, unfortunately i couldn't find a colourful example so this ship with it's grey/green murky texture will have to do:
Image

Code: Select all

// Calculate the basic ship colour & add in the specular effects 
   vec4 color = diffuse * diffuseMap + (specular * diffuseMap * 3.0) * specIntensity; 
here, just multiply the specular by the diffuseMap and in this case then multiply it by 3.0 to really make the effect more notcable.

to break down this line:
the 'diffuse' value is being calculated by the light macro and it's basically the amount of shadowing effect to be added to the colour value depending on how the poly fragment is pointing to or away from the lightsource.

the diffuseMap value is the colour of the relevant pixel from the texture map

the 'specular' value is being calculated by the light macro and it's basically the addition of the lightsource colour to the final colour depending on how the poly fragment is pointing to or away from the lightsource.

the light macro i keep talking about looks like this:

Code: Select all

// Calculate the contribution of a single light. Ought to be a function, but OS X's GLSlang implementation isn't sufficiently clever.
   #define LIGHT(idx) \
        { \
           vec3 lightVector   = normalize(gl_LightSource[idx].position.xyz); \
           vec3 reflection   = normalize(-reflect(lightVector, v_normal)); \
           diffuse += gl_FrontMaterial.diffuse * gl_LightSource[idx].diffuse * max(dot(v_normal, lightVector), 0.0); \
           specular += gl_LightSource[idx].diffuse * pow(max(dot(reflection, eyeVector), 0.0), specExponent); \
        }

Posted: Sat Nov 01, 2008 3:25 pm
by JensAyton
Simon B wrote:
The plists are tricky - you cannot help using a substantial amount of the core plists in your own, that's just the definition. So many lines are just the same as the core ones but with a number a bit different - however, it's the numbers that make it unique.
Anyone claiming copyright on the XML tags themselves or the keys used in dictionaries is just taking the piss. :-)
Simon B wrote:
Using GPL for non-software needs care - what counts as the source code for an oxp?
The GPL is basically unsuitable for stuff that isn’t software in the normal sense, and the Creative Commons licenses are unsuitable for compiled code. This is why Oolite as a whole is licensed under the GPL and the resources also under CC-by-nc-sa; if you’re only using the resources, the CC license makes more sense.
Simon B wrote:
In the long term, OOlite benifits from being free software. (Disagree? We need another thread?) So it is advisable to release oxps under a free license anyway.
Well, since you ask, I personally find the GPL objectionable and would have preferred a less restrictive license, but didn’t argue about it at the time since the issue wasn’t very important to me with respect to Oolite. I definitely don’t intend to have that argument here, though. :-)

Posted: Sat Nov 01, 2008 11:06 pm
by Simon B
I'm munching my way through Griff's shader examples - paying attention to the specular effects.

@Griff: did you ever try reflecting something other than white?

I am assuming that the lack of replies on changing the colour of the specular component means that this is non-trivial?
[edit]Sorry guys - didn't see you there ... OK - I have had some replies :) fortunately, they are useful ones.[/edit]

In that vein - looking for shader tools
Found:

http://createdigitalmotion.com/2006/07/ ... ows-linux/

And a bunch of tutorials...
http://www.typhoonlabs.com/

The SDK:
http://www.opengl.org/sdk/
... bundles the lot.

Note - really needs to be at least OSI (Open Source) compliant, preferably FSF (Free Software). Havn't found a thread discussing tools, I should start one...

I take it the shaders are written in GLSL?

Thanks to the Griff

Posted: Sun Nov 02, 2008 8:10 am
by Simon B
Ta nicely Griff, that's what I need - I think I may have enough information to actually make the most of the tutorials and examples now.

hmmm...

SpecularRGB = { type = vector; value = "0.5 0.7 1.0";}

turns into:

<key>SpecularRGB</key>
<dict>
<key>type</key>
<string>vector</string>
<key>value</key>
<string>0.5 0.7 1.0</string>
</dict>

That one I can test right away - but I'm vearing towards the specular map methods since I can, then, remove all specular effects from the blue parts.

Next stop - turn the shipdata.plist into openstep.

---
Looking through the Griff ships and I start to feel ... inadequate... inspired to greater excellence!

I doubt the arachnid will benifit from a high-detail texture - though I've been reconsidering the textured highlights - dark on the avondale and light on the katipo - which don't quite fit the smoothed model. Perhaps a more ribbed effect?

Possibly I'm just noticing it because I drew it.

Note - the engine effect turns out to be blue - that's actually good for this ship.

Arachnid SB Ready

Posted: Mon Nov 03, 2008 8:09 am
by Simon B
The hard work - as well as the tough part of the learning curve, has been completed. The OXP has been updated and is ready for your enjoyment.

Image

Todo: convert the shipdata.plist to open-step format. I should work in that from now on. The Config file in the oxp contains my attempt to translate the xml... but it just gives me a big "?"!

- HUD could use work - or just use the fighter HUD? Nobody has complained about it being labelled in alien text so I'll leave that part in ;)

- I have yet to see an NPC version of this ship :/

You see something you think should be different - tell me here.
If you can complete the plists or otherwise contribute - please do.

The design philosophy is to create a ship which everyone wants to try but is not a killer ship. particularly do not complain about the stopping distance or weak thrusters - that's deliberate.

Thanks to: the usual suspects... Griff for inspirational work and Ahruman for sanity.

So - should this get included on the big set of oxps in the wiki?

Posted: Mon Nov 03, 2008 10:00 am
by LittleBear
Very nice! If you PM Winston for a log-in you can add a wikki page for the OXP and a link on the OXP page. You can upload the OXP file to the Wikki or just add a page and keep the link to your site. Personally I find it easier to do a page on the Wiki and an external download as Wiki files a limited to a couple of megs. And if a bug is found its a lot easier just to change the link on the Wikki page to point to the bug-fixed version! :wink:

Posted: Mon Nov 03, 2008 11:06 am
by DaddyHoggy
@Simon B - the picture - hmmm.... Seen it somewhere before.... That's it - It's the Bat Signal! :lol:

Posted: Mon Nov 03, 2008 12:15 pm
by Captain Hesperus
DaddyHoggy wrote:
@Simon B - the picture - hmmm.... Seen it somewhere before.... That's it - It's the Bat Signal! :lol:
Better yet:
Image
It's the Batwing!

Captain Hesperus

Posted: Mon Nov 03, 2008 4:55 pm
by Eric Walch
Simon B wrote:
I have yet to see an NPC version of this ship :/
You probably already noticed, but the new oolite 1.72 gives a clear error on this: It can't find the original like_ship. You used "cobra3" instead of "cobra3-trader". cobra3 by itself has never existed as key. (at least not since version 1.55)