How to: Set mipmap texture options using shaders (HPS)

Below is sample code on how to set mipmap on textures using Custom Shadders.
Sample code been tested in HPS 2025.7.0 using hps_mfc_sandbox

Screenshot:

HSF file:

grid.zip (17.8 KB)

Sample Code:

#define DTR(x) (static_cast<float>(x) * 3.141592653f / 180.0f)

static void insertTexturedQuad(SegmentKey& segmentKey)
{
	Point points[] = { {
						  -3.0f,
						  0.0f,
						  0.0f,
					  },
					  {
						  -3.0f,
						  0.0f,
						  +20.0f,
					  },
					  {
						  +3.0f,
						  0.0f,
						  +20.0f,
					  },
					  {
						  +3.0f,
						  0.0f,
						  0.0f,
					  } };
	int facelist[] = { 4, 0, 1, 2, 3 };

	HPS::ShellKey shellKey = segmentKey.InsertShell(4, points, 5, facelist);

	size_t verticesMap[4] = { 0, 1, 2, 3 };
	float const verticesParams[] = {
		0.0f,
		0.0f,
		0.0f,
		0.0f,
		0.0f,
		10.0f,
		0.0f,
		0.0f,
		3.0f,
		10.0f,
		0.0f,
		0.0f,
		3.0f,
		0.0f,
		0.0f,
		0.0f,
	};
	shellKey.SetVertexParametersByList(4, verticesMap, 16, verticesParams, 4);

	float const elevation = 10.0f;
	Point const position{ 0.0f, 2.5f * sin(DTR(elevation)), -2.5f * cos(DTR(elevation)) };
	Point const target{ 0.0f, 0.0f, 1.0f };
	Vector const up{ 0.0f, sin(DTR(90 - elevation)), cos(DTR(90 - elevation)) };

	HPS::CameraKit cameraKit;
	cameraKit.SetPosition(position);
	cameraKit.SetTarget(target);
	cameraKit.SetUpVector(up);
	cameraKit.SetProjection(HPS::Camera::Projection::Perspective);

	segmentKey.SetCamera(cameraKit);
}


static bool addPanel( HPS::SubwindowKit subKit, 
	SegmentKey const& parentSegment,
	VertexShaderKey const& vertexShaderKey,
	ShaderTextureKey const& shaderTextureKey,
	char const* planelLabel,
	char const* name,
	char const* pixelSource,
	ShaderSamplerKit& shaderSamplerKit)
{
	SegmentKey childSegment = parentSegment.Subsegment(name);
	PixelShaderKit pixelShaderKit;
	pixelShaderKit.SetSource(pixelSource);
	PixelShaderKey pixelShaderKey = Database::DefinePixelShader(pixelShaderKit);

	shaderSamplerKit.SetName(name);
	ShaderSamplerKey shaderSamplerKey = Database::DefineShaderSampler(shaderSamplerKit);

	SegmentKey shaderSegment = childSegment.Subsegment("shader");
	insertTexturedQuad(shaderSegment);
	shaderSegment.SetVertexShader(vertexShaderKey, Shader::Primitives::Triangles);
	shaderSegment.SetPixelShader(pixelShaderKey, Shader::Primitives::Triangles);

	ShaderTextureKeyArray textureArray{ shaderTextureKey };
	ShaderSamplerKeyArray samplerArray{ shaderSamplerKey };
	pixelShaderKey.SetShaderTextures(textureArray, samplerArray);

	ShaderTextureKeyArray outTextureArray;
	ShaderSamplerKeyArray outSamplerArray;
	pixelShaderKey.ShowShaderTextures(outTextureArray, outSamplerArray);

	if (outTextureArray != textureArray || outSamplerArray != samplerArray) {
		return false;
	}


    childSegment.SetSubwindow(subKit);
    childSegment.Subsegment("label").GetTextAttributeControl().SetAlignment(HPS::Text::Alignment::BottomCenter);
    childSegment.Subsegment("label").InsertText(HPS::Point(0, -0.5, 0), planelLabel);
    childSegment.Subsegment("label").GetDrawingAttributeControl().SetDepthRange(0, 0);
    childSegment.Subsegment("label").GetMaterialMappingControl().SetTextColor(HPS::RGBAColor(1, 0, 0));
	return true;
}


void CHPSView::OnUserCode3()
{
    // TODO: Add your command handler code here

    GetCanvas().GetFrontView().GetSegmentKey().GetDrawingAttributeControl().SetWorldHandedness(HPS::Drawing::Handedness::Left);

	SegmentKey rootKey = Database::CreateRootSegment();
    
    //GetCanvas().GetWindowKey().IncludeSegment(rootKey);
	GetCanvas().GetFrontView().GetAttachedModel().GetSegmentKey().IncludeSegment(rootKey);
    GetCanvas().GetFrontView().GetAttachedModel().GetSegmentKey().GetVisibilityControl().SetText(true);
    
	Stream::ImportOptionsKit import_kit;
	import_kit.SetSegment(rootKey);
	Stream::ImportNotifier notifier = Stream::File::Import("D:/SDHV/21447/grid.hsf", import_kit);
	notifier.Wait();

	PortfolioKey portfolioKey;
	rootKey.GetPortfolioControl().ShowTop(portfolioKey);
	ImageDefinition imageDefinition;

    if (portfolioKey.ShowImageDefinition("grid", imageDefinition) == false)
    {
        //  Unable to find Image definition
        GetCanvas().UpdateWithNotifier().Wait();
    }

	ImageKit imageKit;
	imageDefinition.Show(imageKit);


	ShaderTextureKit shaderTextureKit;
	shaderTextureKit.SetName("grid");
	unsigned int width = 0, height = 0;

	if (imageKit.ShowSize(width, height) == false) {

		//  ImageKit does not contain size data
		GetCanvas().UpdateWithNotifier().Wait();

	}
	shaderTextureKit.SetSize(width, height);
	shaderTextureKit.SetMipmapLevels(0);
	shaderTextureKit.SetFormat(Shader::Texture::Format::RGBA8Unorm);

	ByteArray imageData;
	if (imageKit.ShowData(imageData) == false) {

		//  ImageKit does not contain data
		GetCanvas().UpdateWithNotifier().Wait();
	}
	ByteArrayArray data{ imageData };
	shaderTextureKit.SetData(data);


	ShaderTextureKey shaderTextureKey;
	shaderTextureKey = Database::DefineShaderTexture(shaderTextureKit);

    // Define VertexShader

	VertexShaderKit vertexShaderKit;
	char const* textureTransfSource = "void custom_main(inout VertexShaderContext ctx) { \n"
		"\tctx.voutput.texcoord0 = mul(ctx.voutput.texcoord0, uniformCommon.TextureMatrix0);\n"
		"}\n\n";
	vertexShaderKit.SetSource(textureTransfSource);
	vertexShaderKit.SetInputs(Shader::VertexInputs::TexCoord0);
	VertexShaderKey vertexShaderKey = Database::DefineVertexShader(vertexShaderKit);


// TEST CASE 1

	char const* nearestMinMagNoMipSource =
		"void custom_main(inout PixelShaderContext ctx) { \n"
		"\tctx.poutput.FinalColor = textureSample(usergridTexture, userNearestMinMagNoMipSampler, ctx.pinput.texcoord0.xy);\n"
		"}\n\n";
	ShaderSamplerKit shaderSamplerKit1;
	shaderSamplerKit1.SetMinFilter(Shader::Sampler::Filter::Nearest);
	shaderSamplerKit1.SetMagFilter(Shader::Sampler::Filter::Nearest);
	shaderSamplerKit1.SetMipFilter(Shader::Sampler::Filter::Nearest);
	shaderSamplerKit1.SetMaxLOD(0.f);


    HPS::SubwindowKit mySubKit;
    mySubKit.SetSubwindow(HPS::Rectangle(-1, -0.5f, 0, 1), HPS::Subwindow::Type::Lightweight);

	addPanel(mySubKit,
		rootKey,
		vertexShaderKey,
		shaderTextureKey,
		"nearest - no mipmap\n\ntest case 1",
		"NearestMinMagNoMip",
		nearestMinMagNoMipSource,
        shaderSamplerKit1);


 // TEST CASE 2

	char const* nearestMinMagNearestMipSource = "void custom_main(inout PixelShaderContext ctx) { \n"
		"\tctx.poutput.FinalColor = textureSample(usergridTexture, "
		"userNearestMinMagNearestMipSampler, ctx.pinput.texcoord0.xy);\n"
		"}\n\n";
	ShaderSamplerKit shaderSamplerKit2;
	shaderSamplerKit2.SetMinFilter(Shader::Sampler::Filter::Nearest);
	shaderSamplerKit2.SetMagFilter(Shader::Sampler::Filter::Nearest);
	shaderSamplerKit2.SetMipFilter(Shader::Sampler::Filter::Nearest);

	mySubKit.SetSubwindow(HPS::Rectangle(-0.5f, 0, 0, 1), HPS::Subwindow::Type::Lightweight);


    addPanel(mySubKit,
        rootKey,
        vertexShaderKey,
        shaderTextureKey,
        "min/mag nearest\nmipmap nearest\n\ntest case 2",
        "NearestMinMagNearestMip",
        nearestMinMagNearestMipSource,
        shaderSamplerKit2);
	
// TEST CASE 3

	mySubKit.SetSubwindow(HPS::Rectangle(0, 0.5f, 0, 1), HPS::Subwindow::Type::Lightweight);


	char const* nearestMinMagLinearMipSource = "void custom_main(inout PixelShaderContext ctx) { \n"
		"\tctx.poutput.FinalColor = textureSample(usergridTexture, "
		"userNearestMinMagLinearMipSampler, ctx.pinput.texcoord0.xy);\n"
		"}\n\n";
	ShaderSamplerKit shaderSamplerKit3;
	shaderSamplerKit3.SetMinFilter(Shader::Sampler::Filter::Nearest);
	shaderSamplerKit3.SetMagFilter(Shader::Sampler::Filter::Nearest);
	shaderSamplerKit3.SetMipFilter(Shader::Sampler::Filter::Linear);
    
    addPanel(mySubKit,
        rootKey,
        vertexShaderKey,
        shaderTextureKey,
        "min/mag nearest\nmipmap linear\n\ntest case 3",
        "NearestMinMagLinearMip",
        nearestMinMagLinearMipSource,
        shaderSamplerKit3);

// TEST CASE 4

	mySubKit.SetSubwindow(HPS::Rectangle(0.5f, 1, 0, 1), HPS::Subwindow::Type::Lightweight);

	char const* nearestMinMagAnisotropySource = "void custom_main(inout PixelShaderContext ctx) { \n"
		"\tctx.poutput.FinalColor = textureSample(usergridTexture, "
		"userNearestMinMagAnisotropySampler, ctx.pinput.texcoord0.xy);\n"
		"}\n\n";
	ShaderSamplerKit shaderSamplerKit4;
	shaderSamplerKit4.SetMinFilter(Shader::Sampler::Filter::Nearest);
	shaderSamplerKit4.SetMagFilter(Shader::Sampler::Filter::Nearest);
	shaderSamplerKit4.SetMipFilter(Shader::Sampler::Filter::Nearest);
	shaderSamplerKit4.SetMaxAnisotropy(4);
	
    addPanel(mySubKit,
        rootKey,
        vertexShaderKey,
        shaderTextureKey,
        "min/mag nearest\nmax aniso = 4\n\ntest case 4",
        "NearestMinMagAnisotropy",
        nearestMinMagAnisotropySource,
        shaderSamplerKit4);

// TEST CASE 5


	mySubKit.SetSubwindow(HPS::Rectangle(-1.0f, -0.5f, -1, 0), HPS::Subwindow::Type::Lightweight);


	char const* linearMinMagNoMipSource =
		"void custom_main(inout PixelShaderContext ctx) { \n"
		"\tctx.poutput.FinalColor = textureSample(usergridTexture, userLinearMinMagNoMipSampler, ctx.pinput.texcoord0.xy);\n"
		"}\n\n";
	ShaderSamplerKit shaderSamplerKit5;
	shaderSamplerKit5.SetMinFilter(Shader::Sampler::Filter::Linear);
	shaderSamplerKit5.SetMagFilter(Shader::Sampler::Filter::Linear);
	shaderSamplerKit5.SetMipFilter(Shader::Sampler::Filter::Nearest);
	shaderSamplerKit5.SetMaxLOD(0);

	addPanel(mySubKit,
		rootKey,
		vertexShaderKey,
		shaderTextureKey,
		"min/mag linear\nno mipmap\n\ntest case 5",
		"LinearMinMagNoMip",
		linearMinMagNoMipSource,
        shaderSamplerKit5);





// TEST CASE 6


	mySubKit.SetSubwindow(HPS::Rectangle(-0.5f, 0, -1, 0), HPS::Subwindow::Type::Lightweight);


	char const* linearMinMagNearestMipSource = "void custom_main(inout PixelShaderContext ctx) { \n"
		"\tctx.poutput.FinalColor = textureSample(usergridTexture, "
		"userLinearMinMagNearestMipSampler, ctx.pinput.texcoord0.xy);\n"
		"}\n\n";
	ShaderSamplerKit shaderSamplerKit6;
	shaderSamplerKit6.SetMinFilter(Shader::Sampler::Filter::Linear);
	shaderSamplerKit6.SetMagFilter(Shader::Sampler::Filter::Linear);
	shaderSamplerKit6.SetMipFilter(Shader::Sampler::Filter::Nearest);

	addPanel(mySubKit,
		rootKey,
		vertexShaderKey,
		shaderTextureKey,
		"min/mag linear\nmipmap nearest\n\ntest case 6",
		"LinearMinMagNearestMip",
		linearMinMagNearestMipSource,
		shaderSamplerKit6);
	


	// TEST CASE 7

	mySubKit.SetSubwindow(HPS::Rectangle(0, 0.5f, -1, 0), HPS::Subwindow::Type::Lightweight);


	char const* linearMinMagLinearMipSource = "void custom_main(inout PixelShaderContext ctx) { \n"
		"\tctx.poutput.FinalColor = textureSample(usergridTexture, "
		"userLinearMinMagLinearMipSampler, ctx.pinput.texcoord0.xy);\n"
		"}\n\n";
	ShaderSamplerKit shaderSamplerKit7;
	shaderSamplerKit7.SetMinFilter(Shader::Sampler::Filter::Linear);
	shaderSamplerKit7.SetMagFilter(Shader::Sampler::Filter::Linear);
	shaderSamplerKit7.SetMipFilter(Shader::Sampler::Filter::Linear);
	addPanel(mySubKit,
		rootKey,
		vertexShaderKey,
		shaderTextureKey,
		"min/mag linear\nmipmap linear\n\ntest case 7",
		"LinearMinMagLinearMip",
		linearMinMagLinearMipSource,
		shaderSamplerKit7);
	



	// TEST CASE 8

	mySubKit.SetSubwindow(HPS::Rectangle(0.5f, 1, -1, 0), HPS::Subwindow::Type::Lightweight);

	char const* linearMinMagAnisotropySource = "void custom_main(inout PixelShaderContext ctx) { \n"
		"\tctx.poutput.FinalColor = textureSample(usergridTexture, "
		"userLinearMinMagAnisotropySampler, ctx.pinput.texcoord0.xy);\n"
		"}\n\n";
	ShaderSamplerKit shaderSamplerKit8;
	shaderSamplerKit8.SetMinFilter(Shader::Sampler::Filter::Linear);
	shaderSamplerKit8.SetMagFilter(Shader::Sampler::Filter::Linear);
	shaderSamplerKit8.SetMipFilter(Shader::Sampler::Filter::Linear);
	shaderSamplerKit8.SetMaxAnisotropy(16);
    addPanel(mySubKit,
        rootKey,
        vertexShaderKey,
        shaderTextureKey,
        "min/mag linear\nmax aniso = 16\n\ntest case 8",
        "LinearMinMagAnisotropy",
        linearMinMagAnisotropySource,
        shaderSamplerKit8);


    GetCanvas().UpdateWithNotifier().Wait();

}