I generate 2D perlin noise and I'm doing it terrain. But I have a problem with this. It's too gradual.
I tried x,z coordinates are divided or multiplied but doesn't work. How can I solve this problem without tessellation shader?
EDIT:
fragment shader code:
#version 430
in vec3 pos;
in vec2 text;
in vec3 norm;
layout(binding=3) uniform sampler2D texture_1;
layout(binding=4) uniform sampler2D texture_2;
layout(binding=5) uniform sampler2D texture_3;
vec3 lightPosition = vec3(-200, 700, 50);
vec3 lightAmbient = vec3(0,0,0);
vec3 lightDiffuse = vec3(1,1,1);
vec3 lightSpecular = vec3(1,1,1);
out vec4 fragColor;
vec4 theColor;
void main()
{
vec3 lightVector = normalize(lightPosition) - normalize(pos);
float cosTheta = clamp(dot(normalize(lightVector), normalize(norm)), 0.5, 1.0);
if(pos.y <= 120){
fragColor = texture2D(texture_2, text*0.05) * cosTheta;
}
if(pos.y > 120 && pos.y < 150){
fragColor = (texture2D(texture_2, text*0.05) * (1 - (pos.y-120)/30) + texture2D(texture_3, text*0.05) * ((pos.y-120)/30))*cosTheta;
}
if(pos.y >= 150)
{
fragColor = texture2D(texture_3, text*0.05) * cosTheta;
}
}
vertex shader code:
#version 430
in layout(location=0) vec3 position;
in layout(location=1) vec2 textCoord;
in layout(location=2) vec3 normal;
out vec3 pos;
out vec2 text;
out vec3 norm;
uniform mat4 transformation;
void main()
{
gl_Position = transformation * vec4(position, 1.0);
norm = normal;
pos = position;
text = position.xz;
}
It looks like you're using an 8bit heightmap which only gives you 256 different elevations. You could try using 16bit greyscale or encode the height in rgb.
Related
trying to implement shadow. I checked my depth texture on a quad, and it seems correct, but the shadow is not displaying. I check my shadow vertex and fragment shaders, and I believe I have done the light space transformation correctly.
Here are my code.
directional light source matrix setup:
//light source states
glm::vec3 Window::lightColor = glm::vec3(0.9f, 0.9f, 0.9f);
glm::vec3 Window::lightDir = glm::vec3(-1.f, -1.f, 0.f);
glm::mat4 Window::lightView = glm::lookAt(glm::vec3(0.f) - glm::normalize(lightDir) * 15.f, glm::vec3(0.0f), glm::vec3(0.f, 1.f, 0.f));
float Window::near_plane = 0.01f;
float Window::far_plane = 50.1f;
float camWidth = 10.f;
glm::mat4 Window::lightProj = glm::ortho(-10.f, 10.f, -10.f, 10.f, Window::near_plane, Window::far_plane);
glm::mat4 Window::lightProjView = lightProj * lightView;
shadow drawing logic:
void Renderer::drawWithShadow(Object* obj) {
//set shader uniforms
Shader* shader = shadowShader;
shader->bind();
shader->setUniformMat4("model", obj->model);
shader->setUniformMat4("projView", projView);
shader->setUniformVec3("viewPos", eyePos);
//need another projection matrix
shader->setUniformMat4("lightSpaceMatrix", shadowProjView);
glcheck(glActiveTexture(GL_TEXTURE0));
glcheck(glBindTexture(GL_TEXTURE_2D, textID));
//light uniforms
shader->setUniformVec3("directionalLightDir", directionalLightDir);
shader->setUniformVec3("lightColor", lightColor);
glcheck(glBindVertexArray(obj->vao));
for (auto i = 0; i < obj->meshList.size(); i++) {
Mesh* mesh = obj->meshList[i];
prepMaterial(mesh->material, shader);
glcheck(glDrawElements(GL_TRIANGLES, mesh->size, GL_UNSIGNED_INT, (GLvoid*)(sizeof(GLuint) * mesh->vertexOffset)));
}
}
vert and frag shaders to prepare shadow depth textures
//vertex shader
#version 330 core
layout (location = 0) in vec3 position;
uniform mat4 projView;
uniform mat4 model;
void main() {
gl_Position = projView * model * vec4(position, 1.0);
}
//fragment shader
#version 330 core
void main()
{
}
vert and frag shaders to draw shadows with Phong lighting
//vertex shader
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoord;
out VS_OUT {
vec4 fragPos;
vec3 normal;
vec2 texCoord;
vec4 fragPosLightSpace;
} vs_out;
uniform mat4 projView;
uniform mat4 model;
uniform mat4 lightSpaceMatrix;
void main()
{
vs_out.fragPos = model * vec4(position, 1.0);
vs_out.normal = transpose(inverse(mat3(model))) * normal;
vs_out.texCoord = texCoord;
vs_out.fragPosLightSpace = lightSpaceMatrix * vs_out.fragPos;
gl_Position = projView * vs_out.fragPos;
}
//fragment shader
#version 330 core
uniform vec3 viewPos; //just the eye pos
uniform vec3 diffuseFactor; //kd
uniform vec3 ambientColor; //ka
uniform vec3 specColor; //ks
uniform float specHighlight; //ns, the larger this value is, the more apparent the light dot on the surface
uniform float dissolve; //d
//lights
uniform vec3 directionalLightDir;
uniform vec3 pointLightPos;
uniform vec3 lightColor;
uniform sampler2D shadowMap;
//uniform sampler2DShadow shadowMap;
in VS_OUT {
vec4 fragPos;
vec3 normal;
vec2 texCoord;
vec4 fragPosLightSpace;
} fs_in;
out vec4 fragColor;
float ShadowCalculation(vec4 fragPosLightSpace)
{
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
vec2 shadowCoords;
shadowCoords.x = projCoords.x * 0.5 + 0.5;
shadowCoords.y = projCoords.y * 0.5 + 0.5;
float closestDepth = texture(shadowMap, shadowCoords).r;
float currentDepth = projCoords.z * 0.5 + 0.5;
float shadowValue = currentDepth + 0.00001 > closestDepth ? 1.0 : 0.0;
//if(currentDepth < 0.0)
//shadowValue = 0.0;
return shadowValue;
}
void main()
{
vec3 lightDir = normalize(-directionalLightDir);
vec3 norm = normalize(fs_in.normal);
//diffuse lighting
float diffStrength = max(dot(norm, lightDir), 0.0); // this calculates diffuse intensity based on angle
vec3 diffuse = lightColor * diffStrength * diffuseFactor;
//specular
vec3 viewDir = normalize(viewPos - fs_in.fragPos.xyz);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = 0.0;
if(specHighlight > 0.0) { // if specHighlight is < 0, pow might produce undefined result if base is also 0
spec = pow(max(dot(viewDir, reflectDir), 0.0), specHighlight);
}
vec3 specular = spec * specColor * lightColor;
float shadow = ShadowCalculation(fs_in.fragPosLightSpace);
//float shadow = textureProj(shadowMap, fs_in.fragPosLightSpace);
//vec3 result = ambientColor * 0.05 * lightColor + (diffuse + specular)*(1-shadow);
vec3 result = (diffuse + specular)*(1.0 - shadow);
fragColor = vec4(result, 1);
}
with just Phong shading, the scene looks like this:
Phong shading
when the scene is seen from the light source as depth value:
depth texture on quad
when I finally render the scene, it is mostly black; I made sure the far plane covers all of the bunnies:
render shadow
I am trying to create a translucent , stained glass effect in OpenGL, using C++.
I use a normal map generated from a perlin noise texture. Refraction is calculated with respect to manipulated normal vectors and it works.
For stained glass, I am trying mixing the colour from skybox through refraction, with another colour. I tried this with a constant value, and that works too.
When I try to get the second colour from a texture, I do not see the object on screen. I can load the texture if i ignore refraction and mixing though.
here is my vertex shader :
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoord;
layout (location = 3) in vec3 aTangent;
layout (location = 4) in vec3 aBitangent;
out vec3 FragPos;
out vec2 texCoord;
out vec3 tangentLightPos;
out vec3 tangentViewPos;
out vec3 tangentFragPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
//normal
uniform vec3 lightPos;
uniform vec3 viewPos;
void main()
{
texCoord = aTexCoord;
FragPos = vec3(view * model * vec4(aPos, 1.0));
mat3 normalMatrix = transpose(inverse(mat3(model)));
vec3 T = normalize(normalMatrix * aTangent);
vec3 N = normalize(normalMatrix * aNormal);
T = normalize(T - dot(T, N) * N);
vec3 B = cross(N, T);
mat3 TBN = transpose(mat3(T, B, N));
tangentLightPos = TBN * lightPos;
tangentViewPos = TBN * viewPos;
tangentFragPos = TBN * FragPos;
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
and my fragment shader :
#version 330 core
out vec4 FragColor;
in vec3 FragPos;
in vec2 texCoord;
in vec3 tangentLightPos;
in vec3 tangentViewPos;
in vec3 tangentFragPos;
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform samplerCube skybox;
uniform vec3 cameraPos;
void main()
{
//normal map - normal
vec3 normalDir = texture(texture2, texCoord).rgb;
normalDir = normalize(normalDir * 2.0 - 1.0);
vec3 Incident = normalize(tangentFragPos - cameraPos);
vec3 RefractedDir = refract(Incident, normalDir, 1.0/1.2);
float DispersionIndex = 1.0 - dot(Incident, normalDir);
vec3 RefractedFragColor = vec3(texture(skybox, RefractedDir).rgb);
//FIXME:
vec3 texColor = texture(texture1, texCoord).rgb;
vec3 constTexColor = vec3(1.0, 1.0, 1.0);
FragColor = mix( vec4(RefractedFragColor, 1.0), vec4(texColor.rgb, 0.5), 0.2); // doesnt show object on screen
// FragColor = mix( vec4(RefractedFragColor, 1.0), vec4(constTexColor.rgb, 0.5), 0.2); --> works , shows a tint on glass
// FragColor = vec4(texColor, 1.0); ---> shows only texture
}
with constant value for color in mix :
with only texture:
Why does the mix not work with color from texture?
I am trying create shadow using shadow maps. I believe that shadow map is rendered well.
It seems that sphere's shadow is not in the correct place, so how would I go about fixing that? Also why is there a black ring around the sphere and how to eliminate it?
In the shadow map vertex shader
gl_Position = u_depthMatrix * worldCoord;
In the shadow map fragment shader
fragmentdepth = gl_FragCoord.z;
vs.glsl
uniform mat4 u_Model;
uniform mat4 u_View;
uniform mat4 u_Persp;
uniform mat4 u_InvTrans;
uniform vec3 u_LightColor;
uniform vec3 u_LightDirection;
uniform vec3 u_EyePos;
uniform mat4 u_depthBiasMatrix;
in vec3 Position;
in vec3 Normal;
in vec2 Texcoord;
out vec3 v_Normal;
out vec2 v_Texcoord;
out vec3 v_Position;
out vec3 v_PositionMC;
out vec4 shadowCoord;
void main(void)
{
v_Normal = (u_InvTrans*vec4(Normal,0.0)).xyz;
vec4 world = u_Model * vec4(Position, 1.0);
vec4 cameraCoord = u_View * world;
v_Position = cameraCoord.xyz;
shadowCoord = u_depthBiasMatrix * world;
gl_Position = u_Persp * cameraCoord;
}
fs.glsl
uniform sampler2D shadowMap;
uniform vec3 u_LightColor;
uniform vec3 u_LightDirection;
uniform vec3 u_EyePos;
uniform vec3 u_Ka;
uniform vec3 u_Kd;
uniform vec3 u_Ks;
in vec3 v_Normal;
in vec2 v_Texcoord;
in vec3 v_Position; //coordinate of vertex in camera coordinate system
in vec4 shadowCoord;
void main(void)
{
vec3 v_Normal1 = normalize(v_Normal);
//Diffuse Lighting
vec3 diff = normalize(u_LightDirection - v_Position);
float diffuse = max(dot(diff , v_Normal1) , 0);
vec3 diffuseColor = diffuse * u_Kd * u_LightColor;
//Specular Lighting
vec3 v = normalize(vec3(u_EyePos - v_Position));
vec3 h = normalize(diff + v);
float sl = pow(max(dot(h, v_Normal1) , 0.0), 50);
if ( diffuse <= 0 ) sl = 0;
vec3 specularColor = sl * u_Ks * u_LightColor;
vec3 v_Color;
v_Color = u_Ka + diffuseColor + specularColor ;
//Shadow Part
vec3 shadowCoord3;
float shadowFactor = 1.0;
if(shadowCoord.w > 0 )
{
shadowCoord3 = shadowCoord.xyz / shadowCoord.w ;
if ( texture2D( shadowMap, shadowCoord3.xy ).z < shadowCoord3.z)
{
shadowFactor = 0.2;
}
}
gl_FragColor = shadowFactor * vec4(v_Color , 1);
}
I wrote parallax mapping shader in GLSL but it is working wrong. In some places it shows correct image with good bump but in other positions it becomes flat. It's became most flat when I moving camera father than platform(forward)
#version 120
varying vec3 pos;
varying vec3 normal;
varying vec2 tc;
varying vec3 color;
uniform vec3 camera;
void main(void)
{
pos = (-gl_Vertex.xyz + camera);
tc = gl_MultiTexCoord0.xy;
normal = normalize(gl_Normal);
color = gl_Color.xyz;
gl_Position = ftransform();
}
#version 120
uniform sampler2D normal_map;
uniform sampler2D diffuse_map;
uniform sampler2D displacement;
uniform float mode;
varying vec2 tc;
varying vec3 pos;
void main(void)
{
vec3 lightPos = vec3( 0.0, -45.0, -40.0);
vec4 color;
if (mode > 1)
{
vec3 eyeVec = normalize(pos);
vec2 eyeProj = normalize(eyeVec.xz);
float curHeight = texture2D(displacement, tc).r - 0.5;
vec2 trTc = tc - (eyeProj) * curHeight * 0.035;
vec3 normal = normalize(texture2D(normal_map, trTc).xzy*2.0 - 1.0);
color = texture2D(diffuse_map, trTc) * dot( normalize(pos - lightPos), normal) * 1.0;
color.w = 1.0;
}
else
{
vec3 normal = normalize(texture2D(normal_map, tc).xzy*2.0 - 1.0);
color = texture2D(diffuse_map, tc) * dot( normalize(pos - lightPos), normal) * 1.0;
}
gl_FragColor = color;
}
I can't even imagine where can be mistake. I was experimenting with camera and vertex values but it is not help;
the title says it all.. using opengls built in lighting system, specularlight does not increase or decrease with distance from the object, but by shader implementation does.
Vertex Shader:
#version 330
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;
layout (location = 2) in vec3 normal;
out vec2 texCoord0;
out vec3 normal0;
out vec3 worldPos0;
uniform mat4 transform;
uniform mat4 normalRotation;
uniform mat4 transformProjected;
void main()
{
gl_Position = transformProjected * vec4(position, 1.0);
texCoord0 = texCoord;
normal0 = normalize((normalRotation * vec4(normal, 0.0))).xyz;
worldPos0 = (transform * vec4(position, 1.0)).xyz;
}
Fragment Shader:
#version 330
in vec2 texCoord0;
in vec3 normal0;
in vec3 worldPos0;
out vec4 fragColor;
struct BaseLight
{
vec3 colorDiffuse;
vec3 colorSpecular;
float intensityDiffuse;
};
struct DirectionalLight
{
BaseLight base;
vec3 direction;
};
uniform vec3 tint;
uniform sampler2D sampler;
uniform vec3 eyePos; // camera pos
uniform vec3 ambientLight;
uniform vec3 emissiveLight;
//material
uniform float specularIntensity;
uniform float specularPower;
uniform DirectionalLight directionalLight;
vec4 calcLight(BaseLight base,vec3 direction, vec3 normal)
{
float diffuseFactor = dot(normal, -direction);
vec4 diffuseColorFinal = vec4(0,0,0,0);
vec4 specularColorFinal = vec4(0,0,0,0);
if(diffuseFactor > 0)
{
diffuseColorFinal = vec4(base.colorDiffuse,1) * diffuseFactor * base.intensityDiffuse;
vec3 directionToEye = normalize(eyePos - worldPos0);
vec3 reflectDirection = normalize(reflect(direction, normal));
float specularFactor = dot(directionToEye, reflectDirection);
specularFactor = pow(specularFactor, specularPower);
if(specularFactor > 0)
specularColorFinal = vec4(base.colorSpecular,1) * specularFactor * specularIntensity;
}
//
return diffuseColorFinal + specularColorFinal;
}
void main()
{
vec4 colorD = texture(sampler, texCoord0.xy) * vec4(tint,1);
vec3 normal = normal0;
vec4 totalLight = vec4(ambientLight,1) + vec4(emissiveLight,1);
totalLight += calcLight(directionalLight.base,-directionalLight.direction,normal);
fragColor = colorD * totalLight;
}
As you can see from the 2 images the specular light takes up a larger surface area the farther the camera gets from the plane.In my test with opengls built in lighting, this doesnt happen. is there a way to fix this? im new to lighting, maybe this is normal for directional light sources? thanks for the help!
Im also setting my eyePos uniform to my cameraPos. i dont know if that helps.
Basically you need to have distance between the fragment and the light dist . This can be a problem for directional light though because you have only the direction and distant is assumed to be infinite. Maybe switch to point light?
when youo have the 'dist' you use a formula
att = 1.0 / (Kc + Kl*dist + Kq*dist^2)
Kc - constant attenuation
Kl - linear attenuation
Kq - quadratic attenuation
simpler version (only Kq used, rest set to 1.0):
float attenuation = 1.0 / (1.0 + light.attenuation * pow(distanceToLight, 2));
then in the lighting equation you basically multiply calculated color by this att factor:
vec4 finalColor = ambient + (diffuseColorFinal + specularColorFinal)*att
http://www.ozone3d.net/tutorials/glsl_lighting_phong_p4.php#part_4
http://tomdalling.com/blog/modern-opengl/07-more-lighting-ambient-specular-attenuation-gamma/