Colour bit-wise shift in OpenGL shader GLSL - c++

I am passing vec4 to the shaders with xyz and a colour value and I tried to bit-wise shift the colour component to their own r g and b floats but having issues:
Vertex shader:
#version 150
in vec4 position;
out vec2 Texcoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;
void main()
{
Texcoord = vec2(position.w, position.w);
gl_Position = proj * view * model * vec4(position.xyz, 1.0);
}
Fragment shader:
#version 150
in vec2 Texcoord;
out vec4 outColor;
uniform sampler2D tex;
void main()
{
float data = Texcoord.r;
float r = (data>> 16) & 0xff;
float g = (data>> 8) & 0xff;
float b = data & 0xff;
outColor = vec4(r, g, b, 1.0);
}
Error:
Error compiling shader:
0(11) : error C1021: operands to ">>" must be integral
0(12) : error C1021: operands to ">>" must be integral
0(13) : error C1021: operands to "&" must be integral
Any ideas what I am doing wrong?

OK got it done :)
#version 150
in vec2 Texcoord;
out vec4 outColor;
uniform sampler2D tex;
vec3 unpackColor(float f)
{
vec3 color;
color.r = floor(f / 65536);
color.g = floor((f - color.r * 65536) / 256.0);
color.b = floor(f - color.r * 65536 - color.g * 256.0);
return color / 256.0;
}
void main()
{
float data = Texcoord.r;
vec3 unpackedValues = unpackColor(Texcoord.r);
outColor = vec4(unpackedValues.bgr, 1.0);
}
I was passing 4 bits of formation to my shader x y z coordinate of a point in the point cloud and 4th value was encoded colour in a float. So I needed to extract rgb information from the float to give each point a colour.
Thanks for help guys :)

Related

Problem with Shader "The shader uses varying --- but previous shader does not write to it"

