├── 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 | 
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