Low level material alpha channel not working

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Hotshot5000
OGRE Contributor
OGRE Contributor
Posts: 256
Joined: Thu Oct 14, 2010 12:30 pm
x 64

Low level material alpha channel not working

Post by Hotshot5000 »

I am porting some materials to 3.0 that used to work on 2.1 and I have encountered an issue where the rendering doesn't seem to take alpha channel of the texture into account.

Code: Select all

// GLSL shaders
vertex_program sh_portal_vs_GLSL glsl
{
	source sh_portal_vs.glsl

}

fragment_program sh_portal_ps_GLSL glsl
{
	source sh_portal_fs.glsl

}

// GLSLES shaders
vertex_program sh_portal_vs_GLSLES glsles
{
	source sh_portal_vs.glsles

}

fragment_program sh_portal_ps_GLSLES glsles
{
	source sh_portal_fs.glsles

}

// VK shaders
vertex_program sh_portal_vs_VK glslvk
{
	source sh_portal_vs.glsl

}

fragment_program sh_portal_ps_VK glslvk
{
	source sh_portal_fs.glsl

}

// HLSL shaders
vertex_program sh_portal_vs_HLSL hlsl
{
    source sh_portal_vs.hlsl
    entry_point main
    target vs_5_0 vs_4_0 vs_4_0_level_9_1 vs_4_0_level_9_3


}

fragment_program sh_portal_ps_HLSL hlsl
{
	source sh_portal_fs.hlsl
	entry_point main
	target ps_5_0 ps_4_0 ps_4_0_level_9_1 ps_4_0_level_9_3

}

// Metal shaders
vertex_program sh_portal_vs_Metal metal
{
	source sh_portal_vs.metal

}

fragment_program sh_portal_ps_Metal metal
{
	source sh_portal_fs.metal
	shader_reflection_pair_hint sh_portal_vs_Metal

}

// Unified definitions
vertex_program sh_portal_vs unified
{
	delegate sh_portal_vs_HLSL
	delegate sh_portal_vs_GLSL
	delegate sh_portal_vs_GLSLES
	delegate sh_portal_vs_Metal
	delegate sh_portal_vs_VK

    default_params
{
	param_named_auto matWorldViewProjection worldviewproj_matrix
}
}

fragment_program sh_portal_ps unified
{
	delegate sh_portal_ps_HLSL
	delegate sh_portal_ps_GLSL
	delegate sh_portal_ps_GLSLES
	delegate sh_portal_ps_Metal
	delegate sh_portal_ps_VK

    default_params
{
	param_named_auto fSinTime0_X sintime_0_x 1.0
	param_named blurAmount float4 1.0 1.0 1.0 1.0
}
}

material portal_mat
{
	technique
	{
		pass
		{
			depth_check on
			depth_write on

		cull_hardware none
		scene_blend src_alpha one_minus_src_alpha
		
		vertex_program_ref sh_portal_vs
		{
		}
		fragment_program_ref sh_portal_ps
		{
		}
		texture_unit
		{
			texture portal_done1.png
		}		
	}
}
}

Shaders code vs:

Code: Select all

#version ogre_glsl_ver_330


vulkan_layout( OGRE_POSITION ) in vec3 vertex;
vulkan_layout( OGRE_DIFFUSE )in vec4 colour;
vulkan_layout( OGRE_TEXCOORD0 ) in vec2 uv0;

vulkan( layout( ogre_P0 ) uniform Params { )
uniform mat4 matWorldViewProjection;
vulkan( }; )


vulkan_layout( location = 0 )
out block
{
	vec2 uv;
	vec4 color;			

} outVs;


void main()
{   
gl_Position = matWorldViewProjection * vec4(vertex, 1.0); outVs.color = colour; outVs.uv = uv0; }

Shader code ps:

Code: Select all

#version ogre_glsl_ver_330


vulkan_layout( ogre_t0 ) uniform texture2D portalTexture;
vulkan( layout( ogre_s0 ) uniform sampler texSampler );
vulkan( layout( ogre_P0 ) uniform Params { )
uniform vec4 blurAmount;
uniform float fSinTime0_X;
vulkan( }; )

vulkan_layout( location = 0 )
in block
{
in vec2 uv;
in vec4 color;
} inPs;

vulkan_layout( location = 0 )
out vec4 o_fragColor;

void main()
{
   int i;
   vec4 tmpOutColor;
   float  diffuseGlowFactor;
   vec2 offsets[4];


   offsets[0] = vec2(-1.8,  -1.8);
   offsets[1] = vec2(-1.8,  1.8);
   offsets[2] = vec2(1.8, -1.8);
   offsets[3] = vec2(1.8, 1.8);

   tmpOutColor = texture( vkSampler2D( portalTexture, texSampler ), inPs.uv );   

   
diffuseGlowFactor = 0.0113 * (2.0 - max( tmpOutColor.r, tmpOutColor.g ));
for (i = 0; i < 4; i++) { tmpOutColor += inPs.color * texture( vkSampler2D( portalTexture, texSampler ), inPs.uv + fSinTime0_X * blurAmount.x * diffuseGlowFactor * offsets[i] ); } tmpOutColor *= vec4(0.25, 0.25, 0.25, 1.0);
o_fragColor = tmpOutColor; }

