Compute Shaders and cubemaps [SOLVED]

Discussion area about developing with Ogre2 branches (2.1, 2.2 and beyond)
Post Reply
User avatar
SolarPortal
OGRE Contributor
OGRE Contributor
Posts: 203
Joined: Sat Jul 16, 2011 8:29 pm
Location: UK
x 51
Contact:

Compute Shaders and cubemaps [SOLVED]

Post by SolarPortal »

Hi, its been a while since i was last here posting, first i hope everyone is doing ok and ogre3d still seems to be moving forward.
Ive been watching commits closely but havent been to the forums in a while xD Im also a little behind on the latest version of 2.1 with a planned upgrade in the near future.

Anyway, i have been experimenting with compute shaders and cubemaps which so far i have not had much luck and was hoping someone would be able to help.

My goal is to generate an irradiance cubemap texture that i can use for IBL.

Basically, in a compositor node like the probes i am rendering the cubemap to six faces ready to do some irradiance math to the cubemap in compute shaders but for the life of me, i have been unable to get anything to happen at all. I searched my ogre3d source code and could not find reference to the RWTexture2DArray anywhere.
Its probably best that i show my code first.

Workspace and texture setup:

Code: Select all

	// Create the irradiance texture, this needs to be both a render target and a UAV since it will be 
	// used in a compute shader to calculate the spherical harmonics on.
	irradianceTexture = Ogre::TextureManager::getSingleton().createManual(
							  "SkyLight_IrradianceTex", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
							  Ogre::TEX_TYPE_CUBE_MAP, irradianceTexSize, irradianceTexSize, 0,
							  Ogre::PF_FLOAT16_RGBA, Ogre::TU_RENDERTARGET | Ogre::TU_UAV, 0, false);
	
	// Create a skyline workspace to manage the shadowmap system
	irradianceWorkspace = mCompositorMgr->createEmptyWorkspace("SkyLightIrradianceWorkspace");
	irradianceWorkspace->setSceneManager(mSceneManager);
	irradianceWorkspace->setCamera(mCamera); // Set camera to NULL as we dont need one as its a compute shader

	Ogre::CompositorChannelVec& finalTarget = irradianceWorkspace->getRtChannels();
	irradianceWorkspace->setNumRenderTargets(1);
	irradianceWorkspace->addRenderTarget(0, irradianceTexture->getBuffer(0)->getRenderTarget());
	irradianceWorkspace->addTexture(0, irradianceTexture);
	irradianceWorkspace->connectTarget(0, irradianceRenderNode, 0);
	irradianceWorkspace->setEnabled(false);
	irradianceWorkspace->generateWorkspace(false);
Note: The reason the workspace code looks different is because we inherited the Workspace manager, nodes, passes and targets into our own classes to make setting up workspaces easier and it works very nicely.

I created a compositor node to hook with the workspace:

Code: Select all

compositor_node SkylineIrradianceRendererNode
{
	in 0 cubemap
	
	//texture tmpCubemap 32 32 PF_FLOAT16_RGBA cubemap no_fsaa uav

	target cubemap +X : irradiance_cubemap_target { }
	target cubemap -X : irradiance_cubemap_target { }
	target cubemap +Y : irradiance_cubemap_target { }
	target cubemap -Y : irradiance_cubemap_target { }
	target cubemap +Z : irradiance_cubemap_target { }
	target cubemap -Z : irradiance_cubemap_target
	{
		
		pass compute
		{
			job	Irradiance_Blur
			uav 0 cubemap write
		}
		
	}
}
Then i created a json material to setup the compute job:

Code: Select all

    
{
    "samplers" :
    {
        "TriLinearWrap" :
        {
            "min" : "linear",
            "mag" : "linear",
            "mip" : "linear",
            "u" : "wrap",
            "v" : "wrap",
            "w" : "wrap",
            "miplodbias" : 0,
            "max_anisotropic" : 1,
            "compare_function" : "disabled",
            "border" : [1, 1, 1, 1],
            "min_lod" : -3.40282347E+38,
            "max_lod" : 3.40282347E+38
        }
    },

    "compute" :
    {
        "Irradiance_Blur" :
        {
            "threads_per_group" : [32, 32, 1],
            "thread_groups" : [1, 1, 6],
            "source" : "IrradianceMapGen_cs",
            "uav_units" : 1,
			"inform_shader_of_texture_data_change" : false,
			"textures" :
			[
				{}
			],
			"params" :
			[
				[ "texRez", [32, 32] ]
			]
        }
    }
}

 
and of course my compute shader which i have been trying to just set a flat colour to each of the cubemap faces.

