I am trying to get a custom shader to work with vertex pulling from a generic buffer. To do this, I’ve created a custom shader that only uses SV_VertexId and a StructuredBuffer as inputs, and then I call Graphics.DrawProcedural to actually draw stuff. The basics work, but I’m having a lot of trouble getting the correct MVP matrix in the shader.
I found How do I reproduce the MVP matrix? - Questions & Answers - Unity Discussions but it doesn’t work reliably on all my platforms; sometimes I need to flip the Y-coordinate, and sometimes I don’t. So I figured I would go back to the shader and attempt to use the UnityObjectToClipPos() function in 2017.1.
That works for the VP part of the MVP matrix, but the model part isn’t updated. If I create a scene then I can see that standard objects/shaders do scale for example, but the object with my custom script and shader doesn’t.
Below is some example code that exhibits the issue. Simply create an empty GameObject, attach this script, create a new Material that uses this custom shader and link that into the script. Although the procedural triangle is correctly rendered as the camera changes position, any changes to the position/rotation/scale aren’t visible.
I have looked at the render calls with RenderDoc, and as far as I can tell there is a matrix in the shader that stays at identity. I suspect that is the model matrix, and that I somehow need to tell Unity to update it from the current transform.
Any help would be greatly appreciated!
Kind regards,
Rick
Script
using UnityEngine;
public class TestDirectProcedural : MonoBehaviour {
public Material mat;
public void OnRenderObject()
{
mat.SetPass(0);
Graphics.DrawProcedural(MeshTopology.Triangles, 3, 1);
}
}
Shader
Shader "Custom/TestProceduralShader" {
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
Pass
{
Cull Off
CGPROGRAM
#include "UnityShaderVariables.cginc"
#pragma only_renderers d3d11
#pragma vertex vs
#pragma fragment ps
#pragma target 3.0
struct v2f {
float4 position : SV_Position;
};
static float3 positions[3] = {
float3(0,0,0),
float3(10,0,0),
float3(0,0,10)
};
v2f vs( uint index : SV_VertexId ) {
v2f o;
float4 position = float4(positions[index], 1);
position = UnityObjectToClipPos(position);
o.position = position;
return o;
}
fixed4 ps(v2f input) : SV_Target0
{
return fixed4(1, 0, 0, 1);
}
ENDCG
}
}
}