Join us at the Oolite Anniversary Party -- London, 7th July 2024, 1pm
More details in this thread.

Shaders’ Outpost

Discussion and information relevant to creating special missions, new ships, skins etc.

Moderators: another_commander, winston

User avatar
Cmdr James
Commodore
Commodore
Posts: 1357
Joined: Tue Jun 05, 2007 10:43 pm
Location: Berlin

Post by Cmdr James »

Firstly, dont do yourself down. The code may not work, but it isnt crappy, its incomplete :)

I dont know much about this problem, in fact, Im assuming this is GLSL, and Ive never written any GLSL in my life, so if there is anything crappy going on, its most likely centered around me.

I think there is at least one problem, that Im not too sure about. What do we expect to happen if isCloacked changes from true to false, then 2 seconds later back to true. Do we expect to have two timers running, one switching one way, the other back?

Generally, I think I would try to have the current % mix (as a float) stored outside of the logic, and have an event triggered at each time event. At the point that the function is triggered we move the % one way if we are cloaked, and the other if we are not. That way we dont worry about counters and stuff (we just need to know how long it is since the last event, so we can scale the changes). This should allow us to have a change in our cloakedness mid change without breaking anything.
If we do it this way, then we simply do not make any changes if the mix is 1.00 and going up, or 0.00 and going down.
A potential problem with this strategy, is that we might have a seriously large number of events firing for every tick of the clock (one for each texture you do this with, per ship in the whole system), but I think it should be possible to do something to sort that out.

Im not sure if that helpful or not, it makes sense to me, but not really knowing the language, I wonder if Im doing more harm than good.
User avatar
TGHC
---- E L I T E ----
---- E L I T E ----
Posts: 2157
Joined: Mon Jan 31, 2005 4:16 pm
Location: Berkshire, UK

Post by TGHC »

Griff wrote:
now you see me......................................now you dont (well except for the engine glow & hull lights)
it's downloadable here
http://www.box.net/shared/bmgecao84c

edit: hmm, thinking about it, a shader binding to 'hasHostileTarget' would probably work better than a shader binding to 'isCloaked'.
here's a version that does that: http://www.box.net/shared/pvc6p2dwsg fire a few shots into them to get them to switch to their camouflage mode
The original GriffKrait is one of my favourites, I presume these will overide it, but which one should I use?
The Grey Haired Commander has spoken!
OK so I'm a PC user - "you know whats scary? Out of billions of sperm I was the fastest"
User avatar
Griff
Oolite 2 Art Director
Oolite 2 Art Director
Posts: 2478
Joined: Fri Jul 14, 2006 12:29 pm
Location: Probably hugging his Air Fryer

Post by Griff »

Hi TGHC
these last few posted shaders i'm probably going to try and use for a Thargoid type ship for the 'ruining the classics' thread, i want to try and make them have a sort of beetle-shell effect, i'm just using the griffkrait ship at moment to demo the shaders but they probably won't be used for it when they are complete.mind you I do have to update the original griffkrait a bit more, for some reason i took out the hull heatglow effect when i was picking apart ahrumans 'shady cobra.oxp' shaders to use on the krait, that needs to go back in, plus the damaged coriolis shaders have a neat blinking on/off effect that i want to put into the krait so that when you damage it heavily it's hull lights start flickering to match the exhaust plume.
User avatar
TGHC
---- E L I T E ----
---- E L I T E ----
Posts: 2157
Joined: Mon Jan 31, 2005 4:16 pm
Location: Berkshire, UK

Post by TGHC »

It truly is an awesome looking beast, I'll hang in there then and wait for the update. I wonder also if the AI needs tinkering a bit, when I launch from a station there are normally about 5 Griffkraits hovering around and then they become mildly agressive whilst you are waiting for the hyperspace, which is no problem, sometimes I hang around for a bit of a punchup, but I would expect vipers to be launching and taking them on as well but this very rarely happens. I guess the point I'm trying to make is that you would think that 5 fugitives shouldn't be able to lurk around a Coriolis being ignored to all intents and purposes by the Galcops!
The Grey Haired Commander has spoken!
OK so I'm a PC user - "you know whats scary? Out of billions of sperm I was the fastest"
User avatar
Griff
Oolite 2 Art Director
Oolite 2 Art Director
Posts: 2478
Joined: Fri Jul 14, 2006 12:29 pm
Location: Probably hugging his Air Fryer

Post by Griff »

I think i'm going to give up on the timer stuff Cmdr James, thanks for your help though, very much appreciated, as a test last night i added this function into the shader:

Code: Select all

// Count up function.
   float count_up(float start_time, float end_time)
   {
   float elapsed_time = time - start_time;
   if (elapsed_time > end_time)
       elapsed_time = 1.0;
   else 
   return (elapsed_time);
   } 
and call it using count_up(time, time+1);
but then i read somewhere that glsl shaders can't store values from one fragment to the next, this meant that 'start_time' would keep counting up along with 'time', so 'elapsed_time' always stayed at 0. apparently you have to use uniforms to hold a static value untill the shaders have had enough time to run for every fragment in the ship, and that means new stuff having to written into the oolite game code.
I do like the fade in/out effect though, so i think i might just tie it into ships speedfactor, so they blend between the textures as they speed up or slow down

@ TGHC do the griffkraits seem a bit reluctant to fire their laser guns at you? as if they can't line up a shot properly so they just keep flying at you then away then back at you but hardly shooting?
I noticed this when i was trying to test the laser gun shader effect but they would never shoot at me, i ended up giving them a custom AI that just made them target & attack the nearest station then they had no problem and were shooting away at it quite happily (as some of the pics i posted in the screenshots thread show).
Have you ever seen them attack any small ships or moving ships? if you haven't i wonder if having the laser guns as subentites quite far apart is giving the targeting code problems, maybe their AI makes them fly too close so they can't draw a bead on their target?
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

Griff wrote:
I think i'm going to give up on the timer stuff Cmdr James, thanks for your help though, very much appreciated, as a test last night i added this function into the shader:

Code: Select all

// Count up function.
   float count_up(float start_time, float end_time)
   {
   float elapsed_time = time - start_time;
   if (elapsed_time > end_time)
       elapsed_time = 1.0;
   else 
   return (elapsed_time);
   } 
and call it using count_up(time, time+1);
but then i read somewhere that glsl shaders can't store values from one fragment to the next, this meant that 'start_time' would keep counting up along with 'time', so 'elapsed_time' always stayed at 0. apparently you have to use uniforms to hold a static value untill the shaders have had enough time to run for every fragment in the ship, and that means new stuff having to written into the oolite game code.
This is true. Since you have no control over how many fragments are rendered for a given frame, or their spacial relationships, or how many are rendered in parallel, this is a feature.

However, it looks like what you’re trying to achieve is a sawtooth effect. Using any of the time bindings and the mod() function should achieve that. For instance, for a timer that ramps up over three seconds and then resets, you’d use mod(uTime, 3.0) / 3.0. This is used by the vertex shader in Shady Billboards to get a looping timer.
User avatar
Griff
Oolite 2 Art Director
Oolite 2 Art Director
Posts: 2478
Joined: Fri Jul 14, 2006 12:29 pm
Location: Probably hugging his Air Fryer

Post by Griff »

Ahruman wrote:
However, it looks like what you’re trying to achieve is a sawtooth effect. Using any of the time bindings and the mod() function should achieve that. For instance, for a timer that ramps up over three seconds and then resets, you’d use mod(uTime, 3.0) / 3.0. This is used by the vertex shader in Shady Billboards to get a looping timer.
if i did something like
float timer = mod(uTime, 3.0) / 3.0;

will that always give a range of values between 0.0000 and 3.0000?

i want to use a timer to control a blend of two textures - basically rather than have a ship change it's texture instantly when a bool becomes true i want a short animated sequence of a new texture fading in from 0 to 100%
i was thinking somthing like

