Jump to content
  • Advertisement
Sign in to follow this  
215648

DX11 Render Instanced models to shadows

This topic is 2022 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Without instancing (DrawIndexed), it works fine.

BGapCO4.png

 

but with instancing it doesn't (DrawIndexedInstanced).

 

djuMJbH.png

 

Shader (BuildShadowMapInstanced.fx)

 
cbuffer cbPerFrame
{
float3 gEyePosW;
 
float gHeightScale;
float gMaxTessDistance;
float gMinTessDistance;
float gMinTessFactor;
float gMaxTessFactor;
};
 
cbuffer cbPerObject
{
float4x4 gWorld;
float4x4 gWorldInvTranspose;
float4x4 gViewProj;
float4x4 gTexTransform;
}; 
 
// Nonnumeric values cannot be added to a cbuffer.
Texture2D gDiffuseMap;
Texture2D gNormalMap;
 
SamplerState samLinear
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
 
struct VertexIn
{
float3 PosL     : POSITION;
float3 NormalL  : NORMAL;
float2 Tex      : TEXCOORD;
row_major float4x4 World  : WORLD;
uint InstanceId : SV_InstanceID;
};
 
struct VertexOut
{
float4 PosH : SV_POSITION;
float3 PosW    : POSITION;
float3 NormalW : NORMAL;
float2 Tex  : TEXCOORD;
};
 
VertexOut VS(VertexIn vin)
{
VertexOut vout;
 
vout.PosW    = mul(float4(vin.PosL, 1.0f), vin.World).xyz;
 
vout.NormalW = mul(vin.NormalL, (float3x3)vin.World);
 
vout.PosH = mul(float4(vout.PosW, 1.0f), gViewProj);
 
vout.Tex  = mul(float4(vin.Tex, 0.0f, 1.0f), gTexTransform).xy;
 
return vout;
}
 
struct TessVertexOut
{
float3 PosW       : POSITION;
float3 NormalW    : NORMAL;
float2 Tex        : TEXCOORD;
float  TessFactor : TESS;
};
 
TessVertexOut TessVS(VertexIn vin)
{
TessVertexOut vout;
 
vout.PosW     = mul(float4(vin.PosL, 1.0f), gWorld).xyz;
vout.NormalW  = mul(vin.NormalL, (float3x3)gWorldInvTranspose);
vout.Tex      = mul(float4(vin.Tex, 0.0f, 1.0f), gTexTransform).xy;
 
float d = distance(vout.PosW, gEyePosW);
 
// Normalized tessellation factor. 
// The tessellation is 
//   0 if d >= gMinTessDistance and
//   1 if d <= gMaxTessDistance.  
float tess = saturate( (gMinTessDistance - d) / (gMinTessDistance - gMaxTessDistance) );
 
// Rescale [0,1] --> [gMinTessFactor, gMaxTessFactor].
vout.TessFactor = gMinTessFactor + tess*(gMaxTessFactor-gMinTessFactor);
 
return vout;
}
 
struct PatchTess
{
float EdgeTess[3] : SV_TessFactor;
float InsideTess  : SV_InsideTessFactor;
};
 
PatchTess PatchHS(InputPatch<TessVertexOut,3> patch, 
                  uint patchID : SV_PrimitiveID)
{
PatchTess pt;
 
// Average tess factors along edges, and pick an edge tess factor for 
// the interior tessellation.  It is important to do the tess factor
// calculation based on the edge properties so that edges shared by 
// more than one triangle will have the same tessellation factor.  
// Otherwise, gaps can appear.
pt.EdgeTess[0] = 0.5f*(patch[1].TessFactor + patch[2].TessFactor);
pt.EdgeTess[1] = 0.5f*(patch[2].TessFactor + patch[0].TessFactor);
pt.EdgeTess[2] = 0.5f*(patch[0].TessFactor + patch[1].TessFactor);
pt.InsideTess  = pt.EdgeTess[0];
 
return pt;
}
 
struct HullOut
{
float3 PosW     : POSITION;
    float3 NormalW  : NORMAL;
float2 Tex      : TEXCOORD;
};
 
