Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #version 450
- layout(binding = 0) uniform CameraProjection {
- mat4 model;
- mat4 view;
- mat4 proj;
- }camera;
- layout(binding = 4) uniform Light {
- vec4 LightPosition;
- vec4 ObjectColor;
- vec4 LightColor;
- vec4 LightViewPosition;
- mat4 LightSpaceMatrix;
- vec4 CameraPosition;
- }light;
- layout(binding = 1) uniform sampler2D gPosition;
- layout(binding = 2) uniform sampler2D gNormal;
- layout(binding = 3) uniform sampler2D depthMap;
- layout(location = 0) in vec3 fragColor;
- layout(location = 1) in vec2 uvCoords;
- layout(location = 0) out vec4 outColor;
- uint MAX_STEPS = 12;
- float MAX_DISTANCE = 0.05;
- float THICKNESS = 0.05;
- float STEP_LENGTH = MAX_DISTANCE / float(MAX_STEPS);
- float MAX_DELTA_FROM_ORIGINAL_DEPTH = 0.005; //max depth variation from origina pixel
- const float zNear = 0.1;
- const float zFar = 1000.0;
- float linearize_depth(float d)
- {
- return zNear * zFar / (zFar + d * (zNear - zFar));
- }
- vec2 ViewToScreen(vec3 position)
- {
- vec4 project = camera.proj * vec4(position, 1.0);
- project.xy /= project.w;
- vec2 screen = project.xy * 0.5 + 0.5;
- return screen;
- }
- bool ValidRay(vec2 uv)
- {
- float bias = 0.0001;
- if(uv.x > bias && uv.x < 1.0 - bias && uv.y > bias && uv.y < 1.0 - bias){
- return true;
- }
- return false;
- }
- float computeScreenSpaceShadow()
- {
- vec3 FragPos = texture(gPosition, uvCoords).rgb;
- vec4 ViewSpaceLightPosition = camera.view * light.LightPosition;
- vec3 LightDirection = ViewSpaceLightPosition.xyz - FragPos.xyz;
- // Ray position and direction in view-space.
- vec3 RayPos = texture(gPosition, uvCoords).xyz; // ray start position
- vec3 RayDirection = normalize(-LightDirection.xyz);
- // Save original depth of the position
- float DepthOriginal = RayPos.z;
- // Ray step
- vec3 RayStep = RayDirection * STEP_LENGTH;
- float occlusion = 0.0;
- for(uint i = 0; i < MAX_STEPS; i++)
- {
- RayPos += RayStep;
- vec2 Ray_UV = ViewToScreen(RayPos);
- // Make sure the UV is inside screen-space
- if(!ValidRay(Ray_UV)){
- return 1.0;
- }
- // Compute difference between ray and cameras depth
- float DepthZ = linearize_depth(texture(depthMap, Ray_UV).x);
- float DepthDelta = RayPos.z - DepthZ;
- // Check if camera cannot see the ray. Ray depth must be larger than camera depth = positive delta
- bool canCameraSeeRay = (DepthDelta > 0.0) && (DepthDelta < THICKNESS);
- bool occludedByOriginalPixel = abs(RayPos.z - DepthOriginal) < MAX_DELTA_FROM_ORIGINAL_DEPTH;
- if(canCameraSeeRay && occludedByOriginalPixel)
- {
- // Mark as occluded
- occlusion = 1.0;
- break;
- }
- }
- return 1.0 - occlusion;
- }
- void main()
- {
- outColor = vec4(vec3(computeScreenSpaceShadow()), 1.0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement