Jump to content

  • Log In with Google      Sign In   
  • Create Account

bearsomg

Member Since 04 Jan 2012
Offline Last Active Jun 10 2013 01:16 PM

Posts I've Made

In Topic: SSAO in Direct3D10

02 June 2013 - 05:27 PM

Yep, I changed it to be 32 bit float and it worked perfectly. I'm going to go through and do some optomization now, but with my computer as it is I can run the algorithm with 255 samples and still retain 30 fps. Still, I think some optimization would help. I'll probably start by going through MJP's post. Thanks for the help!


In Topic: SSAO in Direct3D10

02 June 2013 - 03:36 PM

Thanks for the help!

 

I haven't explicitly done anything to disable blending, but I do not have a blend state set for the technique to generate the G-buffer. Does this suffice, or is there something else I should do?

EDIT: I changed the technique to do this and the clear color doesn't affect the output anymore:

 

BlendState DisableBlending
{
    BlendEnable[0] = FALSE;
    RenderTargetWriteMask[0] = 1 | 2 | 4 | 8;
};
technique10 SSAO_T
{
    pass P0
    {
        SetBlendState(DisableBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF);
        SetVertexShader( CompileShader( vs_4_0, VS_Dif() ) );
        SetPixelShader( CompileShader( ps_4_0, PS_Dif() ) );
        SetGeometryShader( NULL );
    }
}

 

 

 

About the normals, I was a bit confused as to what to do about that. I saw different code samples just writing the normals out, and some encoding it. I changed mine to do the encoding just now.

 

I've also changed the sampler to use point sampling. Does this automatically correct for the 0.5 offset, or do I need to do that myself?

 

I noticed a problem which I also fixed, and this seemed to have the most effect on the output. The textures I was rendering to were created with DXGI_FORMAT_R8G8B8A8_UNORM, and I changed that to DXGI_FORMAT_R16G16B16A16_FLOAT, as that is what is needed to hold the G-buffer.

 

This is my output right now, any idea where that height-map like effect is coming from?

ssaotest.jpg


In Topic: SSAO in Direct3D10

31 May 2013 - 01:17 PM

Alright, so I've got my UV coordinates for the full screen quad (dividing the SV_Position variable by the screen size), and am able to get the algorithm pretty much working. I switched over my map generation shader to render to multiple render targets, one for position, normals, and depth. My problem is now that when I calculate the AO factor, the screen seems to be split in 4 quadrants, and the render fades almost completely to black the further you go down the screen. I'll post screenshots once I get back to my computer.

 

EDIT: I just did some more testing. It appears that the resulting SSAO map changes in strange ways depending on what color I use to clear the pos/normal maps before rendering to them (green was what I was experiencing the problem I described above with). It looks like clearing with black is the right way to go. Now I'm noticing a lot of linear artefacting. Is there really any way to fix this outside of fully uv unwrapping the model? I attached screenshots below.

 

Here is my shader to generate the maps:

 

matrix MatrixPalette[255];
matrix worldMatrix;
matrix viewMatrix;

//Vertex Input
struct VS_INPUT_SKIN
{
     float4 position : POSITION;
     float3 normal    : NORMAL;
     float2 tex0    : TEXCOORD;
     float3 boneLinks : BONELINKS;    
};
struct SSAO_PS_INPUT
{
    float4 pos : SV_POSITION;
    float3 actPos : TEXCOORD0;
    float3 normal : TEXCOORD1;
    float depth : TEXCOORD2;
};
struct SSAO_PS_OUTPUT
{
    float4 posMap : SV_Target0;
    float4 normalMap : SV_Target1;
    float4 depthMap : SV_Target2;
};
float4 skinVert(float4 vert, float fact, matrix bone1, matrix bone2)
{
    float4 p = float4(0.0f, 0.0f, 0.0f, 1.0f);

    //vertex skinning
    float bone1Weight = fact;
    float bone2Weight = 1.0f - bone1Weight;
    p += bone1Weight * mul(vert,bone1);
    p += bone2Weight * mul(vert,bone2);
    p.w = 1.0f;

    return p;
}
float3 skinNorm(float3 vert, float fact, matrix bone1, matrix bone2)
{
    float3 norm = float4(0.0f, 0.0f, 0.0f, 1.0f);
    float bone1Weight = fact;
    float bone2Weight = 1.0f - bone1Weight;
    norm += bone1Weight * mul(vert,bone1);
    norm += bone2Weight * mul(vert,bone2);
    norm = normalize(norm);

    return norm;
}
SSAO_PS_INPUT vs_SSAO(VS_INPUT_SKIN IN)
{
    SSAO_PS_INPUT OUT;

    float4 skinnedPos = skinVert(IN.position, IN.boneLinks[2], MatrixPalette[IN.boneLinks[0]], MatrixPalette[IN.boneLinks[1]]);
    float3 skinnedNormal = skinNorm(IN.normal, IN.boneLinks[2], MatrixPalette[IN.boneLinks[0]], MatrixPalette[IN.boneLinks[1]]);

    float4 worldPos = mul(skinnedPos, worldMatrix);

    OUT.pos = mul(worldPos, viewMatrix);
    OUT.pos = mul(OUT.pos, projMatrix);

    OUT.actPos = mul(worldPos, viewMatrix);

    OUT.normal = mul(skinnedNormal, worldMatrix);
    OUT.normal = mul(OUT.normal, viewMatrix);

    OUT.depth = normalize(mul(worldPos, viewMatrix).z);

    return OUT;
}
SSAO_PS_OUTPUT ps_SSAO(SSAO_PS_INPUT IN) : SV_Target
{
    SSAO_PS_OUTPUT OUT;

    OUT.posMap = float4(IN.actPos, 1);
    OUT.normalMap = float4(IN.normal, 1);
    OUT.depthMap = float4(IN.depth, IN.depth, IN.depth, 1);

    return OUT;
}
technique10 SSAO_T
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, vs_SSAO() ) );
        SetPixelShader( CompileShader( ps_4_0, ps_SSAO() ) );
        SetGeometryShader( NULL );
    }
}
 

 

And here is my shader to generate the AO map:

 

matrix MatrixPalette[255];
matrix worldMatrix;
matrix viewMatrix;
matrix projMatrix;
matrix lightViewMatrix;

float2 texelSize;

Texture2D posMap;
Texture2D normalMap;
Texture2D depthMap;
Texture2D randomTexture;

SamplerState DifferredSampler
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Clamp;
    AddressV = Clamp;
};

struct VS_OUTPUT
{
     float4 position : SV_POSITION;
     float3 normal : NORMAL;
};

float3 getPosition(in float2 uv)
{
    return posMap.Sample(DifferredSampler, uv).xyz;
}
float3 getNormal(in float2 uv)
{
    return normalize(normalMap.Sample(DifferredSampler, uv).xyz * 2.0f - 1.0f);
}
float getDepth(in float2 uv)
{
    return depthMap.Sample(DifferredSampler, uv).w;
}
float3 getRandom(in float2 uv)
{
    return randomTexture.Sample(DifferredSampler, texelSize*uv/float2(64,64)).xyz * 2.0f - 1.0f;
}
float g_sample_rad = 3.0f;
float g_intensity = 3.0f;
float g_scale = 1.0f;
float g_bias = 0.001f;
float doAmbientOcclusion(in float2 tcoord,in float2 uv, in float3 p, in float3 cnorm)
{
    float3 diff = getPosition(tcoord + uv) - p;
    const float3 v = normalize(diff);
    const float d = length(diff)*g_scale;
    return max(0.0,dot(cnorm,v)-g_bias)*(1.0/(1.0+d))*g_intensity;
}

float4 getOcclusion(float2 uv)
{
    float4 o;
    o.rgb = 1.0f;
    o.a = 1.0f;

    const float2 vec[4] = {float2(1,0),float2(-1,0),
                float2(0,1),float2(0,-1)};

    float3 p = getPosition(uv);
    float3 n = getNormal(uv);
    float2 rand = getRandom(uv);

    float ao = 0.0f;
    float rad = g_sample_rad/p.z;

    
    int iterations = 4;
    for (int j = 0; j < iterations; ++j)
    {
      float2 coord1 = reflect(vec[j],rand)*rad;
      float2 coord2 = float2(coord1.x*0.707 - coord1.y*0.707,
                  coord1.x*0.707 + coord1.y*0.707);
 
      ao += doAmbientOcclusion(uv,coord1*0.25, p, n);
      ao += doAmbientOcclusion(uv,coord2*0.5, p, n);
      ao += doAmbientOcclusion(uv,coord1*0.75, p, n);
      ao += doAmbientOcclusion(uv,coord2, p, n);
    }
    ao/=(float)iterations*4.0;

    o.rgb = ao;

    return o;
}

float4 ps_lighting(VS_OUTPUT IN) : SV_Target
{
    float4 ao = float4(1.0f, 1.0f, 1.0f, 1.0f);
    float2 uv = IN.position.xy;
    uv.x /= texelSize[0];
    uv.y /= texelSize[1];
    ao = getOcclusion(uv);
    return ao;
}
VS_OUTPUT vs_Skinning(VS_INPUT_SKIN IN)
{
        VS_OUTPUT OUT = (VS_OUTPUT)0;

        float4 p = float4(0.0f, 0.0f, 0.0f, 1.0f);
        float3 norm = float3(0.0f, 0.0f, 0.0f);

        //vertex skinning
        float bone1Weight = IN.boneLinks[2];
        float bone2Weight = 1.0f - bone1Weight;
        p += bone1Weight * mul(IN.position,MatrixPalette[IN.boneLinks[0]]);
        p += bone2Weight * mul(IN.position,MatrixPalette[IN.boneLinks[1]]);
        p.w = 1.0f;
        norm += bone1Weight * mul(IN.normal,MatrixPalette[IN.boneLinks[0]]);
        norm += bone2Weight * mul(IN.normal,MatrixPalette[IN.boneLinks[1]]);
        norm = normalize(norm);
        norm = mul(norm, worldMatrix);
        OUT.normal = normalize(mul(norm, lightViewMatrix)); 

        //move pos to worldviewproj space
        float4 worldPos = mul(p, worldMatrix);
        OUT.position = mul(worldPos, viewMatrix);
        OUT.position = mul(OUT.position, projMatrix);
        
        return OUT;
}
 

 


 

 

 

Position map with buffer cleared to black:

posnw.png

 

Normal map with buffer cleared to black:

normalep.png

 

Depth map with buffer cleared to black:

depthd.png

 

Resulting SSAO map with all buffers cleared to green:

ssaogreen.jpg

 

Resulting SSAO map with all buffers cleared to white:

ssaowhite.jpg

 

Resulting SSAO map with all buffers cleared to black:

ssaoblack.jpg


In Topic: Shadow Mapping: Bleed through?

21 November 2012 - 01:53 PM

Simplest way is to not do the shadow check when an object is facing away from the light source.

e.g.: shadowing = (dot(faceNormal, lightTangent) > 0.0)?1.0:shadowCalc();


How is lightTangent calculated? I have the light direction and position.

PARTNERS