Shaders’ Outpost

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

Moderators: winston, another_commander

User avatar
spara
---- E L I T E ----
---- E L I T E ----
Posts: 2691
Joined: Wed Aug 15, 2012 4:19 am
Location: Finland

Re: Shaders’ Outpost

Post by spara »

I'm working on adding SimonB's Navy Carrier to the behemoths and want to put a nameplate to it. And I'm doing it with shaders. I have copied the oolite-default-shader.fragment to my oxp and managed to get diffuse map, normal map and emission map working. I have also successfully added the nameplate to the texture.

The thing I'm having trouble is the shininess. When using materials entry Simon has used the same texture for both diffuse map and specular map producing a nice shiny metallic surface. When I do that with my copied fragment shader, it's not shiny any more :(. If I manually multiply specularLight with something like 5, the shine returns. I'm obviously not understanding something. Am I missing something obvious?

The only thing I have changed in the fragment file are these settings
OOSTD_DIFFUSE_MAP 1
OOSTD_SPECULAR 1
OOSTD_SPECULAR_MAP 1
OOSTD_NORMAL_MAP 1
OOSTD_EMISSION_MAP 1

and shipdata snippet looks like this:

Code: Select all

shaders = { 
	      "carrierI.png" = { 
	      
				fragment_shader = "ncc_carrier.fragment";
				vertex_shader = "oolite-tangent-space-vertex.vertex";
                textures =
				(
					"ncc_carrier.png",
					"ncc_carrier-glows.png",
					"ncc_carrier_n.png",
					"ncc_name1.png"
				);
				uniforms =
				{
					uColorMap			= { type = texture; value = 0; };
					uNormalMap			= { type = texture; value = 2; };
					uEmissionMap			= { type = texture; value = 1; };
					uSpecularMap			= { type = texture; value = 0; };
					uTime				= "timeElapsedSinceSpawn";
					uHullHeatLevel		= "hullHeatLevel";
				};
	      }; 
};
Materials entry I'm trying to duplicate looks like this:

Code: Select all

	materials = { 
	      "carrierI.png" = { 	      
				diffuse_map = "ncc_carrier.png";
				specular_map = { name = "ncc_carrier.png";};
				emission_map = { name = "ncc_carrier-glows.png";};
				normal_map = { name = "ncc_carrier_n.png";};
	      }; 
	};
EDIT: I managed to get it working by adding shaders and textures and uniforms to the materials entry. I reckon that the materials entry sets some default values for missing keys and I should have those in my separate shaders definition.

I managed to make it work like this:

Code: Select all

materials = { 
	      "carrierI.png" = { 	      
				diffuse_map = "ncc_carrier.png";
				specular_map = { name = "ncc_carrier.png";};
				emission_map = { name = "ncc_carrier-glows.png";};
				fragment_shader = "ncc_carrier.fragment";
				vertex_shader = "oolite-tangent-space-vertex.vertex";
                textures =
				(
					"ncc_carrier.png",
					"ncc_carrier-glows.png",
					"ncc_carrier_n.png"
				);
				uniforms =
				{
					uColorMap			= { type = texture; value = 0; };
					uNormalMap			= { type = texture; value = 2; };
					uEmissionMap			= { type = texture; value = 1; };
					uSpecularMap			= { type = texture; value = 0; };
					uTime				= "timeElapsedSinceSpawn";
					uHullHeatLevel		= "hullHeatLevel";
				};

	      }; 
 }; 
Don't know if this is the correct way to do it, though.
User avatar
Svengali
Commander
Commander
Posts: 2370
Joined: Sat Oct 20, 2007 2:52 pm

Re: Shaders’ Outpost

Post by Svengali »

spara wrote:
And I'm doing it with shaders. I have copied the oolite-default-shader.fragment to my oxp and managed to get diffuse map, normal map and emission map working.
...
Materials entry I'm trying to duplicate looks like this:
For what a custom shader then? It's more efficient to use materials and will also avoid (reduce) shader swapping which is a framerate killer No1.

Using the same texture unit (type = texture; value = 0;) for multiple textures? I doubt that this works. At least it is not valid.
User avatar
spara
---- E L I T E ----
---- E L I T E ----
Posts: 2691
Joined: Wed Aug 15, 2012 4:19 am
Location: Finland

Re: Shaders’ Outpost

Post by spara »

Svengali wrote:
spara wrote:
And I'm doing it with shaders. I have copied the oolite-default-shader.fragment to my oxp and managed to get diffuse map, normal map and emission map working.
...
Materials entry I'm trying to duplicate looks like this:
For what a custom shader then? It's more efficient to use materials and will also avoid (reduce) shader swapping which is a framerate killer No1.
I have 8 carriers that share the same model and texture, but have different names. I want to put a different name plate to the texture for each individual carrier like the other behemoths have. The other behemoths do this by using multiple textures, but to achieve that I would need to edit the carrier model. I'd rather do it with shaders and decals.

I'm happy with the default shader as such. All I want to do, is put a decal in.
Svengali wrote:
Using the same texture unit (type = texture; value = 0;) for multiple textures? I doubt that this works. At least it is not valid.
Why would it not work and why is it not valid? To my (quite limited) understanding the shader program just gets a copy of the texture. For diffuse map, it uses rgb channels and for specular map it uses rgb for specular colors and alpha for shininess. It seems to work. Is it different from using the same texture twice in material entries?
User avatar
cim
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 4072
Joined: Fri Nov 11, 2011 6:19 pm

Re: Shaders’ Outpost

Post by cim »

spara wrote:
Why would it not work and why is it not valid? To my (quite limited) understanding the shader program just gets a copy of the texture.
Not sure if it works or not (and shaders are not my area), but if you're writing your own shader program it'll be more efficient to change the references to point to a single texture. Just put specular_map = diffuse_map in the shader.
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Re: Shaders’ Outpost

Post by JensAyton »

Binding multiple sampler uniforms to the same texture unit is valid, but inefficient. It's better to use one sampler and sample it once. In an adaptation of the default shader, this boils down to using vec4 diffuseMapColor = specularMapColor; instead of the existing diffuse read.
User avatar
Svengali
Commander
Commander
Posts: 2370
Joined: Sat Oct 20, 2007 2:52 pm

Re: Shaders’ Outpost

Post by Svengali »

JensAyton wrote:
Binding multiple sampler uniforms to the same texture unit is valid, but inefficient.
You mean we could use the same texture unit for a samplerCube and a sampler2D?
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Re: Shaders’ Outpost

Post by JensAyton »

Svengali wrote:
JensAyton wrote:
Binding multiple sampler uniforms to the same texture unit is valid, but inefficient.
You mean we could use the same texture unit for a samplerCube and a sampler2D?
No. Each texture unit has a particular type of texture set, and you can only validly bind a sampler to a texture unit of the right type. What we’re talking about is cases like this:

Code: Select all

uniform sampler2D foo;
uniform sampler2D bar;
where the host application binds both foo and bar to the same texture unit number, and that texture unit has a GL_TEXTURE_2D bound. (The driver can potentially optimize this situation by recompiling the shader when the uniforms are set, but that’s bad for performance if they’re changed often.)
User avatar
Svengali
Commander
Commander
Posts: 2370
Joined: Sat Oct 20, 2007 2:52 pm

Re: Shaders’ Outpost

Post by Svengali »

Ah, I thought so. Thanks for the clarification, Jens.
User avatar
spara
---- E L I T E ----
---- E L I T E ----
Posts: 2691
Joined: Wed Aug 15, 2012 4:19 am
Location: Finland

Re: Shaders’ Outpost

Post by spara »

Thanks. I think I got it right. At least everything seems to be functioning as desired.
ocz
Deadly
Deadly
Posts: 175
Joined: Tue Nov 10, 2015 1:59 pm

Re: Shaders’ Outpost

Post by ocz »

[Solved]

Hi. I have entered the field of model and texture creation. I have learned much, but there are things I can't figure out. I created a dockingbay, that is haunted by a shadow effect I wish to go away:
Image
This looks horrendous. The funny thing is, no matter how its oriented to the sun, it always looks the same. Also, I set smooth = 0; for the shipdata.plist entity of it, but it still kinda look smoothed out. I want it to look like griff's coriolis bay (hard corners, no shadows).

Here's what it looks like in Wings 3D:
Image

Code: Select all

"solar_docking_bay" = {
		model = "solstationbay.dat";
		name = "Cube Station Dock";
		smooth = 0;
		shininess = 0;
		
		
		materials = 
		{ 
			"baywalls1024.png" = 
			{ 
				specular_color = ( 0.2, 0.2, 0.2 );  // Applies when specular map is not used (no shaders) 
				shininess = 0; 
			};
			
			"bayfloors1024.png" = 
			{ 
				specular_color = ( 0.2, 0.2, 0.2 );  // Applies when specular map is not used (no shaders) 
				shininess = 0; 
			}; 
		};
		
		shaders =
			{
				"baywalls1024.png" =
				{
					diffuse_map = "baywalls1024.png";
					normal_and_parallax_map = "baywallsnormalparallax.png";
					
					parallax_bias = 0;
					parallax_scale = "-0.005";
				};
				
				"bayfloors1024.png" =
				{
					diffuse_map = "bayfloors1024.png";
					normal_and_parallax_map = "bayfloorsnormalparallax.png";
					
					parallax_bias = 0;
					parallax_scale = "-0.005";
				};
				
			
		};
		
		
		subentities = 
		(
			//flashers omitted
			
		)
	};


EDIT:
Solution:
I came to an unsatisfying solution for my problem. I got what I wanted by using Obj2DatTex.py instead of the recommended Obj2DatTexNorm.py. Now I still have to look into what I did wrong to get a such horrendous result on the standard way, but at least my project con move on to it's closure. I guess I have to look into Wings 3D.

EDIT2:
I looked further into Wings 3D and indeed found a way to get rid of the smoothness. Edge Selector -> Hardness -> Hard or Object Selector -> Auto-Smooth [parameterbox] do the trick. I can use Obj2DatTexNorm.py now and the shadows got better. Not as good as the Obj2DatTex.pyversion though. Now the wall shadows don't change their when rotating , but stay either dark or lighted up and suddenly at a certain angle (pop!) switch lightness. The floors (cellings) do great though. I start to experiment with light sources and see if it goes away.
Image
(Click me for animation.)
User avatar
Svengali
Commander
Commander
Posts: 2370
Joined: Sat Oct 20, 2007 2:52 pm

Re: Shaders’ Outpost

Post by Svengali »

A while ago I stumbled about an interesting article about shader optimization. It's time to share it .-)

http://www.humus.name/Articles/Persson_ ... inking.pdf
another_commander
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 6682
Joined: Wed Feb 28, 2007 7:54 am

Re: Shaders’ Outpost

Post by another_commander »

Interesting read, Svengali. Thanks!
User avatar
Smivs
Retired Assassin
Retired Assassin
Posts: 8408
Joined: Tue Feb 09, 2010 11:31 am
Location: Lost in space
Contact:

Re: Shaders’ Outpost

Post by Smivs »

Help needed.
As you all know I don't 'do' shaders - haven't got a clue, but do have a problem. I'm currently updating the Liners OXP and am getting a log error.

Code: Select all

11:34:46.265 [shader.load.failed]: ***** ERROR: Could not build shader liners_tigershark.vertex/liners_tigershark.fragment.
  11:35:04.296 [shader.compile.failure]: ***** ERROR: GLSL vertex shader compilation failed for liners_tigershark.vertex:
>>>>> GLSL log:
0:0(9): preprocessor error: Redefinition of macro OO_TANGENT_ATTR
I don't know what this means or what is happening (or not happening) - the ship looks OK in-game. Any advice? .
The shader code from shipdata is below.

Code: Select all

		shaders = {
			"liners_tigershark.png" = {
				fragment_shader = "liners_tigershark.fragment";
				textures = (
					"liners_tigershark.png",
					"liners_tigersharkNormal.png"
				);
				uniforms = {
					PaintColor1 = {
						scale = "1.0";
						type = randomUnitVector;
					};
					hull_heat_level = hullHeatLevel;
					isHostile = hasHostileTarget;
					nearly_dead = throwingSparks;
					uColorMap = {
						type = texture;
						value = 0;
					};
					uNormalMap = {
						type = texture;
						value = 1;
					};
					uTime = universalTime;
				};
				vertex_shader = "liners_tigershark.vertex";
			};
		};
and these are the files in the Shaders folder.

Vertex

Code: Select all

#define OO_TANGENT_ATTR 1  // <---- Define OO_TANGENT_ATTR to 1 so that Oolite gives correct tangent data to shader. 
#ifdef OO_TANGENT_ATTR 
attribute vec3      tangent; 
#else 
const vec3         tangent = vec3(1.0, 0.0, 0.0); 
#endif

varying vec2         vTexCoord;
varying vec3         vEyeVector;   // These are all in tangent space
varying vec3         vLight0Vector;
varying vec3         vLight1Vector;


void main()
{
   // Build tangent basis
   vec3 n = normalize(gl_NormalMatrix * gl_Normal);
   vec3 t = normalize(gl_NormalMatrix *tangent);
   vec3 b = cross(n, t);
   mat3 TBN = mat3(t, b, n);
   
   vec3 eyeVector = -vec3(gl_ModelViewMatrix * gl_Vertex);
   vEyeVector = eyeVector * TBN;
   
#ifdef OO_LIGHT_0_FIX
   vec3 light0Vector = gl_LightSource[0].position.xyz + eyeVector;
   vLight0Vector = light0Vector * TBN;
#endif
   vec3 light1Vector = gl_LightSource[1].position.xyz + eyeVector;
   vLight1Vector = light1Vector * TBN;
   vTexCoord = gl_MultiTexCoord0.st;
   gl_Position = ftransform();

}
Fragment

Code: Select all

uniform sampler2D    uColorMap; // paintmap in Alpha. Blue channel used as spec int
uniform sampler2D    uNormalMap; // Illummap in A

varying vec2         vTexCoord;
varying vec3         vEyeVector;   // These are all in tangent space
varying vec3         vLight0Vector;
varying vec3         vLight1Vector;

// Constants
const float KspecExponent = 15.0;

// Uniforms from Oolite
   uniform float  uTime;
   uniform bool   nearly_dead;
   uniform bool   isHostile;   
   uniform float  hull_heat_level;
   uniform vec4   PaintColor1; // used with paintmask map to tint diffuse texture

// Initialize LampColor vec - it gets recolored later on in the shader
 vec4  LampColor = vec4(1.0);

// Irregular flickering function
   #ifdef OO_REDUCED_COMPLEXITY 
   #define Pulse(v, ts) ((v) * 0.95) 
   #define Blink_on_off(value) (1.0)
   #else

     float Pulse(float value, float timeScale)
     {
        float t = uTime * 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;
      }

// Hull Temperate heat glow effect
     vec4 TemperatureGlow(float level) 
     { 
        vec4 result = vec4(0); 
    
        result.r = level; 
        result.g = level * level * level; 
        result.b = max(level - 0.7, 0.0) * 2.0;
        result.a = 1.0; 
    
        return result;    
     } 
Commander Smivs, the friendliest Gourd this side of Riedquat.
another_commander
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 6682
Joined: Wed Feb 28, 2007 7:54 am

Re: Shaders’ Outpost

Post by another_commander »

Code: Select all

#define OO_TANGENT_ATTR 1  // <---- Define OO_TANGENT_ATTR to 1 so that Oolite gives correct tangent data to shader. 
Delete this line and it should work. This macro should never be defined manually.
User avatar
Smivs
Retired Assassin
Retired Assassin
Posts: 8408
Joined: Tue Feb 09, 2010 11:31 am
Location: Lost in space
Contact:

Re: Shaders’ Outpost

Post by Smivs »

Yes, that's done the trick. Thank you.
Commander Smivs, the friendliest Gourd this side of Riedquat.
Post Reply