I want to use Graphics.DrawProcedural to draw procedural meshs with a surface shader. I can’t get the shader to cast and receive shadows.
Unity version: 2019.4.4f1
I have a test shader:
Shader "Unlit/shaderTest03_surf_no_buffs"
{
Properties
{
_Color("Color", Color) = (1,1,1,1)
_MainTex("Albedo (RGB)", 2D) = "white" {}
_Glossiness("Smoothness", Range(0,1)) = 0.5
_Metallic("Metallic", Range(0,1)) = 0.0
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 200
//Cull Off
CGPROGRAM
#pragma surface surf Standard vertex:vert addshadow
//#pragma surface surf Standard vertex:vert fullforwardshadows
//#pragma surface surf Standard fullforwardshadows
//#pragma surface surf Standard vertex:vert fullforwardshadows addshadow
//#pragma surface surf Standard vertex:vert
//#pragma multi_compile_instancing //don't need in surface shader
#pragma target 4.5
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
//float4 tangent : TANGENT;
float4 color : COLOR;
float4 texcoord : TEXCOORD0;
float4 texcoord1 : TEXCOORD1;
float4 texcoord2 : TEXCOORD2;
uint vId : SV_VertexID;
uint iId: SV_InstanceID;
};
struct Input
{
float2 uv_MainTex;
};
float4x4 _LocalToWorld;
float4x4 _WorldToLocal;
void vert(inout appdata v)
{
v.normal = float3(0.,0.,-1.);
if (v.iId == 0) {
if (v.vId == 0) {
v.vertex = float4(0., 0., 0., 0. );
v.texcoord = float4(0., 0., 0., 0.);
}
else if (v.vId == 1) {
v.vertex = float4(0., 1., 0., 0. );
v.texcoord = float4(0., 1., 0., 0.);
}
else if (v.vId == 2) {
v.vertex = float4(1., 1., 0., 0. );
v.texcoord = float4(1., 1., 0., 0.);
}
}
else {
if (v.vId == 0) {
v.vertex = float4(0., 0., -1., 0.);
v.texcoord = float4(0., 0., 0., 0.);
}
else if (v.vId == 1) {
v.vertex = float4(0., 1., -1., 0.);
v.texcoord = float4(0., 1., 0., 0.);
}
else if (v.vId == 2) {
v.vertex = float4(1., 1., -1., 0. );
v.texcoord = float4(1., 1., 0., 0.);
}
}
// Transform modification
unity_ObjectToWorld = _LocalToWorld;
unity_WorldToObject = _WorldToLocal;
}
fixed4 _Color;
sampler2D _MainTex;
void surf(Input IN, inout SurfaceOutputStandard o)
{
float4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
//o.Albedo = IN.color.rgb;
//o.Metallic = _Metallic;
//o.Smoothness = _Smoothness;
//o.Normal = float3(0, 0, IN.vface < 0 ? -1 : 1); // back face support
//o.Emission = _Emission * IN.color.rgb;
}
ENDCG
}
//FallBack "Diffuse"
}
My test script calls Graphics.DrawProcedural from update:
void Update()
{
Bounds bounds = new Bounds(Vector3.zero, new Vector3(10, 10, 10));
matTest03.SetMatrix("_LocalToWorld", transform.localToWorldMatrix);
matTest03.SetMatrix("_WorldToLocal", transform.worldToLocalMatrix);
matTest03.SetPass(0);
Graphics.DrawProcedural(
matTest03,
bounds,
MeshTopology.Triangles,
3, //triArray.Length
2,
null,
null,
ShadowCastingMode.On,
true,
gameObject.layer
);
}
What am I missing to get the procedural mesh to cast and receive shadows? The shader sometimes has an error: invalid subscript ‘instanceID’ ‘UnitySetupInstanceID’ no matching 1 parameeter function. Sometimes it pops up and other times not. I compile and show code but can’t find the error. Maybe this is breaking the shadow casting pass. I try using addshadow and fullforwardshadows. addshadow should be Generating a shadow caster pass.
My end goal is to read the verts, etc from a StructuredBuffer but can’t get even this simple procedural shader to to cast and receive shadows.
Any help would be appreciated. I would be great if Unity would put a working example shader in the Graphics.DrawProcedural doc.