dev.nlited.com

>>

Shader Math

<<<< prev
next >>>>

2022-12-15 20:50:59 chip Page 2467 📢 PUBLIC

December 15 2022

PxlShader

That square tint over the round circle is bothering me. Let's try to isolate the tint to the circle. I can think of three different approaches to this:

Before I dive into the HLSL code in earnest, it needs to be cleaned up to remove the last remnants of the original RippleEffect code.

Help documents for the D2D HLSL helper functions can be found in the VS Help Viewer under Desktop app technologies > Graphics and Gaming > DirectX > Direct2D > API Reference > HLSL Helpers.

Paring FirstShader.hlsl back to the absolute bare bones:


FirstShader.hlsl: #define D2D_INPUT_COUNT 1 #include "d2d1effecthelpers.hlsli" cbuffer constants: register(b0) { float4 tint:COLOR; }; D2D_PS_ENTRY(main) { float4 color = D2DGetInput(0); color+= tint; return color; } //EOF: FIRSTSHADER.HLSL

And start building it back up by checking for non-black pixels. The any intrinsic function will return true of any member of an array or structure is non-zero. Sounds like a winner...

any: #define D2D_INPUT_COUNT 1 #include "d2d1effecthelpers.hlsli" cbuffer constants: register(b0) { float4 tint:COLOR; }; D2D_PS_ENTRY(main) { float4 color = D2DGetInput(0); if(any(color)) { color+= tint; } return color; } //EOF: FIRSTSHADER.HLSL

Now the tint is restricted to only the non-black pixels.

PxlShader

Lets try using the alpha channel...

alpha: D2D_PS_ENTRY(main) { float4 color = D2DGetInput(0); color+= tint*color.a; return color; }

That works too. Finally, let's try restricting the tint to a circle.

circle: D2D_PS_ENTRY(main) { float4 color = D2DGetInput(0); float2 ptCtr= { 0.5f, 0.5f}; float2 ptPxl= D2DGetInputCoordinate(0).xy; float dist= distance(ptCtr,ptPxl); if(dist < 0.25f) color+= tint; return color; }

PxlShader

I have restricted the tint to 1/2 of the circle to make it obvious what is happening. This is a bit trickier, so lets walk through it.

I sample the current input pixel and store it in the variable color:
float4 color = D2DGetInput(0);

Then I set ptCtr to be the point at the center of the scene and store the coordinates of the input pixel in ptPxl.
float2 ptCtr= { 0.5f, 0.5f}; float2 ptPxl= D2DGetInputCoordinate(0).xy;
Coordinates are normalized, so that (0,0) is always the upper left corner and (1.0,1.0) is always the lower right corner. Also note that ".xy" returns only the X and Y of the coordinates.

I then calculate the distance between ptCtr and ptPxl using the intrinsic distance function.
float dist= distance(ptCtr,ptPxl);

I apply the tint only if the distance is less than 0.25.
if(dist < 0.25f) color+= tint;

Finally, I return the (possibly) modified color to be rendered.

How are the coordinates scaled if the texture is not square? To test this, I created pbmSrc as an oblong rectangle 200x100 pixels. The result clearly shows that X and Y are always scaled to 1.0, disregarding the aspect ratio.

PxlShader

This code is just one step away from a fancy gradient fade:

Gradient: D2D_PS_ENTRY(main) { float4 color = D2DGetInput(0); float2 ptCtr= { 0.5f, 0.5f}; float2 ptPxl= D2DGetInputCoordinate(0).xy; float dist= distance(ptCtr,ptPxl); color*= 1.0f - dist/0.5f; return color; }

PxlShader

Note that the fade needs to be applied to the entire color, applying it only to the alpha does not work since this shader is replacing the normal alpha blend. If I want to apply alpha blending, I need to do it myself. This code produces the same result, but uses the alpha channel.

alpha: D2D_PS_ENTRY(main) { float4 color = D2DGetInput(0); float2 ptCtr= { 0.5f, 0.5f}; float2 ptPxl= D2DGetInputCoordinate(0).xy; float dist= distance(ptCtr,ptPxl); color.a= 1.0f - dist/0.5f; color.rgb*= color.a; return color; }

Moderator: close comments Comments are closed.

Comments are moderated. Anonymous comments are not visible to others until moderated. Comments are owned by the author but may be removed or reused (but not modified) by this site at any time without notice.

HTML
  1. Moderator: [] approve delete HTML



WebV7 (C)2018 nlited | Rendered by tikope in 109.999ms | 18.190.160.6