diff --git a/Graphics/MetalNativeShader/Assets/MetalSimpleTexture.shader b/Graphics/MetalNativeShader/Assets/MetalSimpleTexture.shader index 63c11c7..9803dff 100644 --- a/Graphics/MetalNativeShader/Assets/MetalSimpleTexture.shader +++ b/Graphics/MetalNativeShader/Assets/MetalSimpleTexture.shader @@ -31,10 +31,15 @@ METAL_CONST_VECTOR(half, 4, _Color); }; + struct ColorInput + { + float4 color; + }; + struct InputVP { float4 pos METAL_VERTEX_INPUT(0); - float2 uv METAL_VERTEX_INPUT(3); + float2 uv METAL_VERTEX_INPUT(4); }; struct OutputVP { @@ -53,10 +58,14 @@ output.uv = input.uv; return output; } - fragment OutputFS frag(constant Globals& glob [[ buffer(0) ]], OutputVP input [[ stage_in ]], METAL_TEX_INPUT(texture2d, 0, _MainTex)) + fragment OutputFS frag(constant Globals& glob [[ buffer(0) ]], METAL_BUFFER_INPUT(ColorInput, 1, _ColorBuffer), + METAL_TEX_INPUT(texture2d, 0, _MainTex), + OutputVP input [[ stage_in ]]) { + METAL_BUFFER_INPUT_DATA(ColorInput, _ColorBuffer) + OutputFS output; - output.color.rgb = glob._Color.rgb * _MainTex.sample(sampler__MainTex, input.uv).xyz; + output.color.rgb = glob._Color.rgb * (half3)_ColorBuffer[0].color.xyz * _MainTex.sample(sampler__MainTex, input.uv).xyz; output.color.a = 1; return output; } diff --git a/Graphics/MetalNativeShader/Assets/TestMetalShader.cs b/Graphics/MetalNativeShader/Assets/TestMetalShader.cs index 56d9218..094dd85 100644 --- a/Graphics/MetalNativeShader/Assets/TestMetalShader.cs +++ b/Graphics/MetalNativeShader/Assets/TestMetalShader.cs @@ -6,6 +6,10 @@ public class TestMetalShader : MonoBehaviour { public Shader shader; + private Material mat; + private Texture tex; + private ComputeBuffer buf; + private Texture2D CreateTexture(int ext) { Texture2D tex = new Texture2D(ext,ext,TextureFormat.RGBA32, false,false); @@ -21,6 +25,7 @@ private Texture2D CreateTexture(int ext) } } tex.SetPixels(pixels); + tex.wrapMode = TextureWrapMode.Clamp; tex.Apply(false, false); return tex; @@ -28,9 +33,23 @@ private Texture2D CreateTexture(int ext) void Start() { - Material mat = new Material(shader); - mat.mainTexture = CreateTexture(64); - mat.color = new Color(1,0,0,1); + buf = new ComputeBuffer(1, 4*sizeof(float)); + buf.SetData(new float[]{0.0f,1.0f,0.0f,1.0f}); + + tex = CreateTexture(32); + + mat = new Material(shader); + mat.mainTexture = tex; + mat.SetBuffer("_ColorBuffer", buf); + mat.color = new Color(1,1,0,1); + GetComponent().material = mat; } + + void OnDisable() + { + DestroyImmediate(mat); + buf.Release(); + DestroyImmediate(tex); + } } diff --git a/Graphics/MetalNativeShader/README.md b/Graphics/MetalNativeShader/README.md index deb7c7e..d93f197 100644 --- a/Graphics/MetalNativeShader/README.md +++ b/Graphics/MetalNativeShader/README.md @@ -8,7 +8,7 @@ This is a sample of using Metal Shading Language in Unity Shaders. ##Prerequisites -Unity: 2017 +Unity: 2019 ## How does it work @@ -21,7 +21,7 @@ Please note that you specify entry points for vertex program and fragment shader To connect your shaders with Unity you need to mark vertex inputs, uniforms and textures. Please note that for uniforms only one (shared between vertex program and fragment shaders) uniform buffer is supported. -Use `METAL_VERTEX_INPUT` to mark vertex data. Arguments are: 0 for position, 1 - normal, 2 - color, 3-6 - uvs, 7 - tangent. +Use `METAL_VERTEX_INPUT` to mark vertex data. Arguments are: 0 for position, 1 - normal, 2 - tangent, 3 - color, 4-7 - uvs struct InputVP { @@ -29,9 +29,18 @@ Use `METAL_VERTEX_INPUT` to mark vertex data. Arguments are: 0 for position, 1 - float2 uv METAL_VERTEX_INPUT(3); }; -Use `METAL_TEX_INPUT` to mark used textures. Arguments are: first is metal type to use, second bind point and third texture property name. +Use `METAL_TEX_INPUT` to mark used textures. Arguments are: first is metal type to use, second is the bind point and third is the property name. + + METAL_TEX_INPUT(texture2d, 0, _MainTex) + +Use `METAL_BUFFER_INPUT` to mark used buffers. HLSL analogue is StructuredBuffer, but unlike HLSL you need to pass element count yourself. Arguments are: first is the type of element, second is the bind point and third is the property name. + + METAL_BUFFER_INPUT(ColorInput, 1, _ColorBuffer) + +As metal do not have implicit UAV counters, unity is forced to allocate extra space in all Compute Buffers, so you also need `METAL_BUFFER_INPUT_DATA` to extract data pointer. Arguments are: first is the type of element, second is the property name. + + METAL_BUFFER_INPUT_DATA(ColorInput, _ColorBuffer) - fragment OutputFS frag(<...>, METAL_TEX_INPUT(texture2d, 0, _MainTex)) Use `METAL_CONST_MATRIX` and `METAL_CONST_VECTOR` to mark uniform declarations. Arguments are: `METAL_CONST_VECTOR(type, dim, name)` and `METAL_CONST_MATRIX(type, rows, cols, name)`