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();
}
