├── bin └── data │ ├── .gitkeep │ └── shaders │ ├── blur.vert │ ├── render.vert │ ├── blur.frag │ └── render.frag ├── addons.make ├── multishadow.png ├── multiShadowExample.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── yasuhiro_hoshino.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── xcuserdata │ └── yasuhiro_hoshino.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── xcshareddata │ └── xcschemes │ │ ├── multiShadowExample Debug.xcscheme │ │ └── multiShadowExample Release.xcscheme └── project.pbxproj ├── README.md ├── Makefile ├── src ├── main.cpp ├── ofApp.h ├── customLight.h ├── customLight.cpp └── ofApp.cpp ├── Project.xcconfig ├── openFrameworks-Info.plist └── config.make /bin/data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /addons.make: -------------------------------------------------------------------------------- 1 | ofxAssimpModelLoader 2 | ofxGui 3 | -------------------------------------------------------------------------------- /multishadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yasuhirohoshino/oF-MultiShadowExample/HEAD/multishadow.png -------------------------------------------------------------------------------- /multiShadowExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # oF-MultiShadowExample 2 | 3 | ![sample image](multishadow.png) 4 | 5 | Multi light & shadow example for openFrameworks. 6 | 7 | By Yasuhiro Hoshino 8 | 9 | yasuhiro.hoshino.0122 at gmail.com 10 | 11 | http://www.yasuhirohoshino.com 12 | -------------------------------------------------------------------------------- /multiShadowExample.xcodeproj/project.xcworkspace/xcuserdata/yasuhiro_hoshino.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yasuhirohoshino/oF-MultiShadowExample/HEAD/multiShadowExample.xcodeproj/project.xcworkspace/xcuserdata/yasuhiro_hoshino.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=$(realpath ../../..) 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /bin/data/shaders/blur.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | uniform mat4 projectionMatrix; 4 | uniform mat4 modelViewMatrix; 5 | uniform mat4 textureMatrix; 6 | uniform mat4 modelViewProjectionMatrix; 7 | uniform mat4 inverseProjectionMatrix; 8 | 9 | in vec4 position; 10 | in vec4 color; 11 | in vec3 normal; 12 | in vec2 texcoord; 13 | 14 | out vec2 texCoordVarying; 15 | 16 | void main() { 17 | texCoordVarying = texcoord; 18 | gl_Position = modelViewProjectionMatrix * position; 19 | } -------------------------------------------------------------------------------- /multiShadowExample.xcodeproj/xcuserdata/yasuhiro_hoshino.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SuppressBuildableAutocreation 6 | 7 | E4B69B5A0A3A1756003C02F2 8 | 9 | primary 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | //======================================================================== 5 | int main( ){ 6 | ofGLWindowSettings settings; 7 | settings.setGLVersion(3, 2); 8 | settings.width = 1280; 9 | settings.height = 720; 10 | ofCreateWindow(settings); 11 | 12 | // this kicks off the running of my app 13 | // can be OF_WINDOW or OF_FULLSCREEN 14 | // pass in width and height too: 15 | ofRunApp(new ofApp()); 16 | } 17 | -------------------------------------------------------------------------------- /Project.xcconfig: -------------------------------------------------------------------------------- 1 | //THE PATH TO THE ROOT OF OUR OF PATH RELATIVE TO THIS PROJECT. 2 | //THIS NEEDS TO BE DEFINED BEFORE CoreOF.xcconfig IS INCLUDED 3 | OF_PATH = ../../.. 4 | 5 | //THIS HAS ALL THE HEADER AND LIBS FOR OF CORE 6 | #include "../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig" 7 | 8 | //ICONS - NEW IN 0072 9 | ICON_NAME_DEBUG = icon-debug.icns 10 | ICON_NAME_RELEASE = icon.icns 11 | ICON_FILE_PATH = $(OF_PATH)/libs/openFrameworksCompiled/project/osx/ 12 | 13 | //IF YOU WANT AN APP TO HAVE A CUSTOM ICON - PUT THEM IN YOUR DATA FOLDER AND CHANGE ICON_FILE_PATH to: 14 | //ICON_FILE_PATH = bin/data/ 15 | 16 | OTHER_LDFLAGS = $(OF_CORE_LIBS) $(OF_CORE_FRAMEWORKS) 17 | HEADER_SEARCH_PATHS = $(OF_CORE_HEADERS) 18 | -------------------------------------------------------------------------------- /openFrameworks-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | cc.openFrameworks.ofapp 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | APPL 15 | CFBundleSignature 16 | ???? 17 | CFBundleVersion 18 | 1.0 19 | CFBundleIconFile 20 | ${ICON} 21 | 22 | 23 | -------------------------------------------------------------------------------- /bin/data/shaders/render.vert: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #define MAX_LIGHTS 8 4 | 5 | uniform mat4 projectionMatrix; 6 | uniform mat4 modelViewMatrix; 7 | uniform mat4 textureMatrix; 8 | uniform mat4 modelViewProjectionMatrix; 9 | uniform vec4 globalColor; 10 | 11 | in vec4 position; 12 | in vec3 normal; 13 | in vec2 texcoord; 14 | 15 | out vec4 positionVarying; 16 | out vec3 normalVarying; 17 | out vec2 texCoordVarying; 18 | 19 | out vec4 colorVarying; 20 | out vec3 v_normalVarying; 21 | out vec4 v_positionVarying; 22 | 23 | uniform mat4 viewMatrix; 24 | uniform int numLights; 25 | uniform mat4 shadowMatrix[MAX_LIGHTS]; 26 | out vec4 v_shadowCoord[MAX_LIGHTS]; 27 | 28 | void main() { 29 | mat3 normalMatrix = transpose(inverse(mat3(modelViewMatrix))); 30 | 31 | normalVarying = normal; 32 | positionVarying = position; 33 | texCoordVarying = texcoord; 34 | colorVarying = globalColor; 35 | 36 | v_normalVarying = normalize(vec3(normalMatrix * normal)); 37 | v_positionVarying = modelViewMatrix * position; 38 | 39 | for(int i=0; i roughness; 56 | ofParameter baseColor; 57 | ofParameter numLights; 58 | ofParameter shadowOffset; 59 | 60 | ofParameter isEnabled[MAX_LIGHTS]; 61 | ofParameter lightType[MAX_LIGHTS], shadowType[MAX_LIGHTS]; 62 | ofParameter color[MAX_LIGHTS]; 63 | ofParameter cutoff[MAX_LIGHTS]; 64 | ofParameter exponent[MAX_LIGHTS]; 65 | ofParameter intensity[MAX_LIGHTS]; 66 | ofParameter radius[MAX_LIGHTS]; 67 | ofParameter nearClip[MAX_LIGHTS]; 68 | ofParameter farClip[MAX_LIGHTS]; 69 | ofxPanel lightGui[MAX_LIGHTS]; 70 | ofParameter lightTypeName[MAX_LIGHTS], shadowTypeName[MAX_LIGHTS]; 71 | 72 | int guiWidth; 73 | bool isGuiShown; 74 | 75 | const string lightTypeNames[3] = {"Directional Light", "Spot Light", "Point Light"}; 76 | const string shadowTypeNames[3] = {"No Shadow", "hard Shadow", "Soft Shadow"}; 77 | }; 78 | -------------------------------------------------------------------------------- /src/customLight.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | 5 | enum LightType{ 6 | LightType_Directional = 0, 7 | LightType_Spot = 1, 8 | LightType_Point = 2, 9 | NumLightTypes = 3 10 | }; 11 | 12 | enum ShadowType{ 13 | ShadowType_None = 0, 14 | ShadowType_Hard = 1, 15 | ShadowType_Soft = 2, 16 | NumShadowTypes = 3 17 | }; 18 | 19 | class customLight: protected ofCamera{ 20 | public: 21 | customLight(); 22 | ~customLight(); 23 | 24 | void enable(bool isEnabled = true); 25 | void disable(); 26 | bool getIsEnabled(); 27 | void setPosition(ofVec3f pos); 28 | ofVec3f getPosition(); 29 | 30 | // depth camera 31 | void setNearClip(float near); 32 | float getNearClip(); 33 | void setFarClip(float far); 34 | float getFarClip(); 35 | void lookAt(ofVec3f target); 36 | ofVec3f getLookAtDir(); 37 | void setScale(float scale); 38 | void setDepthMapRes(float resolution); 39 | void beginDepthCamera(); 40 | void endDepthCamera(); 41 | 42 | // for rendering shader 43 | ofVec3f getViewSpacePosition(ofMatrix4x4 viewMatrix); 44 | ofMatrix4x4 getShadowMatrix(ofMatrix4x4 cameraModelViewMatrix); 45 | ofVec3f getViewSpaceDirection(ofMatrix4x4 viewMatrix); 46 | 47 | // color 48 | void setColor(ofFloatColor color); 49 | void setColor(ofColor color); 50 | ofFloatColor getColor(); 51 | 52 | // light 53 | void setLightType(LightType lightType); 54 | LightType getLightType(); 55 | void setIntensity(float intensity); 56 | float getIntensity(); 57 | 58 | // spotlight & pointlight 59 | void setRadius(float radius); 60 | float getRadius(); 61 | 62 | // spotLight 63 | void setCutoff(float cutoff); 64 | float getCutoff(); 65 | void setExponent(float exponent); 66 | float getExponent(); 67 | 68 | // shadow 69 | void setShadowType(ShadowType shadowType); 70 | ShadowType getShadowType(); 71 | void setShadowBias(float shadowBias); 72 | float getShadowBias(); 73 | void setSoftShadowExponent(float softShadowExponent); 74 | float getSoftShadowExponent(); 75 | 76 | private: 77 | ofFloatColor color = ofFloatColor(1.0,1.0,1.0,1.0); 78 | LightType lightType = LightType_Directional; 79 | ShadowType shadowType = ShadowType_Soft; 80 | float exponent = 1; 81 | float cutoff = 45; 82 | float radius = 1000; 83 | float depthMapRes = 1024; 84 | float shadowBias = 0.001; 85 | float softShadowExponent = 75.0; 86 | float intensity = 1.0; 87 | bool isEnabled = true; 88 | ofMatrix4x4 shadowTransMatrix; 89 | 90 | const ofMatrix4x4 biasMatrix = ofMatrix4x4( 91 | 0.5, 0.0, 0.0, 0.0, 92 | 0.0, 0.5, 0.0, 0.0, 93 | 0.0, 0.0, 0.5, 0.0, 94 | 0.5, 0.5, 0.5, 1.0 95 | ); 96 | }; -------------------------------------------------------------------------------- /multiShadowExample.xcodeproj/xcshareddata/xcschemes/multiShadowExample Debug.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /multiShadowExample.xcodeproj/xcshareddata/xcschemes/multiShadowExample Release.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/customLight.cpp: -------------------------------------------------------------------------------- 1 | #include "customLight.h" 2 | 3 | customLight::customLight(){ 4 | setupPerspective(); 5 | setForceAspectRatio(1.0); 6 | setFov(90); 7 | } 8 | 9 | customLight::~customLight(){} 10 | 11 | void customLight::enable(bool isEnabled){ 12 | this->isEnabled = isEnabled; 13 | } 14 | 15 | void customLight::disable(){ 16 | this->isEnabled = false; 17 | } 18 | 19 | bool customLight::getIsEnabled(){ 20 | return isEnabled; 21 | } 22 | 23 | void customLight::setPosition(ofVec3f pos){ 24 | setGlobalPosition(pos); 25 | } 26 | 27 | ofVec3f customLight::getPosition(){ 28 | return getGlobalPosition(); 29 | } 30 | 31 | // depth camera 32 | void customLight::setNearClip(float near){ 33 | ofCamera::setNearClip(near); 34 | } 35 | 36 | float customLight::getNearClip(){ 37 | ofCamera::getNearClip(); 38 | } 39 | 40 | void customLight::setFarClip(float far){ 41 | ofCamera::setFarClip(far); 42 | } 43 | 44 | float customLight::getFarClip(){ 45 | return ofCamera::getFarClip(); 46 | } 47 | 48 | void customLight::lookAt(ofVec3f target){ 49 | return ofCamera::lookAt(target); 50 | } 51 | 52 | ofVec3f customLight::getLookAtDir(){ 53 | return ofCamera::getLookAtDir(); 54 | } 55 | 56 | void customLight::setScale(float scale){ 57 | ofCamera::setScale(scale); 58 | } 59 | 60 | void customLight::setDepthMapRes(float resolution){ 61 | depthMapRes = resolution; 62 | } 63 | 64 | void customLight::beginDepthCamera(){ 65 | begin(); 66 | } 67 | 68 | void customLight::endDepthCamera(){ 69 | end(); 70 | } 71 | 72 | // for rendering shader 73 | ofVec3f customLight::getViewSpacePosition(ofMatrix4x4 viewMatrix){ 74 | if(lightType == LightType_Directional){ 75 | ofVec4f pos = ofVec4f(getGlobalPosition().x, getGlobalPosition().y, getGlobalPosition().z, 0.0); 76 | return pos * viewMatrix; 77 | }else{ 78 | ofVec4f pos = ofVec4f(getGlobalPosition().x, getGlobalPosition().y, getGlobalPosition().z, 1.0); 79 | return pos * viewMatrix; 80 | } 81 | } 82 | 83 | ofMatrix4x4 customLight::getShadowMatrix(ofMatrix4x4 cameraModelViewMatrix){ 84 | ofMatrix4x4 viewMatrix, projectionMatrix; 85 | viewMatrix = getModelViewMatrix(); 86 | if(lightType == LightType_Directional){ 87 | projectionMatrix.makeOrthoMatrix(-depthMapRes * 0.5, depthMapRes * 0.5, -depthMapRes * 0.5, depthMapRes * 0.5, ofCamera::getNearClip(), ofCamera::getFarClip()); 88 | }else{ 89 | projectionMatrix = getProjectionMatrix(); 90 | } 91 | return cameraModelViewMatrix.getInverse() * viewMatrix * projectionMatrix * biasMatrix; 92 | } 93 | 94 | ofVec3f customLight::getViewSpaceDirection(ofMatrix4x4 viewMatrix){ 95 | ofVec4f dir = ofVec4f(getLookAtDir().x, getLookAtDir().y, getLookAtDir().z, 0.0); 96 | return ofVec3f(dir * viewMatrix).getNormalized(); 97 | } 98 | 99 | // color 100 | void customLight::setColor(ofFloatColor color){ 101 | this->color = color; 102 | } 103 | 104 | void customLight::setColor(ofColor color){ 105 | this->color.r = color.r / 255.0; 106 | this->color.g = color.g / 255.0; 107 | this->color.b = color.b / 255.0; 108 | this->color.a = color.a / 255.0; 109 | } 110 | 111 | ofFloatColor customLight::getColor(){ 112 | return color; 113 | } 114 | 115 | // light 116 | void customLight::setLightType(LightType lightType){ 117 | this->lightType = lightType; 118 | if(lightType == LightType_Directional){ 119 | enableOrtho(); 120 | }else{ 121 | disableOrtho(); 122 | } 123 | } 124 | 125 | LightType customLight::getLightType(){ 126 | return lightType; 127 | } 128 | 129 | void customLight::setIntensity(float intensity){ 130 | this->intensity = intensity; 131 | } 132 | 133 | float customLight::getIntensity(){ 134 | return intensity; 135 | } 136 | 137 | // spotlight & pointlight 138 | void customLight::setRadius(float radius){ 139 | this->radius = radius; 140 | } 141 | 142 | float customLight::getRadius(){ 143 | return radius; 144 | } 145 | 146 | // spotLight 147 | void customLight::setCutoff(float cutoff){ 148 | this->cutoff = cutoff; 149 | } 150 | 151 | float customLight::getCutoff(){ 152 | return cutoff; 153 | } 154 | 155 | void customLight::setExponent(float exponent){ 156 | this->exponent = exponent; 157 | } 158 | 159 | float customLight::getExponent(){ 160 | return exponent; 161 | } 162 | 163 | // shadow 164 | void customLight::setShadowType(ShadowType shadowType){ 165 | this->shadowType = shadowType; 166 | } 167 | 168 | ShadowType customLight::getShadowType(){ 169 | return shadowType; 170 | } 171 | 172 | void customLight::setShadowBias(float shadowBias){ 173 | this->shadowBias = shadowBias; 174 | } 175 | 176 | float customLight::getShadowBias(){ 177 | return shadowBias; 178 | } 179 | 180 | void customLight::setSoftShadowExponent(float softShadowExponent){ 181 | this->softShadowExponent = softShadowExponent; 182 | } 183 | 184 | float customLight::getSoftShadowExponent(){ 185 | return softShadowExponent; 186 | } -------------------------------------------------------------------------------- /bin/data/shaders/render.frag: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | #define MAX_LIGHTS 8 4 | 5 | uniform mat4 viewMatrix; 6 | uniform sampler2D shadowMap; 7 | 8 | struct Light{ 9 | bool isEnabled; 10 | vec3 position; 11 | vec4 color; 12 | vec3 direction; 13 | int type; 14 | int shadowType; 15 | float intensity; 16 | float exponent; 17 | float cutoff; 18 | float radius; 19 | float softShadowExponent; 20 | float bias; 21 | }; 22 | 23 | uniform Light lights[MAX_LIGHTS]; 24 | uniform int numLights; 25 | uniform vec2 depthMapAtrasRes; 26 | uniform vec2 depthTexMag; 27 | uniform float roughness; 28 | uniform vec4 shadowOffset; 29 | 30 | in vec4 colorVarying; 31 | in vec2 texCoordVarying; 32 | in vec3 normalVarying; 33 | in vec4 positionVarying; 34 | 35 | in vec3 v_normalVarying; 36 | in vec4 v_positionVarying; 37 | 38 | in vec3 v_lightPos; 39 | in vec3 v_lightDir; 40 | in vec4 v_shadowCoord[MAX_LIGHTS]; 41 | 42 | out vec4 fragColor; 43 | 44 | float BechmannDistribution(float d, float m) { 45 | float d2 = d * d; 46 | float m2 = m * m; 47 | return exp((d2 - 1.0) / (d2 * m2)) / (m2 * d2 * d2); 48 | } 49 | 50 | float CookTorranceSpecular(vec3 lightDirection, vec3 viewDirection, vec3 surfaceNormal, float roughness){ 51 | vec3 l = normalize(lightDirection); 52 | vec3 n = normalize(surfaceNormal); 53 | 54 | vec3 v = normalize(viewDirection); 55 | vec3 h = normalize(l + v); 56 | 57 | float hn = dot(h, n); 58 | float ln = dot(l, n); 59 | float lh = dot(l, h); 60 | float vn = dot(v, n); 61 | 62 | float f = 0.02 + pow(1.0 - dot(v, h), 5.0) * (1.0 - 0.02); 63 | float d = BechmannDistribution(hn, roughness); 64 | float t = 2.0 * hn / dot(v, h); 65 | float g = min(1.0, min(t * vn, t * ln)); 66 | float m = 3.14159265 * vn * ln; 67 | float spec = max(f * d * g / m, 0.0); 68 | return spec; 69 | } 70 | 71 | float Falloff(float dist, float lightRadius) { 72 | float att = clamp(1.0 - dist * dist / (lightRadius * lightRadius), 0.0, 1.0); 73 | att *= att; 74 | return att; 75 | } 76 | 77 | vec3 CalcPointLight(vec4 v_positionVarying, vec3 v_normalVarying, vec3 color, Light light) { 78 | vec3 s = normalize(light.position - v_positionVarying.xyz); 79 | float lambert = max(dot(s, v_normalVarying), 0.0); 80 | float falloff = Falloff(length(light.position - v_positionVarying.xyz), light.radius); 81 | float specular = CookTorranceSpecular(s, -normalize(v_positionVarying.xyz), v_normalVarying, roughness); 82 | return light.intensity * (color.rgb * light.color.rgb * lambert * falloff + color.rgb * light.color.rgb * specular * falloff); 83 | } 84 | 85 | vec3 CalcSpotLight(vec4 v_positionVarying, vec3 v_normalVarying, vec3 color, Light light) { 86 | vec3 s = normalize(light.position - v_positionVarying.xyz); 87 | float angle = acos(dot(-s, light.direction)); 88 | float cutoff = radians(clamp(light.cutoff, 0.0, 90.0)); 89 | if(angle < cutoff){ 90 | float spotFactor = pow(dot(-s, light.direction), light.exponent); 91 | float lambert = max(dot(s, v_normalVarying), 0.0); 92 | float falloff = Falloff(length(light.position - v_positionVarying.xyz), light.radius); 93 | float specular = CookTorranceSpecular(s, -normalize(v_positionVarying.xyz), v_normalVarying, roughness); 94 | return light.intensity * (color.rgb * light.color.rgb * lambert * falloff * spotFactor + color.rgb * light.color.rgb * specular * falloff * spotFactor); 95 | }else{ 96 | return vec3(0.0, 0.0, 0.0); 97 | } 98 | } 99 | 100 | vec3 CalcDirectionalLight(vec4 v_positionVarying, vec3 v_normalVarying, vec3 color, Light light) { 101 | float lambert = max(dot(-light.direction, v_normalVarying), 0.0); 102 | float specular = CookTorranceSpecular(-light.direction, -normalize(v_positionVarying.xyz), v_normalVarying, roughness); 103 | return light.intensity * (color.rgb * light.color.rgb * lambert + color.rgb * light.color.rgb * specular); 104 | } 105 | 106 | float CalcSoftShadow(int index, float expo){ 107 | float visiblity = 1.0; 108 | vec3 projCoords = v_shadowCoord[index].xyz / v_shadowCoord[index].w; 109 | float currentDepth = projCoords.z; 110 | vec2 offset = vec2(depthTexMag.x * (index % 4), depthTexMag.y * floor(index / 4)); 111 | float depth = texture(shadowMap, offset + projCoords.xy * depthTexMag).r; 112 | visiblity = exp(expo * depth) * exp(-expo * currentDepth); 113 | if(projCoords.x >= 1.0 || projCoords.x <= 0.0 || 114 | projCoords.y >= 1.0 || projCoords.y <= 0.0 || 115 | projCoords.z >= 1.0 || projCoords.z <= 0.0){ 116 | visiblity = 1.0; 117 | } 118 | return visiblity; 119 | } 120 | 121 | float CalcHardShadow(int index){ 122 | float visiblity = 1.0; 123 | vec3 projCoords = v_shadowCoord[index].xyz / v_shadowCoord[index].w; 124 | float currentDepth = projCoords.z; 125 | vec2 offset = vec2(depthTexMag.x * (index % 4), depthTexMag.y * floor(index / 4)); 126 | if(currentDepth - lights[index].bias > texture(shadowMap, offset + projCoords.xy * depthTexMag).r){ 127 | visiblity -= 1.0; 128 | } 129 | if(projCoords.x >= 1.0 || projCoords.x <= 0.0 || 130 | projCoords.y >= 1.0 || projCoords.y <= 0.0 || 131 | projCoords.z >= 1.0 || projCoords.z <= 0.0){ 132 | visiblity = 1.0; 133 | } 134 | return visiblity; 135 | } 136 | 137 | vec3 CalcLightAndShadow(vec4 v_positionVarying, vec3 v_normalVarying, vec3 color, int index) 138 | { 139 | vec3 light = vec3(0.0); 140 | if(lights[index].type == 0){ 141 | light = CalcDirectionalLight(v_positionVarying, v_normalVarying, color, lights[index]); 142 | }else if(lights[index].type == 1){ 143 | light = CalcSpotLight(v_positionVarying, v_normalVarying, color, lights[index]); 144 | }else if(lights[index].type == 2){ 145 | light = CalcPointLight(v_positionVarying, v_normalVarying, color, lights[index]); 146 | } 147 | 148 | float shadow = 1.0; 149 | if(lights[index].shadowType == 0){ 150 | shadow = 1.0; 151 | }else if(lights[index].shadowType == 1){ 152 | shadow = CalcHardShadow(index); 153 | }else if(lights[index].shadowType == 2){ 154 | shadow = CalcSoftShadow(index, lights[index].softShadowExponent); 155 | } 156 | 157 | return vec3(light * clamp(shadow, 0.0, 1.0)); 158 | } 159 | 160 | void main (void) { 161 | vec3 color = vec3(shadowOffset.rgb); 162 | vec3 light = vec3(0.0); 163 | float shadow = 0.0; 164 | for(int i=0; i(lightType[i].get())); 95 | pbrLight[i].setShadowType(static_cast(shadowType[i].get())); 96 | pbrLight[i].setColor(color[i]); 97 | pbrLight[i].setCutoff(cutoff[i]); 98 | pbrLight[i].setExponent(exponent[i]); 99 | pbrLight[i].setIntensity(intensity[i]); 100 | pbrLight[i].setRadius(radius[i]); 101 | pbrLight[i].setNearClip(nearClip[i]); 102 | pbrLight[i].setFarClip(farClip[i]); 103 | 104 | float rad = ofGetElapsedTimef() + TWO_PI * i / fmaxf(numLights, 1); 105 | pbrLight[i].setPosition(ofVec3f(1500.0 * cos(rad), 1500.0, 1500.0 * sin(rad))); 106 | pbrLight[i].lookAt(ofVec3f(0, 0, 0)); 107 | 108 | lightTypeName[i].set(lightTypeNames[lightType[i].get()]); 109 | shadowTypeName[i].set(shadowTypeNames[shadowType[i].get()]); 110 | } 111 | 112 | ofSetWindowTitle(ofToString(ofGetFrameRate())); 113 | } 114 | 115 | //-------------------------------------------------------------- 116 | void ofApp::draw(){ 117 | 118 | for(int i=0; i