OpenGL Triangle pipe around line segment - opengl

I would like to ask how can I render in geometry shader a triangle pipe from a line segment?
I first compute perpendicular vector "perp" to the line vector "axis".
Then I rotate the "perp" vector few times by "rotate" function.
Since mesh is composed from 8 vertices I am trying to use "triangle_strip".
My current code :
#version 330 core
layout (lines) in;
layout(triangle_strip, max_vertices = 8) out;//triangle_strip
uniform float u_thickness ;
uniform vec2 u_viewportSize ;
uniform bool u_scale_width_by_zoom ;
in gl_PerVertex
{
vec4 gl_Position;
//float gl_PointSize;
//float gl_ClipDistance[];
} gl_in[];
vec4 rotate(vec4 p, float x, float y, float z,float angle )
{
vec3 q;
q[0] = p[0] * (x*x * (1.0 - cos(angle)) + cos(angle))
+ p[1] * (x*y * (1.0 - cos(angle)) + z * sin(angle))
+ p[2] * (x*z * (1.0 - cos(angle)) - y * sin(angle));
q[1] = p[0] * (y*x * (1.0 - cos(angle)) - z * sin(angle))
+ p[1]* (y*y * (1.0 - cos(angle)) + cos(angle))
+ p[2] * (y*z * (1.0 - cos(angle)) + x * sin(angle));
q[2] = p[0] * (z*x * (1.0 - cos(angle)) + y * sin(angle))
+ p[1] * (z*y * (1.0 - cos(angle)) - x * sin(angle))
+ p[2] * (z*z * (1.0 - cos(angle)) + cos(angle));
return vec4(q, 0.0);
}
void main() {
//https://stackoverflow.com/questions/54686818/glsl-geometry-shader-to-replace-gllinewidth
vec4 p1 = gl_in[0].gl_Position;
vec4 p2 = gl_in[1].gl_Position;
//tube
// Specify the axis to rotate about:
vec4 axis = p2-p1;
float x = axis[0];
float y = axis[1];
float z = axis[2];
axis = normalize(axis);
//float length = hypotf(axis[0], hypotf(axis[1], axis[2]));
float length = sqrt((axis[0]*axis[0]) + sqrt(axis[1]*axis[1]+ axis[2]*axis[2]));
float dir_scalar = (axis[0] > 0.0) ? length : -length;
float xt = axis[0] + dir_scalar;
float dot = -axis[1] / (dir_scalar * xt);
vec3 perp_0 = vec3(dot * xt, 1.0f + dot * axis.y, dot * axis.z);
perp_0 = normalize(perp_0);
vec4 perp = vec4(perp_0,0)*u_thickness*0.001;
//side0
vec4 p1_1 = p1+perp;
vec4 p1_2 = p2+perp;
vec4 perp_rot_2=rotate(perp,x,y,z,60.0 * 3.14 / 180.0);
vec4 p2_1 = p1+perp_rot_2;
vec4 p2_2 = p2+perp_rot_2;
vec4 perp_rot_3=rotate(perp,x,y,z, 120.0 * 3.14 / 180.0);
vec4 p3_1 = p1+perp_rot_3;
vec4 p3_2 = p2+perp_rot_3;
gl_Position = p1_1;
EmitVertex();
gl_Position = p1_2;
EmitVertex();
gl_Position = p2_1;
EmitVertex();
gl_Position = p2_2;
EmitVertex();
gl_Position = p3_1;
EmitVertex();
gl_Position = p3_2;
EmitVertex();
gl_Position = p1_1;
EmitVertex();
gl_Position = p1_2;
EmitVertex();
EndPrimitive();
}
It produces wrong results:

Related

Why shadows are not rendered when PBR directional light is applied?

