diff --git a/lightSample.cpp b/lightSample.cpp index f8ad059..dd6f7ab 100644 --- a/lightSample.cpp +++ b/lightSample.cpp @@ -37,12 +37,22 @@ int main(){ mat->setTexturingEnabled(true); mat->setLightingEnabled(true); mat->setNormalMapEnabled(true); + mat->setSpecularMapEnabled(true); + string im0[] = {TEX_PATH + "bricks.jpg"}; - string im1[] = {TEX_PATH + "bricksNormal.jpg"}; Texture *diffuseTex = new Texture(im0, 1); mat->addDiffuseMap(diffuseTex); + + string im1[] = {TEX_PATH + "bricksNormal.jpg"}; Texture *normalTex = new Texture(im1, 1, Texture::NORMAL); mat->addNormalMap(normalTex); + + string im2[] = {TEX_PATH + "bricksSpecular.jpg"}; + Texture *specularTex = new Texture(im2, 1, Texture::SPECULAR); + mat->addSpecularMap(specularTex); + + mat->setSpecularStrength(1); + mat->setShinyness(2); box->setMaterial(mat); rootNode->attachChild(box); @@ -52,8 +62,8 @@ int main(){ Node *lightNode = new Node(Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK, "", new AnimationController()); lightNode->addLight(light); rootNode->attachChild(lightNode); - lightNode->setOrientation(Quaternion(1.2, Vector3(1, 0, 0))); - lightNode->setPosition(Vector3(0, 5, 0)); + lightNode->setOrientation(Quaternion(.7, Vector3(1, 0, 0))); + lightNode->setPosition(Vector3(0, 5, -5)); KeyframeChannel kcA; kcA.animatable = light; diff --git a/material.cpp b/material.cpp index b5a2857..e631e82 100755 --- a/material.cpp +++ b/material.cpp @@ -95,6 +95,10 @@ namespace vb01{ if(type == MATERIAL_2D){ shader->setBool(lightingEnabled, "lightingEnabled"); shader->setBool(normalMapEnabled, "normalMapEnabled"); + shader->setBool(specularMapEnabled, "specularMapEnabled"); + shader->setInt(shinyness, "shinyness"); + shader->setFloat(specularStrength, "specularStrength"); + shader->setVec4(specularColor, "specularColor"); for(int i = 0; i < 4; i++){ shader->setInt(TEXTURE_SLOTS[i], "textures[" + to_string(i) + "].pastTexture"); shader->setInt(TEXTURE_SLOTS[i] + 1, "textures[" + to_string(i) + "].nextTexture"); @@ -120,10 +124,10 @@ namespace vb01{ textures.insert(textures.end(), parallaxMapTextures.begin(), parallaxMapTextures.end()); for(Texture *t : textures){ - int id = t->getTextureTypeId() * 2; + int id = t->getTextureTypeId(); shader->setBool(t->getNumFrames() > 1, "textures[" + to_string(id) + "].animated"); shader->setFloat(t->getMixRatio(), "textures[" + to_string(id) + "].mixRatio"); - t->update(id); + t->update(2 * id); } } else diff --git a/material.h b/material.h index d8a804e..c94cf51 100755 --- a/material.h +++ b/material.h @@ -27,7 +27,10 @@ namespace vb01{ inline void setTexturingEnabled(bool texturing){this->texturingEnabled = texturing;} inline void setDiffuseColorEnabled(bool diffuseColor){this->diffuseColorEnabled = diffuseColor;} inline void setNormalMapEnabled(bool enabled){this->normalMapEnabled = enabled;} + inline void setSpecularMapEnabled(bool enabled){this->specularMapEnabled = enabled;} inline void setParallaxMapEnabled(bool enabled){this->parallaxMapEnabled = enabled;} + inline void setShinyness(int shinyness){this->shinyness = shinyness;} + inline void setSpecularStrength(float specStr){this->specularStrength = specStr;} inline bool isLightingEnabled(){return lightingEnabled;} inline bool isTexturingEnabled(){return texturingEnabled;} inline bool isDiffuseColorEnabled(){return diffuseColorEnabled;} @@ -38,9 +41,11 @@ namespace vb01{ inline Type getType(){return type;} private: Type type; - bool lightingEnabled = false, texturingEnabled = true, diffuseColorEnabled = false, normalMapEnabled = false, parallaxMapEnabled = false; + int shinyness = 32; + float specularStrength = .5; + bool lightingEnabled = false, texturingEnabled = true, diffuseColorEnabled = false, normalMapEnabled = false, specularMapEnabled = false, parallaxMapEnabled = false; std::vector diffuseMapTextures, normalMapTextures, specularMapTextures, parallaxMapTextures; - Vector4 diffuseColor = Vector4::VEC_IJKL, specularColor = Vector4::VEC_IJKL; + Vector4 diffuseColor = Vector4::VEC_IJKL, specularColor = Vector4::VEC_ZERO; Shader *shader = nullptr; void initShader(); diff --git a/samples/textures/bricksSpecular.jpg b/samples/textures/bricksSpecular.jpg new file mode 100644 index 0000000..dee2187 Binary files /dev/null and b/samples/textures/bricksSpecular.jpg differ diff --git a/texture.frag b/texture.frag index ddc3133..e3a379b 100755 --- a/texture.frag +++ b/texture.frag @@ -32,44 +32,40 @@ struct Texture{ uniform Texture textures[4]; uniform samplerCube environmentMap; uniform Light light[numLights]; -uniform bool lightingEnabled; -uniform bool texturingEnabled; -uniform bool normalMapEnabled; -uniform bool castShadow; -uniform bool environmentMapEnabled; -uniform vec4 diffuseColor; -uniform float specularStrength; +uniform bool lightingEnabled, texturingEnabled, normalMapEnabled, specularMapEnabled, castShadow, environmentMapEnabled; +uniform vec4 diffuseColor, specularColor; +uniform float shinyness, specularStrength; uniform vec3 camPos; -float linDepth(float depth,int i){ - float z=depth*2-1,near=light[i].near,far=light[i].far; - return (2*near*far)/(far+near-z*(far-near)); +float linDepth(float depth, int i){ + float z = depth * 2 - 1, near = light[i].near, far = light[i].far; + return (2 * near * far) / (far + near - z * (far - near)); } float getShadow(int id){ - int type=light[id].type; + int type = light[id].type; - float shadow=0,closestDepth=0,currentDepth=0,bias=.005,val=.7; - if(type==0){ - vec3 projDir=fragPos-light[id].pos; - closestDepth=texture(light[id].depthMapCube,projDir).r*light[id].far; - currentDepth=length(projDir); - shadow=(currentDepth-bias>closestDepth)?val:0; + float shadow = 0, closestDepth = 0, currentDepth = 0, bias = .005, val = .7; + if(type == 0){ + vec3 projDir = fragPos - light[id].pos; + closestDepth = texture(light[id].depthMapCube, projDir).r * light[id].far; + currentDepth = length(projDir); + shadow = (currentDepth - bias > closestDepth) ? val : 0; } /* */ else{ - vec3 projCoords=(light[id].lightMat*vec4(fragPos,1)).xyz/(light[id].lightMat*vec4(fragPos,1)).w; - projCoords=projCoords*.5+.5; - closestDepth=texture(light[id].depthMap,projCoords.xy).r; - currentDepth=projCoords.z; - if(type==2){ - closestDepth=linDepth(closestDepth,id); - currentDepth=linDepth(currentDepth,id); + vec3 projCoords = (light[id].lightMat * vec4(fragPos, 1)).xyz / (light[id].lightMat * vec4(fragPos, 1)).w; + projCoords = projCoords * .5 + .5; + closestDepth = texture(light[id].depthMap, projCoords.xy).r; + currentDepth = projCoords.z; + if(type == 2){ + closestDepth = linDepth(closestDepth, id); + currentDepth = linDepth(currentDepth, id); } - shadow=(currentDepth-bias>closestDepth)?val:0; - if(projCoords.z>1) - shadow=0; + shadow = (currentDepth - bias > closestDepth) ? val : 0; + if(projCoords.z > 1) + shadow = 0; } return shadow; } @@ -91,15 +87,13 @@ void main(){ normal = mat3(tan, biTan, norm) * n; } - vec3 diffuseColor = vec3(0), specularColor = vec3(0); - float coef = 1; + vec3 diffuseCol = vec3(0), specularCol = vec3(0); for(int i = 0; i < numLights; i++){ - vec3 lightDir = vec3(0), reflectVec, viewDir = normalize(camPos - fragPos); + vec3 lightDir = vec3(0), viewDir = normalize(camPos - fragPos); float attenuation = 1.0; - float factor; - float a = light[i].a, b = light[i].b, c = light[i].c, dist = length(fragPos - light[i].pos); - coef = 1; + float a = light[i].a, b = light[i].b, c = light[i].c, dist = length(fragPos - light[i].pos), factor, coef = 1; + if(light[i].type == 0){ lightDir = normalize(light[i].pos - fragPos); attenuation = 1.0 / (a * dist * dist + b * dist + c); @@ -116,31 +110,35 @@ void main(){ coef = (angle - outerAngle) / (innerAngle - outerAngle); } if(angle > light[i].outerAngle){ - coef = 0; + continue; } } - float specularSample = texture(textures[2].pastTexture, texCoords).r; - reflectVec = reflect(lightDir, normal); - float spec = pow(max(dot(viewDir, reflectVec), 0), 32); - specularColor += vec3(1) * spec * specularSample; factor = max(dot(lightDir, normal), 0.); - diffuseColor += light[i].color * (factor * attenuation * coef); - } + diffuseCol += light[i].color * (factor * attenuation * coef); + + if(specularMapEnabled){ + float specularSample = texture(textures[2].pastTexture, texCoords).r; + vec3 halfwayVec = normalize(lightDir + viewDir); + float spec = pow(max(dot(normal, halfwayVec), 0), shinyness); + specularCol += specularStrength * spec * specularSample * light[i].color; + } + } /* for(int i = 0; i < numLights; i++){ float shadow = getShadow(i); - diffuseColor *= (1 - shadow); + diffuseCol *= (1 - shadow); } */ if(environmentMapEnabled){ vec3 projDir = normalize(fragPos - camPos); projDir = reflect(projDir, norm); vec3 sample = texture(environmentMap, projDir).rgb; - diffuseColor.rgb += sample; + diffuseCol.rgb += sample; } - finalColor *= vec4(diffuseColor + specularColor, 1); + + finalColor *= vec4(diffuseCol + specularCol, 1); } float brightness = dot(finalColor.rgb, vec3(0.2126, 0.7152, 0.0722));