I suspect the issue is that the png file texture's alpha channel is not read properly.

Later edit: Nope. Vk returns texture format VK_FORMAT_R8G8B8A8_UNORM so the alpha channel is there.

You do not have the required permissions to view the files attached to this post.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5496
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1365

Re: Low level material alpha channel not working

Post by dark_sylinc »

Hi!

2 possible suspects:

  1. HlmsBlendblock is incorrectly setup. Could be a silly mistake. Or it could be that someone passed a stack-generated pointer instead of one generated by HlmsManager.
  2. Several months ago we updated to a newer FreeImage version and this caused issues: Missing alpha channels, swapped R & B channels. Make sure you are using latest ogre-next-deps; and that there are no lingering older versions (e.g. old *.lib files). This is a bigger problem on Linux because sometimes the build system will prefer using the system-installed version (e.g. freeimage in /usr/lib/x86_64-linux-gnu/libfreeimage.so) which is not ABI-compatible with the one used by Ogre-Next. If you're on Windows using Visual Studio 2022, download the latest VC Redistributables. There's an issue introduced by Microsoft.

RenderDoc can see the contents of all pictures, and has source-level debugging of Vulkan and D3D11, you should be able to narrow down further where the problem is.

Hotshot5000
OGRE Contributor
OGRE Contributor
Posts: 256
Joined: Thu Oct 14, 2010 12:30 pm
x 64

Re: Low level material alpha channel not working

Post by Hotshot5000 »

Checked with another material:

Code: Select all

abstract hlms BaseSettingsAlphaBlend unlit
{
	scene_blend	alpha_blend
	depth_check	on
	depth_write	on
	cull_hardware	none
}

hlms Fx/ExplosionMaterial unlit : BaseSettingsAlphaBlend
{
	diffuse_map explosion0.png
}

Image

Checked with RenderDoc and the blending looks fine when comparing with this example.

Code: Select all

CreateInfo                VkGraphicsPipelineCreateInfo()
sType                   VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
pNext                   NULL
flags                   VkPipelineCreateFlagBits(0)
stageCount              2
pStages                 VkPipelineShaderStageCreateInfo[2]
pVertexInputState       VkPipelineVertexInputStateCreateInfo()
pInputAssemblyState     VkPipelineInputAssemblyStateCreateInfo()
pTessellationState      NULL
pViewportState          VkPipelineViewportStateCreateInfo()
pRasterizationState     VkPipelineRasterizationStateCreateInfo()
pMultisampleState       VkPipelineMultisampleStateCreateInfo()
pDepthStencilState      VkPipelineDepthStencilStateCreateInfo()
pColorBlendState        VkPipelineColorBlendStateCreateInfo()
sType                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
pNext                 NULL
flags                 VkPipelineColorBlendStateCreateFlagBits(0)
logicOpEnable         0
logicOp               VK_LOGIC_OP_CLEAR
attachmentCount       1
pAttachments          VkPipelineColorBlendAttachmentState[1]
[0]                 VkPipelineColorBlendAttachmentState()
blendEnable       1
srcColorBlendFactor VK_BLEND_FACTOR_SRC_ALPHA
dstColorBlendFactor VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA
colorBlendOp      VK_BLEND_OP_ADD
srcAlphaBlendFactor VK_BLEND_FACTOR_ONE
dstAlphaBlendFactor VK_BLEND_FACTOR_ZERO
alphaBlendOp      VK_BLEND_OP_ADD
colorWriteMask    VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
blendConstants        float[4]
pDynamicState           VkPipelineDynamicStateCreateInfo()
sType                 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO
pNext                 NULL
flags                 0
dynamicStateCount     3
pDynamicStates        VkDynamicState[3]
[0]                 VK_DYNAMIC_STATE_VIEWPORT
[1]                 VK_DYNAMIC_STATE_SCISSOR
[2]                 VK_DYNAMIC_STATE_STENCIL_REFERENCE
layout                  Pipeline Layout 3525
renderPass              Render Pass 1165
subpass                 0
basePipelineHandle      No Resource
basePipelineIndex       0
CreateInfo                VkGraphicsPipelineCreateInfo()
sType                   VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
pNext                   NULL
flags                   VkPipelineCreateFlagBits(0)
stageCount              2
pStages                 VkPipelineShaderStageCreateInfo[2]
pVertexInputState       VkPipelineVertexInputStateCreateInfo()
pInputAssemblyState     VkPipelineInputAssemblyStateCreateInfo()
pTessellationState      NULL
pViewportState          VkPipelineViewportStateCreateInfo()
pRasterizationState     VkPipelineRasterizationStateCreateInfo()
pMultisampleState       VkPipelineMultisampleStateCreateInfo()
pDepthStencilState      VkPipelineDepthStencilStateCreateInfo()
pColorBlendState        VkPipelineColorBlendStateCreateInfo()
sType                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
pNext                 NULL
flags                 VkPipelineColorBlendStateCreateFlagBits(0)
logicOpEnable         0
logicOp               VK_LOGIC_OP_CLEAR
attachmentCount       1
pAttachments          VkPipelineColorBlendAttachmentState[1]
[0]                 VkPipelineColorBlendAttachmentState()
blendEnable       1
srcColorBlendFactor VK_BLEND_FACTOR_SRC_ALPHA
dstColorBlendFactor VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA
colorBlendOp      VK_BLEND_OP_ADD
srcAlphaBlendFactor VK_BLEND_FACTOR_ONE
dstAlphaBlendFactor VK_BLEND_FACTOR_ZERO
alphaBlendOp      VK_BLEND_OP_ADD
colorWriteMask    VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
blendConstants        float[4]
pDynamicState           VkPipelineDynamicStateCreateInfo()
sType                 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO
pNext                 NULL
flags                 0
dynamicStateCount     3
pDynamicStates        VkDynamicState[3]
[0]                 VK_DYNAMIC_STATE_VIEWPORT
[1]                 VK_DYNAMIC_STATE_SCISSOR
[2]                 VK_DYNAMIC_STATE_STENCIL_REFERENCE
layout                  Pipeline Layout 3525
renderPass              Render Pass 1165
subpass                 0
basePipelineHandle      No Resource
basePipelineIndex       0

