Jump to content
  • Advertisement
skyemaidstone

3D Stable Cascaded Shadow Maps - Sphere Based Bounding Help

Recommended Posts

Hiya again guys,

I have a niggling problem with my CSM. The middle an far cascades noticeably "swim" as you move around. It's not really noticeable on the close one but i'm that's probably just due to the filtering and the factor it has such a high quality map to work from.

Anyway I have 3 cascades and i'm using a bounding box for each. They all overlap with they near clip and this works fairly nicely but I was looking at the csm sample that some nicely ported over to monogame. The problem is I can't get the sphere based bounding boxes working at all for me. My debug rendertargets for all the cascades are just blank. If I switch my camera to be the shadow light camera (the sun) it seems fine (and it works using my bounding box method so i think that's fine). I THINK i'm just calculating the bounding box (using a sphere) incorrectly some how.

Could someone help me make this method use sphere's instead please:

public void GenerateCSMOrthoSlice(float pfarClip)
        {
            Vector3[] frustumCornersWS = new Vector3[8];
            Vector3[] frustumCornersLS = new Vector3[8];
            BoundingFrustum viewFrustum = new BoundingFrustum(_Camera.CameraView * Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, _Camera._aspectRatio, 10, pfarClip));
            frustumCornersWS = viewFrustum.GetCorners();


            Vector3 frustumCentroid = new Vector3(0, 0, 0);
            for (int i = 0; i < 8; i++)
                frustumCentroid += frustumCornersWS;
            frustumCentroid /= 8;

            lightsView = Matrix.Identity;
            lightsViewProjectionMatrix = Matrix.Identity;

            ShadowLightPos = frustumCentroid + (SunlightDirection * 100);

            ShadowLookAt = frustumCentroid;

            ShadowLightView = Matrix.CreateLookAt(ShadowLightPos, ShadowLookAt, new Vector3(0, 1, 0));

            Vector3.Transform(frustumCornersWS, ref ShadowLightView, frustumCornersLS);

            Vector3 mins = frustumCornersLS[0];
            Vector3 maxes = frustumCornersLS[0];
            for (int i = 0; i < 8; i++)
            {
                if (frustumCornersLS.X > maxes.X)
                    maxes.X = frustumCornersLS.X;
                else if (frustumCornersLS.X < mins.X)
                    mins.X = frustumCornersLS.X;
                if (frustumCornersLS.Y > maxes.Y)
                    maxes.Y = frustumCornersLS.Y;
                else if (frustumCornersLS.Y < mins.Y)
                    mins.Y = frustumCornersLS.Y;
                if (frustumCornersLS.Z > maxes.Z)
                    maxes.Z = frustumCornersLS.Z;
                else if (frustumCornersLS.Z < mins.Z)
                    mins.Z = frustumCornersLS.Z;
            }

            float diagonalLength = (frustumCornersWS[0] - frustumCornersWS[6]).Length();
            diagonalLength += 2;    //Without this, the shadow map isn't big enough in the world.
            float worldsUnitsPerTexel = diagonalLength / (float)4096;

            Vector3 vBorderOffset = (new Vector3(diagonalLength, diagonalLength, diagonalLength) - (maxes - mins)) * 0.5f;
            maxes += vBorderOffset;
            mins -= vBorderOffset;

            mins /= worldsUnitsPerTexel;
            mins.X = (float)Math.Floor(mins.X);
            mins.Y = (float)Math.Floor(mins.Y);
            mins.Z = (float)Math.Floor(mins.Z);
            mins *= worldsUnitsPerTexel;

            maxes /= worldsUnitsPerTexel;
            maxes.X = (float)Math.Floor(maxes.X);
            maxes.Y = (float)Math.Floor(maxes.Y);
            maxes.Z = (float)Math.Floor(maxes.Z);
            maxes *= worldsUnitsPerTexel;

            ShadowLightProjection = Matrix.CreateOrthographicOffCenter(mins.X, maxes.X, mins.Y, maxes.Y, -maxes.Z - 500f, -mins.Z);
            lightsView = Matrix.CreateLookAt(ShadowLightPos, ShadowLookAt, new Vector3(0, 1, 0));
            lightsViewProjectionMatrix = lightsView * ShadowLightProjection;
        }

