SpiderPig Posted January 27 Share Posted January 27 Second go at this. Not as hard as it looks to get something basic going. I think the majority of the work will be performance improvements and making the shadows look nicer. It's "semi" real-time now. Still on the CPU but on another thread who's sole purpose is to calculate the shadow map until the program quits. Takes about 500 or so milliseconds to calculate the shadow map, hence the jitter as the sun get's higher. I think I can improve the ray casting speed but I want to focus on smoothing out those shadows. I'm wondering if signed distance fields can help... maybe by storing each pixels distance to the nearest shadow I can calculate the fragments distance and blend accordingly. Works in my head anyway. I think I'll sleep on it. Quote Link to comment Share on other sites More sharing options...
Josh Posted January 27 Share Posted January 27 Wow, that is fast enough that it could be real-time. You said it takes 500 milliseconds, so if you used four threads that would go down to 125 msecs. But the whole things doesn't have to be updated all at once. You could easily cycle through and just do a limited number each frame, and a slow-moving light would look the same. Without threading, at 60 FPS it would take 30 frames to get through the entire job, so the whole thing would update twice each second. If you use Collider::Pick instead of the world raycast function, that will get rid of a lot of overhead and should be thread-safe. 1 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...
SpiderPig Posted January 27 Author Share Posted January 27 My thoughts exactly. A slow light would only need updating every second or so. It's only a 512x512 terrain. The slowest part is when the whole terrain is in light because then every ray cast dosnt hit somthing so is very long. I allready stop the ray when it leaves the AABB of the terrain. I also want to blend in the default shadow system when up close. That should look real good. Will have to match the shadow color. Are the shadows in Ultra just multiplied over the final frag color? Quote Link to comment Share on other sites More sharing options...
SpiderPig Posted January 27 Author Share Posted January 27 Got it down to 150 to 300ms by removing lots of sqrts(). Quote Link to comment Share on other sites More sharing options...
Josh Posted January 27 Share Posted January 27 1 hour ago, SpiderPig said: Are the shadows in Ultra just multiplied over the final frag color? The lighting calculation is a bit complex in Ultra, so the shadow is checked first and if the pixel is in the shadow, that light is skipped. 1 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...
SpiderPig Posted January 27 Author Share Posted January 27 I was trying something similar in the frag shader. I just didn't call RenderLighting if the fragment was in shadow but I thought the results were too dark. (the gif above) if(enable_lighting == true) { RenderLighting(material, materialInfo, vertexWorldPosition.xyz, n, v, NdotV, f_diffuse, f_specular, renderprobes, ibldiffuse, iblspecular); } Can I simply disable lighting like this to see the shadow or is this not the best approach? Quote Link to comment Share on other sites More sharing options...
SpiderPig Posted January 27 Author Share Posted January 27 Faster and shadows are just multiplied by the final frag color. Much faster. Also not using texelfetch anymore which smoothed the shadows a bit but still needs more work. 1 Quote Link to comment Share on other sites More sharing options...
SpiderPig Posted March 10 Author Share Posted March 10 This iteration is a bit slower but looks a lot nicer. The shadows are just multiplied by the final color so fragments within the shadow are still having light calculated on them. @Josh Can I make a bool variable in the fragment shader to simply not calculate lighting for certain pixels? Something like this perhaps? EDIT : There's a RENDERFLAGS_NO_LIGHTING right there.... I might play with that if(canDoLighting == true) { if ((RenderFlags & RENDERFLAGS_NO_LIGHTING) == 0) { RenderLighting(material, materialInfo, vertexWorldPosition.xyz, n, v, NdotV, f_diffuse, f_specular, renderprobes, ibldiffuse, iblspecular); if (!renderprobes) { ibldiffuse = vec4(0.0f); iblspecular = vec4(0.0f); f_specular = vec3(0.0);// we don't want specular reflection in probe renders since it is view-dependent } } else { renderprobes = false; f_diffuse.rgb = materialInfo.c_diff * AmbientLight; f_specular = vec3(0.0f);// we don't want specular reflection in probe renders since it is view-dependent } } Quote Link to comment Share on other sites More sharing options...
SpiderPig Posted March 10 Author Share Posted March 10 Did this and it seems to work nice. if (enable_lighting == true && (RenderFlags & RENDERFLAGS_NO_LIGHTING) == 0) Only issue left to solve are the edges of the shadows are very harsh. If I can use a single bit as a Boolean to disable lighting I may also be able to use a few bits to determine the distance from the light source so that I can soften the edges. Quote Link to comment Share on other sites More sharing options...
SpiderPig Posted March 10 Author Share Posted March 10 Got it back down to about 200ms by increasing ray step size based on how high the ray is above the terrain at that time. I have another idea that could decrease the amount of rays that actually need casting by up to 50%. 2 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.