Code: Select all

RWTexture2DArray<float4> outputTexture : register(u0);

uniform float2 texRez;

[numthreads(32,32,1)]
void main(uint3 ThreadID : SV_DispatchThreadId)
{
	if (ThreadID.x >= texRez.x || ThreadID.y >= texRez.y)
        return;
		
	outputTexture[ThreadID] = float4(1.0, 0.0, 0.0, 1.0);
}
The cubemap texture is only 32x32x6, so i set threadgroups to 1,1,6 and the threads per group to 32,32,1

Just no matter what i do, i cannot get the compute shader to change the cubemap data, it only shows the rendered scene and the compute shader does not affect it one bit.

I really hope this makes sense and that someone might be able to provide me an answer to my problem. Little bit banging head against the table at the moment lol XD

If you need me to provide any more information, then please do ask :)

Thanks again everyone :)

Edit: I forgot to mention that i manually execute the update to the workspace: here is that code too:

Code: Select all

 if(irradianceWorkspace)irradianceWorkspace->update(true); 
Last edited by SolarPortal on Wed Nov 06, 2019 11:56 am, edited 1 time in total.
Lead developer of the Skyline Game Engine: https://aurasoft-skyline.co.uk
User avatar
SolarPortal
OGRE Contributor
OGRE Contributor
Posts: 203
Joined: Sat Jul 16, 2011 8:29 pm
Location: UK
x 51
Contact:

Re: Compute Shaders and cubemaps

Post by SolarPortal »

Ok Solved, its some missing code in OgreD3D11Texture.cpp

In D3D11Texture::createUavView(...), Cubemap texture type was missing, so no matter how much i tried it would not work.
So to fix it i created a Texture2DArray UAV For the cubemap texture format.
On line 192, add a return and add this bit of code:

Code: Select all

		
//...  case TEX_TYPE_2D_ARRAY:
 case TEX_TYPE_CUBE_MAP:
 	descUAV.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
	descUAV.Texture2DArray.MipSlice = static_cast<UINT>(mipmapLevel);
	descUAV.Texture2DArray.FirstArraySlice = 0;
	descUAV.Texture2DArray.ArraySize = 6;
	break;
	//... case TEX_TYPE_3D:
Then you will be able to use a cubemap as an output as the UAV will be mapped as a Texture2DArray.
All my code posted above was also working and output red across the cubemap :)
Now to do some diffuse irradiance cubemap convolution! :P
Hope this helps someone :)
Lead developer of the Skyline Game Engine: https://aurasoft-skyline.co.uk
User avatar
SolarPortal
OGRE Contributor
OGRE Contributor
Posts: 203
Joined: Sat Jul 16, 2011 8:29 pm
Location: UK
x 51
Contact:

Re: Compute Shaders and cubemaps [SOLVED]

Post by SolarPortal »

Found another place in ogre source which does not include the cubemap as a UAV

file: OgreD3D11RenderSystem.cpp
function: queueBindUAV(...)

Add this after the "case TEX_TYPE_2D_ARRAY:" roughly on line 2430

Code: Select all

case TEX_TYPE_CUBE_MAP:
				descUAV.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
				descUAV.Texture2DArray.MipSlice = static_cast<UINT>(mipmapLevel);
				descUAV.Texture2DArray.FirstArraySlice = 0;
				descUAV.Texture2DArray.ArraySize = 6;
				break;
Lead developer of the Skyline Game Engine: https://aurasoft-skyline.co.uk
chengzhigao
Gnoblar
Posts: 5
Joined: Tue Nov 26, 2019 6:53 am

Re: Compute Shaders and cubemaps [SOLVED]

Post by chengzhigao »

Hi,

I am so glad that i found something related to IBL in Ogre V2. I was researching on IBL PBS rendering in OgreV2, I found that it works with the reflection map by setting "datablock->setTexture( Ogre::PBSM_REFLECTION, texture );" from the PbsMaterial sample. However, from the V1 it seems the IBL setting of PBS sample contains 2 cubemaps, diffuse and specular. I did not see any relavent information or example on setting up a diffuse IBL cube map in V2. So may i ask how do you do it in your project? And would you share some example or codes on this topic(IBL in V2)?

I would really really appreciate your answer and lights on this.

thanks & regards,
Spencer
Post Reply