[domain("tri")]
[partitioning("fractional_odd")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
[patchconstantfunc("PatchHS")]
HullOut HS(InputPatch<TessVertexOut,3> p, 
           uint i : SV_OutputControlPointID,
           uint patchId : SV_PrimitiveID)
{
HullOut hout;
 
// Pass through shader.
hout.PosW     = p[i].PosW;
hout.NormalW  = p[i].NormalW;
hout.Tex      = p[i].Tex;
 
return hout;
}
 
struct DomainOut
{
float4 PosH     : SV_POSITION;
    float3 PosW     : POSITION;
    float3 NormalW  : NORMAL;
float2 Tex      : TEXCOORD;
};
 
// The domain shader is called for every vertex created by the tessellator.  
// It is like the vertex shader after tessellation.
[domain("tri")]
DomainOut DS(PatchTess patchTess, 
             float3 bary : SV_DomainLocation, 
             const OutputPatch<HullOut,3> tri)
{
DomainOut dout;
 
// Interpolate patch attributes to generated vertices.
dout.PosW     = bary.x*tri[0].PosW     + bary.y*tri[1].PosW     + bary.z*tri[2].PosW;
dout.NormalW  = bary.x*tri[0].NormalW  + bary.y*tri[1].NormalW  + bary.z*tri[2].NormalW;
dout.Tex      = bary.x*tri[0].Tex      + bary.y*tri[1].Tex      + bary.z*tri[2].Tex;
 
// Interpolating normal can unnormalize it, so normalize it.
dout.NormalW = normalize(dout.NormalW);
 
//
// Displacement mapping.
//
 
// Choose the mipmap level based on distance to the eye; specifically, choose
// the next miplevel every MipInterval units, and clamp the miplevel in [0,6].
const float MipInterval = 20.0f;
float mipLevel = clamp( (distance(dout.PosW, gEyePosW) - MipInterval) / MipInterval, 0.0f, 6.0f);
 
// Sample height map (stored in alpha channel).
float h = gNormalMap.SampleLevel(samLinear, dout.Tex, mipLevel).a;
 
// Offset vertex along normal.
dout.PosW += (gHeightScale*(h-1.0))*dout.NormalW;
 
// Project to homogeneous clip space.
dout.PosH = mul(float4(dout.PosW, 1.0f), gViewProj);
 
return dout;
}
 
// This is only used for alpha cut out geometry, so that shadows 
// show up correctly.  Geometry that does not need to sample a
// texture can use a NULL pixel shader for depth pass.
void PS(VertexOut pin)
{
float4 diffuse = gDiffuseMap.Sample(samLinear, pin.Tex);
 
// Don't write transparent pixels to the shadow map.
clip(diffuse.a - 0.15f);
}
 
// This is only used for alpha cut out geometry, so that shadows 
// show up correctly.  Geometry that does not need to sample a
// texture can use a NULL pixel shader for depth pass.
void TessPS(DomainOut pin)
{
float4 diffuse = gDiffuseMap.Sample(samLinear, pin.Tex);
 
// Don't write transparent pixels to the shadow map.
clip(diffuse.a - 0.15f);
}
 
RasterizerState Depth
{
// [From MSDN]
// If the depth buffer currently bound to the output-merger stage has a UNORM format or
// no depth buffer is bound the bias value is calculated like this: 
//
// Bias = (float)DepthBias * r + SlopeScaledDepthBias * MaxDepthSlope;
//
// where r is the minimum representable value > 0 in the depth-buffer format converted to float32.
// [/End MSDN]
// 
// For a 24-bit depth buffer, r = 1 / 2^24.
//
// Example: DepthBias = 100000 ==> Actual DepthBias = 100000/2^24 = .006
 
// You need to experiment with these values for your scene.
DepthBias = 100000;
    DepthBiasClamp = 0.0f;
SlopeScaledDepthBias = 1.0f;
};
 
technique11 BuildShadowMapTech
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( NULL );
 
SetRasterizerState(Depth);
    }
}
 
technique11 BuildShadowMapAlphaClipTech
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}
 
technique11 TessBuildShadowMapTech
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, TessVS() ) );
SetHullShader( CompileShader( hs_5_0, HS() ) );
        SetDomainShader( CompileShader( ds_5_0, DS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( NULL );
 
SetRasterizerState(Depth);
    }
}
 
