Hi,
Caveat - I'm not the author of the code below, and neither do I fully understand it. However what I do know is that the HD3000 fails to produce the expected output, whilst other hardware (including my old XP laptop with an ATI x700 OpenGL 2.1 card, and the authors OpenGL 4.1 Nvidia card) does. The part of the code that does not seem to be processed as expected is designed to place and rotate a decal texture on a 3d models base texture. The placement works, the rotation value (defined as a float (Decal1_Rotation) is picked up and bound to the model correctly, but the value passed to the shader appears to be ignored. No errors are reported to the host application.
| uniform sampler2D | uColorMap; |
| uniform sampler2D | uNormalMap; |
| uniform sampler2D | uEffectsMap; |
| uniform sampler2D | uDecalMap; |
| varying vec2 | vTexCoord; |
| varying vec3 | vEyeVector; // These are all in tangent space |
| varying vec3 | vLight0Vector; |
| varying vec3 | vLight1Vector; |
// Constants
const float KspecExponent = 5.0;
const vec3 kLampColorNoAlert = vec3(0);
const vec3 kLampColorYellowAlert = vec3(0.9926, 0.9686, 0.7325);
const vec3 kLampColorRedAlert = vec3(1.0, 0.1, 0.0);
// Uniforms from Oolite
uniform float uTime;
| uniform int | alertlevel; |
| uniform int | damage_amount; |
uniform float hull_heat_level;
uniform float engine_power;
uniform vec4 PaintColor1; // used with paintmask map to tint diffuse texture
uniform vec4 PaintColor2; // used with paintmask map to tint diffuse texture
uniform vec4 Decal1_Scale_and_Position; // position & scale settings for decal 1
uniform float Decal1_Rotation; // rotation settings for decal 1
// 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
| vec3 TemperatureGlow(float level) | |
| { | |
| vec3 result = vec3(0); |
| result.r = level; | |
| result.g = level * level * level; | |
| result.b = max(level - 0.7, 0.0) * 2.0; | |
| return result; | |
| } | |
// Blink_on_off_function.
float Blink_on_off(float timeScale)
{
float result = step(0.5, sin(uTime * timeScale));
return 0.5 + result;
| } | |
// Cyan color exhaust glow effect
vec3 cyanGlow(float level)
{
| vec3 result; | |
| result.rgb = vec3(0.2, 0.7, 0.9) * level * 1.5; | |
| return result; | |
| } | |
// Red/Orange color heated metal effect
vec3 redGlow(float level)
{
| vec3 result; | |
| result.rgb = vec3(1.5, 0.55, 0.2) * level * 1.3; | |
| return result; |
}
#endif
void Light(in vec3 lightVector, in vec3 normal, in vec3 lightColor, in vec3 eyeVector,
| in float KspecExponent, inout vec3 totalDiffuse, inout vec3 totalSpecular) |
{
lightVector = normalize(lightVector);
vec3 reflection = normalize(-reflect(lightVector, normal));
totalDiffuse += gl_FrontMaterial.diffuse.rgb * lightColor * max(dot(normal, lightVector), 0.0);
totalSpecular += lightColor * pow(max(dot(reflection, eyeVector), 0.0), KspecExponent);
}
#define LIGHT(idx, vector) Light(vector, normal, gl_LightSource[idx].diffuse.rgb, eyeVector, KspecExponent, diffuse, specular)
#ifndef OO_REDUCED_COMPLEXITY
// function to read in the colour map then scale and position the decal map onto it.
/*
"the_decaliser" - this function scales & positions the decal image using data passed
to it from the main shader
*/
vec4 the_decaliser(vec4 Your_Decal_Settings, float Your_decal_Rotation)
{
// Setup the basic texture co-ords for the decals
vec2 decal_TexCoord = vTexCoord;
| // Position the decal |
decal_TexCoord -= vec2(Your_Decal_Settings.s, Your_Decal_Settings.t - (0.5 / Your_Decal_Settings.p));
// Orientate & scale the decal
float decal_s = sin(Your_decal_Rotation);
float decal_c = cos(Your_decal_Rotation);
decal_TexCoord *= mat2(decal_c, decal_s, -decal_s, decal_c);
decal_TexCoord += vec2(0.5 / Your_Decal_Settings.p);
decal_TexCoord *= vec2(Your_Decal_Settings.p, Your_Decal_Settings.p);
// Get texture values.
vec4 decal_Tex = texture2D(uDecalMap, decal_TexCoord);
// Modify the Decals texture co-oords
decal_TexCoord.s += 1.0;
decal_Tex *= step(1.0, decal_TexCoord.s) *
| step(0.0, decal_TexCoord.t) * | |
| step(-2.0, -decal_TexCoord.s) * | |
| step(-1.0, -decal_TexCoord.t); | |
// Use the Alpha in the decal as a transparency mask so you can 'cutout' your decal from it's background
float alpha = decal_Tex.a;
// Return the scaled, position & rotated decal, it's mixed into the colour texture further on in the shader .
return alpha * decal_Tex;
| } |
#endif
void main()
{
vec3 eyeVector = normalize(vEyeVector);
vec2 texCoord = vTexCoord;
vec3 normal = normalize(texture2D(uNormalMap, vTexCoord).rgb - 0.5);
vec3 colorMap = texture2D(uColorMap, texCoord).rgb;
vec4 effectsMap = texture2D(uEffectsMap, texCoord);
vec3 diffuse = vec3(0.0), specular = vec3(0);
float specIntensity = texture2D(uColorMap, texCoord).a;
float glowMap = texture2D(uNormalMap, texCoord).a;
vec3 LampColor = vec3(0.9926, 0.9686, 0.7325);
#ifdef OO_LIGHT_0_FIX
LIGHT(0, normalize(vLight0Vector));
#endif
LIGHT(1, normalize(vLight1Vector));
diffuse += gl_FrontMaterial.ambient.rgb * gl_LightModel.ambient.rgb;
#ifndef OO_REDUCED_COMPLEXITY
// Full Shader Mode - Repaint the hull
colorMap += effectsMap.g * PaintColor1.rgb;
colorMap += effectsMap.a * PaintColor2.rgb;
// Full Shader Mode - Apply the decals
vec4 decals = the_decaliser(Decal1_Scale_and_Position, Decal1_Rotation);
// mix the decals into the texture using the decal alpha as a mask
vec3 color = mix(colorMap, decals.rgb, decals.a) * diffuse;
// Calculate the lighting for full shader mode
color += color * specular * specIntensity * 2.5;
#endif
// Calculate the lighting for simple shader mode
#ifdef OO_REDUCED_COMPLEXITY
vec3 color = diffuse * colorMap;
color += colorMap * specular * specIntensity * 2.5;
// Add in simple shader hull lights
color += LampColor * glowMap;
#endif
// these next glow effects are only available in full shader mode
#ifndef OO_REDUCED_COMPLEXITY
// check Alert Level, Adjust Lamp Colour Accordingly
if (alertlevel > 0)
| { | |
| LampColor = (alertlevel > 2) ? kLampColorRedAlert * max(mod(uTime, 1.5), 0.5): kLampColorYellowAlert; | |
| } |
else
| { | |
| LampColor = kLampColorNoAlert; | |
| } |
// Damage Calculator
float tempvar = float(damage_amount);
float DamageAmount = mod(tempvar, 100.0) / 100.0;
vec3 Lampglow = LampColor * glowMap * Pulse(2.0, 1.0) * (1.0 - DamageAmount);
vec3 Cyanglow = cyanGlow(effectsMap.b * Pulse(min(engine_power, 1.0), 1.0));
vec3 Redglow = redGlow(effectsMap.r * Pulse(min(engine_power, 1.0), 1.0));
color += mix(Lampglow + Cyanglow + Redglow,
| Redglow + | |
| Lampglow * Blink_on_off(Pulse(1.0, 0.4)) * 4.0 + | |
| Cyanglow * Blink_on_off(Pulse(1.0, 1.0)), max(0.0, DamageAmount - 0.4)); |
// Add the all over hull temperature glow. Full Shader mode only
float hullHeat = max(hull_heat_level - 0.5, 0.0) * 2.0;
hullHeat = Pulse(hullHeat * hullHeat, 0.1);
color += TemperatureGlow(hullHeat);
#endif
gl_FragColor = vec4(color.rgb, 1.0);
}
To start working on this problem more details are needed.
It is unclear what corruptions are observed and what does it mean “but the value passed to the shader appears to be ignored”. We do not know the OpenGL state (that sometimes affect the compiled code) nor the corresponding vertex shader either.
Additional details and the original application or simplified application that reproduce the problem is needed to further understand the issue.
Thanks for the reply Robert_U
The application is the open source and free to download game Oolite.
Link to Windows Installer - BerliOS Download - The Open Source Mediator
The models exhibiting the problem are in an optional add-on - the download is in two parts.
http://deephorizonindustries.com/griffind/Griff_Shipset_Resources_v1.2.24.zip
http://deephorizonindustries.com/griffind/Griff_Shipset_Addition_v1.021.zip
Download and install the game, before unzipping the additional downloads and copying the folders ending .oxp to the games AddOns folder. Launch the game. After a splash screen a model that demonstrates the problem will be displayed on screen.
The issue is with the little skull and crossbones decal, which is not responding to values passed to the model's shader which should change its rotation/orientation in relation to the model. As said it works on other hardware.
The values are set up in a Config file called shipdata.plist which is in the Griff_Shipset_Addition download. At line 2860 you will see this entry. Changes to the value of the "Decal1_Rotation" uniform binding should alter the orientation of the skull and crossbones but doesn't on the HD3000. On the other hand the shader is correctly processing the value passed by "Decal1_Scale_and_Position".
| shaders = | { | |
| "griff_cobra_mk3_mainhull_diffuse_spec.png" = | { | |
| "fragment_shader" = "griff_cobra_mk3_player.fragment"; | ||
| textures = | ( | |
| "griff_cobra_mk3_mainhull_diffuse_spec.png", | ||
| "griff_cobra_mk3_mainhull_normal.png", | ||
| "griff_cobra_mk3_mainhull_effects.png", | ||
| "griff_player_decal.png" | ||
| ); | ||
| uniforms = | { | |
| "Decal1_Rotation" = | { | |
| type = float; | ||
| value = "-0.73840"; | ||
| }; | ||
| "Decal1_Scale_and_Position" = | { | |
| type = vector; | ||
| value = "0.59 0.2 9.6"; | ||
| }; | ||
| PaintColor1 = | { | |
| scale = "0.17"; | ||
| type = randomUnitVector; | ||
| }; | ||
| PaintColor2 = | { | |
| scale = "0.17"; | ||
| type = randomUnitVector; | ||
| }; | ||
| alertlevel = alertCondition; | ||
| "damage_amount" = damage; | ||
| "engine_power" = speedFactor; | ||
| "hull_heat_level" = hullHeatLevel; | ||
| uColorMap = | { | |
| type = texture; | ||
| value = 0; | ||
| }; | ||
| uDecalMap = | { | |
| type = texture; | ||
| value = 3; | ||
| }; | ||
| uEffectsMap = | { | |
| type = texture; | ||
| value = 2; | ||
| }; | ||
| uNormalMap = | { | |
| type = texture; | ||
| value = 1; | ||
| }; | ||
| uTime = universalTime; | ||
| }; | ||
| "vertex_shader" = "griff_normalmap_ships.vertex"; | ||
| }; | ||
| }; |
The fragment (which was the code posted above) and vertex shader files referenced are both in the Griff_Shipset_Resources download.
I hope that's enough to get you going. If you need to look at the games source code see WebSVN - oolite-linux - Rev 5028 - /tags/1.76.1/src/SDL/
Hello, smurphdude!
I decided to try to give your issue a shot and see if it would happen on my intel system. I think I'm really close to a breakthrough, but I'm confused in regards to your final step in which you say, "On the other hand the shader is correctly processing the value passed by 'Decal1_Scale_and_Position'."
Could you please provide specific step-by-step instructions on how to check that the shader is correctly processing the value, both in code and in game? If it's important, I'm using a python as my ship with skull and crossbones.