Code: Select all

vkCreateImage             vkCreateImage({ VK_FORMAT_R8G8B8A8_SRGB, { 512, 32, 1 } })
device                  Device 805
CreateInfo              VkImageCreateInfo()
sType                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
pNext                 NULL
flags                 VkImageCreateFlagBits(0)
imageType             VK_IMAGE_TYPE_2D
format                VK_FORMAT_R8G8B8A8_SRGB
extent                VkExtent3D()
width               512
height              32
depth               1
mipLevels             1
arrayLayers           8
samples               VK_SAMPLE_COUNT_1_BIT
tiling                VK_IMAGE_TILING_OPTIMAL
usage                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT
sharingMode           VK_SHARING_MODE_EXCLUSIVE
queueFamilyIndexCount 0
pQueueFamilyIndices   uint32_t[0]
initialLayout         VK_IMAGE_LAYOUT_UNDEFINED
pAllocator              NULL
Image                   _InternalTex16
memoryRequirements      VkMemoryRequirements()

Same behavior. I see the black and white pixels around the explosion as if the alpha is completely ignored. Tried on both integrated AMD GPU and dedicated nVidia 3070.

Hotshot5000
OGRE Contributor
OGRE Contributor
Posts: 256
Joined: Thu Oct 14, 2010 12:30 pm
x 64

Re: Low level material alpha channel not working

Post by Hotshot5000 »

I think I understand the cause of the issue. It's not at all related to rendering the texture with alpha. It related to the dynamic cubemap compositor.

EDIT: yep. I just copied the dynamic cubemap tutorial compositor without thinking about it too much. in the tutorial it renders the scene, then the cubemap quad with the sky and then overlays, etc.

Code: Select all

compositor_node Tutorial_DynamicCubemapRenderingNode
{
	in 0 rt_renderwindow
	in 1 demo_dynamic_cubemap

target rt_renderwindow
{
	pass render_scene
	{
		load
		{
			all				clear
			clear_colour	0 0 0 1
		}
		store
		{
			depth			dont_care
			stencil			dont_care
		}

		//Our materials in this pass will be using this cubemap,
		//so we need to expose it to the pass.
		//Note: Even if it "just works" without exposing, the reason for
		//exposing is to ensure compatibility with Vulkan & D3D12.
		expose demo_dynamic_cubemap

		shadows		Tutorial_DynamicCubemapShadowNode
		overlays	off
		rq_first	0
		rq_last		200
	}

	//Render sky (see TutorialSky_Postprocess)
	pass render_quad
	{
		store
		{
			depth			dont_care
			stencil			dont_care
		}
		quad_normals	camera_direction
		material SkyPostprocess
	}

	//Render transparent stuff after sky
	pass render_scene
	{
		store
		{
			depth			dont_care
			stencil			dont_care
		}
		overlays	on
		rq_first	200
	}
}
}

But in my case if I keep it like this then the explosion billboard will do ONE_MINUS_ALPHA from the cleared color, which is black. Then the sky gets rendered but it's too late. The explosion will have black background instead of the sky.

Last edited by Hotshot5000 on Thu Apr 24, 2025 6:19 pm, edited 1 time in total.
Hotshot5000
OGRE Contributor
OGRE Contributor
Posts: 256
Joined: Thu Oct 14, 2010 12:30 pm
x 64

Re: Low level material alpha channel not working

Post by Hotshot5000 »

Something is still bugging me: items are created on renderQueueId 10 while billboardSets are on 110u.
But with RenderDoc I can clearly see that the explosion billboards are rendered before items. And because of that they look weird with transparency as they are always rendered behind the target that they hit.
I've changed the billboardSet to go to setRenderQueueSubGroup(1) and now everything is rendered correctly
If I setRenderQueueGroup(1) I get a crash with no errors. I am a bit time constrained so I don't know if I'll have time today to investigate that crash.