technique11 TessBuildShadowMapAlphaClipTech
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, TessVS() ) );
SetHullShader( CompileShader( hs_5_0, HS() ) );
        SetDomainShader( CompileShader( ds_5_0, DS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, TessPS() ) );
    }
}

InstancedBasic.fx

//=============================================================================
// Basic.fx by Frank Luna (C) 2011 All Rights Reserved.
//
// Basic effect that currently supports transformations, lighting, and texturing.
//=============================================================================
 
#include "LightHelper.fx"
 
cbuffer cbPerFrame
{
DirectionalLight gDirLights[3];
float3 gEyePosW;
 
 
 
float  gFogStart;
float  gFogRange;
float4 gFogColor;
};
 
cbuffer cbPerObject
{
float4x4 gWorld;
float4x4 gWorldInvTranspose;
float4x4 gViewProj;
float4x4 gTexTransform;
float4x4 gShadowTransform; 
Material gMaterial;
}; 
 
// Nonnumeric values cannot be added to a cbuffer.
Texture2D gDiffuseMap;
Texture2D gShadowMap;
 
SamplerState samAnisotropic
{
Filter = ANISOTROPIC;
MaxAnisotropy = 4;
 
AddressU = WRAP;
AddressV = WRAP;
};
 
SamplerComparisonState samShadow
{
Filter   = COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
AddressU = BORDER;
AddressV = BORDER;
AddressW = BORDER;
BorderColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
 
    ComparisonFunc = LESS;
};
 
struct VertexIn
{
float3 PosL     : POSITION;
float3 NormalL  : NORMAL;
float2 Tex      : TEXCOORD;
row_major float4x4 World  : WORLD;
uint InstanceId : SV_InstanceID;
};
 
struct VertexOut
{
float4 PosH    : SV_POSITION;
    float3 PosW    : POSITION;
    float3 NormalW : NORMAL;
float2 Tex     : TEXCOORD0;
float4 ShadowPosH : TEXCOORD1;
};
 
VertexOut VS(VertexIn vin)
{
VertexOut vout;
 
// Transform to world space space.
vout.PosW    = mul(float4(vin.PosL, 1.0f), vin.World).xyz;
vout.NormalW = mul(vin.NormalL, (float3x3)vin.World);
 
// Transform to homogeneous clip space.
vout.PosH = mul(float4(vout.PosW, 1.0f), gViewProj);
 
// Output vertex attributes for interpolation across triangle.
vout.Tex   = mul(float4(vin.Tex, 0.0f, 1.0f), gTexTransform).xy;
 
vout.ShadowPosH = mul(float4(vin.PosL, 1.0f), gShadowTransform);
 
return vout;
}
 
float4 PS(VertexOut pin, uniform int gLightCount, uniform bool gUseTexure, uniform bool gAlphaClip, uniform bool gFogEnabled) : SV_Target
{
// Interpolating normal can unnormalize it, so normalize it.
    pin.NormalW = normalize(pin.NormalW);
 
// The toEye vector is used in lighting.
float3 toEye = gEyePosW - pin.PosW;
 
// Cache the distance to the eye from this surface point.
float distToEye = length(toEye);
 
// Normalize.
toEye /= distToEye;
 
    // Default to multiplicative identity.
    float4 texColor = float4(1, 1, 1, 1);
    if(gUseTexure)
{
// Sample texture.
texColor = gDiffuseMap.Sample( samAnisotropic, pin.Tex );
 
if(gAlphaClip)
{
// Discard pixel if texture alpha < 0.1.  Note that we do this
// test as soon as possible so that we can potentially exit the shader 
// early, thereby skipping the rest of the shader code.
clip(texColor.a - 0.1f);
}
}
 
//
// Lighting.
//
 
float4 litColor = texColor;
if( gLightCount > 0  )
{  
// Start with a sum of zero. 
float4 ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 spec    = float4(0.0f, 0.0f, 0.0f, 0.0f);
 
float3 shadow = float3(1.0f, 1.0f, 1.0f);
shadow[0] = CalcShadowFactor(samShadow, gShadowMap, pin.ShadowPosH);
 
// Sum the light contribution from each light source.  
[unroll]
for(int i = 0; i < gLightCount; ++i)
{
float4 A, D, S;
ComputeDirectionalLight(gMaterial, gDirLights[i], pin.NormalW, toEye, 
A, D, S);
 
ambient += A;
diffuse += shadow[i]*D;
spec    += shadow[i]*S;
}
 
// Modulate with late add.
litColor = texColor*(ambient + diffuse) + spec;
}
 
//
// Fogging
//
 
if( gFogEnabled )
{
float fogLerp = saturate( (distToEye - gFogStart) / gFogRange ); 
 
// Blend the fog color and the lit color.
litColor = lerp(litColor, gFogColor, fogLerp);
}
 
// Common to take alpha from diffuse material and texture.
litColor.a = gMaterial.Diffuse.a * texColor.a;
 
    return litColor;
}
 
 
technique11 Light1
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(1, false, false, false) ) );
    }
}
 