Does anyone know why I keep getting the error that says:
The ♦ shader uses varying _I;DATA;g_mapCoord, but previous shader does not write to it.
The ♦ shader uses varying _I;DATA;worldPosition, but previous shader does not write to it.
Take a look at my shaders here.
Vertex
#version 430
layout (location = 0) in vec2 position0;
out DATA {
vec2 v_mapCoord;
vec3 worldPosition;
} Out;
uniform vec3 u_cameraPosition;
uniform mat4 u_localMatrix;
uniform mat4 u_worldMatrix;
uniform float u_scaleY;
uniform int u_lod;
uniform vec2 u_index;
uniform float u_gap;
uniform vec2 u_location;
uniform sampler2D s_heightmap;
uniform int u_lodMorphArea[8];
float morphLatitude(vec2 position)
{
//not important code
return 0;
}
float morphLongitude(vec2 position)
{
//not important code
return 0;
}
vec2 morph(vec2 localPosition, int morph_area){
//not important code
return vec2(0);
}
void main()
{
vec2 localPosition = (u_localMatrix * vec4(position0.x,0,position0.y,1)).xz;
if (u_lod > 0) {
localPosition += morph(localPosition, u_lodMorphArea[u_lod-1]); // Translate position by morphing vector
}
float height = texture(s_heightmap, localPosition).r;
Out.v_mapCoord = localPosition;
vec4 _worldPosition = u_worldMatrix * vec4(localPosition.x, height, localPosition.y,1);
Out.worldPosition = _worldPosition.xyz;
gl_Position = u_worldMatrix * vec4(localPosition.x, height, localPosition.y,1);
}
Fragment
#version 430
layout (location = 0) out vec4 outputColor;
in DATA {
vec2 g_mapCoord;
vec3 worldPosition;
} In;
const vec3 lightDirection = vec3(-0.2, -1.0, -0.2);
const float intensity = 1.2;
uniform sampler2D s_textureNormal;
uniform sampler2D s_textureWater;
uniform sampler2D s_textureLand;
float diffuse(vec3 direction, vec3 normal, float intensity)
{
return max(0.01, dot(normal, -direction) * intensity);
}
void main()
{
vec3 normal = texture(s_textureNormal, In.g_mapCoord).rgb;
float diff = diffuse(lightDirection, normal, intensity);
outputColor = vec4(1,0,0,1);
}
Geom
#version 430
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
in vec2 te_mapCoord[];
out vec2 g_mapCoord;
uniform mat4 u_viewProjection;
void main() {
for (int i = 0; i < gl_in.length(); ++i)
{
vec4 position = gl_in[i].gl_Position;
gl_Position = u_viewProjection * position;
g_mapCoord = te_mapCoord[i];
EmitVertex();
}
EndPrimitive();
}
TCS
#version 430
layout(vertices = 16) out;
in DATA {
vec2 v_mapCoord;
vec3 worldPosition;
} In[];
out vec2 tc_mapCoord[];
const int AB = 2;
const int BC = 3;
const int CD = 0;
const int DA = 1;
uniform int u_tessellationFactor;
uniform float u_tessellationSlope;
uniform float u_tessellationShift;
uniform vec3 u_cameraPosition;
// Calculate tessellation levels
float lodFactor(float dist)
{
float tessellationLevel = max(0.0, u_tessellationFactor/pow(dist, u_tessellationSlope) + u_tessellationShift);
return tessellationLevel;
}
void main()
{
if (gl_InvocationID == 0){
// Calculate mid points of the edges of the quad
vec3 abMid = vec3(gl_in[0].gl_Position + gl_in[3].gl_Position)/2.0; //Bottom left, Bottom right
vec3 bcMid = vec3(gl_in[3].gl_Position + gl_in[15].gl_Position)/2.0; //Bottom right Top right
vec3 cdMid = vec3(gl_in[15].gl_Position + gl_in[12].gl_Position)/2.0; //Top right, Top left
vec3 daMid = vec3(gl_in[12].gl_Position + gl_in[0].gl_Position)/2.0; //Top left, Bottom left
// Calculate distance between camera and mid points of the edges of the quad
float distanceAB = distance(abMid, u_cameraPosition);
float distanceBC = distance(bcMid, u_cameraPosition);
float distanceCD = distance(cdMid, u_cameraPosition);
float distanceDA = distance(daMid, u_cameraPosition);
// Tesselation levels used by tessellation primitive generator (define how much tessellation to apply to the patch). Value between 1 and gl_MaxTessGenLevel, depending on lodFactor.
gl_TessLevelOuter[AB] = mix(1, gl_MaxTessGenLevel, lodFactor(distanceAB));
gl_TessLevelOuter[BC] = mix(1, gl_MaxTessGenLevel, lodFactor(distanceBC));
gl_TessLevelOuter[CD] = mix(1, gl_MaxTessGenLevel, lodFactor(distanceCD));
gl_TessLevelOuter[DA] = mix(1, gl_MaxTessGenLevel, lodFactor(distanceDA));
gl_TessLevelInner[0] = (gl_TessLevelOuter[BC] + gl_TessLevelOuter[DA])/4;
gl_TessLevelInner[1] = (gl_TessLevelOuter[AB] + gl_TessLevelOuter[CD])/4;
}
tc_mapCoord[gl_InvocationID] = In[gl_InvocationID].v_mapCoord; // Just pass to the next stage
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}
TES
#version 430
layout(quads, fractional_odd_spacing, cw) in;
in vec2 tc_mapCoord[];
out vec2 te_mapCoord;
uniform sampler2D s_heightmap;
uniform float u_scaleY;
void main(){
float u = gl_TessCoord.x;
float v = gl_TessCoord.y;
// Compute new position for each tessellated vertex within the patch. gl_in with index 12, 0, 3, 15 are corners of the patch.
vec4 position = ((1 - u) * (1 - v) * gl_in[12].gl_Position + u * (1 - v) * gl_in[0].gl_Position + u * v * gl_in[3].gl_Position +(1 - u) * v * gl_in[15].gl_Position);
vec2 mapCoord = ((1 - u) * (1 - v) * tc_mapCoord[12] + u * (1 - v) * tc_mapCoord[0] + u * v * tc_mapCoord[3] +(1 - u) * v * tc_mapCoord[15]);
float height = texture(s_heightmap, mapCoord).r;
height *= u_scaleY;
position.y = height;
te_mapCoord = mapCoord;
gl_Position = position;
}
Can anyone help me find the error here which is why I'm getting that error message?
When you introduce a geometry shader you need to pass the varyings for the fragment shader from the geometry shader, not the vertex shader.
You can see how your geometry shader doing this:
out vec2 g_mapCoord;
is incompatible with your fragment shader expecting this:
in DATA {
vec2 g_mapCoord;
vec3 worldPosition;
} In;
Related question and subsequent answers here.

