Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!

1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


Member Since 19 Oct 2009
Offline Last Active May 16 2015 03:12 AM

Posts I've Made

In Topic: Directional light shadow mapping

12 March 2015 - 06:44 PM

Nice! A couple of questions:
1. Why transform the bounding frustrum into lights view space?
2. What is the point of the crop matrix? Couldn't the 'scale' go into making the ortho matrix? What is the purpose of the 'offset' - to translate the view matrix from the center?

Short answer: you need the min/max values by the light point of view.


Here you can find the answers, this is a nice nvidia paper. It was a great reference for me, at least. :) The algorithm is described on the 7th page.

Another good reference for PSSM.

In Topic: Directional light shadow mapping

11 March 2015 - 02:01 PM

First (minor) thing is you should normalize your lightDir as well. And your lightView matrix is actually a lookAt matrix.


I've implemented a 1-cascade shadow map, the solution is very similar. This is based on an nvidia paper and other resources which can be found in the internet. smile.png


So the first step, I calculate a view matrix like you do. This is actually the same as your code (just normalize your direction! smile.png)

view.lookAt(Vector3::Zero, lightDir, Vector3::Up);

After I calculate the bounds of the view frustum points "looked from the direction of the light"

Vector3 min = Vector3::Max;
Vector3 max = Vector3::Min;

for (int i = 0; i < BoundingFrustum::NumCorners; i++)
    transformed = Vector3::transformCoord(corners[i], view);

    min = Vector3::getMin(transformed, min);
    max = Vector3::getMax(transformed, max);

Then my projection matrix is a simple ortho:

proj.orthographicOffCenter(-1, 1, -1, 1, min.z, max.z);

But I'm using another matrix called cropMat which will "position and clip".

const float32 scaleX = 2.0f / (max.x - min.x);
const float32 scaleY = 2.0f / (max.y - min.y);
const float32 offsetX = -0.5f * (min.x + max.x) * scaleX;
const float32 offsetY = -0.5f * (min.y + max.y) * scaleY;

cropMat.m00 = scaleX;
cropMat.m11 = scaleY;
cropMat.m22 = 1.0f;
cropMat.m30 = offsetX;
cropMat.m31 = offsetY;
cropMat.m33 = 1.0f;

The final viewProj matrix is calculated by multiplying the view, the projection and the crop matrix. NOTE that I'm using the DX-based matrices, care with the matrix row/column order. smile.png


As a side note:

You can use a sphere instead of a box. With a sphere you loose some precision but it also disables the flickering when the camera rotates:

Vector3 center;
for (int i = 0; i < BoundingFrustum::NumCorners; i++)
    center += corners[i];
center /= BoundingFrustum::NumCorners;
center = Vector3::transformCoord(center, view);

const float32 radius = Vector3::distance(corners[BoundingFrustum::FLB], corners[BoundingFrustum::NRT]);

min = center - Vector3(radius);
max = center + Vector3(radius);

You can also apply a rounding matrix which disables flickering when camera moves, something like this:

// round to textel
Vector3 origin = Vector3::transformCoord(Vector3::Zero, viewProj);
origin *= halfSize;

Vector3 rounding;
rounding.x = Math::round(origin.x) - origin.x;
rounding.y = Math::round(origin.y) - origin.y;
rounding /= halfSize;

viewProj *= roundMat;


This is an old code, can contains bugs. :)

In Topic: UE4-like shaders from materials (theory)

11 March 2015 - 01:28 PM

I've started to work on a similar system but I need some help about how I can integrate it to my rendering system. Sorry, for the long post... :)


The old way:

- a Material class defined a fixed set of input parameters, like textures (diffuse, normal, specular) and others (spec power, shininess)

- a Drawable(Mesh) stored a Material reference and the drawables was sorted by the material's properties (mostly by its shading model)

- a DeferredRenderer class loaded the fixed shader source and compiled it (gbuffer, lighting, etc shaders)

- in the draw pass, the deferred renderer asked for the visible drawables and rendered it using the shaders


This obviously won't work so I have to figure out a new system.


Currently, I have a class called MaterialBuilder which will be controlled by the Graph Editor (when I'll have one smile.png). While testing, I can create shader snippets by calling its methods (addNode, connect, etc.) by hand. This class can generate GLSL code from the node graph. So it's working, and it provides a valid GLSL code (of course can be optimized, but first I want the whole system to work).


I've removed the fixed set of parameters from the Material class, instead it stores a reference to a MaterialBuilder. So this Material class is similar to the Material Instance in UE4. It doesn't generate new shader, just use it and set the paremeters.


Here comes my problem: I have a predefined "base shader code" which depends on the renderer. So the deferred renderer has a different base shader code than the forward renderer. I have to create the shaders by concat the base shader code with the code provided by the MaterialBuilder so the shader can't be compiled in the MaterialBuilder. And the shader compiling depends on the mesh as well (static or animated) and maybe on other parameters.


And as a second problem, I'm not sure how the recompilation should work in this system. I have some drawables in the scene which has its own Material which refers to a MaterialBuilder. In the future, while I'm editing a material, I'll have 3 objects:

- a MaterialBuilder which contains the nodes and connections and can generate the source code. Actually, this is what the editor modifies.

- a test Material which contains test values

- a test Drawable which has a reference to the test material.

In Topic: UE4-like shaders from materials (theory)

06 March 2015 - 03:19 AM

I have. It's a very intuitive way to work with shaders

Agree. Oh, and your tool looks pretty cool. happy.png


I built one a while back.

Do you have any reference? My main problem is just how I can identify that two materials should use the same shader with different uniform values. Or let it be controlled by the user? Like in UE4, they have material instances which uses the same "base material" aka shaders.

In Topic: UE4-like shaders from materials (theory)

05 March 2015 - 12:37 PM

Oh yea, I didn't write the original post accurate enough. I meant new shader for each material which differs not just the values but the "structure" as well. So the same as you wrote here. :) BTW, this is a pretty flexible system, I love it. Has anyone tried to implement similar system?


Thanks for your replies! :)