technique11 Light2
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(2, false, false, false) ) );
    }
}
 
technique11 Light3
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(3, false, false, false) ) );
    }
}
 
technique11 Light0Tex
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(0, true, false, false) ) );
    }
}
 
technique11 Light1Tex
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(1, true, false, false) ) );
    }
}
 
technique11 Light2Tex
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(2, true, false, false) ) );
    }
}
 
technique11 Light3Tex
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(3, true, false, false) ) );
    }
}
 
technique11 Light0TexAlphaClip
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(0, true, true, false) ) );
    }
}
 
technique11 Light1TexAlphaClip
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(1, true, true, false) ) );
    }
}
 
technique11 Light2TexAlphaClip
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(2, true, true, false) ) );
    }
}
 
technique11 Light3TexAlphaClip
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(3, true, true, false) ) );
    }
}
 
technique11 Light1Fog
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(1, false, false, true) ) );
    }
}
 
technique11 Light2Fog
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(2, false, false, true) ) );
    }
}
 
technique11 Light3Fog
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(3, false, false, true) ) );
    }
}
 
technique11 Light0TexFog
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(0, true, false, true) ) );
    }
}
 
technique11 Light1TexFog
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(1, true, false, true) ) );
    }
}
 
technique11 Light2TexFog
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(2, true, false, true) ) );
    }
}
 
technique11 Light3TexFog
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(3, true, false, true) ) );
    }
}
 
technique11 Light0TexAlphaClipFog
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(0, true, true, true) ) );
    }
}
 
technique11 Light1TexAlphaClipFog
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(1, true, true, true) ) );
    }
}
 
technique11 Light2TexAlphaClipFog
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(2, true, true, true) ) );
    }
}
 
technique11 Light3TexAlphaClipFog
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS(3, true, true, true) ) ); 
    }
}

RenderInstanced and RenderInstancedToShadowMap functions

void Model::RenderInstancedShadowMap(CXMMATRIX World)
{
pDeviceContext->IASetInputLayout(InputLayouts::InstancedBasic32);
    pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
 
XMMATRIX view = XMLoadFloat4x4(&d3d->m_LightView);
XMMATRIX proj = XMLoadFloat4x4(&d3d->m_LightProj);
XMMATRIX viewProj = XMMatrixMultiply(view, proj);
XMMATRIX W = World;
 
Effects::BuildShadowMapInstancedFX->SetEyePosW(d3d->m_Cam.GetPosition());
Effects::BuildShadowMapInstancedFX->SetViewProj(viewProj);
 
ID3DX11EffectTechnique* Tech;
 
//if (mInfo.AlphaClip)
//Tech = Effects::InstancedBasicFX->BuildShadowMapAlphaClipTech;
//else
Tech = Effects::BuildShadowMapInstancedFX->BuildShadowMapTech;
 
UINT stride[2] = {sizeof(Vertex::Basic32), sizeof(InstancedData)};
    UINT offset[2] = {0,0};
 
ID3D11Buffer* vbs[2] = {*mModel.Mesh.GetVertexBuffer(), mInstancedBuffer};
 
//if (!mInfo.BackfaceCulling)
// pDeviceContext->RSSetState(RenderStates::NoCullRS);
 
 
D3DX11_TECHNIQUE_DESC techDesc;
    Tech->GetDesc(&techDesc);
 
    for(UINT p = 0; p < techDesc.Passes; ++p)
    {
for (UINT i = 0; i < mModel.mSubsetCount; i++)
   {   
XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(W);
   XMMATRIX TexTransform = XMMatrixIdentity();
 
   Effects::BuildShadowMapInstancedFX->SetWorld(W);
   Effects::BuildShadowMapInstancedFX->SetWorldInvTranspose(worldInvTranspose);
       Effects::BuildShadowMapInstancedFX->SetTexTransform(TexTransform);
 
pDeviceContext->IASetVertexBuffers(0, 2, vbs, stride, offset);
   pDeviceContext->IASetIndexBuffer(*mModel.Mesh.GetIndexBuffer(), DXGI_FORMAT_R16_UINT, 0);
 
Tech->GetPassByIndex(p)->Apply(0, pDeviceContext);
 
pDeviceContext->DrawIndexedInstanced(mModel.Mesh.SubsetTable[i].FaceCount * 3, 
mVisibleObjectCount, mModel.Mesh.SubsetTable[i].FaceStart * 3,  0, 0);
   }
}
 
  //if (!mInfo.BackfaceCulling)
      pDeviceContext->RSSetState(0);
}
 
