Compare commits
3 Commits
0a702e155d
...
49865aa158
Author | SHA1 | Date | |
---|---|---|---|
|
49865aa158 | ||
|
e4d425a915 | ||
|
72fbf03ed2 |
@ -3,11 +3,12 @@
|
|||||||
uniform sampler2D colorTexture;
|
uniform sampler2D colorTexture;
|
||||||
uniform sampler2D normalSampler;
|
uniform sampler2D normalSampler;
|
||||||
|
|
||||||
|
uniform vec3 cameraPos;
|
||||||
|
|
||||||
uniform vec3 sunPos;
|
uniform vec3 sunPos;
|
||||||
uniform vec3 sunColor;
|
uniform vec3 sunColor;
|
||||||
uniform float sunLightExp;
|
uniform float sunLightExp;
|
||||||
|
|
||||||
uniform vec3 cameraPos;
|
|
||||||
uniform float time;
|
uniform float time;
|
||||||
|
|
||||||
uniform vec3 reflectorPos;
|
uniform vec3 reflectorPos;
|
||||||
@ -17,54 +18,41 @@ uniform float reflectorAngle;
|
|||||||
uniform float reflectorLightExp;
|
uniform float reflectorLightExp;
|
||||||
|
|
||||||
vec3 normalizedVertexNormal;
|
vec3 normalizedVertexNormal;
|
||||||
mat3 TBN;
|
|
||||||
|
|
||||||
in vec3 vertexNormalOut;
|
in vec3 vertexPosWld;
|
||||||
in vec3 vertexTangentOut;
|
|
||||||
in vec3 vertexBitangentOut;
|
|
||||||
in vec3 vertexPosOut;
|
|
||||||
in vec2 vertexTexCoordOut;
|
in vec2 vertexTexCoordOut;
|
||||||
|
in vec3 viewDirTS;
|
||||||
|
in vec3 sunLightDirTS;
|
||||||
|
in vec3 reflectorLightDirTS;
|
||||||
|
|
||||||
out vec4 outColor;
|
out vec4 outColor;
|
||||||
|
|
||||||
vec4 calcPointLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, float lightExp) {
|
vec4 calcPointLight(vec3 fragColor, vec3 lightPos, vec3 lightDirTS, vec3 lightColor, float lightExp) {
|
||||||
vec3 lightDir = normalize(vertexPosOut - lightPos);
|
float lightDistance = length(vertexPosWld - lightPos);
|
||||||
vec3 viewDir = normalize(cameraPos - vertexPosOut);
|
|
||||||
|
|
||||||
// tangent space
|
|
||||||
vec3 viewDirTS = TBN * viewDir;
|
|
||||||
vec3 lightDirTS = TBN * lightDir;
|
|
||||||
|
|
||||||
//tmp solution
|
|
||||||
viewDir = normalize(viewDirTS);
|
|
||||||
lightDir = normalize(lightDirTS);
|
|
||||||
|
|
||||||
float lightDistance = length(vertexPosOut - lightPos);
|
|
||||||
vec3 newLightColor = lightColor / pow(lightDistance, 2);
|
vec3 newLightColor = lightColor / pow(lightDistance, 2);
|
||||||
|
|
||||||
float intensity = dot(normalizedVertexNormal, -lightDir);
|
float intensity = dot(normalizedVertexNormal, -lightDirTS);
|
||||||
intensity = max(intensity, 0.0);
|
intensity = max(intensity, 0.0);
|
||||||
|
|
||||||
vec3 reflectDir = reflect(lightDir, normalizedVertexNormal);
|
vec3 reflectDir = reflect(lightDirTS, normalizedVertexNormal);
|
||||||
|
|
||||||
|
|
||||||
float glossPow = 8;
|
float glossPow = 8;
|
||||||
float specular = pow(max(dot(viewDir, reflectDir), 0.0), glossPow);
|
float specular = pow(max(dot(viewDirTS, reflectDir), 0.0), glossPow);
|
||||||
|
|
||||||
float diffuse = intensity;
|
float diffuse = intensity;
|
||||||
vec3 resultColor = newLightColor * (fragColor * diffuse + specular );
|
vec3 resultColor = newLightColor * (fragColor * diffuse + specular );
|
||||||
return vec4(1 - exp(-resultColor * lightExp), 1.0);
|
return vec4(1 - exp(-resultColor * lightExp), 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 calcSpotLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, float lightExp) {
|
vec4 calcSpotLight(vec3 fragColor, vec3 lightPos, vec3 lightDirTS, vec3 lightColor, float lightExp) {
|
||||||
vec3 reflectorLightDir = normalize(vertexPosOut - lightPos);
|
vec3 reflectorLightDir = normalize(vertexPosWld - lightPos);
|
||||||
float angleCos = dot(reflectorLightDir, reflectorDir);
|
float angleCos = dot(reflectorLightDir, reflectorDir);
|
||||||
float reflectorOutAngle = reflectorAngle + radians(10);
|
float reflectorOutAngle = reflectorAngle + radians(10);
|
||||||
float epsilon = cos(reflectorAngle) - cos(reflectorOutAngle);
|
float epsilon = cos(reflectorAngle) - cos(reflectorOutAngle);
|
||||||
vec4 res = vec4(0, 0, 0, 1);
|
vec4 res = vec4(0, 0, 0, 1);
|
||||||
if (angleCos > cos(reflectorOutAngle)) {
|
if (angleCos > cos(reflectorOutAngle)) {
|
||||||
float intensity = clamp((angleCos - cos(reflectorOutAngle)) / epsilon, 0.0, 1.0);
|
float intensity = clamp((angleCos - cos(reflectorOutAngle)) / epsilon, 0.0, 1.0);
|
||||||
res = calcPointLight(fragColor, lightPos, lightColor, lightExp * intensity);
|
res = calcPointLight(fragColor, lightPos, lightDirTS, lightColor, lightExp * intensity);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -72,22 +60,19 @@ vec4 calcSpotLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, float lightEx
|
|||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
TBN = transpose(mat3(vertexTangentOut, vertexBitangentOut, vertexNormalOut));
|
|
||||||
|
|
||||||
vec3 textureColor = texture2D(colorTexture, vertexTexCoordOut).rgb;
|
vec3 textureColor = texture2D(colorTexture, vertexTexCoordOut).rgb;
|
||||||
|
|
||||||
normalizedVertexNormal = normalize(vertexNormalOut);
|
|
||||||
//get normal from normal sampler
|
//get normal from normal sampler
|
||||||
vec3 samplerNormal = texture2D(normalSampler, vertexTexCoordOut).xyz;
|
vec3 samplerNormal = texture2D(normalSampler, vertexTexCoordOut).xyz;
|
||||||
samplerNormal = 2 * samplerNormal - 1;//since sampler has values from [0, 1], but we want [-1, 1]
|
samplerNormal = 2 * samplerNormal - 1;//since sampler has values from [0, 1], but we want [-1, 1]
|
||||||
normalizedVertexNormal = normalize(samplerNormal);// to avoid potential precision problems in sampler texture
|
normalizedVertexNormal = normalize(samplerNormal);// to avoid potential precision problems in sampler texture
|
||||||
|
|
||||||
//tmp solution
|
//Debug
|
||||||
//normalizedVertexNormal = vec3(0, 0, 1);
|
//normalizedVertexNormal = vec3(0, 0, 1);
|
||||||
|
|
||||||
outColor = calcPointLight(textureColor, sunPos, sunColor, sunLightExp);
|
outColor = calcPointLight(textureColor, sunPos, sunLightDirTS, sunColor, sunLightExp);
|
||||||
|
|
||||||
outColor += calcSpotLight(textureColor, reflectorPos, reflectorColor, reflectorLightExp);
|
outColor += calcSpotLight(textureColor, reflectorPos, reflectorLightDirTS, reflectorColor, reflectorLightExp);
|
||||||
|
|
||||||
//Debug
|
//Debug
|
||||||
//outColor = vec4(textureColor, 1);
|
//outColor = vec4(textureColor, 1);
|
||||||
|
@ -9,19 +9,42 @@ layout(location = 4) in vec3 vertexBitangent;
|
|||||||
uniform mat4 transformation;
|
uniform mat4 transformation;
|
||||||
uniform mat4 modelMat;
|
uniform mat4 modelMat;
|
||||||
|
|
||||||
out vec3 vertexNormalOut;
|
uniform vec3 cameraPos;
|
||||||
out vec3 vertexTangentOut;
|
uniform vec3 sunPos;
|
||||||
out vec3 vertexBitangentOut;
|
uniform vec3 reflectorPos;
|
||||||
out vec3 vertexPosOut;
|
|
||||||
|
out vec3 vertexPosWld;
|
||||||
out vec2 vertexTexCoordOut;
|
out vec2 vertexTexCoordOut;
|
||||||
|
out vec3 viewDirTS;
|
||||||
|
out vec3 sunLightDirTS;
|
||||||
|
out vec3 reflectorLightDirTS;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||||
vertexNormalOut = (modelMat * vec4(vertexNormal, 0.0)).xyz;
|
vec3 normal = (modelMat * vec4(vertexNormal, 0.0)).xyz;
|
||||||
vertexTangentOut = (modelMat * vec4(vertexTangent, 0.0)).xyz;
|
vec3 tangent = (modelMat * vec4(vertexTangent, 0.0)).xyz;
|
||||||
vertexBitangentOut = (modelMat * vec4(vertexBitangent, 0.0)).xyz;
|
vec3 bitangent = (modelMat * vec4(vertexBitangent, 0.0)).xyz;
|
||||||
vertexPosOut = (modelMat * vec4(vertexPosition, 1.0)).xyz;
|
vertexPosWld = (modelMat * vec4(vertexPosition, 1.0)).xyz;
|
||||||
vertexTexCoordOut = vertexTexCoord;
|
vertexTexCoordOut = vertexTexCoord;
|
||||||
|
|
||||||
|
mat3 TBN = transpose(mat3(tangent, bitangent, normal));
|
||||||
|
|
||||||
|
//`lightPos - vertexPos` from tutorial is wrong?
|
||||||
|
//TODO why should we normalize here if we would normalize Tangent Space vectors later?
|
||||||
|
// and why do it here, mb fragment shader?
|
||||||
|
vec3 sunLightDir = normalize(vertexPosWld - sunPos);
|
||||||
|
vec3 reflectorLightDir = normalize(vertexPosWld - reflectorPos);
|
||||||
|
vec3 viewDir = normalize(cameraPos - vertexPosWld);
|
||||||
|
|
||||||
|
// tangent space
|
||||||
|
viewDirTS = TBN * viewDir;
|
||||||
|
sunLightDirTS = TBN * sunLightDir;
|
||||||
|
reflectorLightDirTS = TBN * reflectorLightDir;
|
||||||
|
|
||||||
|
//TODO should normilize here or in the fragment shader?
|
||||||
|
viewDirTS = normalize(viewDirTS);
|
||||||
|
sunLightDirTS = normalize(sunLightDirTS);
|
||||||
|
reflectorLightDirTS = normalize(reflectorLightDirTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
uniform sampler2D colorTexture;
|
uniform sampler2D colorTexture;
|
||||||
uniform sampler2D clouds;
|
uniform sampler2D clouds;
|
||||||
|
uniform sampler2D normalSampler;
|
||||||
|
|
||||||
uniform vec3 sunPos;
|
uniform vec3 sunPos;
|
||||||
uniform vec3 sunColor;
|
uniform vec3 sunColor;
|
||||||
@ -18,40 +19,40 @@ uniform float reflectorLightExp;
|
|||||||
|
|
||||||
vec3 normalizedVertexNormal;
|
vec3 normalizedVertexNormal;
|
||||||
|
|
||||||
in vec3 vertexNormalOut;
|
in vec3 vertexPosWld;
|
||||||
in vec3 vertexPosOut;
|
|
||||||
in vec2 vertexTexCoordOut;
|
in vec2 vertexTexCoordOut;
|
||||||
|
in vec3 viewDirTS;
|
||||||
|
in vec3 sunLightDirTS;
|
||||||
|
in vec3 reflectorLightDirTS;
|
||||||
|
|
||||||
out vec4 outColor;
|
out vec4 outColor;
|
||||||
|
|
||||||
vec4 calcPointLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, float lightExp) {
|
vec4 calcPointLight(vec3 fragColor, vec3 lightPos, vec3 lightDirTS, vec3 lightColor, float lightExp) {
|
||||||
vec3 lightDir = normalize(vertexPosOut - lightPos);
|
float lightDistance = length(vertexPosWld - lightPos);
|
||||||
float lightDistance = length(vertexPosOut - lightPos);
|
|
||||||
vec3 newLightColor = lightColor / pow(lightDistance, 2);
|
vec3 newLightColor = lightColor / pow(lightDistance, 2);
|
||||||
|
|
||||||
float intensity = dot(normalizedVertexNormal, -lightDir);
|
float intensity = dot(normalizedVertexNormal, -lightDirTS);
|
||||||
intensity = max(intensity, 0.0);
|
intensity = max(intensity, 0.0);
|
||||||
|
|
||||||
vec3 viewDir = normalize(cameraPos - vertexPosOut);
|
vec3 reflectDir = reflect(lightDirTS, normalizedVertexNormal);
|
||||||
vec3 reflectDir = reflect(lightDir, normalizedVertexNormal);
|
|
||||||
|
|
||||||
float glossPow = 8;
|
float glossPow = 8;
|
||||||
float specular = pow(max(dot(viewDir, reflectDir), 0.0), glossPow);
|
float specular = pow(max(dot(viewDirTS, reflectDir), 0.0), glossPow);
|
||||||
|
|
||||||
float diffuse = intensity;
|
float diffuse = intensity;
|
||||||
vec3 resultColor = newLightColor * (fragColor * diffuse + specular );
|
vec3 resultColor = newLightColor * (fragColor * diffuse + specular );
|
||||||
return vec4(1 - exp(-resultColor * lightExp), 1.0);
|
return vec4(1 - exp(-resultColor * lightExp), 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 calcSpotLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, vec3 lightDir,
|
vec4 calcSpotLight(vec3 fragColor, vec3 lightPos, vec3 lightDirTS, vec3 lightColor, float lightExp) {
|
||||||
float innerCutOff, float outerCutOff, float lightExp) {
|
vec3 reflectorLightDir = normalize(vertexPosWld - lightPos);
|
||||||
vec3 lightToFragDir = normalize(vertexPosOut - lightPos);
|
float angleCos = dot(reflectorLightDir, reflectorDir);
|
||||||
float angleCos = dot(lightToFragDir, lightDir);
|
float reflectorOutAngle = reflectorAngle + radians(10);
|
||||||
float epsilon = cos(innerCutOff) - cos(outerCutOff);
|
float epsilon = cos(reflectorAngle) - cos(reflectorOutAngle);
|
||||||
vec4 res = vec4(0, 0, 0, 1);
|
vec4 res = vec4(0, 0, 0, 1);
|
||||||
if (angleCos > cos(outerCutOff)) {
|
if (angleCos > cos(reflectorOutAngle)) {
|
||||||
float intensity = clamp((angleCos - cos(outerCutOff)) / epsilon, 0.0, 1.0);
|
float intensity = clamp((angleCos - cos(reflectorOutAngle)) / epsilon, 0.0, 1.0);
|
||||||
res = calcPointLight(fragColor, lightPos, lightColor, reflectorLightExp * intensity);
|
res = calcPointLight(fragColor, lightPos, lightDirTS, lightColor, lightExp * intensity);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -62,13 +63,22 @@ void main()
|
|||||||
vec3 textureColor = texture2D(colorTexture, vertexTexCoordOut).rgb;
|
vec3 textureColor = texture2D(colorTexture, vertexTexCoordOut).rgb;
|
||||||
vec3 cloudColor = texture2D(clouds, vertexTexCoordOut).rgb;
|
vec3 cloudColor = texture2D(clouds, vertexTexCoordOut).rgb;
|
||||||
|
|
||||||
|
//disabled to prevent riffled clouds
|
||||||
textureColor = mix(vec3(1), textureColor, cloudColor.r);
|
textureColor = mix(vec3(1), textureColor, cloudColor.r);
|
||||||
|
|
||||||
normalizedVertexNormal = normalize(vertexNormalOut);
|
normalizedVertexNormal = vec3(0, 0, 1);
|
||||||
|
if (cloudColor.r < 1) {
|
||||||
|
//get normal from normal sampler
|
||||||
|
vec3 samplerNormal = texture2D(normalSampler, vertexTexCoordOut).xyz;
|
||||||
|
samplerNormal = 2 * samplerNormal - 1;//since sampler has values from [0, 1], but we want [-1, 1]
|
||||||
|
normalizedVertexNormal = normalize(samplerNormal);// to avoid potential precision problems in sampler texture
|
||||||
|
}
|
||||||
|
|
||||||
|
outColor = calcPointLight(textureColor, sunPos, sunLightDirTS, sunColor, sunLightExp);
|
||||||
|
|
||||||
outColor = calcPointLight(textureColor, sunPos, sunColor, sunLightExp);
|
outColor += calcSpotLight(textureColor, reflectorPos, reflectorLightDirTS, reflectorColor, reflectorLightExp);
|
||||||
|
|
||||||
outColor += calcSpotLight(textureColor, reflectorPos, reflectorColor, reflectorDir,
|
//Debug
|
||||||
reflectorAngle, reflectorAngle + radians(10), reflectorLightExp);
|
//outColor = vec4(textureColor, 1);
|
||||||
|
|
||||||
}
|
}
|
@ -3,20 +3,49 @@
|
|||||||
layout(location = 0) in vec3 vertexPosition;
|
layout(location = 0) in vec3 vertexPosition;
|
||||||
layout(location = 1) in vec3 vertexNormal;
|
layout(location = 1) in vec3 vertexNormal;
|
||||||
layout(location = 2) in vec2 vertexTexCoord;
|
layout(location = 2) in vec2 vertexTexCoord;
|
||||||
|
layout(location = 3) in vec3 vertexTangent;
|
||||||
|
layout(location = 4) in vec3 vertexBitangent;
|
||||||
|
|
||||||
uniform mat4 transformation;
|
uniform mat4 transformation;
|
||||||
uniform mat4 modelMat;
|
uniform mat4 modelMat;
|
||||||
|
|
||||||
out vec3 vertexNormalOut;
|
uniform vec3 cameraPos;
|
||||||
out vec3 vertexPosOut;
|
uniform vec3 sunPos;
|
||||||
|
uniform vec3 reflectorPos;
|
||||||
|
|
||||||
|
out vec3 vertexPosWld;
|
||||||
out vec2 vertexTexCoordOut;
|
out vec2 vertexTexCoordOut;
|
||||||
|
out vec3 viewDirTS;
|
||||||
|
out vec3 sunLightDirTS;
|
||||||
|
out vec3 reflectorLightDirTS;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||||
vec4 worldNormal = modelMat * vec4(vertexNormal, 0.0);
|
vec3 normal = (modelMat * vec4(vertexNormal, 0.0)).xyz;
|
||||||
vertexNormalOut = worldNormal.xyz;
|
vec3 tangent = (modelMat * vec4(vertexTangent, 0.0)).xyz;
|
||||||
vertexPosOut = (modelMat * vec4(vertexPosition, 1.0)).xyz;
|
vec3 bitangent = (modelMat * vec4(vertexBitangent, 0.0)).xyz;
|
||||||
|
vertexPosWld = (modelMat * vec4(vertexPosition, 1.0)).xyz;
|
||||||
vertexTexCoordOut = vertexTexCoord;
|
vertexTexCoordOut = vertexTexCoord;
|
||||||
vertexTexCoordOut.y = 1 - vertexTexCoord.y;// corrects inversion (bottom at top) of the earth
|
vertexTexCoordOut.y = 1 - vertexTexCoord.y;// corrects inversion (bottom at top) of the earth
|
||||||
}
|
|
||||||
|
mat3 TBN = transpose(mat3(tangent, bitangent, normal));
|
||||||
|
|
||||||
|
//`lightPos - vertexPos` from tutorial is wrong?
|
||||||
|
//TODO why should we normalize here if we would normalize Tangent Space vectors later?
|
||||||
|
// and why do it here, mb fragment shader?
|
||||||
|
vec3 sunLightDir = normalize(vertexPosWld - sunPos);
|
||||||
|
vec3 reflectorLightDir = normalize(vertexPosWld - reflectorPos);
|
||||||
|
vec3 viewDir = normalize(cameraPos - vertexPosWld);
|
||||||
|
|
||||||
|
// tangent space
|
||||||
|
viewDirTS = TBN * viewDir;
|
||||||
|
sunLightDirTS = TBN * sunLightDir;
|
||||||
|
reflectorLightDirTS = TBN * reflectorLightDir;
|
||||||
|
|
||||||
|
//TODO should normilize here or in the fragment shader?
|
||||||
|
viewDirTS = normalize(viewDirTS);
|
||||||
|
sunLightDirTS = normalize(sunLightDirTS);
|
||||||
|
reflectorLightDirTS = normalize(reflectorLightDirTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
uniform sampler2D colorTexture;
|
uniform sampler2D colorTexture;
|
||||||
uniform sampler2D rust;
|
uniform sampler2D rust;
|
||||||
uniform sampler2D scratches;
|
uniform sampler2D scratches;
|
||||||
|
uniform sampler2D shipNormalSampler;
|
||||||
|
uniform sampler2D rustNormalSampler;
|
||||||
|
|
||||||
uniform vec3 sunPos;
|
uniform vec3 sunPos;
|
||||||
uniform vec3 sunColor;
|
uniform vec3 sunColor;
|
||||||
@ -18,69 +20,82 @@ uniform float reflectorAngle;
|
|||||||
uniform float reflectorLightExp;
|
uniform float reflectorLightExp;
|
||||||
|
|
||||||
vec3 normalizedVertexNormal;
|
vec3 normalizedVertexNormal;
|
||||||
|
vec3 scratchesColor;
|
||||||
|
|
||||||
in vec3 vertexNormalOut;
|
in vec3 vertexPosWld;
|
||||||
in vec3 vertexPosOut;
|
|
||||||
in vec2 vertexTexCoordOut;
|
in vec2 vertexTexCoordOut;
|
||||||
|
in vec3 viewDirTS;
|
||||||
|
in vec3 sunLightDirTS;
|
||||||
|
in vec3 reflectorLightDirTS;
|
||||||
in vec3 vertexLocPos;
|
in vec3 vertexLocPos;
|
||||||
|
|
||||||
out vec4 outColor;
|
out vec4 outColor;
|
||||||
|
|
||||||
vec4 calcPointLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, float lightExp) {
|
vec4 calcPointLight(vec3 fragColor, vec3 lightPos, vec3 lightDirTS, vec3 lightColor, float lightExp) {
|
||||||
vec3 lightDir = normalize(vertexPosOut - lightPos);
|
float lightDistance = length(vertexPosWld - lightPos);
|
||||||
float lightDistance = length(vertexPosOut - lightPos);
|
|
||||||
vec3 newLightColor = lightColor / pow(lightDistance, 2);
|
vec3 newLightColor = lightColor / pow(lightDistance, 2);
|
||||||
|
|
||||||
float intensity = dot(normalizedVertexNormal, -lightDir);
|
float intensity = dot(normalizedVertexNormal, -lightDirTS);
|
||||||
intensity = max(intensity, 0.0);
|
intensity = max(intensity, 0.0);
|
||||||
|
|
||||||
vec3 viewDir = normalize(cameraPos - vertexPosOut);
|
vec3 reflectDir = reflect(lightDirTS, normalizedVertexNormal);
|
||||||
vec3 reflectDir = reflect(lightDir, normalizedVertexNormal);
|
|
||||||
|
|
||||||
float glossPow = 8;
|
float glossPow = 8;
|
||||||
float specular = pow(max(dot(viewDir, reflectDir), 0.0), glossPow);
|
float specular = pow(max(dot(viewDirTS, reflectDir), 0.0), glossPow);
|
||||||
|
|
||||||
float diffuse = intensity;
|
float diffuse = intensity;
|
||||||
vec3 resultColor = newLightColor * (fragColor * diffuse + specular );
|
vec3 resultColor = newLightColor * (fragColor * diffuse + specular );
|
||||||
return vec4(1 - exp(-resultColor * lightExp), 1.0);
|
return vec4(1 - exp(-resultColor * lightExp), 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 calcSpotLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, vec3 lightDir, float lightExp) {
|
vec4 calcSpotLight(vec3 fragColor, vec3 lightPos, vec3 lightDirTS, vec3 lightColor, float lightExp) {
|
||||||
vec3 reflectorLightDir = normalize(vertexPosOut - reflectorPos);
|
vec3 reflectorLightDir = normalize(vertexPosWld - lightPos);
|
||||||
float angleCos = dot(reflectorLightDir, reflectorDir);
|
float angleCos = dot(reflectorLightDir, reflectorDir);
|
||||||
float reflectorOutAngle = reflectorAngle + radians(10);
|
float reflectorOutAngle = reflectorAngle + radians(10);
|
||||||
float epsilon = cos(reflectorAngle) - cos(reflectorOutAngle);
|
float epsilon = cos(reflectorAngle) - cos(reflectorOutAngle);
|
||||||
vec4 res = vec4(0, 0, 0, 1);
|
vec4 res = vec4(0, 0, 0, 1);
|
||||||
if (angleCos > cos(reflectorOutAngle)) {
|
if (angleCos > cos(reflectorOutAngle)) {
|
||||||
float intensity = clamp((angleCos - cos(reflectorOutAngle)) / epsilon, 0.0, 1.0);
|
float intensity = clamp((angleCos - cos(reflectorOutAngle)) / epsilon, 0.0, 1.0);
|
||||||
res = calcPointLight(fragColor, reflectorPos, reflectorColor, reflectorLightExp * intensity);
|
res = calcPointLight(fragColor, lightPos, lightDirTS, lightColor, lightExp * intensity);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 calcShipColor() {
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec3 shipColor = texture2D(colorTexture, vertexTexCoordOut).rgb;
|
vec3 shipColor = texture2D(colorTexture, vertexTexCoordOut).rgb;
|
||||||
vec3 rustColor = texture2D(rust, vertexTexCoordOut).rgb;
|
vec3 rustColor = texture2D(rust, vertexTexCoordOut).rgb;
|
||||||
vec3 scratchesColor = texture2D(scratches, vertexTexCoordOut).rgb;
|
vec3 textureColor = mix(rustColor, shipColor, scratchesColor.r);
|
||||||
vec3 textureColor = mix(rustColor, shipColor, scratchesColor .r);
|
|
||||||
|
|
||||||
if (sin(vertexLocPos.y * vertexLocPos.x * vertexLocPos.z) > 0) {
|
if (sin(vertexLocPos.y * vertexLocPos.x * vertexLocPos.z) > 0) {
|
||||||
textureColor = vec3(1, 0, 0);
|
textureColor = vec3(1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
normalizedVertexNormal = normalize(vertexNormalOut);
|
|
||||||
|
|
||||||
outColor = calcPointLight(textureColor, sunPos, sunColor, sunLightExp);
|
return textureColor;
|
||||||
|
}
|
||||||
vec3 reflectorLightDir = normalize(vertexPosOut - reflectorPos);
|
|
||||||
float angleCos = dot(reflectorLightDir, reflectorDir);
|
vec3 calcShipNormal() {
|
||||||
float reflectorOutAngle = reflectorAngle + radians(10);
|
vec3 shipNormal = texture2D(shipNormalSampler, vertexTexCoordOut).xyz;
|
||||||
float epsilon = cos(reflectorAngle) - cos(reflectorOutAngle);
|
shipNormal = 2 * shipNormal - 1;//since sampler has values from [0, 1], but we want [-1, 1]
|
||||||
if (angleCos > cos(reflectorOutAngle)) {
|
vec3 rustNormal = texture2D(rustNormalSampler, vertexTexCoordOut).xyz;
|
||||||
float intensity = clamp((angleCos - cos(reflectorOutAngle)) / epsilon, 0.0, 1.0);
|
rustNormal = 2 * rustNormal - 1;//since sampler has values from [0, 1], but we want [-1, 1]
|
||||||
outColor += calcSpotLight(textureColor, reflectorPos, reflectorColor, reflectorLightDir, reflectorLightExp * intensity);
|
//normalize to avoid potential precision problems in sampler texture
|
||||||
}
|
return normalize(mix(rustNormal, shipNormal, scratchesColor.r));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
scratchesColor = texture2D(scratches, vertexTexCoordOut).rgb;
|
||||||
|
vec3 textureColor = calcShipColor();
|
||||||
|
|
||||||
|
normalizedVertexNormal = calcShipNormal();
|
||||||
|
//Debug
|
||||||
|
//normalizedVertexNormal = vec3(0, 0, 1);
|
||||||
|
|
||||||
|
outColor = calcPointLight(textureColor, sunPos, sunLightDirTS, sunColor, sunLightExp);
|
||||||
|
|
||||||
|
outColor += calcSpotLight(textureColor, reflectorPos, reflectorLightDirTS, reflectorColor, reflectorLightExp);
|
||||||
|
|
||||||
|
//Debug
|
||||||
|
//outColor = vec4(textureColor, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,21 +3,50 @@
|
|||||||
layout(location = 0) in vec3 vertexPosition;
|
layout(location = 0) in vec3 vertexPosition;
|
||||||
layout(location = 1) in vec3 vertexNormal;
|
layout(location = 1) in vec3 vertexNormal;
|
||||||
layout(location = 2) in vec2 vertexTexCoord;
|
layout(location = 2) in vec2 vertexTexCoord;
|
||||||
|
layout(location = 3) in vec3 vertexTangent;
|
||||||
|
layout(location = 4) in vec3 vertexBitangent;
|
||||||
|
|
||||||
uniform mat4 transformation;
|
uniform mat4 transformation;
|
||||||
uniform mat4 modelMat;
|
uniform mat4 modelMat;
|
||||||
|
|
||||||
out vec3 vertexNormalOut;
|
uniform vec3 cameraPos;
|
||||||
out vec3 vertexPosOut;
|
uniform vec3 sunPos;
|
||||||
out vec2 vertexTexCoordOut;
|
uniform vec3 reflectorPos;
|
||||||
|
|
||||||
|
out vec3 vertexPosWld;
|
||||||
out vec3 vertexLocPos;
|
out vec3 vertexLocPos;
|
||||||
|
out vec2 vertexTexCoordOut;
|
||||||
|
out vec3 viewDirTS;
|
||||||
|
out vec3 sunLightDirTS;
|
||||||
|
out vec3 reflectorLightDirTS;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||||
vec4 worldNormal = modelMat * vec4(vertexNormal, 0.0);
|
vec3 normal = (modelMat * vec4(vertexNormal, 0.0)).xyz;
|
||||||
vertexNormalOut = worldNormal.xyz;
|
vec3 tangent = (modelMat * vec4(vertexTangent, 0.0)).xyz;
|
||||||
vertexPosOut = (modelMat * vec4(vertexPosition, 1.0)).xyz;
|
vec3 bitangent = (modelMat * vec4(vertexBitangent, 0.0)).xyz;
|
||||||
|
vertexPosWld = (modelMat * vec4(vertexPosition, 1.0)).xyz;
|
||||||
vertexTexCoordOut = vertexTexCoord;
|
vertexTexCoordOut = vertexTexCoord;
|
||||||
|
|
||||||
vertexLocPos = vertexPosition;
|
vertexLocPos = vertexPosition;
|
||||||
|
|
||||||
|
mat3 TBN = transpose(mat3(tangent, bitangent, normal));
|
||||||
|
|
||||||
|
//`lightPos - vertexPos` from tutorial is wrong?
|
||||||
|
//TODO why should we normalize here if we would normalize Tangent Space vectors later?
|
||||||
|
// and why do it here, mb fragment shader?
|
||||||
|
vec3 sunLightDir = normalize(vertexPosWld - sunPos);
|
||||||
|
vec3 reflectorLightDir = normalize(vertexPosWld - reflectorPos);
|
||||||
|
vec3 viewDir = normalize(cameraPos - vertexPosWld);
|
||||||
|
|
||||||
|
// tangent space
|
||||||
|
viewDirTS = TBN * viewDir;
|
||||||
|
sunLightDirTS = TBN * sunLightDir;
|
||||||
|
reflectorLightDirTS = TBN * reflectorLightDir;
|
||||||
|
|
||||||
|
//TODO should normilize here or in the fragment shader?
|
||||||
|
viewDirTS = normalize(viewDirTS);
|
||||||
|
sunLightDirTS = normalize(sunLightDirTS);
|
||||||
|
reflectorLightDirTS = normalize(reflectorLightDirTS);
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,10 @@ namespace texture {
|
|||||||
GLuint grid;
|
GLuint grid;
|
||||||
|
|
||||||
GLuint earthNormal;
|
GLuint earthNormal;
|
||||||
|
GLuint moonNormal;
|
||||||
GLuint asteroidNormal;
|
GLuint asteroidNormal;
|
||||||
GLuint shipNormal;
|
GLuint shipNormal;
|
||||||
|
GLuint rustNormal;
|
||||||
|
|
||||||
GLuint cubemap;
|
GLuint cubemap;
|
||||||
}
|
}
|
||||||
@ -143,12 +145,15 @@ void drawObjectColor(GLuint program, Core::RenderContext& context, glm::mat4 mod
|
|||||||
}
|
}
|
||||||
|
|
||||||
void drawObjectProc(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec3 color) {
|
void drawObjectProc(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec3 color) {
|
||||||
program = programProcTex;
|
GLuint program = programProcTex;
|
||||||
|
|
||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
|
|
||||||
Core::SetActiveTexture(texture::ship, "colorTexture", program, 0);
|
Core::SetActiveTexture(texture::ship, "colorTexture", program, 0);
|
||||||
Core::SetActiveTexture(texture::rust, "rust", program, 1);
|
Core::SetActiveTexture(texture::rust, "rust", program, 1);
|
||||||
Core::SetActiveTexture(texture::scratches, "scratches", program, 2);
|
Core::SetActiveTexture(texture::scratches, "scratches", program, 2);
|
||||||
|
Core::SetActiveTexture(texture::shipNormal, "shipNormalSampler", program, 3);
|
||||||
|
Core::SetActiveTexture(texture::rustNormal, "rustNormalSampler", program, 4);
|
||||||
|
|
||||||
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
|
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
|
||||||
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
|
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
|
||||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
||||||
@ -173,9 +178,11 @@ void drawObjectProc(Core::RenderContext& context, glm::mat4 modelMatrix, glm::ve
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawObjectTexture(GLuint program, Core::RenderContext& context, glm::mat4 modelMatrix, GLuint textureId) {
|
void drawObjectTexture(GLuint program, Core::RenderContext& context, glm::mat4 modelMatrix,
|
||||||
|
GLuint textureId, GLuint normalsTextureId) {
|
||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
Core::SetActiveTexture(textureId, "colorTexture", program, 0);
|
Core::SetActiveTexture(textureId, "colorTexture", program, 0);
|
||||||
|
Core::SetActiveTexture(normalsTextureId, "normalSampler", program, 1);
|
||||||
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
|
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
|
||||||
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
|
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
|
||||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
||||||
@ -205,6 +212,7 @@ void drawEarth(Core::RenderContext& context, glm::mat4 modelMatrix) {
|
|||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
Core::SetActiveTexture(texture::earth, "colorTexture", program, 0);
|
Core::SetActiveTexture(texture::earth, "colorTexture", program, 0);
|
||||||
Core::SetActiveTexture(texture::clouds, "clouds", program, 1);
|
Core::SetActiveTexture(texture::clouds, "clouds", program, 1);
|
||||||
|
Core::SetActiveTexture(texture::earthNormal, "normalSampler", program, 2);
|
||||||
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
|
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
|
||||||
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
|
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
|
||||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
||||||
@ -266,7 +274,7 @@ void renderScene(GLFWwindow* window)
|
|||||||
|
|
||||||
drawObjectTexture(programTex, sphereContext,
|
drawObjectTexture(programTex, sphereContext,
|
||||||
glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::translate(glm::vec3(1.f, 0, 0)) * glm::scale(glm::vec3(0.1f)),
|
glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::translate(glm::vec3(1.f, 0, 0)) * glm::scale(glm::vec3(0.1f)),
|
||||||
texture::grid);
|
texture::grid, texture::moonNormal);
|
||||||
|
|
||||||
glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f)));
|
glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f)));
|
||||||
glm::vec3 spaceshipUp = glm::normalize(glm::cross(spaceshipSide, spaceshipDir));
|
glm::vec3 spaceshipUp = glm::normalize(glm::cross(spaceshipSide, spaceshipDir));
|
||||||
@ -370,8 +378,10 @@ void init(GLFWwindow* window)
|
|||||||
texture::grid = Core::LoadTexture("./textures/grid_color.png");
|
texture::grid = Core::LoadTexture("./textures/grid_color.png");
|
||||||
|
|
||||||
texture::earthNormal = Core::LoadTexture("./textures/earth_normalmap.png");
|
texture::earthNormal = Core::LoadTexture("./textures/earth_normalmap.png");
|
||||||
|
texture::moonNormal = Core::LoadTexture("./textures/moon_normal.jpg");
|
||||||
texture::asteroidNormal = Core::LoadTexture("./textures/rust_normal.jpg");
|
texture::asteroidNormal = Core::LoadTexture("./textures/rust_normal.jpg");
|
||||||
texture::shipNormal = Core::LoadTexture("./textures/spaceship_normalmap.jpg");
|
texture::shipNormal = Core::LoadTexture("./textures/spaceship_normalmap.jpg");
|
||||||
|
texture::rustNormal = Core::LoadTexture("./textures/rust_normal.jpg");
|
||||||
|
|
||||||
init_cubemap();
|
init_cubemap();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user