What I tried (which doesn't work at all) is:

public void GenerateCSMOrthoSlice(float pfarClip)
        {

            bool StabilizeCascades = true;
            Vector3 minExtents = Vector3.Zero;
            Vector3 maxExtents = Vector3.Zero;
            Vector3[] frustumCornersWS = new Vector3[8];
            Vector3[] frustumCornersLS = new Vector3[8];
            BoundingFrustum viewFrustum = new BoundingFrustum(_Camera.CameraView * Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, _Camera._aspectRatio, 10, pfarClip));
            frustumCornersWS = viewFrustum.GetCorners();


            Vector3 frustumCentroid = new Vector3(0, 0, 0);
            for (int i = 0; i < 8; i++)
                frustumCentroid += frustumCornersWS;
            frustumCentroid /= 8;



            // sphere based  cascade
            if (StabilizeCascades)
            {
            
            // This needs to be constant for it to be stable
            var upDir = Vector3.Up;

            // Calculate the radius of a bounding sphere surrounding the frustum corners
            var sphereRadius = 0.0f;
            for (var i = 0; i < 8; ++i)
            {
                var dist = (_frustumCorners - frustumCentroid).Length();
                sphereRadius = Math.Max(sphereRadius, dist);
            }

            sphereRadius = (float)Math.Ceiling(sphereRadius * 16.0f) / 16.0f;

            maxExtents = new Vector3(sphereRadius);
            minExtents = -maxExtents;
            }



            lightsView = Matrix.Identity;
            lightsViewProjectionMatrix = Matrix.Identity;

            //Vector3 sunlightdirection = new Vector3(0.21f, 0.11f, -0.5f);
            ShadowLightPos = frustumCentroid + (SunlightDirection * 100);


            //ShadowLookAt = _SLLookAt;
            ShadowLookAt = frustumCentroid;

            ShadowLightView = Matrix.CreateLookAt(ShadowLightPos, ShadowLookAt, new Vector3(0, 1, 0));

            Vector3.Transform(frustumCornersWS, ref ShadowLightView, frustumCornersLS);

            Vector3 mins = frustumCornersLS[0];
            Vector3 maxes = frustumCornersLS[0];
            for (int i = 0; i < 8; i++)
            {
                if (frustumCornersLS.X > maxes.X)
                    maxes.X = frustumCornersLS.X;
                else if (frustumCornersLS.X < mins.X)
                    mins.X = frustumCornersLS.X;
                if (frustumCornersLS.Y > maxes.Y)
                    maxes.Y = frustumCornersLS.Y;
                else if (frustumCornersLS.Y < mins.Y)
                    mins.Y = frustumCornersLS.Y;
                if (frustumCornersLS.Z > maxes.Z)
                    maxes.Z = frustumCornersLS.Z;
                else if (frustumCornersLS.Z < mins.Z)
                    mins.Z = frustumCornersLS.Z;
            }



            float diagonalLength = (frustumCornersWS[0] - frustumCornersWS[6]).Length();
            diagonalLength += 2;    //Without this, the shadow map isn't big enough in the world.
            float worldsUnitsPerTexel = diagonalLength / (float)4096;

            Vector3 vBorderOffset = (new Vector3(diagonalLength, diagonalLength, diagonalLength) - (maxes - mins)) * 0.5f;
            maxes += vBorderOffset;
            mins -= vBorderOffset;

            mins /= worldsUnitsPerTexel;
            mins.X = (float)Math.Floor(mins.X);
            mins.Y = (float)Math.Floor(mins.Y);
            mins.Z = (float)Math.Floor(mins.Z);
            mins *= worldsUnitsPerTexel;

            maxes /= worldsUnitsPerTexel;
            maxes.X = (float)Math.Floor(maxes.X);
            maxes.Y = (float)Math.Floor(maxes.Y);
            maxes.Z = (float)Math.Floor(maxes.Z);
            maxes *= worldsUnitsPerTexel;

            lightsView = Matrix.CreateLookAt(ShadowLightPos, ShadowLookAt, new Vector3(0, 1, 0));
            lightsViewProjectionMatrix = lightsView * ShadowLightProjection;
            ShadowLightProjection = Matrix.CreateOrthographicOffCenter(mins.X, maxes.X, mins.Y, maxes.Y, -maxes.Z - 500f, -mins.Z);

            if (StabilizeCascades)
            {
                ShadowLightProjection = Matrix.CreateOrthographicOffCenter(minExtents.X, minExtents.Y, maxExtents.X, maxExtents.Y, 0.0f, pfarClip);


                // Create the rounding matrix, by projecting the world-space origin and determining
                // the fractional offset in texel space
                var shadowMatrixTemp = lightsViewProjectionMatrix;
                var shadowOrigin = new Vector4(0.0f, 0.0f, 0.0f, 1.0f);
                shadowOrigin = Vector4.Transform(shadowOrigin, shadowMatrixTemp);
                shadowOrigin = shadowOrigin * (4096 / 2.0f);

                var roundedOrigin = Round(shadowOrigin);
                var roundOffset = roundedOrigin - shadowOrigin;
                roundOffset = roundOffset * (2.0f / 4096);
                roundOffset.Z = 0.0f;
                roundOffset.W = 0.0f;

                ShadowLightProjection.M41 += roundOffset.X;
                ShadowLightProjection.M42 += roundOffset.Y;
                ShadowLightProjection.M43 += roundOffset.Z;
                ShadowLightProjection.M44 += roundOffset.W;
            }

            //
            //lightsView = Matrix.CreateLookAt(ShadowLightPos, ShadowLookAt, new Vector3(0, 1, 0));
            //lightsViewProjectionMatrix = lightsView * ShadowLightProjection;
        }

 

