Showing posts with label Shaders. Show all posts
Showing posts with label Shaders. Show all posts

Converting Effect XNBs to HLSL

This guide describes a method of converting XNA effects from XNB to HLSL source code. The XNB files used in this guide are XNA 4.0 originally compiled for HiDef Xbox 360. This guide should still apply to XNA 3.1 and all other target platforms regardless of HiDef/Reach or compressed or not. Untested with XNA versions prior to 3.1.

Step 1 - Extract the CSO (DX9 compiled shader) from the XNB container using an extractor of your choice (such as this).

Step 2 - Open the CSO in a hex editor and grab any variable information (more details available here).


Step 3 - Run the CSO through the XenosRecomp tool (streamlined through the implementation here).

Step 4 - Clean the output by removing everything before main().


Step 5 - Review the actual shader code (located within main() after the variable declarations) and remove any unused variables.

Step 6 - Reformat to fit the standard XNA HLSL format using the additional variable information from the CSO.


Step 7 - Clean up as desired.





DirectX 9 CSO Teardown (XNA 3.1/4.0)

This is going to be one of those things I doubt anyone will ever need to know, but it might be useful if you're decompiling XNA games.

Note: The CSO file in this example was compiled using XNA 4.0 for Xbox 360, so everything will be in big-endian and there may be some chunks missing compared to other platforms.

Converting Shadertoy code to DirectX HLSL

Lessons learned from someone who didn't know GLSL, HLSL, or any kind of shader code a week ago.

Shadertoy is an online tool that uses WebGL (a version of GLSL) to write and run shader code. You don't need a compiler or an IDE, and you can even use it on mobile.

Shadertoy

        void mainImage( out vec4 fragColor, in vec2 fragCoord )
        {
                vec2 uv = fragCoord/iResolution.xy;
                vec4 col = texture(iChannel0, uv);
                fragColor = col;
        }

Since Shadertoy code is almost exclusively pixel shaders, your HLSL code will be a pixel shader as well. In HLSL, fragColor is COLOR0, fragCoord is SV_POSITION, and uv is TEXCOORD0. This means your mainImage() function will look like

HLSL

        float4 MainPS(float4 pos : SV_POSITION, float4 color0 : COLOR0, float2 texCoord : TEXCOORD0) : COLOR
        {
                float2 iResolution = float2(<resolutionX>, <resolutionY>);
                float4 color = tex2D(<sampler>, texCoord);
                return color;
        } 

Everything else is a 1:1 conversion between GLSL and HLSL. For example, vec4 becomes float4 and mix() becomes lerp(). Here are a few reference lists for that: