Last active
January 5, 2025 14:34
-
-
Save kraj0t/3275c44b1d200b9997e625d66f1be9f1 to your computer and use it in GitHub Desktop.
How to include C# code in an HLSL file - useful for sharing code between CPU and shader without duplicating any files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Share code between HLSL (shaders) and C# | |
// | |
// Limitations: | |
// - Cannot use #include | |
// - Must use defines to hide certain keywords, such as public, private, protected, or any other object-oriented programming keywords | |
// - Use defines to convert half or fixed to your desired C# equivalent | |
// - Must always write f after float literals | |
// - Use #if !MY_DEFINE instead of #ifndef MY_DEFINE | |
// - #define cannot be used with a value in C#, not even inside an '#if SHADER_TARGET' block. Therefore, you have two options for declaring valued constants: | |
// a. Declare each constant separately in HLSL (using 'static const float MyConstant = 1.0f') and in C# (using 'const float MyConstant = 1.0f'). C# does not support 'static const'. | |
// b. Declare the constants inside the methods in your shared code using 'const float MyConstant = 1.0f;' | |
// Include guard that works identically in both HLSL and C# | |
#if !MY_CODE_INCLUDED | |
#define MY_CODE_INCLUDED | |
// SHADER_TARGET is a preprocessor directive that is defined for shaders, but not for C# code. We can use it to know if we are being included from a shader. | |
#if SHADER_TARGET | |
// HLSL exclusive header section: HLSL constants, macros, remove the C# keywords... | |
// These defines let your C# code use certain keywords normally, because they will get replaced with "" in HLSL. Feel free to add others. | |
#define public | |
#define private | |
#define internal | |
#else | |
// C# exclusive header section: references, class, namespace... | |
// The two lines below let you use HLSL syntax in C# such as float3, mul, lerp, etc. | |
using Unity.Mathematics; | |
using static Unity.Mathematics.math; | |
public static class UsingCsCodeInHLSL | |
{ | |
#endif | |
//////// SHARED CODE START //////// | |
float3 TestFunctionWrittenInCs(float3 color) | |
{ | |
float lum = dot(color, float3(0.2126f, 0.7152f, 0.0722f)); | |
return float3(lum, lum, lum); | |
} | |
//////// SHARED CODE END //////// | |
// End the C# class | |
#if !SHADER_TARGET | |
} | |
#endif | |
#endif // MY_CODE_INCLUDED |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "Unlit/UsingCsCodeInHLSL" | |
{ | |
Properties | |
{ | |
_MainTex ("Texture", 2D) = "white" {} | |
} | |
SubShader | |
{ | |
Pass | |
{ | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
// Include the C# file | |
#include "UsingCsCodeInHLSL.cs" | |
struct v2f | |
{ | |
float2 uv : TEXCOORD0; | |
float4 vertex : SV_POSITION; | |
}; | |
sampler2D _MainTex; | |
float4 _MainTex_ST; | |
v2f vert (float4 vertex : POSITION, float2 uv : TEXCOORD0) | |
{ | |
v2f o; | |
o.vertex = UnityObjectToClipPos(vertex); | |
o.uv = uv; | |
return o; | |
} | |
fixed4 frag (v2f i) : SV_Target | |
{ | |
fixed4 col = tex2D(_MainTex, i.uv); | |
// Use the C# code! | |
col.rgb = TestFunctionWrittenInCs(col.rgb); | |
return col; | |
} | |
ENDCG | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment