Josh Posted November 27, 2016 Share Posted November 27, 2016 I basically took the ray-tracing code that Igor and Shadmar developed, with my own additions, and am trying to use that to trace shadows in screen space. The result of the shadowmap lookup is multiplied by the result of the ray-trace lookup for finer resolution. It's very expensive to render and not that great, but go ahead and try it out if you like. DirectionalLight.shader pixel shader: #version 400 #define PI 3.14159265359 #define HALFPI PI/2.0 #define LOWERLIGHTTHRESHHOLD 0.001 #ifndef SHADOWSTAGES #define SHADOWSTAGES 4 #endif #ifndef SAMPLES #define SAMPLES 1 #endif #ifndef KERNEL #define KERNEL 3 #endif #define KERNELF float(KERNEL) #define GLOSS 10.0 #if SAMPLES==0 uniform sampler2D texture0;//depth uniform sampler2D texture1;//diffuse.rgba uniform sampler2D texture2;//normal.xyz, diffuse.a uniform sampler2D texture3;//specular, ao, flags, diffuse.a uniform sampler2D texture4;//emission.rgb, diffuse.a #else uniform sampler2DMS texture0;//depth uniform sampler2DMS texture1;//diffuse.rgba uniform sampler2DMS texture2;//normal.xyz, diffuse.a uniform sampler2DMS texture3;//specular, ao, flags, diffuse.a uniform sampler2DMS texture4;//emission.rgb, diffuse.a #endif uniform sampler2DShadow texture5;//shadowmap /* Possible future optimization: uniform sampler2DMS texture0;//depth uniform sampler2DMS texture1;//diffuse.rgba uniform sampler2DMS texture2;//normal.xyz, specular uniform sampler2DMS texture4;//emission.rgb, flags */ uniform mat3 cameranormalmatrix; uniform mat3 camerainversenormalmatrix; uniform vec2[4] shadowstagepositon; uniform vec2 shadowstagescale; uniform vec4 ambientlight; uniform vec2 buffersize; uniform vec3 lightdirection; uniform vec4 lightcolor; uniform vec4 lightspecular; uniform vec2 camerarange; uniform float camerazoom; uniform vec2[sHADOWSTAGES] lightshadowmapoffset; uniform mat4 lightmatrix; uniform mat3 lightnormalmatrix0; uniform mat3 lightnormalmatrix1; uniform mat3 lightnormalmatrix2; uniform mat3 lightnormalmatrix3; uniform vec2 shadowmapsize; uniform vec2 lightrange; uniform vec3[sHADOWSTAGES] lightposition; //uniform vec3 lightposition0; //uniform vec3 lightposition1; //uniform vec3 lightposition2; //uniform vec3 lightposition3; uniform float[sHADOWSTAGES] shadowstagearea; uniform float[sHADOWSTAGES] shadowstagerange; uniform bool isbackbuffer; uniform mat4 projectioncameramatrix; uniform vec3 cameraposition; //User variables #define reflectionfalloff 10.0 #define maxstep 100 #define edgefadefactor 0.95 #define raylength 0.01 #define hitThreshold 0.01 out vec4 fragData0; vec4 getPosition(in vec2 texCoord, out float z) { float x = texCoord.s * 2.0f - 1.0f; float y = texCoord.t * 2.0f - 1.0f; z = texelFetch(texture0, ivec2(texCoord*buffersize),0).r; vec4 posProj = vec4(x,y,z,1.0f); vec4 posView = inverse(projectioncameramatrix) * posProj; posView /= posView.w; return posView; } float LinePointDistance(in vec3 v, in vec3 w, in vec3 p) { // Return minimum distance between line segment vw and point p vec3 d = w-v; float l2 = d.x*d.x+d.y*d.y+d.z*d.z; // i.e. |w-v|^2 - avoid a sqrt if (l2 == 0.0) return distance(p, v); // v == w case //float t = max(0.0f, min(1.0f, dot(p - v, w - v) / l2)); float t = dot(p - v, w - v) / l2; vec3 projection = v + t * (w - v); // Projection falls on the segment return distance(p, projection); } float rand(vec2 co){ return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); } float depthToPosition(in float depth, in vec2 depthrange) { return depthrange.x / (depthrange.y - depth * (depthrange.y - depthrange.x)) * depthrange.y; } float positionToDepth(in float z, in vec2 depthrange) { return (depthrange.x / (z / depthrange.y) - depthrange.y) / -(depthrange.y - depthrange.x); } float ScreenSpaceShadow() { vec2 icoord = gl_FragCoord.xy / buffersize; if (isbackbuffer) icoord.y = 1.0f - icoord.y; float roughness=1.0; vec4 color; vec3 normalView; //Get position and out depth (z) float z; vec3 posView = getPosition(icoord,z).xyz; //Reflect vector vec3 reflected = -normalize(cameranormalmatrix * lightdirection); float rayLength = raylength; vec4 T = vec4(0.0f); vec3 newPos; //Raytrace for (int i = 0; i < maxstep; i++) { //newPos = posView + reflected * rayLength; newPos = posView + reflected * raylength * float(i); T = projectioncameramatrix * vec4(newPos, 1.0f); T.xy = vec2(0.5f) + 0.5f * T.xy / T.w; T.z /= T.w; if (abs(z - T.z) < 1.0f && T.x <= 1.0f && T.x >= 0.0f && T.y <= 1.0f && T.y >= 0.0f) { float depth; newPos = getPosition(T.xy,depth).xyz; rayLength = length(posView - newPos); //Check distance of this pixel to the reflection ray. If it's close enough we count it as a hit. if (LinePointDistance(posView,posView+reflected,newPos) < hitThreshold) { //Get the pixel at this normal vec4 n1=texelFetch(texture2, ivec2(T.xy*buffersize),0); vec3 normalView1 = normalize(n1.xyz * 2.0f - 1.0f); //Make sure the pixel faces the reflection vector if (dot(reflected,normalView1)<0.0f) { //Fading to screen edges vec2 fadeToScreenEdge = vec2(1.0f); fadeToScreenEdge.x *= distance(T.x , 1.0f); fadeToScreenEdge.x *= distance(T.x, 0.0f) * 4.0f; fadeToScreenEdge.y *= distance(T.y, 1.0f); fadeToScreenEdge.y *= distance(T.y, 0.0f) * 4.0f; float edgefade = 1.0 - clamp(fadeToScreenEdge.x * fadeToScreenEdge.y,0.0,1.0); float stepfade = float(i) / float(maxstep); //stepfade = clamp(stepfade,0.0,1.0); return max(edgefade,stepfade); } } } else { return 1.0f; } } return 1.0f; } float shadowLookup(in sampler2DShadow shadowmap, in vec3 shadowcoord, in vec2 offset) { if (shadowcoord.y<0.0) return 0.5; if (shadowcoord.y>1.0) return 0.5; if (shadowcoord.x<0.0) return 0.5; if (shadowcoord.x>1.0) return 0.5; float f=0.0; int x,y; vec2 sampleoffset; for (x=0; x<KERNEL; ++x) { sampleoffset.x = float(x) - KERNELF*0.5 + 0.5; for (y=0; y<KERNEL; ++y) { sampleoffset.y = float(y) - KERNELF*0.5 + 0.5; f += texture(shadowmap,vec3(shadowcoord.x+sampleoffset.x*offset.x,shadowcoord.y+sampleoffset.y*offset.y,shadowcoord.z)); } } //return f/(KERNEL*KERNEL); return f/float(KERNEL*KERNEL) * ScreenSpaceShadow(); //return ScreenSpaceShadow(); } void main(void) { vec3 flipcoord = vec3(1.0); if (!isbackbuffer) flipcoord.y = -1.0; //---------------------------------------------------------------------- //Calculate screen texcoord //---------------------------------------------------------------------- vec2 coord = gl_FragCoord.xy / buffersize; if (isbackbuffer) coord.y = 1.0 - coord.y; ivec2 icoord = ivec2(gl_FragCoord.xy); if (isbackbuffer) icoord.y = int(buffersize.y) - icoord.y; float depth; vec4 diffuse; vec3 normal; vec4 materialdata; float specularity; float ao; bool uselighting; vec4 emission; vec4 sampleoutput; vec4 stagecolor; vec3 screencoord; vec3 screennormal; float attenuation; vec4 specular; vec3 lightreflection; float fade; vec3 shadowcoord; float dist; vec3 offset; mat3 lightnormalmatrix; vec2 sampleoffset; vec3 lp; vec4 normaldata; int materialflags; fragData0 = vec4(0.0); for (int i=0; i<max(1,SAMPLES); i++) { //---------------------------------------------------------------------- //Retrieve data from gbuffer //---------------------------------------------------------------------- #if SAMPLES==0 depth = texture(texture0,coord).x; diffuse = texture(texture1,coord); normaldata = texture(texture2,coord); emission = texture(texture3,coord); #else depth = texelFetch(texture0,icoord,i).x; diffuse = texelFetch(texture1,icoord,i); normaldata = texelFetch(texture2,icoord,i); emission = texelFetch(texture3,icoord,i); #endif normal = camerainversenormalmatrix * normalize(normaldata.xyz*2.0-1.0); specularity = emission.a; materialflags = int(normaldata.a * 255.0 + 0.5); uselighting = false; if ((1 & materialflags)!=0) uselighting=true; sampleoutput = diffuse + emission; stagecolor = vec4(1.0,0.0,1.0,1.0); //Calculate gloss float gloss=70.0; if ((32 & materialflags)!=0) gloss -= 40.0; if ((64 & materialflags)!=0) gloss -= 20.0; //---------------------------------------------------------------------- //Calculate screen position and vector //---------------------------------------------------------------------- screencoord = vec3(((gl_FragCoord.x/buffersize.x)-0.5) * 2.0 * (buffersize.x/buffersize.y),((-gl_FragCoord.y/buffersize.y)+0.5) * 2.0,depthToPosition(depth,camerarange)); screencoord.x *= screencoord.z / camerazoom; screencoord.y *= -screencoord.z / camerazoom; screennormal = normalize(screencoord); if (!isbackbuffer) screencoord.y *= -1.0; if (uselighting) { //---------------------------------------------------------------------- //Calculate lighting //---------------------------------------------------------------------- attenuation = max(0.0,-dot(lightdirection,normal)); lightreflection = normalize(reflect(lightdirection,normal)); if (!isbackbuffer) lightreflection.y *= -1.0; specular = lightspecular * specularity * vec4( pow(clamp(-dot(lightreflection,screennormal),0.0,1.0),gloss) * 0.5); specular *= lightcolor.r * 0.299 + lightcolor.g * 0.587 + lightcolor.b * 0.114; #ifdef USESHADOW fade=1.0; if (attenuation>LOWERLIGHTTHRESHHOLD) { //---------------------------------------------------------------------- //Shadow lookup //---------------------------------------------------------------------- dist = clamp(length(screencoord)/shadowstagerange[0],0.0,1.0); offset = vec3(0.0); //vec3 lightposition; lightnormalmatrix = mat3(0); sampleoffset = shadowstagepositon[0]; fade=1.0; lp = vec3(0); if (dist<1.0) { //offset.x = 0.0; offset.z = -lightshadowmapoffset[0].x; lp = lightposition[0]; lightnormalmatrix = lightnormalmatrix0; fade=0.0; stagecolor=vec4(1.0,0.0,0.0,1.0); } else { //fade=0.0; dist = clamp(length(screencoord)/shadowstagerange[1],0.0,1.0); if (dist<1.0) { //offset.x = 1.0; offset.z = -lightshadowmapoffset[1].x; lp = lightposition[1]; lightnormalmatrix = lightnormalmatrix1; fade=0.0; sampleoffset = shadowstagepositon[1]; stagecolor=vec4(0.0,1.0,0.0,1.0); #if SHADOWSTAGES==2 fade = clamp((dist-0.75)/0.25,0.0,1.0);// gradually fade out the last shadow stage #endif } #if SHADOWSTAGES>2 else { dist = clamp(length(screencoord)/shadowstagerange[2],0.0,1.0); if (dist<1.0) { //offset.x = 2.0; offset.z = -lightshadowmapoffset[2].x; lp = lightposition[2]; lightnormalmatrix = lightnormalmatrix2; stagecolor=vec4(0.0,0.0,1.0,1.0); fade=0.0; sampleoffset = shadowstagepositon[2]; #if SHADOWSTAGES==3 fade = clamp((dist-0.75)/0.25,0.0,1.0);// gradually fade out the last shadow stage #endif } #if SHADOWSTAGES==4 else { dist = clamp(length(screencoord)/shadowstagerange[3],0.0,1.0); if (dist<1.0) { stagecolor=vec4(0.0,1.0,1.0,1.0); //offset.x = 3.0; offset.z = -lightshadowmapoffset[3].x; lp = lightposition[3]; lightnormalmatrix = lightnormalmatrix3; fade = clamp((dist-0.75)/0.25,0.0,1.0);// gradually fade out the last shadow stage sampleoffset = shadowstagepositon[3]; } else { fade = 1.0; } } #endif } #endif } if (fade<1.0) { shadowcoord = lightnormalmatrix * (screencoord - lp); shadowcoord += offset; shadowcoord.z = (shadowcoord.z - lightrange.x) / (lightrange.y-lightrange.x); shadowcoord.xy += 0.5; shadowcoord.xy *= shadowstagescale; shadowcoord.xy += sampleoffset; attenuation = attenuation * fade + attenuation * shadowLookup(texture5,shadowcoord,1.0/shadowmapsize) * (1.0-fade); } } #endif //---------------------------------------------------------------------- //Final light calculation //---------------------------------------------------------------------- sampleoutput = (diffuse * lightcolor + specular) * attenuation + emission + diffuse * ambientlight; //sampleoutput = (sampleoutput + stagecolor) / 2.0; } //Blend with red if selected if ((2 & materialflags)!=0) { sampleoutput = (sampleoutput + vec4(1.0,0.0,0.0,0.0))/2.0; } fragData0 += sampleoutput * 1.0; } fragData0 /= float(max(1,SAMPLES)); fragData0 = max(fragData0,0.0); gl_FragDepth = depth; } Without: With: 3 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
shadmar Posted November 27, 2016 Share Posted November 27, 2016 How do you load this? Nvm just replace the DL shader. Quote HP Omen - 16GB - i7 - Nvidia GTX 1060 6GB Link to comment Share on other sites More sharing options...
Einlander Posted November 28, 2016 Share Posted November 28, 2016 How much more expensive is this shader renderwise? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.