問題描述
在新紋理上切割具有圓形形狀的 Direct3D 紋理或更改部分像素的 Alpha 值 (cut Direct3D texture with circular shape on a new texture OR change Alpha value of a part of pixels)
你好,對不起我的英語。
我需要剪切/裁剪一個圓形的LPDIRECT3DTEXTURE9。在相同紋理上的新紋理上。
我可以更改每個像素的 ARBG 值並使用圓形區域方程將 Alpha 值更改為外部區域的 255(透明)嗎?
其他方法是創建一個透明的新紋理並僅複製我需要圓形的像素。
我怎麼不知道我是否解釋得很好......
參考解法
方法 1:
This is a compositing/masking problem. You can do it on the CPU or on the GPU.
To do it on the CPU, you can manipulate the pixels in the texture map directly with IDirect3DTexture9::LockRect.
To do it on the GPU, there are a number of techniques. The simplest is probably to set a new texture as the current render target, use the stencil or alpha buffer to mask off a circular area, then draw the old texture onto the new one using a quadrilateral that fills the render target.
方法 2:
If you already load this texture to LPDIRECT3DTEXTURE9
interface there is no way to change it. The only way is to create new by some offscreen manipulation and shaders, or using texture staging with combiners and some circular mask (wich masks proper pixels as transparent). Or just create proper texture in Photoshop with aphamask and load it.
PS. Do not forget to enable blending state by IDirect3DDevice9‑>SetRenderSate()
Here is the example of generating procedural mask to texture.
Vertex shader.
struct VS_INPUT
{
float4 Position : POSITION0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
float2 Mask : TEXCOORD1;
};
VS_OUTPUT vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.Position = Input.Position;
Output.TexCoord = (Input.Position.xy ‑ 1) * ‑0.5f;
Output.Mask = Input.Position.xy;
return( Output );
}
Pixel shader.
struct PS_INPUT
{
float2 TexCoord : TEXCOORD0;
float2 Mask : TEXCOORD1;
};
sampler Texture0;
float4 ps_main(PS_INPUT Input) : COLOR0
{
float maskCoef = 0.0f;
if ((Input.Mask.x * Input.Mask.x + Input.Mask.y * Input.Mask.y) < 1.0f)
{
maskCoef = 1.0f;
}
return maskCoef * tex2D(Texture0, Input.TexCoord);
}
The result will be.
the size of circle can be simple changed in condition check if ((Input.Mask.x * Input.Mask.x + Input.Mask.y * Input.Mask.y) < 1.0f)
by replacing 1.0f
value with lesser 0.5f
for example will reduce mask on half.
(by SergiPanadero、legalize、Mykola)