aboutsummaryrefslogtreecommitdiff
From Const-me @ https://news.ycombinator.com/item?id=28346931

These shaders are *.bin resources embedded in dwmcore.dll.

This tool can extract https://www.nirsoft.net/utils/resources_extract.html Then, cmd_decompiler.exe from there https://github.com/bo3b/3Dmigoto can either disassemble or decompile these binaries.

The pixel shaders there include both ps_4_0 code for new GPUs, and ps_2_0 for running on DirectX 9 GPUs. This makes the disassembler slightly more useful than the decompiler, the *.asm will contain both programs.

They first sample from 4 locations of the source texture. The sample locations are computed by vertex shaders somehow, and passed in TEXCOORD1 and TEXCOORD2 input registers. 2D sampler needs 2 floats for UV on input, texture coordinate vectors have up to 4 components on GPUs, so they’re packing 4 2D vectors into two 4D ones, and using xy and zw slices of these vectors. Because they probably using bilinear sampling (these are setup by CPU-running code, I have not looked), these 4 sample instructions are actually reading from 16 texels of the source texture.

Then, they compute the average of the 4 colors.

At this stage, they’re using pre-multiplied alpha.

For the next step of the pixel shader, they compare alpha with zero. If not zero, they convert the color to straight alpha, apply this formula https://entropymine.com/imageworsener/srgbformula/ to convert from sRGB to linear, then convert back to pre-multiplied alpha.

For the last step, they’re applying linear transformation to the color using input values passed in the constant buffer. This part varies a lot for different shaders. Some shaders only using a single scalar constant, and returning (alpha.wwww*result)^2 color. Other shaders are using 4x5 transformation matrix in the constant buffer to transform the final color.

P.S. There’re 282 compiled pixel shaders there, and I only looked at a few of them. It’s very possible some other ones are doing something completely different. I think Microsoft compiled them from just a few source *.hlsl files, with different preprocessor macros. At least that’s how I would do that if I were implementing these effects.