[bool = true]
color = texture1 + (texture2 * timer)
and when timer gets to 3 seconds there's a jump to a new part of the shader that replaces the above color line with:
colour = texture2

[bool = false]
color = texture2 + (texture1 * timer)
timer >3? then colour = texture1
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

Griff wrote:
if i did something like
float timer = mod(uTime, 3.0) / 3.0;

will that always give a range of values between 0.0000 and 3.0000?
No, it would give you a value between 0 and 1, because it divides by three.
i want to use a timer to control a blend of two textures - basically rather than have a ship change it's texture instantly when a bool becomes true i want a short animated sequence of a new texture fading in from 0 to 100%
Look up the step, smoothstep and clamp functions.
User avatar
Griff
Oolite 2 Art Director
Oolite 2 Art Director
Posts: 2478
Joined: Fri Jul 14, 2006 12:29 pm
Location: Probably hugging his Air Fryer

Post by Griff »

One last question - now with pictures!
I've had another attempt at mixing the two textures, the part relating to my problem now looks like this:

Code: Select all

// Initialize the color Vec4   
 vec4 color = vec4(0.0);

 float counting_up   = smoothstep(0.0, 3.0, mod(uTime, 3.0));
 float counting_down = smoothstep(0.0, 3.0, mod(-uTime, 3.0));

// check if the ship is angry, if so mix out the normal colour & specular lighting, 
// leaving only the environmentmap textue, do the reverse when stops being angry   

   if (!hasHostileTarget)
      { 
      color += diffuse * mix(envMap, diffuseMap, counting_up) + specular * (specIntensity * counting_up); 
      }  
   if (hasHostileTarget) 
      { 
      color += diffuse * mix(envMap, diffuseMap, counting_down) + specular * (specIntensity * counting_down);
      } 
is there a way to stop the values of 'counting_up' & 'counting_down' 'sawtoothing'? at the moment they behave like the top graph in the image below, is there a way to make them behave more like the bottom graph in the image below?
Image
a griffgraph of my embarassing problem
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

That shape can be achieved using linear functions (y = ax + b) and clamp(). A smoothed version can be achieved with smoothstep(). Again, the vertex shader in Shady Billboards has code for both approaches (the clamp() version is commented out).

A more fundamental problem, though, is that there’s no way to get the time since some arbitrary value changed…
User avatar
Griff
Oolite 2 Art Director
Oolite 2 Art Director
Posts: 2478
Joined: Fri Jul 14, 2006 12:29 pm
Location: Probably hugging his Air Fryer

Post by Griff »

can vertex color values be used as a 'weightmap' when deforming or moving verticies with a vertex shader?, i only want to move some points in a mesh and not all of them.
Image

Rendermonkey has a simple bouncing ball vertex shader animation and i thought i might try and adapt it to make an oolite turret barrel recoil when it fires but i don't want to recoil the sphere part at the base of the turret, just the barrel.
I was wondering if i could use a vertex color value to control the effect, but i'm not sure if vertex colors, when set in wings3d are preserved in the .dat-ification process and if they can then be read back by a glsl shader, also will mixing both vertex color values and texture maps cause weird colours in the final texture?
am i going about this the wrong way, instead of trying to use weightmaps could this be better achieved by splitting the turret into 2 sererate .dat parts - the spherical base and the barrel and just apply a vertex shader to the barrel letting it clip into the spherical base part?

Edit:
I found a 'twist' deform example in the Rendermonkey Sample scenes, it used the current vertex X position and an IF statement to weightmap the effect, i've bunged it all into a test shader and it seems to work OK at least for turret barrels where the split between deforming & non deforming halves of the model is clear, there is quite a lot of texture distortion along the barrel but it's not too noticable if you leave the texture on the affected polys fairly undetailed

Code: Select all

varying vec3         v_normal;      // Surface normal
varying vec3         v_pos;      // Vertex/fragment position in eye space
uniform float  laser_heat_level;
float recoil_offset = laser_heat_level * 8.0; // modify the 8.0 to control the amount of recoil 
float vertex_Z_pos = gl_Vertex.z; 
  
