Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #version 450
- //transforms the occlusion map into a lightmap
- //that can be multiblended onto the screen buffer
- //texture with solidity information
- uniform sampler2D occlusion_map;
- //color of ambient light
- uniform vec3 ambient;
- //dimensions of the buffers (occlusion map and cast texture should have same size)
- uniform vec2 dimensions;
- //aspect ratio, for example 0.5625 for 1280x720
- float aspect;
- //define amount of lights to be processed
- uniform int light_amount;
- //define all light property uniforms
- #define DL(INDEX) \
- uniform vec3 light##INDEX##ob; \
- uniform vec3 light##INDEX##c;
- DL(0)
- DL(1)
- DL(2)
- DL(3)
- DL(4)
- DL(5)
- DL(6)
- DL(7)
- DL(8)
- DL(9)
- DL(10)
- DL(11)
- DL(12)
- DL(13)
- DL(14)
- DL(15)
- //define function that sets "light" class instance to uniform params
- #define FETCHLIGHT(ID) \
- if(light_index == ID)\
- {\
- light.origin = light##ID##ob.rg;\
- light.color = light##ID##c.rgb;\
- light.brightness = light##ID##ob.b;\
- }
- //checks whether the pixel is in a wall or if it can be illuminated
- bool isOccluded(vec2 uv)
- {
- return texture2D(occlusion_map, vec2(uv.x, 1.0 - uv.y)).r > 0.1;
- }
- //max iteration steps for function below
- #define MAX_STEPS 300.0
- #define EPS 0.00001
- //calculates whether the tar-get position can be reached without hitting an occluder
- bool canBeReached(vec2 orig, vec2 tar)
- {
- vec2 path = tar - orig;
- //distance between light and pixel
- highp float maxdistance = length(path);
- //amount of occlusion pixels to sample along the way
- int sample_amount = int(round(MAX_STEPS * maxdistance));
- //distance the ray reaches from the origin before hitting a solid pixel
- highp float d;
- for(int i = 0;i < sample_amount; i++)
- {
- //how much along path?
- d = float(i) / float(sample_amount);
- //where along the path to sample from?
- // origin path distance along path
- vec2 sample_point = orig + (path * d);
- //check if point along path is occluded
- bool occluded = !isOccluded(sample_point);
- //break condition: pixel is black/occluded
- if(occluded)
- {
- return false;
- }
- }
- return true;
- }
- //Light struct for light info
- struct Light
- {
- vec2 origin;
- vec3 color;
- float brightness;
- };
- void main(){
- //set aspect ratio
- aspect = dimensions.y / dimensions.x;
- //for this pixel...
- vec2 this_pixel = vec2(gl_FragCoord.x, gl_FragCoord.y);
- //final color of pixel, this will be modified down below
- vec3 final_color = ambient;
- //check if its occluded, if its not...
- if(!isOccluded(this_pixel / dimensions)){
- gl_FragColor = vec4(ambient * 0.5, 1.0);
- }
- else{
- vec2 this_pixel_ratiod = vec2(this_pixel.x, this_pixel.y * aspect);
- vec2 light_origin_ratiod;
- float distance_between_light_and_pixel;
- float distance_between_light_and_pixel_ratiod;
- float distance_between_light_and_occluder;
- //check for all the lights...
- for(int light_index = 0; light_index < light_amount; light_index++){
- //well, grab the light info first, but then...
- Light light;
- FETCHLIGHT(0)
- else FETCHLIGHT(1)
- else FETCHLIGHT(2)
- else FETCHLIGHT(3)
- else FETCHLIGHT(4)
- else FETCHLIGHT(5)
- else FETCHLIGHT(6)
- else FETCHLIGHT(7)
- else FETCHLIGHT(8)
- else FETCHLIGHT(9)
- else FETCHLIGHT(10)
- else FETCHLIGHT(11)
- else FETCHLIGHT(12)
- else FETCHLIGHT(13)
- else FETCHLIGHT(14)
- else FETCHLIGHT(15)
- //calculate distance between light and this pixel
- /////distance_between_light_and_pixel = length(light.origin - (this_pixel / dimensions));
- //calculate distance between light and this pixel (for this, consider aspect ratio!)
- light_origin_ratiod = light.origin * vec2(1.0, aspect);
- //light_origin_ratiod = vec2(light.origin.x, light.origin.y * aspect);
- distance_between_light_and_pixel_ratiod = length((this_pixel_ratiod / dimensions) - light_origin_ratiod);
- //calculate distance between light and first occluded pixel in direction of this_pixel
- /////distance_between_light_and_occluder = MarchShadow((this_pixel / dimensions), (this_pixel / dimensions) - light.origin);
- //check if this light ray even reaches this pixel
- if(canBeReached(light.origin, (this_pixel / dimensions))){
- //determine light falloff!
- final_color += light.color * pow((1.0 - distance_between_light_and_pixel_ratiod), 5);
- //done!
- }
- }
- gl_FragColor = vec4(final_color, 1.0);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement