|
|
@@ -9,7 +9,7 @@
|
|
|
//Shader Interface for a class that emulates modern GPU fragment and vertex shaders
|
|
|
struct IShader {
|
|
|
virtual ~IShader() {};
|
|
|
- virtual Vector3f vertex(Vector3f &vertex, Vector3f &normals, Vector3f &textureVals, Vector3f &light, int i) = 0;
|
|
|
+ virtual Vector3f vertex(const Vector3f &vertex, const Vector3f &normal, const Vector3f &textureVals, const Vector3f &tangent, const Vector3f &biTangent, const Vector3f &light, int index) = 0;
|
|
|
virtual Vector3f fragment(float u, float v) = 0;
|
|
|
};
|
|
|
|
|
|
@@ -19,8 +19,8 @@ struct FlatShader : public IShader {
|
|
|
float varIntensity;
|
|
|
Vector3f rgb{255,255,255};
|
|
|
|
|
|
- Vector3f vertex(Vector3f &vertex, Vector3f &normals, Vector3f &textureVals, Vector3f &light, int index) override{
|
|
|
- varIntensity = std::max(0.0f,normals.dotProduct(light));
|
|
|
+ Vector3f vertex(const Vector3f &vertex, const Vector3f &normal, const Vector3f &textureVals,const Vector3f &tangent,const Vector3f &biTangent,const Vector3f &light, int index) override{
|
|
|
+ varIntensity = std::max(0.0f,normal.dotProduct(light));
|
|
|
return MVP.matMultVec(vertex); //Transforms verts into projected space
|
|
|
}
|
|
|
|
|
|
@@ -37,11 +37,11 @@ struct GouraudShader : public IShader {
|
|
|
float ambientStrength = 0.05, diffStrength = 0, specularStrength = 0.5, spec = 0;
|
|
|
Vector3f ambient, diffuse, specular;
|
|
|
Vector3f lightColor1{1,1,1}, lightColor2{0,0,1}, lightColor3{1,1,1};
|
|
|
- Vector3f varying_diffuse, varying_specular, reflectDir, viewDir, light2;
|
|
|
+ Vector3f varying_diffuse, varying_specular, reflectDir, viewDir, light2, normal2;
|
|
|
Vector3f rgb{255,255,255};
|
|
|
|
|
|
- Vector3f vertex(Vector3f &vertex, Vector3f &normal, Vector3f &textureVals, Vector3f &light, int index) override{
|
|
|
- normal = N.matMultDir(normal).normalized();
|
|
|
+ Vector3f vertex(const Vector3f &vertex, const Vector3f &normal, const Vector3f &textureVals,const Vector3f &tangent,const Vector3f &biTangent,const Vector3f &light, int index) override{
|
|
|
+ normal2 = N.matMultDir(normal).normalized();
|
|
|
light2 = V.matMultDir(light).normalized();
|
|
|
reflectDir = Vector3f::reflect(-light2, normal);
|
|
|
viewDir = MV.matMultVec(vertex).normalized();
|
|
|
@@ -75,7 +75,7 @@ struct PhongShader : public IShader {
|
|
|
Vector3f varying_diffuse, varying_specular, reflectDir, light2;
|
|
|
Vector3f rgb{255,255,255};
|
|
|
|
|
|
- Vector3f vertex(Vector3f &vertex, Vector3f &normal, Vector3f &textureVals, Vector3f &light, int index) override{
|
|
|
+ Vector3f vertex(const Vector3f &vertex, const Vector3f &normal, const Vector3f &textureVals,const Vector3f &tangent,const Vector3f &biTangent,const Vector3f &light, int index) override{
|
|
|
normals[index] = N.matMultDir(normal).normalized();
|
|
|
viewDir[index] = MV.matMultVec(vertex).normalized();
|
|
|
light2 = V.matMultDir(light).normalized();
|
|
|
@@ -106,7 +106,7 @@ struct PhongShader : public IShader {
|
|
|
//Optimized version of Phong shader that uses a half angle instead of individual reflection
|
|
|
//angles
|
|
|
struct BlinnPhongShader : public IShader {
|
|
|
- Texture *albedo;
|
|
|
+ Texture *albedoT, *normalT;
|
|
|
Matrix4 MVP, MV, V, N;
|
|
|
float ambientStrength = 0.05, diffStrength=1 , specularStrength= 0.5;
|
|
|
float diff, spec, shininess = 128;
|
|
|
@@ -116,7 +116,7 @@ struct BlinnPhongShader : public IShader {
|
|
|
Vector3f halfwayDir, lightDir;
|
|
|
Vector3f interpCol, white{255,255,255};
|
|
|
|
|
|
- Vector3f vertex(Vector3f &vertex, Vector3f &normal, Vector3f &textureVals, Vector3f &light, int index) override{
|
|
|
+ Vector3f vertex(const Vector3f &vertex, const Vector3f &normal, const Vector3f &textureVals,const Vector3f &tangent,const Vector3f &biTangent,const Vector3f &light, int index) override{
|
|
|
normals[index] = N.matMultDir(normal).normalized();
|
|
|
UV[index] = textureVals;
|
|
|
viewDir[index] = MV.matMultVec(vertex).normalized();
|
|
|
@@ -130,7 +130,13 @@ struct BlinnPhongShader : public IShader {
|
|
|
interpViewDir = viewDir[0] + (viewDir[1] - viewDir[0])* u + (viewDir[2] - viewDir[0]) * v;
|
|
|
interpUV = UV[0] + (UV[1] - UV[0])* u + (UV[2] - UV[0]) * v;
|
|
|
//Albedo
|
|
|
- interpCol = albedo->getPixelVal(interpUV.x, interpUV.y);
|
|
|
+ interpCol = albedoT->getPixelVal(interpUV.x, interpUV.y);
|
|
|
+ //interpNormal = normalT->getPixelVal(interpUV.x, interpUV.y);
|
|
|
+ // interpNormal.x = (interpNormal.x*2/256.0f) -1;
|
|
|
+ // interpNormal.y = (interpNormal.y*2/256.0f) -1;
|
|
|
+ // interpNormal.z = 1 - interpNormal.z*1/256.0f;
|
|
|
+ // interpNormal = interpNormal.normalized();
|
|
|
+
|
|
|
//rgb.print();
|
|
|
|
|
|
//Ambient
|
|
|
@@ -150,51 +156,88 @@ struct BlinnPhongShader : public IShader {
|
|
|
|
|
|
};
|
|
|
|
|
|
+// Shader that uses normal mapping instead of vertex normal interpolation
|
|
|
+struct NormalMapShader : public IShader {
|
|
|
+ //Variables set per model
|
|
|
+ Texture *albedoT, *normalT;
|
|
|
+ Matrix4 MVP, MV, V, M, N;
|
|
|
+ Vector3f cameraPos;
|
|
|
|
|
|
-struct TestShader{
|
|
|
- Texture *albedo;
|
|
|
- Matrix4 MVP, MV, V, N;
|
|
|
- float ambientStrength = 0.05, diffStrength=1 , specularStrength= 0.5;
|
|
|
+ //Light Variables
|
|
|
+ Vector3f lightColor{1,1,1}, white{1,1,1};
|
|
|
+ float ambientStrength = 0.05, diffStrength = 1, specularStrength = 0.5;
|
|
|
float diff, spec, shininess = 128;
|
|
|
- Vector3f normals[3], viewDir[3], UV[3];
|
|
|
- Vector3f ambient, diffuse, specular, interpNormal, interpViewDir, interpUV;
|
|
|
- Vector3f lightColor{1,1,1};
|
|
|
- Vector3f halfwayDir, lightDir;
|
|
|
- Vector3f interpCol, white{255,255,255};
|
|
|
|
|
|
- Vector3f vertex(Vector3f &vertex, Vector3f &normal, Vector3f &textureVals, Vector3f &light, int index) {
|
|
|
- normals[index] = N.matMultDir(normal).normalized();
|
|
|
+ //Variables set per vertex
|
|
|
+ Vector3f normals[3], viewDir[3], UV[3], tangentFragPos[3], viewPos[3];
|
|
|
+ Vector3f lightDir, vertexPos[3],vertTangent[3], vertBiTangent[3] ;
|
|
|
+
|
|
|
+ //Interpolated variables
|
|
|
+ Vector3f interpUV, interpNormal, interpViewPos, interpCol, interpTangentFragPos;
|
|
|
+
|
|
|
+ //Per fragment
|
|
|
+ Vector3f ambient, diffuse, specular ;
|
|
|
+ Vector3f halfwayDir;
|
|
|
+
|
|
|
+ Vector3f vertex(const Vector3f &vertex, const Vector3f &normal,const Vector3f &textureVals,const Vector3f &tangent,const Vector3f &biTangent,const Vector3f &light, int index) override{
|
|
|
+ //Creating TBN matrix
|
|
|
+ normals[index] = N.matMultDir(normal).normalized();
|
|
|
+ vertTangent[index] = N.matMultDir(tangent).normalized();
|
|
|
+ vertBiTangent[index] = N.matMultDir(biTangent).normalized();
|
|
|
+ vertexPos[index] = M.matMultVec(vertex);
|
|
|
+ // Matrix4 TBN = Matrix4::TBNMatrix(vertTangent[index], vertBiTangent[index], normals[index]);
|
|
|
+
|
|
|
+ //Getting UV coordinates for use in both albedo and normal textures
|
|
|
UV[index] = textureVals;
|
|
|
- viewDir[index] = MV.matMultVec(vertex).normalized();
|
|
|
- lightDir = V.matMultDir(light).normalized();
|
|
|
+
|
|
|
+ //Passing all lighting related data to tangent space
|
|
|
+ // tangentFragPos[index] = TBN.matMultVec(N.matMultVec(vertex));
|
|
|
+ // viewPos[index] = TBN.matMultVec(cameraPos);
|
|
|
+ // lightDir = TBN.matMultVec(light);
|
|
|
+
|
|
|
return MVP.matMultVec(vertex);
|
|
|
}
|
|
|
|
|
|
- Vector3f fragment(float u, float v) {
|
|
|
+ Vector3f fragment(float u, float v) override{
|
|
|
//Interpolated stuff
|
|
|
- interpNormal = (normals[0] + (normals[1] - normals[0])* u + (normals[2] - normals[0]) * v).normalized();
|
|
|
- interpViewDir = viewDir[0] + (viewDir[1] - viewDir[0])* u + (viewDir[2] - viewDir[0]) * v;
|
|
|
- interpUV = UV[0] + (UV[1] - UV[0])* u + (UV[2] - UV[0]) * v;
|
|
|
+ // interpTangentFragPos = tangentFragPos[0] + (tangentFragPos[1] - tangentFragPos[0])* u + (tangentFragPos[2] - tangentFragPos[0]) * v;
|
|
|
+ // interpViewPos = viewPos[0] + (viewPos[1] - viewPos[0])* u + (viewPos[2] - viewPos[0]) * v;
|
|
|
+ //interpUV = UV[0] + (UV[1] - UV[0])* u + (UV[2] - UV[0]) * v;
|
|
|
+ Vector3f interpPos = vertexPos[0] + (vertexPos[1] - vertexPos[0])* u + (vertexPos[2] - vertexPos[0]) * v;
|
|
|
+ Vector3f interpTan = vertTangent[0] + (vertTangent[1] - vertTangent[0])* u + (vertTangent[2] - vertTangent[0]) * v;
|
|
|
+ Vector3f interpBiTan = vertBiTangent[0] + (vertBiTangent[1] - vertBiTangent[0])* u + (vertBiTangent[2] - vertBiTangent[0]) * v;
|
|
|
+ Vector3f interpNorm = normals[0] + (normals[1] - normals[0])* u + (normals[2] - normals[0]) * v;
|
|
|
+
|
|
|
//Albedo
|
|
|
- interpCol = albedo->getPixelVal(interpUV.x, interpUV.y);
|
|
|
- //rgb.print();
|
|
|
+ // interpCol = albedoT->getPixelVal(interpUV.x, interpUV.y);
|
|
|
+ // interpNormal = normalT->getPixelVal(interpUV.x, interpUV.y);
|
|
|
+ // interpNormal.x = (interpNormal.x * 2/256.0f) - 1;
|
|
|
+ // interpNormal.y = (interpNormal.y * 2/256.0f) - 1;
|
|
|
+ // interpNormal.z = (interpNormal.z * 2/256.0f) - 1;
|
|
|
+ // interpNormal = interpNormal.normalized();
|
|
|
+
|
|
|
|
|
|
//Ambient
|
|
|
- ambient = lightColor * ambientStrength;
|
|
|
+ // ambient = lightColor * ambientStrength;
|
|
|
|
|
|
//Diffuse
|
|
|
- diff = std::max(0.0f, interpNormal.dotProduct(lightDir));
|
|
|
- diffuse = lightColor * diff * diffStrength;
|
|
|
+ //lightDir = (interpTangentFragPos - lightDir).normalized();
|
|
|
+ // diff = std::max(0.0f, interpNormal.dotProduct(lightDir));
|
|
|
+ // diffuse = lightColor * diff * diffStrength;
|
|
|
|
|
|
//Specular
|
|
|
- halfwayDir = (lightDir - interpViewDir).normalized();
|
|
|
- spec = std::pow(std::max(0.0f, interpNormal.dotProduct(halfwayDir)), shininess);
|
|
|
- specular = lightColor * spec * specularStrength;
|
|
|
+ // halfwayDir = (lightDir - interpViewDir).normalized();
|
|
|
+ // spec = std::pow(std::max(0.0f, interpNormal.dotProduct(halfwayDir)), shininess);
|
|
|
+ // specular = lightColor * spec * specularStrength;
|
|
|
|
|
|
- return (ambient + diffuse) * interpCol + specular * white;
|
|
|
+ //return (ambient + diffuse) * interpCol + specular * white;
|
|
|
+ return interpPos;
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
#endif
|