void main()
{
   v_normal = normalize(gl_NormalMatrix * gl_Normal);
   v_pos = vec3(gl_ModelViewMatrix * gl_Vertex);
   vec4 recoil_deform_effect = vec4(gl_Vertex.x, gl_Vertex.y, gl_Vertex.z - recoil_offset, gl_Vertex.w);
   
   gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
   
   
if (vertex_Z_pos>50.0) // check the vert Z co-ords in Wings and modify the 50.0 as required
       gl_Position = gl_ModelViewProjectionMatrix * recoil_deform_effect;
   else
   {
       gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
   } 
   
}
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

Oolite doesn’t use vertex colours. I was going to suggest using the vertex positions, given the convenient shape of the model.

To avoid the texture distortion, you could animate just the outer part of the gun (but you’d need to lose the greebles).
User avatar
Griff
Oolite 2 Art Director
Oolite 2 Art Director
Posts: 2478
Joined: Fri Jul 14, 2006 12:29 pm
Location: Probably hugging his Air Fryer

Post by Griff »

I just had another thought, there used to be a technique you could use when rigging objects in 3d software to make sure you isolated parts of the mesh - basically you exploded the model into seperate parts and then, using the rigging controls (bones) in the 3d software, you brought all the parts back together again.
In the pic below,
box 1: offset the barrel from the base of the turret and save out your dat
box 2: the shader code checks for all verts a certain distance along Z and subtracts the offset value from their Z position re-assembling the model.
box3: when the turret fires the recoil offset is added - the barrel clips into the base but does not distort and as long as the base is wider than the barrel everything will look OK unless of course you play oolite with shaders switched off, in that case everything is going to look all odd and dislocated.
Image

amazingly, i was able edit the shader to create this effect! yay! go me!

Code: Select all

varying vec3         v_normal;      // Surface normal
varying vec3         v_pos;      // Vertex/fragment position in eye space
uniform float  laser_heat_level;
float recoil_offset = laser_heat_level * 28.0;   
float vertex_Z_pos = gl_Vertex.z; 
  
void main()
{
   v_normal = normalize(gl_NormalMatrix * gl_Normal);
   v_pos = vec3(gl_ModelViewMatrix * gl_Vertex);
   vec4 recoil_deform_effect = vec4(gl_Vertex.x, gl_Vertex.y, gl_Vertex.z - 25.0 - recoil_offset, gl_Vertex.w); // the 25.0 is the offset value we need to subtract to re-assemble the mesh
   
   gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
   
   
if (vertex_Z_pos>40.0) // check the vert Z co-ords in Wings and modify the 50.0 as required
       gl_Position = gl_ModelViewProjectionMatrix * recoil_deform_effect;
   else
   {
       gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
   } 
   
}
User avatar
Svengali
Commander
Commander
Posts: 2370
Joined: Sat Oct 20, 2007 2:52 pm

Post by Svengali »

@Griff: Very cool. Can't wait to see it in action :-)
User avatar
Griff
Oolite 2 Art Director
Oolite 2 Art Director
Posts: 2478
Joined: Fri Jul 14, 2006 12:29 pm
Location: Probably hugging his Air Fryer

Post by Griff »

I've managed to finish the 'recoiling turret ship' (see shader code on previous page), it kind of works ok, i've splayed the turrets out a bit so the ship makes a Y shape to minimise how much they accidentally cut into the hull - (a problem more to do with the design of the ship than anything else) and they look completely wrong on the demoscreen - they seem to point at some hidden target to the left of the screen - a stealth trumble perhaps?

Image Image


download here: http://www.box.net/shared/xm8vkj2qqy about 650KB
By the way does anybody know if it's possible to have exhaust plumes of different lengths on a ship? there's 3 plumes on this ship and even though i tried differing length values for each of them they always seem to be drawn exactly the same length as each other when in game? anybody else see this or is it just me?
Post Reply