I've got a problem with rendering hard shadows in a PBR pipeline.
I believe there is something wrong with PBR calculations because with a Blinn-Phong lighting model everything looks fine.
These are lightning calculations - basic PBR
struct DirectionalLight
{
vec3 direction;
};
layout(std140, binding = 2) uniform Scene
{
DirectionalLight directionalLight;
vec3 viewPosition;
} u_scene;
layout(std140, binding = 4) uniform Material
{
vec4 baseColor;
float roughness;
float metalness;
} u_material;
const float PI = 3.14159265359;
const float epsilon = 0.00001;
int lightCount = 1;
vec3 CalculateDirectionalLight(vec3 N, vec3 V, float NdotV, vec3 F0)
{
vec3 result;
for(int i = 0; i < lightCount; ++i) {
vec3 L = normalize(-u_scene.directionalLight.direction);
float NdotL = max(0.0f, dot(N, L));
vec3 H = normalize(V + L);
float NdotH = max(0.0f, dot(N, H));
vec3 F = FresnelSchlickRoughness(max(0.0f, dot(H, V)), F0, u_material.roughness);
float D = NDFGGX(NdotH, u_material.roughness);
float G = GeometrySmith(NdotL, NdotV, u_material.roughness);
vec3 kd = (1.0f - F) * (1.0f - u_material.metalness);
vec3 diffuse = kd * u_material.baseColor.rgb;
vec3 nominator = F * G * D;
float denominator = max(epsilon, 4.0f * NdotV * NdotL);
vec3 specular = nominator / denominator;
specular = clamp(specular, vec3(0.0f), vec3(10.0f));
result += (diffuse + specular) /* u_material.radiance */ * NdotL;
}
return result;
}
float NDFGGX(float NdotH, float roughness)
{
float alpha = roughness * roughness;
float alphaSq = alpha * alpha;
float denom = (NdotH * NdotH) * (alphaSq - 1.0) + 1.0;
return alphaSq / (PI * denom * denom);
}
float GeometrySchlickGGX(float Ndot, float k)
{
float nom = Ndot;
float denom = Ndot * (1.0 - k) + k;
return nom / denom;
}
float GeometrySmith(float NdotL, float NdotV, float roughness)
{
float r = (roughness + 1.0f);
float k = (r * r) / 8.0f;
float ggx2 = GeometrySchlickGGX(NdotV, k);
float ggx1 = GeometrySchlickGGX(NdotL, k);
return ggx1 * ggx2;
}
vec3 FresnelSchlick(float cosTheta, vec3 F0)
{
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
}
vec3 FresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
{
return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0);
}
shadow functions
layout(binding = 2) uniform sampler2D u_shadowMap;
float ShadowFade = 1.0;
float GetShadowBias()
{
const float MINIMUM_SHADOW_BIAS = 0.002;
float bias = max(MINIMUM_SHADOW_BIAS * (1.0 - dot(normalize(v_normal), -normalize(u_scene.directionalLight.direction))), MINIMUM_SHADOW_BIAS);
return bias;
}
float HardShadows_DirectionalLight(vec4 fragPosLightSpace)
{
vec3 shadowCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
float bias = GetShadowBias();
float shadowMapDepth = texture(u_shadowMap, vec2(shadowCoords.xy * 0.5 + 0.5)).r;
return step(shadowCoords.z, shadowMapDepth + bias) * ShadowFade;
}
and the main function
void main()
{
vec3 F0 = vec3(0.04f);
F0 = mix(F0, u_material.baseColor.rgb, u_material.metalness);
vec3 N = normalize(v_normal);
vec3 V = normalize(u_scene.viewPosition - v_position);
float NdotV = max(0.0f, dot(N, V));
//v_positionFromLight is calculated in a vertex shader like this:
//v_positionFromLight = u_lightViewProjection * vec4(v_position, 1.0f);
//where v_position is modelMatrix * a_position;
//where a_position is a input position of a vertex
float shadow = HardShadows_DirectionalLight(v_positionFromLight);
vec3 ambient = u_material.baseColor.rgb * 0.3f;
vec3 lightContribution = ambient + CalculateDirectionalLight(N, V, NdotV, F0) * shadow;
f_color = vec4(lightContribution, 1.0);
}
and this is how the scene looks like - there should be visible shadows, but there aren't:
I've tested 2 things.
First - Blinn-Phong lighting model - shadows render just fine.
Second - output shadow calculations without PBR lightning
like this:
void main()
{
float shadow = HardShadows_DirectionalLight(v_positionFromLight);
vec3 ambient = u_material.baseColor.rgb * 0.3f;
f_color = vec4(ambient * shadow, 1.0f);
}
and it also works (besides that they're not placed in a good spot, but that is another topic):
Why this PBR model does not work with shadows?
How can I fix it?

GLSL: Sample from previous output and not texture2D

I'm trying to write a custom shader where I first blur the texture and then run sobel edge finding.
I've got sobel running ok via the following script
vec4 colorSobel = texture2D(texture, uv);
float bottomLeftIntensity = texture2D(texture, uv + vec2(-0.0015625, 0.0020833)).r;
float topRightIntensity = texture2D(texture, uv + vec2(0.0015625, -0.0020833)).r;
float topLeftIntensity = texture2D(texture, uv + vec2(-0.0015625, 0.0020833)).r;
float bottomRightIntensity = texture2D(texture, uv + vec2(0.0015625, 0.0020833)).r;
float leftIntensity = texture2D(texture, uv + vec2(-0.0015625, 0)).r;
float rightIntensity = texture2D(texture, uv + vec2(0.0015625, 0)).r;
float bottomIntensity = texture2D(texture, uv + vec2(0, 0.0020833)).r;
float topIntensity = texture2D(texture, uv + vec2(0, -0.0020833)).r;
float h = -secondary * topLeftIntensity - coef * topIntensity - secondary * topRightIntensity + secondary * bottomLeftIntensity + coef * bottomIntensity + secondary * bottomRightIntensity;
float v = -secondary * bottomLeftIntensity - coef * leftIntensity - secondary * topLeftIntensity + secondary * bottomRightIntensity + coef * rightIntensity + secondary * topRightIntensity;
float mag = length(vec2(h, v));
// alpha values removed atm
if (mag < 0.5) {
colorSobel.rgb *= (1.0 - 1.0);
colorSobel.r += 0.0 * 1.0;
colorSobel.g += 0.0 * 1.0;
colorSobel.b += 0.0 * 1.0;
colorSobel.rgb += 1.0 * mag;
} else {
colorSobel.rgb *= (1.0 - 1.0);
colorSobel.r += 0.0 * 1.0;
colorSobel.g += 0.0 * 1.0;
colorSobel.b += 0.0 * 1.0;
colorSobel.rgb += 1.0 * mag;
}
gl_FragColor = colorSobel;
However I know it works by sampling the texture via texture2D.
If I were to first manipulate the output via a simple script such as this which reduces the colours
vec4 bg = texture2D(texture,uv);
gl_FragColor = vec4(gb.rgb, 1.0);
gl_FragColor.r = float(floor(gl_FragColor.r * 0.5 ) / 0.5);
gl_FragColor.g = float(floor(gl_FragColor.g * 0.5 ) / 0.5);
gl_FragColor.b = float(floor(gl_FragColor.b * 0.5 ) / 0.5);
The output still samples from the texture and ignores the first paint.
Is there a way to sample from the color output rather than using texture2D?
The reason I'm asking is that i'm chaining my shaders at runtime depending on user interaction?

Why do all my particles share the same rotation and color? (GLSL Shaders)

Like the title suggests, I am building a particle system in OpenGL using a geometry shader to create billboards from points. Everything seems okay but it looks like all particles share the rotation and color of the first particle. I've checked the inputs of course.
Here are my current vertex and geometry shaders:
Vertex Shader:
#version 330 core
layout(location=0) in vec4 in_position;
layout(location=2) in float in_angle;
layout(location=3) in vec4 in_color;
uniform mat4 P;
uniform mat4 V;
out VertexData
{
vec4 color;
float angle;
} vertex;
void main()
{
vertex.color = in_color;
vertex.angle = in_angle;
gl_Position = in_position;
}
Geometry shader:
#version 330
layout (points) in;
layout (triangle_strip, max_vertices = 4) out;
uniform mat4 V;
uniform mat4 P;
in VertexData
{
vec4 color;
float angle;
} vertex[];
out vec4 fragColor;
out vec2 texcoord;
mat4 rotationMatrix(vec3 axis, float angle)
{
axis = normalize(axis);
float s = sin(angle);
float c = cos(angle);
float oc = 1.0 - c;
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0,
0.0, 0.0, 0.0, 1.0);
} // http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/
void main()
{
mat4 R = rotationMatrix( vec3(0,0,1), vertex[0].angle );
vec4 pos = V * vec4( gl_in[0].gl_Position.xyz, 1.0 );
float size = gl_in[0].gl_Position.w;
texcoord = vec2( 0.0, 0.0);
gl_Position = P * ( pos + vec4( texcoord, 0, 0 ) * R * size );
fragColor = vertex[0].color;
EmitVertex();
texcoord = vec2( 1.0, 0.0);
gl_Position = P * ( pos + vec4( texcoord, 0, 0 ) * R * size );
fragColor = vertex[0].color;
EmitVertex();
texcoord = vec2( 0.0, 1.0);
gl_Position = P * ( pos + vec4( texcoord, 0, 0 ) * R * size );
fragColor = vertex[0].color;
EmitVertex();
texcoord = vec2( 1.0, 1.0);
gl_Position = P * ( pos + vec4( texcoord, 0, 0 ) * R * size );
fragColor = vertex[0].color;
EmitVertex();
EndPrimitive();
}
Am I doing something wrong in here?
Ahh I found out what was causing my problem.
I still had two calls to glVertexAttribDivisor(), from when I was still using glDrawArraysInstanced().