glGetUniformLocation returns -1 for an array of struct in GLSL

I'm trying to call glGetUniformLocation() on an array of struct. I read that I should use this name format: "uniformName[index].element", but the method always returns -1. I tried to delete the array and only use the structure and it worked so I guess that the problem might there. Here is the struct and the array in my fragment shader:
const int MAX_BLOCKS = 16;
struct sblock{
vec4 color;
float shineDamper;
float reflectivity;
};
uniform sblock blocks[MAX_BLOCKS];
And here is my call:
for(int i = 0; i < 16; i++) {
location_block_color[i] = super.getUniformLocation("blocks["+i+"].color");
location_block_reflectivity[i] = super.getUniformLocation("blocks["+i+"].reflectivity");
location_block_shineDamper[i] = super.getUniformLocation("blocks["+i+"].shineDamper");
System.out.println(location_block_color[i] + " " + location_block_reflectivity[i] + " " + location_block_shineDamper[i]); // prints -1 -1 -1 ...
}
getUniformLocation method:
protected int getUniformLocation(String uniformName) {
return GL20.glGetUniformLocation(programID, uniformName);
}
and this how I create programID (before anything else):
vertexShaderID = loadShader(vertexFile, GL20.GL_VERTEX_SHADER);
fragmentShaderID = loadShader(fragmentFile, GL20.GL_FRAGMENT_SHADER);
programID = GL20.glCreateProgram();
My question is what is happening here and what am I doing wrong?
Thanks for your help.
EDIT 1:
Here is my full fragment shader:
#version 400 core
const int MAX_LIGHTS = 16;
const int MAX_BLOCKS = 16;
struct sblock{
vec4 color;
float shineDamper;
float reflectivity;
};
uniform sblock blocks[MAX_BLOCKS];
in int block_id_out;
in vec3 unitNormal;
in vec3 lightVector[MAX_LIGHTS];
in vec3 directionalLightFinalColour;
in vec3 directionalLightReflected;
in vec3 toCameraVector;
in float visibility;
out vec4 outColor;
uniform float ambientLight;
uniform vec3 skyColor;
uniform vec3 lightColour[MAX_LIGHTS];
uniform vec3 attenuation[MAX_LIGHTS];
uniform int lightCount;
uniform vec3 directionalLightColour;
uniform vec3 directionalLightDirection;
vec3 calculateDiffuse(vec3 unitNormal, vec3 unitLightVector, vec3 lightColour, float attFactor){
float nDotl = dot(unitNormal,unitLightVector);
float brightness = max(nDotl,0);
return (brightness * lightColour) / attFactor;
}
vec3 calculateSpecular(vec3 unitNormal, vec3 unitLightVector, vec3 unitToCameraVector, float shineDamper, float reflectivity, vec3 lightColour, float attFactor){
vec3 reflectedLightDirection = reflect(-unitLightVector,unitNormal);
float specularFactor = max(dot(reflectedLightDirection, unitToCameraVector),0.0);
float dampedFactor = pow(specularFactor,shineDamper);
return (dampedFactor * reflectivity * lightColour) / attFactor;
}
void main(void){
vec3 totalDiffuse = vec3(0.0);
vec3 totalSpecular = vec3(0.0);
vec3 unitToCameraVector = normalize(toCameraVector);
for(int i = 0; i < lightCount;i++){
vec3 unitLightVector = normalize(lightVector[i]);
float lightDistance = length(lightVector[i]);
float attFactor = attenuation[i].x + attenuation[i].y*lightDistance + attenuation[i].z*lightDistance*lightDistance;
totalSpecular += calculateSpecular(unitNormal, unitLightVector, unitToCameraVector, blocks[block_id_out].shineDamper, blocks[block_id_out].reflectivity, lightColour[i], attFactor);
totalDiffuse += calculateDiffuse(unitNormal, unitLightVector, lightColour[i], attFactor);
}
totalDiffuse += directionalLightFinalColour;
totalSpecular += pow(max(dot(directionalLightReflected,unitToCameraVector),0.0),blocks[block_id_out].shineDamper)*blocks[block_id_out].reflectivity*directionalLightColour;
totalDiffuse = max(totalDiffuse,ambientLight);
outColor = vec4(totalDiffuse,1.0) * blocks[block_id_out].color + vec4(totalSpecular,1.0);
outColor = mix(vec4(skyColor,1.0),outColor,visibility);
}
EDIT 2:
Here is my VertexShader:
#version 400 core
const vec4 normals[] = vec4[6](vec4(1,0,0,0),vec4(0,1,0,0),vec4(0,0,1,0),vec4(-1,0,0,0),vec4(0,-1,0,0),vec4(0,0,-1,0));
const int MAX_LIGHTS = 16;
in vec3 position;
in int block_id;
in int normal;
out int block_id_out;
out vec3 unitNormal;
out vec3 lightVector[MAX_LIGHTS];
out vec3 directionalLightFinalColour;
out vec3 directionalLightReflected;
out vec3 toCameraVector;
out float visibility;
uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition[MAX_LIGHTS];
uniform vec3 directionalLight;
uniform vec3 directionalLightColor;
uniform int lightCount;
uniform float fogDensity;
uniform float fogGradient;
void main(void){
vec4 worldPosition = transformationMatrix * vec4(position,1.0);
vec4 positionRelativeToCam = viewMatrix * worldPosition;
gl_Position = projectionMatrix * positionRelativeToCam;
block_id_out = block_id;
unitNormal = normalize((transformationMatrix * normals[normal]).xyz);
for(int i = 0; i < lightCount;i++){
lightVector[i] = lightPosition[i] - worldPosition.xyz;
}
directionalLightFinalColour = max(dot(unitNormal, directionalLight),0)*directionalLightColor;
directionalLightReflected = reflect(-directionalLight,unitNormal);
toCameraVector = (inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz;
visibility = clamp(exp(-pow(length(positionRelativeToCam.xyz)*fogDensity,fogGradient)),0.0,1.0);
}
From (most recent) OpenGL Shading Language 4.60 Specification (HTML) - 4.3.9. Interface Blocks
A uniform or shader storage block array can only be indexed with a dynamically uniform integral expression, otherwise results are undefined.
block_id_out is fragment shader input (set by a vertex shader input) and not a Dynamically uniform expression. Hence blocks[block_id_out] is undefined and is not guaranteed, that blocks[i] becomes an active program resource.
I recommend to change the declaration. Do not create an array of uniforms. Create a single Uniform block:
const int MAX_BLOCKS = 16;
struct Block
{
vec4 color;
float shineDamper;
float reflectivity;
};
layout(std140) uniform Blocks
{
Block blocks[MAX_BLOCKS];
};
You have to create a Uniform Buffer Object to bind data to the uniform block.
I think that #Rabbid76 answer is correct, but I found a more satisfying workaround. I defined the struct and the uniform in the vertex shader, and then pass the correct values for color, shinedamper and reflectivity to the fragment shader. This makes more sense since I only want to access the values for each vertex and they are going to be same in the fragment shader, so doing it 3 times for each triangle is better than doing it hundreds of times for each pixel.

smooth 64bit input from vertex to frag shader - "error C7570: 64 bit input should be flat"

I've made a small program in OpenGL that draws the Mandelbrot set, however I am having some trouble using 64bit values in my fragment shader. Everything works as intended when i use the vec2 type in my shaders like so and an array of doubles for my vertex array in c++:
#shader vertex
#version 410 core
layout(location = 0) in vec4 a_position;
layout(location = 1) in vec3 a_colour;
layout(location = 2) in vec2 mandelbrot;
smooth out vec3 frag_colour;
smooth out vec2 frag_mandelbrot;
uniform float view_zoom;
uniform vec2 view_translate;
void main()
{
gl_Position = a_position;
frag_colour = a_colour;
frag_mandelbrot = (mandelbrot / view_zoom) + view_translate;
};
#shader fragment
#version 410 core
layout(location = 0) out vec3 colour;
in vec3 frag_colour;
in vec2 frag_mandelbrot;
void main()
{
double x = 0;
double y = 0;
vec3 start = vec3(0.0f, 0.0f, 0.0f);
vec3 end = vec3(1.0f, 1.0f, 1.0f);
int iteration = 0;
int max_iteration = 250;
while (x*x + y * y <= 2 * 2 && iteration < max_iteration) {
double xtemp = x * x - y * y + frag_mandelbrot[0];
y = 2 * x*y + frag_mandelbrot[1];
x = xtemp;
iteration++;
}
float t = float(iteration) / float(max_iteration);
colour = mix(start,end,t);
};
However when I tried to use the dvec2 type like this:
#shader vertex
#version 410 core
layout(location = 0) in vec4 a_position;
layout(location = 1) in vec3 a_colour;
layout(location = 2) in dvec2 mandelbrot;
smooth out vec3 frag_colour;
smooth out dvec2 frag_mandelbrot;
uniform double view_zoom;
uniform dvec2 view_translate;
void main()
{
gl_Position = a_position;
frag_colour = a_colour;
frag_mandelbrot = (mandelbrot / view_zoom) + view_translate;
};
#shader fragment
#version 410 core
layout(location = 0) out vec3 colour;
in vec3 frag_colour;
in dvec2 frag_mandelbrot;
void main()
{
double x = 0;
double y = 0;
vec3 start = vec3(0.0f, 0.0f, 0.0f);
vec3 end = vec3(1.0f, 1.0f, 1.0f);
int iteration = 0;
int max_iteration = 250;
while (x*x + y * y <= 2 * 2 && iteration < max_iteration) {
double xtemp = x * x - y * y + frag_mandelbrot[0];
y = 2 * x*y + frag_mandelbrot[1];
x = xtemp;
iteration++;
}
float t = float(iteration) / float(max_iteration);
colour = mix(start,end,t);
};
I get the following compilation error in my frag shader :
0(5) : error C7570: 64 bit input 'frag_mandelbrot' should be flat
My question is, why should it be flat? The GLSL documentation states the following:
"Note: Precision qualifiers in GLSL are supported for compatibility with OpenGL ES. They use the same syntax as ES's qualifiers, but they have no functional effects. Do not use them unless you want your shaders to be ES compatible."
so I take it that these (highp, mediump, ect.) are not to be used for ordinary desktop opengl. Is it not possible for the frag shader to take 64 bit values interpolated from vertex attributes as input? Or have I just made some silly mistake somewhere?
The type of the fragment shader input
in dvec2 frag_mandelbrot;
is a double-precision floating-point type.
See the most recent GLSL specification, OpenGL Shading Language 4.60 Specification (HTML) - 4.3.3. Constant Expressions
[...]
Fragment shader inputs that are, or contain, integral or double-precision floating-point types must be qualified with the interpolation qualifier flat.
[...]

OpenGL 0(84): error C7623: implicit narrowing of type from "vec4" to "float"

I am working on shadows for a Minecraft shader, and im stuck at trying to resolve the following error.
21:51:27.725
[Shaders] Error compiling fragment shader: /shaders/composite.fsh
21:51:27.726
[Shaders] Shader info log: /shaders/composite.fsh
0(84) : error C7623: implicit narrowing of type from "vec4" to "float"
21:51:27.727
[Shaders] Error linking program: 10 (composite)
I know the error is caused by incompatible types, but I'm still not sure how to solve it, so any help is appreciated.
#version 120
const int shadowMapResolution = 2048;
const float shadowDistance = 128;
const float shadowMapBias = 0.85;
const int noiseTextureResolution = 256;
#define SHADOWMAP_BIAS 0.85
uniform sampler2D colortex0;
uniform sampler2D shadowtex0;
uniform sampler2D shadowcolor0;
uniform sampler2D depthtex1;
uniform sampler2D noisetex;
uniform vec3 cameraPosition;
uniform mat4 gbufferModelViewInverse;
uniform mat4 gbufferModelView;
uniform mat4 shadowProjection;
uniform mat4 gbufferProjection;
uniform mat4 gbufferProjectionInverse;
uniform mat4 shadowModelView;
uniform float viewWidth;
uniform float viewHeight;
varying vec4 texcoord;
float depth = 0.5;
vec4 getCameraPosition(in vec2 coord)
{
float getdepth = depth;
vec4 positionNdcSpace = vec4(coord.s * 2.0 - 1.0, coord.t * 2.0 - 1.0, 2.0 * getdepth - 1.0, 1.0);
vec4 positionCameraSpace = gbufferProjectionInverse * positionNdcSpace;
return positionCameraSpace / positionCameraSpace.w;
}
vec4 getWorldSpacePosition(in vec2 coord)
{
vec4 cameraPos = getCameraPosition(coord);
vec4 worldPos = gbufferModelViewInverse * cameraPos;
worldPos.xyz += cameraPosition;
return worldPos;
}
vec3 getShadowSpacePosition(in vec2 coord)
{
vec4 worldSpacePos = getWorldSpacePosition(coord);
worldSpacePos.xyz -= cameraPosition;
vec4 shadowSpacePos = shadowModelView * worldSpacePos;
shadowSpacePos = shadowProjection * shadowSpacePos;
return shadowSpacePos.xyz * 0.5 + 0.5;
}
mat2 getRotationMatrix(in vec2 coord)
{
float rotationAmount = texture2D(
noisetex,
coord * vec2(
viewWidth / noiseTextureResolution,
viewHeight / noiseTextureResolution
)
).r;
return mat2(
cos(rotationAmount), -sin(rotationAmount),
sin(rotationAmount), cos(rotationAmount)
);
}
vec3 getShadows(in vec2 coord)
{
vec3 shadowCoord = getShadowSpacePosition(coord);
mat2 rotationMatrix = getRotationMatrix(coord);
vec3 shadowCol = vec3(0.0);
for (int i = 0; i < 32; i++)
{
vec2 offset = vec2(32 / shadowMapResolution);
offset = rotationMatrix * offset;
float shadowMapSample = texture2D(shadowtex0, shadowCoord.st + offset);
float visibility = step(shadowCoord.z - shadowMapSample, 0.001);
vec3 dayCol = vec3(1.0);
vec3 colorSample = texture2D(shadowcolor0, shadowCoord.st + offset).rgb;
shadowCol += mix(colorSample, dayCol, visibility);
}
return vec3(shadowCol) / 32;
}
vec3 calculateLighting(in vec3 color)
{
vec3 sunLight = getShadows(texcoord.st);
vec3 ambientLight = vec3(0.5, 0.7, 1.0) * 0.5;
return color * (sunLight + ambientLight);
}
void main()
{
depth = texture2D(depthtex1, texcoord.st).r;
vec3 color = texture2D(colortex0, texcoord.st).rbg;
color = calculateLighting(color);
gl_FragData[0] = vec4(color, 1.0);
gl_FragData[1] = vec4(depth);
}
The problem is that texture2D returns a vec4, but you are treating as a float. Read the red component instead
float shadowMapSample = texture2D(shadowtex0, shadowCoord.st + offset).r;

Same shaders behaving differently on Nvidia and ATI cards

Me and a friend are developing an editor (CAD-like) to use in our future game.
We are using the Qt framework and OpenGL.
The problem we are encountering is that on his laptop with an integrated nVidia card, the shading is working as expected and renders well. On my laptop with an integrated ATI card, as well as on my desktop with Radeon HD5850, the phong lighting is behaving slightly differently. There are more bright spots and dark spots and the image doesn't look good. Also, we are using a toon shader to draw a silhouette around the edges and to limit the amount of shades a color can have.
The toon shader uses 2-pass rendering - first pass renders the object in black, slightly larger than original (shifting each vertex in its normals direction slightly) to make the silhouette and then the second pass renders the object normally (only limiting the shade spectrum, so it looks more comic-like).
The images are of the same thing on our 2 computers. The first difference I mentioned above, the second is that the silhouette is stretched out as it should be on my friends computer, so it makes an even silhouette around the object, but is moved slightly up on my computer, making a thick line on the top and no line on the bottom.
The other thing is the phong lighting, illuminating the cube within which the object is edited. Again, rendering well on my friends computer, but being almost all-black or all-white on mine.
First image (nVidia card):
Second image (ATI cards):
I understand that the code is long and maybe the problem lays in some Qt settings, not in the shaders, but if you see anything that strikes you as bad practice, please answer.
Code for the phong shading follows
#version 400
in vec4 aVertex;
in vec4 aNormal;
in vec2 aTexCoord;
uniform mat4 uPVM;
uniform mat4 uViewModel;
uniform mat4 uNormal;
uniform int uLightsOn;
out vec2 vTexCoord;
out vec3 vNormal;
flat out vec3 mEye;
flat out vec3 mLightDirection;
flat out vec4 mAxisColor;
void main(void)
{
if(uLightsOn == 1) {
mEye = (uViewModel * aVertex).xyz;
mLightDirection = vec4(2.0,-2.0,1.0,0.0).xyz;
vNormal = (uNormal * aNormal).xyz;
}
gl_Position = uPVM * aVertex;
vTexCoord = aTexCoord;
mAxisColor = aNormal;
}
The phong fragment shader :
#version 400
uniform sampler2D uTexture0;
uniform int uLightsOn;
uniform vec3 uHighlightColor;
uniform int uTextured;
uniform int uAxisRender;
in vec2 vTexCoord;
in vec3 vNormal;
flat in vec3 mEye;
flat in vec3 mLightDirection;
out vec4 fragColor;
flat in vec4 mAxisColor;
struct TMaterial {
vec4 diffuse;
vec4 ambient;
vec4 specular;
float shininess;
};
TMaterial material;
void setup() {
// setupMaterials
material.ambient = vec4(0.4);
material.diffuse = vec4(0.9);
material.specular = vec4(0.0);
material.shininess = 0.3;
}
void main(void)
{
setup();
vec3 finalHighlightColor = uHighlightColor;
if(finalHighlightColor.x <= 0.0) finalHighlightColor.x = 0.1;
if(finalHighlightColor.y <= 0.0) finalHighlightColor.y = 0.1;
if(finalHighlightColor.z <= 0.0) finalHighlightColor.z = 0.1;
if(uLightsOn == 0) {
if(uAxisRender == 1) fragColor = mAxisColor;
else fragColor = vec4(finalHighlightColor,1.0);
return;
}
vec4 diffuse;
vec4 spec = vec4(0.0);
vec4 ambient;
vec3 L = normalize(mLightDirection - mEye);
vec3 E = normalize(-mEye);
vec3 R = normalize(reflect(-L,vNormal));
ambient = material.ambient;
float intens = max(dot(vNormal,L), 0.0);
diffuse = clamp( material.diffuse * intens , 0.0, 1.0 );
if(intens > 0.0) spec = clamp ( material.specular * pow(max(dot(R,E),0.0),material.shininess) , 0.0, 1.0 );
if(uTextured == 1) fragColor = (ambient + diffuse + spec) * texture(uTexture0,vTexCoord);
else fragColor = (ambient + diffuse + spec) * vec4(finalHighlightColor,1.0);
}
And the toon shaders :
#version 400
in vec4 aVertex;
in vec4 aNormal;
in vec2 aTexCoord;
uniform mat4 uPV;
uniform mat4 uM;
uniform mat4 uN;
uniform vec3 uLightPosition;
uniform vec3 uCameraPosition;
uniform int uSilhouetteMode;
uniform float uOffset;
// if this uniform is passed, all the toon rendering is going off and only simple axis are rendered
// last data in aNormal are colors of those axis if everything was ser properly.
uniform int uAxisRendering;
flat out vec4 fAxisColor;
out vec4 vNormal;
out vec2 vTexCoord;
out vec3 vDirectionToCamera;
out vec3 vDirectionToLight;
void silhouetteMode() {
gl_Position = uPV * uM * vec4(aVertex.xyz + aNormal.xyz * uOffset,1.0f);
}
void toonMode() {
vec4 worldPosition = uM * aVertex;
vDirectionToCamera = uCameraPosition - worldPosition.xyz;
vDirectionToLight = uLightPosition - worldPosition.xyz;
vNormal = uN * aNormal;
gl_Position = uPV * worldPosition;
}
void axisMode() {
fAxisColor = aNormal;
gl_Position = uPV * uM * aVertex;
}
void main(void)
{
vTexCoord = aTexCoord;
if(uSilhouetteMode == 1) {
silhouetteMode();
} else {
if(uAxisRendering == 1) axisMode();
else toonMode();
}
}
and the fragment shader
#version 400
uniform sampler2D uTexture;
uniform vec3 uBaseColor;
uniform float uNumShades;
uniform int uSilhouetteMode;
uniform int uAxisRendering;
flat in vec4 fAxisColor;
in vec4 vNormal;
in vec2 vTexCoord;
in vec3 vDirectionToCamera;
in vec3 vDirectionToLight;
out vec4 outFragColor;
void main(void)
{
if(uSilhouetteMode == 1) {
outFragColor = vec4(uBaseColor,1.0);
return;
}
if(uAxisRendering == 1) {
outFragColor = fAxisColor;
return;
}
float l_ambient = 0.1;
float l_diffuse = clamp(dot(vDirectionToLight,vNormal.xyz),0.0,1.0);
float l_specular;
vec3 halfVector = normalize(vDirectionToCamera + vDirectionToLight);
if(dot(vDirectionToLight,vNormal.xyz) > 0.0) {
l_specular = pow(clamp(dot(halfVector,vNormal.xyz),0.0,1.0),64.0);
} else {
l_specular = 0.0;
}
float intensity = l_ambient + l_diffuse + l_specular;
float shadeIntesity = ceil(intensity * uNumShades)/ uNumShades;
outFragColor = vec4(texture(uTexture,vTexCoord).xyz * shadeIntesity * uBaseColor,1.0);
}
And finally, our OpenGLWindow initialization (in Qt)
OpenGLWindow::OpenGLWindow(QWindow *parent) :
QWindow(parent),m_animating(false), m_initialized(false), m_animationTimer(NULL)
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setDepthBufferSize( 24 );
format.setMajorVersion( 4 );
format.setMinorVersion( 0 );
format.setSamples( 4 );
format.setProfile( QSurfaceFormat::CoreProfile );
setFormat( format );
create();
if(!m_context) {
m_context = new QOpenGLContext(this);
m_context->setFormat(requestedFormat());
m_context->create();
m_context->makeCurrent(this);
initializeOpenGLFunctions();
}
m_animationTimer = new QTimer(this);
connect(m_animationTimer, SIGNAL(timeout()), this, SLOT(renderer()));
m_animationTimer->setInterval(16);
}
To my eyes the nVidia image seems to be using alpha whereas the AMD one is not. I also can't see a
format.setAlpha(true);
in your Qt setup so may be that.