Click here to Skip to main content
15,883,336 members

-~-Tiba-~- 2 - Professional Profile



Summary

    Blog RSS
0
Author
30
Authority
2
Debator
21
Editor
15
Enquirer
176
Organiser
735
Participant
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Reputation

Weekly Data. Recent events may not appear immediately. For information on Reputation please see the FAQ.

Privileges

Members need to achieve at least one of the given member levels in the given reputation categories in order to perform a given action. For example, to store personal files in your account area you will need to achieve Platinum level in either the Author or Authority category. The "If Owner" column means that owners of an item automatically have the privilege. The member types column lists member types who gain the privilege regardless of their reputation level.

ActionAuthorAuthorityDebatorEditorEnquirerOrganiserParticipantIf OwnerMember Types
Have no restrictions on voting frequencysilversilversilversilver
Bypass spam checks when posting contentsilversilversilversilversilversilvergoldSubEditor, Mentor, Protector, Editor
Store personal files in your account areaplatinumplatinumSubEditor, Editor
Have live hyperlinks in your profilebronzebronzebronzebronzebronzebronzesilverSubEditor, Protector, Editor
Have the ability to include a biography in your profilebronzebronzebronzebronzebronzebronzesilverSubEditor, Protector, Editor
Edit a Question in Q&AsilversilversilversilverYesSubEditor, Protector, Editor
Edit an Answer in Q&AsilversilversilversilverYesSubEditor, Protector, Editor
Delete a Question in Q&AYesSubEditor, Protector, Editor
Delete an Answer in Q&AYesSubEditor, Protector, Editor
Report an ArticlesilversilversilversilverSubEditor, Mentor, Protector, Editor
Approve/Disapprove a pending ArticlegoldgoldgoldgoldSubEditor, Mentor, Protector, Editor
Edit other members' articlesSubEditor, Protector, Editor
Create an article without requiring moderationplatinumSubEditor, Mentor, Protector, Editor
Approve/Disapprove a pending QuestionProtector
Approve/Disapprove a pending AnswerProtector
Report a forum messagesilversilverbronzeProtector, Editor
Approve/Disapprove a pending Forum MessageProtector
Have the ability to send direct emails to members in the forumsProtector
Create a new tagsilversilversilversilver
Modify a tagsilversilversilversilver

Actions with a green tick can be performed by this member.


 
GeneralDynamic CubeMap SharpDX Pin
-~-Tiba-~- 215-Oct-15 16:04
-~-Tiba-~- 215-Oct-15 16:04 
This will be my first blog post, I'm really new at this so I'm sorry if this sucks!.


Dynamic Cubemaps with SharpDX using the Geometry shader and instancing:


First we need to setup a few things up:

Cubemap texture.
Cubemap renderarget.
Cubemap shaderresourceview.
Cubemap DepthStencil.


VB
Dim dstex As New Texture2DDescription
dstex.Width = 512
dstex.Height = 512
dstex.MipLevels = 1
dstex.ArraySize = 6
dstex.SampleDescription = New SampleDescription(1, 0)
dstex.Format = Format.R32_Typeless
dstex.Usage = ResourceUsage.Default
dstex.BindFlags = BindFlags.ShaderResource Or BindFlags.DepthStencil
dstex.CPUAccessFlags = 0
dstex.OptionFlags = ResourceOptionFlags.TextureCube
g_pEnvMapDepth = CreateTexture("CubeDepth)", dstex)

Dim DescDS As New DepthStencilViewDescription
DescDS.Format = Format.D32_Float
DescDS.Dimension = DepthStencilViewDimension.Texture2DArray
DescDS.Texture2DArray.FirstArraySlice = 0
DescDS.Texture2DArray.ArraySize = 6
DescDS.Texture2DArray.MipSlice = 0
g_pEnvMapDSV = New DepthStencilView(Engine.Device, g_pEnvMapDepth, DescDS)
DescDS.Texture2DArray.ArraySize = 1
g_pEnvMapOneDSV = New DepthStencilView(Engine.Device, g_pEnvMapDepth, DescDS)

dstex.Format = Format.R8G8B8A8_SNorm
dstex.BindFlags = BindFlags.RenderTarget Or BindFlags.ShaderResource Or BindFlags.UnorderedAccess
dstex.OptionFlags = ResourceOptionFlags.TextureCube
dstex.MipLevels = 1
g_pEnvMap = CreateTexture("g_pEnvMap)", dstex)

Dim DescRT As New RenderTargetViewDescription
DescRT.Format = dstex.Format
DescRT.Dimension = RenderTargetViewDimension.Texture2DArray
DescRT.Texture2DArray.FirstArraySlice = 0
DescRT.Texture2DArray.ArraySize = 6
DescRT.Texture2DArray.MipSlice = 0
g_pEnvMapRTV = New RenderTargetView(Engine.Device, g_pEnvMap, DescRT)

Dim SRVDesc As New ShaderResourceViewDescription
SRVDesc.Format = dstex.Format
SRVDesc.Dimension = ShaderResourceViewDimension.TextureCube
SRVDesc.TextureCube.MipLevels = 1
SRVDesc.TextureCube.MostDetailedMip = 0

g_pEnvMapSRV = CreateShaderResourceView("FinishedCubeMap" & i, g_pEnvMap, SRVDesc)

