skyemaidstone

Members
  • Content count

    27
  • Joined

  • Last visited

Community Reputation

160 Neutral

About skyemaidstone

  • Rank
    Member

Personal Information

  • Interests
    Programming
  1. 3D Converting my DX9 HLSL to DX10/11

    So essentially what i'm doing is correct with SampleCmpLevelZero is it? It compares whatever is at that texture coordinate with the float I pass in parameter 3 (using whatever samplercomparisionstate is have set)? Or have I misunderstood something else?
  2. Just a quick one (hopefully). I'm trying to use hardward PCF that's apparently built in later than dx9 so I'm updating some old shaders. I was using: distanceStoredInDepthMap = tex2D(ShadowMapSamplerHQ, lightSamplePos); shadowCondition = distanceStoredInDepthMap <= (realDistanceToLight); float lit = float(ShadowMapHQ.SampleCmpLevelZero(cmpSampler, lightSamplePos, realDistanceToLight)); distanceStoredInDepthMap = tex2D(ShadowMapSamplerHQ, lightSamplePos); shadowCondition = distanceStoredInDepthMap <= (realDistanceToLight); I'm trying update it to use the comparison method on the Texture2D object; float lit = float(ShadowMapHQ.SampleCmpLevelZero(cmpSampler, lightSamplePos, realDistanceToLight)); But it's just returning 0. I've just left SamplerComparisonState as defaults. Sorry if this is a dumb question.
  3. Ok I came back to this after working on more interesting parts of my game and although I've improved it by using a sphere based approach to making the projections it hasn't really improved the shimmering that much. In fact if i comment out my texel snapping part it makes little difference. I'm getting a bit stumped. Maybe I've been looking at it too long. It's acceptable now I guess but i'd like it to be totally rock solid ideally This creates the projection and view for each cascade. Any ideas what i've missed? public void GenerateCSMOrthoSliceTS(float pNearClip, float pfarClip) { Vector3[] frustumCorners = new Vector3[8]; Matrix mCameraViewProj = _Camera.CameraView; mCameraViewProj *= Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, _Camera._aspectRatio, pNearClip, pfarClip); BoundingFrustum oCameraViewProjFrustum = new BoundingFrustum(mCameraViewProj); frustumCorners = oCameraViewProjFrustum.GetCorners(); Vector3 frustumCenter = new Vector3(0, 0, 0); for (int i = 0; i < 8; i++) frustumCenter += frustumCorners[i]; frustumCenter /= 8; lightsView = Matrix.Identity; lightsViewProjectionMatrix = Matrix.Identity; float radius = (frustumCorners[0] - frustumCorners[6]).Length() / 2.0f; float texelsPerUnit = (float)4096 / (radius * 2.0f); Matrix mTexelScaling = Matrix.CreateScale(texelsPerUnit); SunlightDirection.Normalize(); Vector3 baselookAt = new Vector3(SunlightDirection.X, SunlightDirection.Y, SunlightDirection.Z); Matrix mLookAt = Matrix.CreateLookAt(Vector3.Zero, baselookAt, Vector3.Up); mLookAt = Matrix.Multiply(mTexelScaling, mLookAt); Matrix mLookAtInv = Matrix.Invert(mLookAt); frustumCenter = Vector3.Transform(frustumCenter, mLookAt); frustumCenter.X = (float)Math.Floor(frustumCenter.X); //clamp to texel increment frustumCenter.Y = (float)Math.Floor(frustumCenter.Y); //clamp to texel increment frustumCenter = Vector3.Transform(frustumCenter, mLookAtInv); Vector3 eye = frustumCenter + (SunlightDirection * radius * 2.0f); ShadowLightPos = eye; Vector3 ShadowLookAt = frustumCenter; ShadowLightView = Matrix.CreateLookAt(eye, ShadowLookAt, new Vector3(0, 1, 0)); ShadowLightProjection = Matrix.CreateOrthographicOffCenter(-radius, radius, -radius, radius, -radius * 8.0f, radius * 8.0f); mCascadeProjection = ShadowLightProjection; lightsView = ShadowLightView; lightsViewProjectionMatrix = lightsView * ShadowLightProjection; }
  4. Thanks for the answers. That's exactly what I'm trying now Joe, ie simplifying the problem. If I can get rid of the jiggling for 1 CSM "slice" then I'm there really. Filtering and stuff works fine already. I'll read some more and see if I can figure out how to make my slice ignore camera rotation. I've tried moving them to texel increments (based on one of the links above CSM which i've read and reread) but the problem isn't real;y improved. Increasing my shadow map size to something ridiculous didn't improve the jiggling either so it does seem to be the rotation causing the problem. Hence I was trying to use the sphere based approach for bounding sphere but i just don't "get it". Or maybe I'm just doing the "move bounding box in texel increments" incorrectly.. I shall persevere.
  5. 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.
  6. 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.
  7. Thanks, your help is much appreciated. I'm not familiar with that language but i'll see if I can work it out (I'm just a c# xna/monogame guy)
  8. 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
  9. 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
  10. 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[i]; 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[i].X > maxes.X) maxes.X = frustumCornersLS[i].X; else if (frustumCornersLS[i].X < mins.X) mins.X = frustumCornersLS[i].X; if (frustumCornersLS[i].Y > maxes.Y) maxes.Y = frustumCornersLS[i].Y; else if (frustumCornersLS[i].Y < mins.Y) mins.Y = frustumCornersLS[i].Y; if (frustumCornersLS[i].Z > maxes.Z) maxes.Z = frustumCornersLS[i].Z; else if (frustumCornersLS[i].Z < mins.Z) mins.Z = frustumCornersLS[i].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[i]; 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[i] - 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[i].X > maxes.X) maxes.X = frustumCornersLS[i].X; else if (frustumCornersLS[i].X < mins.X) mins.X = frustumCornersLS[i].X; if (frustumCornersLS[i].Y > maxes.Y) maxes.Y = frustumCornersLS[i].Y; else if (frustumCornersLS[i].Y < mins.Y) mins.Y = frustumCornersLS[i].Y; if (frustumCornersLS[i].Z > maxes.Z) maxes.Z = frustumCornersLS[i].Z; else if (frustumCornersLS[i].Z < mins.Z) mins.Z = frustumCornersLS[i].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; }
  11. Soft Particles Vanishing in the Distance

    Ok i got it. Multiplying the value from my depthmap back by w then doing the line to use linear depth from my post above worked perfectly. Now i must resist the urge to endlessly fidding with the size, brightness, scale of my ground mist and actually get on with something that someone besides me will care about! Thanks guys
  12. Soft Particles Vanishing in the Distance

    I can't seem to get that to work. Just as a test i switched my terrain shader and soft particle shader to both calculate/store the depth using output.Depth.x = output.Position.z * output.Position.w / 20000.0f; (20000 being a hardcoded farclip for now) and bingo it worked great. Mist appears nicely in the distance and close up. But I don't really want to switch everything to using linear depth ideally. I switched it to just my soft particle shader calculating depth as the line of code above then the Passing the depth into the function above but it didn't work. I'm not sure what's wrong at all though. My depth buffer depth is just a z/w. I'm missing something. 
  13. Soft Particles Vanishing in the Distance

    Hmm thats an interesting function thanks. But how do i get linear depth? Currently i get depth by doing z/w in the pixel shader
  14. Soft Particles Vanishing in the Distance

    Thanks. That makes sense. The article maths got a bit confusing for me. Right now im storing depth by passing a float2 z and w to the pixel shader and then dividing z/w. This is a log depth maybe? Not sure of the exact name. So whats the easiest way of getting a linear depth? Ive read few article but they seems little conflicting. Also is it too late to convert my non linear depth to linear once its stored in the depth map texture? Thanks for your help so far. This problem has been bugging me for days.
  15.     Hi Guys, I'm having a problem with my soft particles. They look great and nice and "soft" and blend into the floor/geometry but since they use the depthbuffer to determine how soft/faded they are then they vanish if you go too far away and are more faint the further you are away.  This looks a bit weird if you look at a misty graveyard from the distance its "spooky mist" free and when you get closer to it is covered in the stuff.  Hopefully someone has a fix for my shader. PixelShaderOutput output; output.Color = tex2D(texSampler, input.UV); //sample depth from depth map //map the clip space coords (input.Position) to texture space float2 depthTex = input.Pos.xy / input.Pos.w; depthTex.y = -depthTex.y; depthTex.xy = depthTex.xy / 2 + 0.5; float depthFromMap = tex2D(DepthMapSampler, depthTex).r; float depthOfPixel = input.Depth.x; //input.Depth.y; // this makes the particle soft or not float scale = 20.0f; float4 fade=saturate(((depthFromMap-depthOfPixel))*scale); output.Color.rbga *= fade; return output; } Thanks