void Model::RenderInstanced(CXMMATRIX World)
{
pDeviceContext->IASetInputLayout(InputLayouts::InstancedBasic32);
    pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
 
UINT stride[2] = {sizeof(Vertex::Basic32), sizeof(InstancedData)};
    UINT offset[2] = {0,0};
 
ID3D11Buffer* vbs[2] = {*mModel.Mesh.GetVertexBuffer(), mInstancedBuffer};
 
XMMATRIX view     = d3d->m_Cam.View();
XMMATRIX proj     = d3d->m_Cam.Proj();
XMMATRIX viewProj = d3d->m_Cam.ViewProj();
 
XMMATRIX W = World;
XMMATRIX ShadowTransform = W * XMLoadFloat4x4(&d3d->m_ShadowTransform);
 
Effects::InstancedBasicFX->SetDirLights(Lights);
Effects::InstancedBasicFX->SetEyePosW(d3d->m_Cam.GetPosition());
 
ID3DX11EffectTechnique* activeTech;
 
if (mInfo.AlphaClip)
{
if (mInfo.NumLights == 1)
activeTech = Effects::InstancedBasicFX->Light1TexAlphaClipTech;
else if (mInfo.NumLights == 2)
activeTech = Effects::InstancedBasicFX->Light2TexAlphaClipTech;
else if (mInfo.NumLights == 3)
activeTech = Effects::InstancedBasicFX->Light3TexAlphaClipTech;
else
activeTech = activeTech = Effects::InstancedBasicFX->Light0TexAlphaClipTech;
}
else
{
if (mInfo.NumLights == 1)
activeTech = Effects::InstancedBasicFX->Light1TexTech;
else if (mInfo.NumLights == 2)
activeTech = Effects::InstancedBasicFX->Light2TexTech;
else if (mInfo.NumLights == 3)
activeTech = Effects::InstancedBasicFX->Light3TexTech;
else
activeTech = activeTech = Effects::InstancedBasicFX->Light0TexTech;
 
}
 
if (!mInfo.BackfaceCulling)
pDeviceContext->RSSetState(RenderStates::NoCullRS);
 
 
float blendFactor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
 
    D3DX11_TECHNIQUE_DESC techDesc;
    activeTech->GetDesc( &techDesc );
for(UINT p = 0; p < techDesc.Passes; ++p)
    {
XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(W);
 
Effects::InstancedBasicFX->SetWorld(W);
Effects::InstancedBasicFX->SetWorldInvTranspose(worldInvTranspose);
Effects::InstancedBasicFX->SetViewProj(viewProj);
Effects::InstancedBasicFX->SetTexTransform(XMMatrixIdentity());
Effects::InstancedBasicFX->SetShadowMap(d3d->GetShadowMap());
Effects::InstancedBasicFX->SetShadowTransform(ShadowTransform);
 
 
for (UINT i = 0; i < mModel.mSubsetCount; i++)
   {   
 
 
pDeviceContext->IASetVertexBuffers(0, 2, vbs, stride, offset);
   pDeviceContext->IASetIndexBuffer(*mModel.Mesh.GetIndexBuffer(), DXGI_FORMAT_R16_UINT, 0);
 
   Effects::InstancedBasicFX->SetMaterial(Materials[i]);
Effects::InstancedBasicFX->SetDiffuseMap(DiffuseMapSRV[i]);
 
   activeTech->GetPassByIndex(p)->Apply(0, pDeviceContext);
 
if (mInfo.AlphaToCoverage)
pDeviceContext->OMSetBlendState(RenderStates::AlphaToCoverageBS, blendFactor, 0xffffffff);
 
pDeviceContext->DrawIndexedInstanced(mModel.Mesh.SubsetTable[i].FaceCount * 3, mVisibleObjectCount, mModel.Mesh.SubsetTable[i].FaceStart * 3,  0, 0);
 
if (mInfo.AlphaToCoverage)
   pDeviceContext->OMSetBlendState(0, blendFactor, 0xffffffff);
   }
 
 }
 
if (!mInfo.BackfaceCulling)
   pDeviceContext->RSSetState(0);
}