'Debug Views
Dim SRVDesc2 As New ShaderResourceViewDescription
SRVDesc2.Format = dstex.Format
SRVDesc2.Dimension = ShaderResourceViewDimension.Texture2DArray
SRVDesc2.Texture2DArray.MipLevels = 1
SRVDesc2.Texture2DArray.MostDetailedMip = 0
SRVDesc2.Texture2DArray.ArraySize = 1

Dim i As Integer = 0
While i < 6
    DescRT.Texture2DArray.FirstArraySlice = i
    SRVDesc2.Texture2DArray.FirstArraySlice = i
    g_apEnvMapOneSRV(i) = CreateShaderResourceView("g_apEnvMapOneSRV_" & i, g_pEnvMap, SRVDesc2)
    System.Threading.Interlocked.Increment(i)
End While


We now have a Cubemap that we can draw into.

We need to set up the view matrix for each face of the cubemap, this will be done each frame or every 2nd frame.

VB
Dim temp As Matrix
temp = Matrix.RotationX(MathHelper.ToRadians(90)) * Matrix.RotationY(MathHelper.ToRadians(0)) * Matrix.Translation(_Pos)
CubeUpView = Matrix.Invert(temp)
temp = Matrix.RotationX(MathHelper.ToRadians(-90)) * Matrix.RotationY(MathHelper.ToRadians(0)) * Matrix.Translation(_Pos)
CubeDownView = Matrix.Invert(temp)
temp = Matrix.RotationX(MathHelper.ToRadians(0)) * Matrix.RotationY(MathHelper.ToRadians(90)) * Matrix.Translation(_Pos)
CubeLeftView = Matrix.Invert(temp)
temp = Matrix.RotationX(MathHelper.ToRadians(0)) * Matrix.RotationY(MathHelper.ToRadians(-90)) * Matrix.Translation(_Pos)
CubeRightView = Matrix.Invert(temp)
temp = Matrix.RotationX(MathHelper.ToRadians(0)) * Matrix.RotationY(MathHelper.ToRadians(0)) * Matrix.Translation(_Pos)
CubeForwardView = Matrix.Invert(temp)
temp = Matrix.RotationX(MathHelper.ToRadians(0)) * Matrix.RotationY(MathHelper.ToRadians(180)) * Matrix.Translation(_Pos)
CubeBackView = Matrix.Invert(temp)



When its time to draw into the cubemap I store each of the cube view matrix in an array and set it as a Cbuffer in the shader I'm drawing with.

VB
_context.OutputMerger.SetTargets(g_pEnvMapDSV, g_pEnvMapRTV)
_context.ClearDepthStencilView(g_pEnvMapDSV, DepthStencilClearFlags.Depth, 1, 0)
_context.ClearRenderTargetView(g_pEnvMapRTV, New Color4(0, 0, 0, 0))
_context.OutputMerger.DepthStencilState = Default
Dim old As ViewportF = _context.Rasterizer.GetViewports(0)

CubeViews(0) = CubeRightView
CubeViews(1) = CubeLeftView
CubeViews(2) = CubeUpView
CubeViews(3) = CubeDownView
CubeViews(4) = CubeForwardView
CubeViews(5) = CubeBackView

_context.Rasterizer.SetViewport(ReflectionViewport)

 _effect.GetVariableByName("CubeViews").AsMatrix().SetMatrix(CubeViews)

 DrawIndexedInstanced(6)


That is about all that is needed on the CPU side of things.

The hard part for me was getting the shaders set up, the basic idea is to draw with instancing and use a pass through geometry shader with SV_RenderTargetArrayIndex to select the correct render target based on the runtime generated SV_InstanceID, the Instance ID is also used to select the View matrix.

C++
struct VertexShaderInput
{
	float3 Position : POSITION0;
        row_major float4x4 World  : WORLD;	
	uint   CubeIndex : SV_InstanceID;
};
struct VertexShaderOutput
{
	float4 Position : SV_POSITION;
	uint RTIndex : RTARRAYINDEX;
};
struct VertexShaderOutput2
{
	float4 Position : SV_POSITION;
	uint RTIndex : SV_RenderTargetArrayIndex;
};

matrix  CubeViews[6];
VertexShaderOutput VShader(VertexShaderInput input)
{
    
        VertexShaderOutput  output=(VertexShaderOutput)0;

		float4x4 view = CubeViews[input.CubeIndex];
		float4x4 VP = mul(input.World, view);
		float4x4 WVP = mul(VP, Projection);
		output.Position = mul(float4(input.Position,1), WVP);
	        output.RTIndex = input.CubeIndex;
		
    return output;
}

[maxvertexcount(3)]
void GS_CubeMap_Inst(triangle VertexShaderOutput input[3], inout TriangleStream<VertexShaderOutput2> CubeMapStream)
{
	VertexShaderOutput2 output;
	for (int v = 0; v < 3; v++)
	{
		output.Position = input[v].Position;
		output.RTIndex = input[v].RTIndex;
		CubeMapStream.Append(output);
	}
}



This is not a full code listing, I'm just going over the parts that I found in the DirectX SDK and converted to SharpDX.


This method for drawing a dynamic cube map is fast but there is still a noticeable drop in frames when doing this, another way would be do drop the instancing and the geometry shader then just spread the face drawing over 6 frames but then it wouldn't be fully dynamic.

The small size of the cube map also sees a very big drop in image quality but as I'm using it for the ambient term in my lighting it looks very nice.



modified 21-Oct-15 7:58am.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.