Share this post


Link to post
Share on other sites
Advertisement

I'm no MonoGame expert, but looking at your code it looks like you mixed up the parameters to Matrix.CreateOrthographicOffCenter() in the stabilized version. 

Share this post


Link to post
Share on other sites

Thanks, yes. Well spotted. Unfortunately that had no effect. 

Shimmery shadows have been bugging me for ages but I can't seem to figure out how to use the sphere method of making my cascades

Share this post


Link to post
Share on other sites

If anyone could give  me some code/pseudo code for finding the bounding sphere of my shadow camera that would do. I was reading shaderx7 on this subject. Which was interedting but the math is over my head. I don't mind the wasted space. By the time my game is finished games will be able to support one giant texture lol

Thanks

Share this post


Link to post
Share on other sites

Here is my code that is used in production (So I know it works ;-) )

 

	V4 vMin = vCorners[0];
	V4 vMax = vCorners[0];
	for(int j = 1; j<8; j++) {
		vMin = VMin(vMin, vCorners[j]);
		vMax = VMax(vMax, vCorners[j]);
	}
	V4 vSize = vMax - vMin;
	float fRadius = VLen3(vSize).x() * 0.5f;
	mShadowProj = MOrthoRH(-fRadius, fRadius, -fRadius, fRadius, -fMaxZ, -fMinZ);

	// Snap center to shadow texel
	// This is done by transforming center of CSM frustum into light post projection (texel space) and
	// perform snapping in this space.
	M44 mCameraToLight = MInverseAffine(mLightToCamera);
	V4 vCenterCamera = VLerp(vMin, vMax, VSplat(0.5f));
	V4 vCenterLight = VTransform43(mCameraToLight, vCenterCamera);
	V4 vCenterTexel = VTransform44(mShadowProj, vCenterLight);
	vCenterTexel = VProject(vCenterTexel);
	uint32 nCascadeSize = descShadowCSM.nWidth >> 1;
	float fShadowSize = nCascadeSize * 0.25f;
	V4 vShadowSize = VSplat(fShadowSize);
	V4 vShadowSizeInv = VSplat(1.0f / fShadowSize);
	V4 vSnap = VMul(vCenterTexel, vShadowSize);
	vSnap = VFloor(vSnap);
	vSnap = VMul(vSnap, vShadowSizeInv);
	V4 vSnapOffset = VLoadZero() - vSnap;
	M44 mSnapTrans = MLoadIdentity();
	mSnapTrans.vTrans = VXY01(vSnapOffset);
	mShadowProj = mSnapTrans * mShadowProj;
     

 

