Is it possible to pass an index to a texture array through instancing?

Started by
2 comments, last by Neometron 7 years ago

Hello everyone,
It has been some time since I have been on gamedev and programming in D3D. In the last month or so I have been working on a voxel terrain of 512x512x256 placed within a home brewed octree. I'm currently using D3D11 with instancing and batch based on textures. I discovered that I could bind multiple textures into a texture array. I attempted to pass an unsigned int as a texture index value along with my instance data, but I hit a wall trying to receive that uint in the pixel shader as it will not compile. I have read that the pixel shader does not take uint as input. However, the compile error is X3512: sampler array index must be a literal expression. Which I figure that the array index must be known during compile time.

Either way, I ask:

Is it possible to pass an index to a texture array through instancing?

PS code:


Texture2D texture_data[2];
SamplerState sample_state;

struct PS_INPUT
{
	float4 position : SV_POSITION;
	float4 normal   : NORMAL;
	float2 uv       : TEXCOORD0;
        uint instance_texture : TEXCOORD1;
};

float4 main(PS_INPUT input) : SV_TARGET
{
	float4 light = { 0.707f, -0.707f, 0.0f, 0.0f }; // In World Space //0 = Vector : 1 = Point
	light = normalize(-light);

        float4 texture_color = texture_data[input.instance_texture].Sample(sample_state, input.uv);

	float  ambient_scalar = 0.5f;
	float4 ambient_color = ambient_scalar * texture_color;

	float  light_scalar = dot(light, input.normal);
	float4 light_color  = light_scalar * texture_color;
	
	if (light_scalar > 0.0f)
		return saturate(ambient_color + light_color);
	else
		return saturate(ambient_color);
}
Advertisement

Note that there's a big difference between a "texture array" and an "array of textures". What you're doing here is an array of textures.
Your array in the HLSL code is just syntactic sugar for making two texture inputs, bound to two consecutive registers.


Texture2D texture_data0 : register(t0);
Texture2D texture_data1 : register(t1);

You can index that array using compile-time constants, but no, you can't index it with any kind of variable data.
However, In D3D12, there is a new ability where you can index these kinds of arrays... :wink:

The D3D11 solution is to use "texture array" resource types.
In HLSL, that looks like:


Texture2DArray texture_data;
...
float4 texture_color = texture_data.Sample(sample_state, input.uv, input.instance_texture);

On the C++ side, you create a single texture array resource, instead of creating two individual texture resources. The downside of this technique is that every texture in the array has to have the same dimensions (e.g. you can't put a 512px texture and a 256px texture in the same array).

Thank you Hodgman for your explanation. I'll give this a shot and keep in mind about the limitation.

Thanks again for the help. Here's an image of my results.

This topic is closed to new replies.

Advertisement