This is how I draw it:

void Direct3D::UpdateInstancedModelsData()
{
for (USHORT i = 0; i < ModelInstances.size(); ++i)
{
if (ModelInstances[i].Model == 0)
continue;
 
if (ModelInstances[i].UseInstancing)
ModelInstances[i].UpdateInstanceData();
}
}
 
 
void Direct3D::DrawInstancedModels()
{
for (USHORT i = 0; i < ModelInstances.size(); ++i)
{
if (ModelInstances[i].Model == 0)
continue;
 
if (ModelInstances[i].UseInstancing)
ModelInstances[i].RenderInstanced();
}
 
}
 
void Direct3D::DrawInstancedModelsToShadowMap()
{
for (USHORT i = 0; i < ModelInstances.size(); ++i)
{
if (ModelInstances[i].Model == 0)
continue;
 
if (ModelInstances[i].UseInstancing)
   ModelInstances[i].Model->RenderInstancedShadowMap(ModelInstances[i].GetWorldXM());
}  
 
}
 
void Direct3D::DrawModelsToShadowMap()
{
for (USHORT i = 0; i < ModelInstances.size(); ++i)
{
if (ModelInstances[i].Model == 0)
continue;
 
if (ModelInstances[i].UseInstancing)
continue;
 
XMMATRIX W = ModelInstances[i].GetWorldXM();
 
if (IntersectAABBFrustum(&ModelInstances[i].box, W))
{
ModelInstances[i].Visible = true;
ModelInstances[i].Model->RenderShadowMap(W);
}
else
ModelInstances[i].Visible = false;
}  
 
m_Land.DrawShadowMap(m_Cam);
}
 
void Direct3D::DrawModels()
{
for (USHORT i = 0; i < ModelInstances.size(); ++i)
{
if (ModelInstances[i].Model == 0)
continue;
 
if (ModelInstances[i].UseInstancing)
continue; 
 
if (ModelInstances[i].Visible)
ModelInstances[i].Model->Render(ModelInstances[i].GetWorldXM());
}
}
 
void Direct3D::DrawScene()
{
 
m_Smap->BindDsvAndSetNullRenderTarget(pDeviceContext);
 
pDeviceContext->IASetInputLayout(InputLayouts::Basic32);
pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
 
DrawModelsToShadowMap();
 
DrawInstancedModelsToShadowMap();
 
pDeviceContext->RSSetState(0);
 
RestoreRenderTarget();
 
pDeviceContext->ClearRenderTargetView(m_RenderTargetView, reinterpret_cast<const float*>(&Colors::Silver));
pDeviceContext->ClearDepthStencilView(m_DepthStencilView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0);
 
if (GetAsyncKeyState('1'))
pDeviceContext->RSSetState(RenderStates::WireframeRS);
 
m_Land.Draw(pDeviceContext, m_Cam, mDirLights);
 
DrawInstancedModels();
 
m_tree.Draw(XMMatrixIdentity());
 
DrawModels();
//......... rest other code
 
}

PS: I use a different shader and a different function for rendering non-instanced models.

Edited by newtechnology

Share this post


Link to post
Share on other sites
Advertisement

I fixed it. (the problem was with draw order)

10003368_858285324197823_867323870_n.jpg

Edited by newtechnology

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!