Hope it makes sense.

BTW: Looking at your code I think the issue is the way you apply the offset directly to the matrix instead of doing a multiplication with a translation matrix (Like I do in the last line)

Henning

Oh, and I now use the quantization trick instead of the code above to get more precision (http://dev.theomader.com/stable-csm/)

Edited by semler
Added comment

Share this post


Link to post
Share on other sites

This ia  video of the problem. I'm not if i'm barking up the wrong tree. But shadows are very "jiggly" on some objects. I wanted to try the sphere based approach. Which from my understanding is making a bounding sphere from the shadow camera view frustrum then creating my usual orthographic projection for my cascade from that. Am I undestanding it correctly?

Here's a video of the annoying problem I have. Shortly into the video i turn on the rendertarget display so you can see the 3 cascade render targets on the right. As you can see theres a lot of jiggle going on. Depth Bias doesn't seem to make any difference really.

 

 

 

Share this post


Link to post
Share on other sites

I'm a complete noob here but i see that you rotate your shadow maps with camera orientation and this way it's impossible to avoid jittering. I think you have to keep the shadow map orientation constant in worldspace and only adapt it to the position of the camera ignoring player view direction. So when you rotate but don't move, you would see the corners of cascade transitions fixed to the floor.  Does this make sense?

Share this post


Link to post
Share on other sites

I think you're probably correct/ That's what I was referring to with using a sphere from the camera frustrum to build the bounding box for my orthographic projection for the shadow like.

I think i'm missing something though. I've found some examples here and there but I'm just not getting it. Maybe some pseudo code would help me.

Edited by skyemaidstone

Share this post


Link to post
Share on other sites

Semlers linked blog contains more articles and code, however...

Looking at code snippets often raises more questions than answers: What conventions are used here (is this a camera to world matrix or world to camera? what multiplication order do they use? etc. etc.) - mostly you have to care for the deatils yourself and after you undrestood the concept it's only the details that's left.

I recommend you simplyfy the problem instead so cou can solve it more easily in your own:

1. Ignore frustum and any bounds and make each cascade just centered to the texel closest to the camera. (visualizing texel grid on a simple ground plane should help to set this up. And if this works all math is known.)

2. If you get this to work robustly so the cascades move with the camera without jitter the main problem is solved and you can start to optimize it for the frustum, which shouldn't be that hard at this point.

 

 

 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
  • Advertisement
  • Popular Tags

  • Similar Content

    • By cozzie
      Hi guys,
      I've been struggling to create a function to draw an arrow with 2 lines making up the arrowhead.
      The challenge is that I somehow can't get the rotation right.
      I've pasted the code below and an image of the result.
      Findings so far, when I replace the 3x3 part of the transform matrix to identity, I get the same visual result.
      Also when I switch colums A and C in the matrix, this specific arrow looks good (with is pointing in the positive X direction).
      Any input would be appreciated.
      bool CDebugDraw::AddArrow(const CR_VECTOR3 &pPos1, const CR_VECTOR3 &pPos2, const CR_VECTOR3 &pColor, const bool pDepthEnabled, const bool pPersistent, const uint64_t pLifeTime) { if(!AddLine(pPos1, pPos2, pColor, pDepthEnabled, pPersistent, pLifeTime)) return false; /* p1 ------- X / | \ | / | \ | / | \ | p2 -----|-----p3 | Z | | | | p0 */ CR_VECTOR3 arrowDir = pPos2 - pPos1; arrowDir.Normalize(); // model space CR_VECTOR3 p1 = CR_VECTOR3(0.0f, 0.0f, 0.0f); CR_VECTOR3 p2 = CR_VECTOR3(0.2f, 0.0f, -0.2f); CR_VECTOR3 p3 = CR_VECTOR3(-0.2f, 0.0f, -0.2f); // transformation: translate and rotate CR_VECTOR3 transl = pPos2; CR_VECTOR3 colA = arrowDir; CR_VECTOR3 tVec; if(colA.x != 0 && colA.z != 0) tVec = CR_VECTOR3(0.0f, 1.0f, 0.0); else tVec = CR_VECTOR3(0.0f, 0.0f, 1.0f); CR_VECTOR3 colB = CMathHelper::CrossVec3(colA, tVec); CR_VECTOR3 colC = CMathHelper::CrossVec3(colB, colA); CR_MATRIX4X4 transform; transform.m11 = colA.x; transform.m12 = colB.x; transform.m13 = colC.x; transform.m14 = 0.0f; transform.m21 = colA.y; transform.m22 = colB.y; transform.m23 = colC.y; transform.m24 = 0.0f; transform.m31 = colA.z; transform.m32 = colB.z; transform.m33 = colC.z; transform.m34 = 0.0f; transform.m41 = transl.x; transform.m42 = transl.y; transform.m43 = transl.z; transform.m44 = 1.0f; // transform = CMathHelper::ComposeWorldMatrix(transform, CR_VECTOR3(1.0f), CR_VECTOR3(0.0f, 90.0f, 0.0f), pPos2); // transform to worldspace p1 = CMathHelper::TransformVec3Coord(p1, transform); p2 = CMathHelper::TransformVec3Coord(p2, transform); p3 = CMathHelper::TransformVec3Coord(p3, transform); if(!AddLine(p1, p2, CR_VECTOR3(1.0f, 0.0f, 0.0f), pDepthEnabled, pPersistent, pLifeTime)) return false; if(!AddLine(p1, p3, CR_VECTOR3(1.0f, 0.0f, 0.0f), pDepthEnabled, pPersistent, pLifeTime)) return false; if(!AddCross(p2, 0.02f, CR_VECTOR3(0.0f, 0.0f, 1.0f), pDepthEnabled, pPersistent, pLifeTime)) return false; if(!AddCross(p3, 0.02f, CR_VECTOR3(0.0f, 0.0f, 1.0f), pDepthEnabled, pPersistent, pLifeTime)) return false; return true; } Incorrect result:

      Aimed/ correct result (independent of arrow direction):

    • By NanaMarfo
      Hello Everyone!
      I am looking for a small team to do a rendering project with me. The roles I need are:
      -Character Modeller
      -Environment Designer
      -Environment Modeller(Found)
      You can use this in your portfolio and you will be credited at the end.
      If you are interested, please email me at marfo343@gmail.com. Thank you!
    • By D34DPOOL
      Edit Your Profile D34DPOOL 0 Threads 0 Updates 0 Messages Network Mod DB GameFront Sign Out Add jobEdit jobDeleteC# Programmer for a Unity FPS at Anywhere   Programmers located Anywhere.
      Posted by D34DPOOL on May 20th, 2018
      Hello, my name is Mason, and I've been working on a Quake style arena shooter about destroying boxes on and off for about a year now. I have a proof of concept with all of the basic features, but as an artist with little programming skill I've reached the end of my abilities as a programmer haha. I need someone to help fix bugs, optomize code, and to implent new features into the game. As a programmer you will have creative freedom to suggest new features and modes to add into the game if you choose to, I'm usually very open to suggestions :).
      What is required:
      Skill using C#
      Experience with Unity
      Experience using UNET (since it is a multiplayer game), or the effort and ability to learn it
      Compensation:
      Since the game currently has no funding, we can split whatever revenue the game makes in the future. However if you would perfer I can create 2D and/or 3D assets for whatever you need in return for your time and work.
      It's a very open and chill enviornment, where you'll have relative creative freedom. I hope you are interested in joining the team, and have a good day!
       
      To apply email me at mangemason@yahoo.com
    • By Andrew Parkes
      I am a talented 2D/3D artist with 3 years animation working experience and a Degree in Illustration and Animation. I have won a world-wide art competition hosted by SFX magazine and am looking to develop a survival game. I have some knowledge of C sharp and have notes for a survival based game with flexible storyline and PVP. Looking for developers to team up with. I can create models, animations and artwork and I have beginner knowledge of C sharp with Unity. The idea is Inventory menu based gameplay and is inspired by games like DAYZ.
      Here is some early sci-fi concept art to give you an idea of the work level. Hope to work with like minded people and create something special. email me andrewparkesanim@gmail.com.
      Developers who share the same passion please contact me, or if you have a similar project and want me to join your team email me. 
      Many thanks, Andrew.

    • By thecheeselover
      I made this post on Reddit. I need ideas and information on how to create the ground mesh for my specifications.
    • By Canadian Map Makers
      GOVERNOR is a modernized version of the highly popular series of “Caesar” games. Our small team has already developed maps, written specifications, acquired music and performed the historical research needed to create a good base for the programming part of the project.

      Our ultimate goal is to create a world class multi-level strategic city building game, but to start with we would like to create some of the simpler modules to demonstrate proof of concept and graphical elegance.

       

      We would like programmers and graphical artists to come onboard to (initially) create:

      A module where Province wide infrastructure can be built on an interactive 3D map of one of the ancient Roman Provinces.
      A module where city infrastructure can be built on a real 3D interactive landscape.
      For both parts, geographically and historically accurate base maps will be prepared by our team cartographer. Graphics development will be using Blender. The game engine will be Unity.

       

      More information, and examples of the work carried out so far can be found at http://playgovernor.com/ (most of the interesting content is under the Encyclopedia tab).

       

      This project represents a good opportunity for upcoming programmers and 3D modeling artists to develop something for their portfolios in a relatively short time span, working closely with one of Canada’s leading cartographers. There is also the possibility of being involved in this project to the point of a finished game and commercial success! Above all, this is a fun project to work on.

       

      Best regards,

      Steve Chapman (Canadian Map Makers)

       
    • By RobMaddison
      Hi
      I’ve been working on a game engine for years and I’ve recently come back to it after a couple of years break.  Because my engine uses DirectX9.0c I thought maybe it would be a good idea to upgrade it to DX11. I then installed Windows 10 and starting tinkering around with the engine trying to refamiliarise myself with all the code.
      It all seems to work ok in the new OS but there’s something I’ve noticed that has caused a massive slowdown in frame rate. My engine has a relatively sophisticated terrain system which includes the ability to paint roads onto it, ala CryEngine. The roads are spline curves and built up with polygons matching the terrain surface. It used to work perfectly but I’ve noticed that when I’m dynamically adding the roads, which involves moving the spline curve control points around the surface of the terrain, the frame rate comes to a grinding halt.
      There’s some relatively complex processing going on each time the mouse moves - the road either side of the control point(s) being moved, is reconstructed in real time so you can position and bend the road precisely. On my previous OS, which was Win2k Pro, this worked really smoothly and in release mode there was barely any slow down in frame rate, but now it’s unusable. As part of the road reconstruction, I lock the vertex and index buffers and refill them with the new values so my question is, on windows 10 using DX9, is anyone aware of any locking issues? I’m aware that there can be contention when locking buffers dynamically but I’m locking with LOCK_DISCARD and this has never been an issue before.
      Any help would be greatly appreciated.
    • By MikhailGorobets
      I have a problem with SSAO. On left hand black area.
      Code shader:
      Texture2D<uint> texGBufferNormal : register(t0); Texture2D<float> texGBufferDepth : register(t1); Texture2D<float4> texSSAONoise : register(t2); float3 GetUV(float3 position) { float4 vp = mul(float4(position, 1.0), ViewProject); vp.xy = float2(0.5, 0.5) + float2(0.5, -0.5) * vp.xy / vp.w; return float3(vp.xy, vp.z / vp.w); } float3 GetNormal(in Texture2D<uint> texNormal, in int3 coord) { return normalize(2.0 * UnpackNormalSphermap(texNormal.Load(coord)) - 1.0); } float3 GetPosition(in Texture2D<float> texDepth, in int3 coord) { float4 position = 1.0; float2 size; texDepth.GetDimensions(size.x, size.y); position.x = 2.0 * (coord.x / size.x) - 1.0; position.y = -(2.0 * (coord.y / size.y) - 1.0); position.z = texDepth.Load(coord); position = mul(position, ViewProjectInverse); position /= position.w; return position.xyz; } float3 GetPosition(in float2 coord, float depth) { float4 position = 1.0; position.x = 2.0 * coord.x - 1.0; position.y = -(2.0 * coord.y - 1.0); position.z = depth; position = mul(position, ViewProjectInverse); position /= position.w; return position.xyz; } float DepthInvSqrt(float nonLinearDepth) { return 1 / sqrt(1.0 - nonLinearDepth); } float GetDepth(in Texture2D<float> texDepth, float2 uv) { return texGBufferDepth.Sample(samplerPoint, uv); } float GetDepth(in Texture2D<float> texDepth, int3 screenPos) { return texGBufferDepth.Load(screenPos); } float CalculateOcclusion(in float3 position, in float3 direction, in float radius, in float pixelDepth) { float3 uv = GetUV(position + radius * direction); float d1 = DepthInvSqrt(GetDepth(texGBufferDepth, uv.xy)); float d2 = DepthInvSqrt(uv.z); return step(d1 - d2, 0) * min(1.0, radius / abs(d2 - pixelDepth)); } float GetRNDTexFactor(float2 texSize) { float width; float height; texGBufferDepth.GetDimensions(width, height); return float2(width, height) / texSize; } float main(FullScreenPSIn input) : SV_TARGET0 { int3 screenPos = int3(input.Position.xy, 0); float depth = DepthInvSqrt(GetDepth(texGBufferDepth, screenPos)); float3 normal = GetNormal(texGBufferNormal, screenPos); float3 position = GetPosition(texGBufferDepth, screenPos) + normal * SSAO_NORMAL_BIAS; float3 random = normalize(2.0 * texSSAONoise.Sample(samplerNoise, input.Texcoord * GetRNDTexFactor(SSAO_RND_TEX_SIZE)).rgb - 1.0); float SSAO = 0; [unroll] for (int index = 0; index < SSAO_KERNEL_SIZE; index++) { float3 dir = reflect(SamplesKernel[index].xyz, random); SSAO += CalculateOcclusion(position, dir * sign(dot(dir, normal)), SSAO_RADIUS, depth); } return 1.0 - SSAO / SSAO_KERNEL_SIZE; }  



    • By Ike aka Dk
      Hello everyone 
      I am a programmer from Baku.
      I need a 3D Modeller for my shooter project in unity.I have 2 years Unity exp.
      Project will paid when we finish the work 
      If you interested write me on email:
      mr.danilo911@gmail.com
    • By MarcusAseth
      Hi guys, I'm trying to learn this stuff but running into some problems 😕
      I've compiled my .hlsl into a header file which contains the global variable with the precompiled shader data:
      //... // Approximately 83 instruction slots used #endif const BYTE g_vs[] = { 68, 88, 66, 67, 143, 82, 13, 236, 152, 133, 219, 113, 173, 135, 18, 87, 122, 208, 124, 76, 1, 0, 0, 0, 16, 76, 0, 0, 6, 0, //.... And now following the "Compiling at build time to header files" example at this msdn link , I've included the header files in my main.cpp and I'm trying to create the vertex shader like this:
      hr = g_d3dDevice->CreateVertexShader(g_vs, sizeof(g_vs), nullptr, &g_d3dVertexShader); if (FAILED(hr)) { return -1; } and this is failing, entering the if and returing -1.
      Can someone point out what I'm doing wrong? 😕 
  • Advertisement
  • Popular Now

  • Forum Statistics

    • Total Topics
      631399
    • Total Posts
      2999854
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!