GLSL Fragment shader slowdown

I have been spending the last few days writing a fragment shader that will handle the background for a 2d game im making. However, today I noticed that my cloud rendering is extremley slow (drop from 3000 to 300 fps) when rendering.
At first I thought that it was because I had done something stupid when generating the clouds, but after some experiments I noticed that the slowdown only happned when I added the clouds t the gl_FragColor. Calculating them seemed to not have any impact on performance.
I generate the clouds like this:
float rand(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
float hash( float n ) //Borrowed from voltage
{
return fract(sin(n)*43758.5453);
}
float fBmWRand( vec2 p )//Borroowed from Mark Sleith
{
float f = 0.0;
f += 0.50000*rand( p ); p = p*2.02;
f += 0.25000*rand( p ); p = p*2.03;
f += 0.12500*rand( p ); p = p*2.01;
f += 0.06250*rand( p ); p = p*2.04;
f += 0.03125*rand( p );
return f/0.984375;
}
float noise( in vec2 x )//Borroowed from Mark Sleith
{
vec2 p = floor(x);
vec2 f = fract(x);
f = f*f*(3.0-2.0*f);
float n = p.x + p.y*57.0;
float res = mix(mix( hash(n+ 0.0), hash(n+ 1.0),f.x), mix( hash(n+ 57.0), hash(n+ 58.0),f.x),f.y);
return res;
}
float fbm( vec2 p ) //Borroowed from Mark Sleith
{
float f = 0.0;
f += 0.50000*noise( p ); p = p*2.02;
f += 0.25000*noise( p ); p = p*2.03;
f += 0.12500*noise( p ); p = p*2.01;
f += 0.06250*noise( p ); p = p*2.04;
f += 0.03125*noise( p );
return f/0.984375;
}
vec3 bgGradient()
{
//Getting the height of the current pixel
float height = gl_FragCoord.y / iResolution.y;
//Calculating the brightness of the pixel
float brightness = 1.0 - 0.4 * height;
//Combining everything into a background
vec3 grad = vec3(1., 1., 1.);// * brightness;
return grad;
}
bool star()
{
/*//Getting a position to run random calculations with
float pos = (gl_FragCoord.x / iResolution.x) * (gl_FragCoord.y / iResolution.y) + 0.5;
if(hash(pos) < 0.001)
{
return true;
}
return false*/;
if(fBmWRand(gl_FragCoord.xy / iResolution.xy) < 0.08)
{
return true;
}
return false;
}
float cloudFadeDist = 0.1; //The distance at which the clouds will start fading away
vec4 clouds( vec2 point )
{
vec4 result = vec4(0., 0., 0., 0.);
//Checking if the cloud is above
float fbmResult = fbm(point * 5.);
if(fbmResult > overcast)
{
result = vec4(fbmResult, fbmResult, fbmResult, 1.0);
//result = vec4(1., 1., 1., 1.);
}
else if(fbmResult > overcast - (cloudFadeDist / resFact)) //Outlining the clouds
{
float dist = overcast - fbmResult;
float colorFac = 1.0 - dist / (cloudFadeDist / resFact);
if(colorFac > 0.0001)
{
result = vec4(fbmResult, fbmResult, fbmResult, colorFac);
}
}
//Finer details
float fbmDetail = fbm(point * 20.);
vec4 details = vec4( 0.7 + fbmDetail, 0.7 + fbmDetail, 0.7 + fbmDetail, 1.0);
//result = mix(result, details, result.a);
result = result * details;
result = result * details;
return result;
}
And I add the clouds to the rest of the "image" with this
//Generating the clouds
vec4 cloudLayer = vec4(0., 0., 0., 0.);
for(int i = 0; i < 4; i++)
{
//clouds( (15.0 * float(i)) + gl_FragCoord.xy / iResolution.xy + posX * float(i + 1));
/*vec4 cloud = clouds( vec2((15. * float(i)) + gl_FragCoord.x / iResolution.x + posX * float(i + 1)),
(15. * float(i)) + gl_FragCoord.y / iResoulution.y);*/
vec4 cloud = clouds( vec2( (15. * float(i)) + gl_FragCoord.x / iResolution.x + posX * float(i + 1),
(15. * float(i)) + gl_FragCoord.y / iResolution.y + posY * float(i + 1)));
//finalColor = finalColor + vec4(cloud, 1.);
cloudLayer = mix(cloudLayer, cloud, cloud.a);
}
if(time > nStart || time < nEnd) //Nighttime
{
finalColor = finalColor * nSky;
finalColor = mix(finalColor, starLayer, starLayer.a);
cloudLayer = cloudLayer * nCloud;
//finalColor = mix(finalColor, cloudLayer, cloudLayer.a);
vec4 genericColor = cloudLayer;
finalColor = mix(finalColor, cloudLayer, cloudLayer.a);
//finalColor = vec4(nSky.r, nSky.g, nSky.b, 1.0);
}
else if(time > dStart && time < dEnd)
{
finalColor = finalColor * dSky;
//cloudLayer = cloudLayer * dCloud;
finalColor = mix(finalColor, cloudLayer, cloudLayer.a);
}
else if(time > dEnd && time < nStart) //Evening
{
float timeFact = (time - dEnd) / (nStart - dEnd);
//Calculating the diffirence between night and day
vec4 skyDiff = vec4(nSky.r - dSky.r, nSky.g - dSky.g, nSky.b - dSky.b, 1.);
vec4 skyColor = vec4(dSky.r + (skyDiff.r * timeFact), dSky.g + (skyDiff.g * timeFact), dSky.b + (skyDiff.b * timeFact), 1.);
finalColor = skyColor;
//Stars
finalColor = mix(finalColor, starLayer, starLayer * timeFact);
//Clouds
vec4 cloudDiff = vec4(nCloud.r - dCloud.r, nCloud.g - dCloud.g, nCloud.b - dCloud.b, 1.);
vec4 cloudColor = vec4(dCloud.r + (cloudDiff.r * timeFact), dCloud.g + (cloudDiff.g * timeFact), dCloud.b + (cloudDiff.b * timeFact), 1.);
vec4 cloudLayer = cloudLayer * cloudColor;
finalColor = mix(finalColor, cloudLayer, cloudLayer.a);
}
else if(time > nEnd && time < dStart) //Evening
{
float timeFact = (time - nEnd) / (dStart - nEnd);
//Calculating the diffirence between night and day
vec4 skyDiff = vec4(dSky.r - nSky.r, dSky.g - nSky.g, dSky.b - nSky.b, 1.);
vec4 skyColor = vec4(nSky.r + (skyDiff.r * timeFact), nSky.g + (skyDiff.g * timeFact), nSky.b + (skyDiff.b * timeFact), 1.);
finalColor = skyColor;
//Stars
finalColor = mix(finalColor, starLayer, starLayer * 1. - timeFact);
//Clouds
vec4 cloudDiff = vec4(dCloud.r - nCloud.r, dCloud.g - nCloud.g, dCloud.b - nCloud.b, 1.);
vec4 cloudColor = vec4(nCloud.r + (cloudDiff.r * timeFact), nCloud.g + (cloudDiff.g * timeFact), nCloud.b + (cloudDiff.b * timeFact), 1.);
vec4 cloudLayer = cloudLayer * cloudColor;
finalColor = mix(finalColor, cloudLayer, cloudLayer.a);
}
gl_FragColor = finalColor;
The slowdown only happens when I do:
gl_FragColor = finalColor;
I also double the FPS from 300 to 600 if I remove the details part of the cloud generation
Is there something I have done wrong or is it just natural for the shader to be this performance intensive when I do something like this.
For reference, this is the whole shader
uniform vec2 iResolution;
uniform vec2 iMouse;
uniform float time;
uniform float overcast;
uniform float posX;
uniform float posY;
uniform vec4 dSky; //The color of the sky during the day
uniform vec4 nSky; //The color of the sky during the night
uniform vec4 dCloud; //The color of the clouds at day
uniform vec4 nCloud; //The color of the clouds at night
float resFact = iResolution.x / 500;
//float overcast = iMouse.y / iResolution.y;
//float posX = iMouse.x / iResolution.x;
/*float nSkyR = 0.05;
float nSkyG = 0.05;
float nSkyB = 0.39;*/
float rand(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
float hash( float n ) //Borrowed from voltage
{
return fract(sin(n)*43758.5453);
}
float fBmWRand( vec2 p )//Borroowed from Mark Sleith
{
float f = 0.0;
f += 0.50000*rand( p ); p = p*2.02;
f += 0.25000*rand( p ); p = p*2.03;
f += 0.12500*rand( p ); p = p*2.01;
f += 0.06250*rand( p ); p = p*2.04;
f += 0.03125*rand( p );
return f/0.984375;
}
float noise( in vec2 x )//Borroowed from Mark Sleith
{
vec2 p = floor(x);
vec2 f = fract(x);
f = f*f*(3.0-2.0*f);
float n = p.x + p.y*57.0;
float res = mix(mix( hash(n+ 0.0), hash(n+ 1.0),f.x), mix( hash(n+ 57.0), hash(n+ 58.0),f.x),f.y);
return res;
}
float fbm( vec2 p ) //Borroowed from Mark Sleith
{
float f = 0.0;
f += 0.50000*noise( p ); p = p*2.02;
f += 0.25000*noise( p ); p = p*2.03;
f += 0.12500*noise( p ); p = p*2.01;
f += 0.06250*noise( p ); p = p*2.04;
f += 0.03125*noise( p );
return f/0.984375;
}
vec3 bgGradient()
{
//Getting the height of the current pixel
float height = gl_FragCoord.y / iResolution.y;
//Calculating the brightness of the pixel
float brightness = 1.0 - 0.4 * height;
//Combining everything into a background
vec3 grad = vec3(1., 1., 1.);// * brightness;
return grad;
}
bool star()
{
/*//Getting a position to run random calculations with
float pos = (gl_FragCoord.x / iResolution.x) * (gl_FragCoord.y / iResolution.y) + 0.5;
if(hash(pos) < 0.001)
{
return true;
}
return false*/;
if(fBmWRand(gl_FragCoord.xy / iResolution.xy) < 0.08)
{
return true;
}
return false;
}
float cloudFadeDist = 0.1; //The distance at which the clouds will start fading away
vec4 clouds( vec2 point )
{
vec4 result = vec4(0., 0., 0., 0.);
//Checking if the cloud is above
float fbmResult = fbm(point * 5.);
if(fbmResult > overcast)
{
result = vec4(fbmResult, fbmResult, fbmResult, 1.0);
//result = vec4(1., 1., 1., 1.);
}
else if(fbmResult > overcast - (cloudFadeDist / resFact)) //Outlining the clouds
{
float dist = overcast - fbmResult;
float colorFac = 1.0 - dist / (cloudFadeDist / resFact);
if(colorFac > 0.0001)
{
result = vec4(fbmResult, fbmResult, fbmResult, colorFac);
}
}
//Finer details
float fbmDetail = fbm(point * 20.);
vec4 details = vec4( 0.7 + fbmDetail, 0.7 + fbmDetail, 0.7 + fbmDetail, 1.0);
//result = mix(result, details, result.a);
result = result * details;
result = result * details;
return result;
}
vec2 sunPos = vec2(0.15, 0.1);
float sunWidth = 0.03;
float sunGlow = 0.015;
float sunR = 1.;
float sunG = 1.;
float sunB = 0.8;
vec4 sun()
{
vec4 result = vec4(0., 0., 0., 0.);
float xPos = gl_FragCoord.x / iResolution.x;
float yPos = gl_FragCoord.y / iResolution.x;
float xDist = xPos - sunPos.x;
float yDist = yPos - sunPos.y;
float dist = sqrt(pow(xDist, 2.) + pow(yDist, 2.));
if(dist < sunWidth)
{
result = vec4(sunR, sunG, sunB, 1.);
}
else if(dist < sunWidth + sunGlow)
{
float distFact = (dist - sunWidth) / sunGlow;
result = vec4(sunR, sunG, sunB , 1. - distFact);
}
return result;
}
float nStart = 2200;
float nEnd = 600;
float dStart = 800;
float dEnd = 2000;
void main(void)
{
//Cretaing the final color variable and adding the gradient
vec4 finalColor = vec4(bgGradient(), 1.0);
//Creating stars
vec4 starLayer = vec4(0., 0., 0., 0.);
if(star() == true)
{
starLayer = vec4(1., 1., 1., 1.); //Make the pixel very bright
}
//Generating the clouds
vec4 cloudLayer = vec4(0., 0., 0., 0.);
for(int i = 0; i < 4; i++)
{
//clouds( (15.0 * float(i)) + gl_FragCoord.xy / iResolution.xy + posX * float(i + 1));
/*vec4 cloud = clouds( vec2((15. * float(i)) + gl_FragCoord.x / iResolution.x + posX * float(i + 1)),
(15. * float(i)) + gl_FragCoord.y / iResoulution.y);*/
vec4 cloud = clouds( vec2( (15. * float(i)) + gl_FragCoord.x / iResolution.x + posX * float(i + 1),
(15. * float(i)) + gl_FragCoord.y / iResolution.y + posY * float(i + 1)));
//finalColor = finalColor + vec4(cloud, 1.);
cloudLayer = mix(cloudLayer, cloud, cloud.a);
}
if(time > nStart || time < nEnd) //Nighttime
{
finalColor = finalColor * nSky;
finalColor = mix(finalColor, starLayer, starLayer.a);
cloudLayer = cloudLayer * nCloud;
//finalColor = mix(finalColor, cloudLayer, cloudLayer.a);
vec4 genericColor = cloudLayer;
finalColor = mix(finalColor, cloudLayer, cloudLayer.a);
//finalColor = vec4(nSky.r, nSky.g, nSky.b, 1.0);
}
else if(time > dStart && time < dEnd)
{
finalColor = finalColor * dSky;
//cloudLayer = cloudLayer * dCloud;
finalColor = mix(finalColor, cloudLayer, cloudLayer.a);
}
else if(time > dEnd && time < nStart) //Evening
{
float timeFact = (time - dEnd) / (nStart - dEnd);
//Calculating the diffirence between night and day
vec4 skyDiff = vec4(nSky.r - dSky.r, nSky.g - dSky.g, nSky.b - dSky.b, 1.);
vec4 skyColor = vec4(dSky.r + (skyDiff.r * timeFact), dSky.g + (skyDiff.g * timeFact), dSky.b + (skyDiff.b * timeFact), 1.);
finalColor = skyColor;
//Stars
finalColor = mix(finalColor, starLayer, starLayer * timeFact);
//Clouds
vec4 cloudDiff = vec4(nCloud.r - dCloud.r, nCloud.g - dCloud.g, nCloud.b - dCloud.b, 1.);
vec4 cloudColor = vec4(dCloud.r + (cloudDiff.r * timeFact), dCloud.g + (cloudDiff.g * timeFact), dCloud.b + (cloudDiff.b * timeFact), 1.);
vec4 cloudLayer = cloudLayer * cloudColor;
finalColor = mix(finalColor, cloudLayer, cloudLayer.a);
}
else if(time > nEnd && time < dStart) //Evening
{
float timeFact = (time - nEnd) / (dStart - nEnd);
//Calculating the diffirence between night and day
vec4 skyDiff = vec4(dSky.r - nSky.r, dSky.g - nSky.g, dSky.b - nSky.b, 1.);
vec4 skyColor = vec4(nSky.r + (skyDiff.r * timeFact), nSky.g + (skyDiff.g * timeFact), nSky.b + (skyDiff.b * timeFact), 1.);
finalColor = skyColor;
//Stars
finalColor = mix(finalColor, starLayer, starLayer * 1. - timeFact);
//Clouds
vec4 cloudDiff = vec4(dCloud.r - nCloud.r, dCloud.g - nCloud.g, dCloud.b - nCloud.b, 1.);
vec4 cloudColor = vec4(nCloud.r + (cloudDiff.r * timeFact), nCloud.g + (cloudDiff.g * timeFact), nCloud.b + (cloudDiff.b * timeFact), 1.);
vec4 cloudLayer = cloudLayer * cloudColor;
finalColor = mix(finalColor, cloudLayer, cloudLayer.a);
}
//finalColor = vec4(1., 0., 0., 1.);
//vec4 sunColor = sun();
//finalColor = mix(finalColor, sunColor, sunColor.a);
//If there is a star
/*if(star() == true)
{
finalColor = vec4(1., 1., 1., 1.); //Make the pixel very bright
}*/
/*for(int i = 0; i < 4; i++)
{
//clouds( (15.0 * float(i)) + gl_FragCoord.xy / iResolution.xy + posX * float(i + 1));
//vec4 cloud = clouds( vec2((15. * float(i)) + gl_FragCoord.x / iResolution.x + posX * float(i + 1)),
(15. * float(i)) + gl_FragCoord.y / iResoulution.y);
vec4 cloud = clouds( vec2( (15. * float(i)) + gl_FragCoord.x / iResolution.x + posX * float(i + 1),
(15. * float(i)) + gl_FragCoord.y / iResolution.y + posY * float(i + 1)));
//finalColor = finalColor + vec4(cloud, 1.);
finalColor = mix(finalColor, cloud, cloud.a);
}*/
gl_FragColor = finalColor;
}
And a working version without the time stuff can be found here to get an idea of what the shader actually does
Generally shader compilers (being either glsl/hlsl) are pretty good at removing dead code.
So if you calculate some value but don't use it, the compiler will just strip it off before to send the shader bytecode to the graphics card. So in the final compiled version the calculation will actually just not happen.
As soon as you start using this value (which you do as soon as soon you assign it to gl_FragColor) then it's actually "really" integrated in your final shader.
And noise calculations are generally quite ALU intensive, so a slowdown to 300 is not unusual (and actually not even too bad, depending on which card you use).

OpenGL FXAA issues

I am a Computer Science Student and I am currently doing a 2d Game for my Coursework.
I know that it's kind of unnecessary, but I tried to implement the FXAA algorithm for the AA of the game. The shader I am using is this one, because I thought using just a simple frag shader would be alright. I can also be found on Github.
#version 120
#define FXAA_REDUCE_MIN (1.0/128.0)
#define FXAA_REDUCE_MUL (1.0/8.0)
#define FXAA_SPAN_MAX 8.0
uniform sampler2D sampler0;
uniform vec2 resolution;
void main(){
vec2 inverse_resolution=vec2(1.0/resolution.x,1.0/resolution.y);
vec3 rgbNW = texture2D(sampler0, (gl_FragCoord.xy + vec2(-1.0,-1.0)) * inverse_resolution).xyz;
vec3 rgbNE = texture2D(sampler0, (gl_FragCoord.xy + vec2(1.0,-1.0)) * inverse_resolution).xyz;
vec3 rgbSW = texture2D(sampler0, (gl_FragCoord.xy + vec2(-1.0,1.0)) * inverse_resolution).xyz;
vec3 rgbSE = texture2D(sampler0, (gl_FragCoord.xy + vec2(1.0,1.0)) * inverse_resolution).xyz;
vec3 rgbM = texture2D(sampler0, gl_FragCoord.xy * inverse_resolution).xyz;
vec3 luma = vec3(0.299, 0.587, 0.114);
float lumaNW = dot(rgbNW, luma);
float lumaNE = dot(rgbNE, luma);
float lumaSW = dot(rgbSW, luma);
float lumaSE = dot(rgbSE, luma);
float lumaM = dot(rgbM, luma);
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
vec2 dir;
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL),FXAA_REDUCE_MIN);
float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
dir = min(vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),dir * rcpDirMin)) * inverse_resolution;
vec3 rgbA = 0.5 * (texture2D(sampler0, gl_FragCoord.xy * inverse_resolution + dir * (1.0/3.0 - 0.5)).xyz + texture2D(sampler0, gl_FragCoord.xy * inverse_resolution + dir * (2.0/3.0 - 0.5)).xyz);
vec3 rgbB = rgbA * 0.5 + 0.25 * (texture2D(sampler0, gl_FragCoord.xy * inverse_resolution + dir * - 0.5).xyz + texture2D(sampler0, gl_FragCoord.xy * inverse_resolution + dir * 0.5).xyz);
float lumaB = dot(rgbB, luma);
if((lumaB < lumaMin) || (lumaB > lumaMax)) {
gl_FragColor = vec4(rgbA,1.0);
} else {
gl_FragColor = vec4(rgbB,1.0);
}
}
The problem I ran into is, that whenever I turn the shader on my screen is flipped upside down... How do I solve this? It's probably because of the Orthographic Projection, but I am just a student, so I can't come up with a solution.
It seems to be a texture coordinate problem. Use 1-V instead of V to flip your mirrored image.
vec2 correctedFragCoord;
correctedFragCoord.x = gl_FragCoord.x;
correctedFragCoord.y = resolution.y - gl_FragCoord.y;
Then replace gl_FragCoord by correctedFragCoord in the shader.