I don’t know what don’t work. I guess it’s relevant to UNITY_SETUP_INSTANCE_ID or UNITY_ACCESS_INSTANCED_PROP or UNITY_VERTEX_INPUT_INSTANCE_ID. I spent a big amont of time trying to find the problem, but unsuccessfully.
Would you tell me, what’s wrong? Guys, did you see some geometry shader+GPI Instancing examples?
It’s totally possible. But you have all of the lines you’d need to make it work commented out above for some reason. The vertex shader has the instance ID as an input. The main issue I see is you’re calling UNITY_INITIALIZE_OUTPUT after you’ve setup the instance ID, which blows the value you just set away. That UNITY_INITIALIZE_OUTPUT macro sets all values of the struct to 0.0. So you need to call that first, before you call UNITY_TRANSFER_INSTANCE_ID if you’re going to call it at all. Personally I never use it because it masks when I have an error someplace else, like having an unused value in the v2f, or in your case the v2g.
To add on to this problem, I’m trying to reconfigure this script to support VR for single passed instanced rendering in the built-in renderer. But I can’t figure out a way to show it in both eyes. The script is not made by me, its free and got it from here : https://www.patreon.com/posts/53587750.
Shader "Custom/GrassForCompute"
{
Properties
{
[Toggle(FADE)] _TransparentBottom("Transparency at Bottom", Float) = 0
_Fade("Fade Multiplier", Range(1,10)) = 6
}
CGINCLUDE
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
#pragma multi_compile _SHADOWS_SCREEN
#pragma multi_compile_fwdbase_fullforwardshadows
#pragma multi_compile_fog
#pragma shader_feature FADE
struct appdata
{
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct DrawVertex
{
float3 positionWS; // The position in world space
float2 uv;
float3 diffuseColor;
};
// A triangle on the generated mesh
struct DrawTriangle
{
float3 normalOS;
DrawVertex vertices[3]; // The three points on the triangle
};
StructuredBuffer<DrawTriangle> _DrawTriangles;
struct v2f
{
float4 pos : SV_POSITION; // Position in clip space
float2 uv : TEXCOORD0; // The height of this vertex on the grass blade
float3 positionWS : TEXCOORD1; // Position in world space
float3 normalWS : TEXCOORD2; // Normal vector in world space
float3 diffuseColor : COLOR;
LIGHTING_COORDS(3, 4)
UNITY_FOG_COORDS(5)
UNITY_VERTEX_OUTPUT_STEREO
};
// Properties
float4 _TopTint;
float4 _BottomTint;
float _AmbientStrength;
float _Fade;
// Vertex function
struct unityTransferVertexToFragmentSucksHack
{
float3 vertex : POSITION;
};
v2f vert(appdata v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v); //Insert
UNITY_INITIALIZE_OUTPUT(v2f, o); //Insert
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); //Insert
return o;
}
// -- retrieve data generated from compute shader
v2f vert(uint vertexID : SV_VertexID)
{
// Initialize the output struct
v2f output = (v2f)0;
// Get the vertex from the buffer
// Since the buffer is structured in triangles, we need to divide the vertexID by three
// to get the triangle, and then modulo by 3 to get the vertex on the triangle
DrawTriangle tri = _DrawTriangles[vertexID / 3];
DrawVertex input = tri.vertices[vertexID % 3];
output.pos = UnityObjectToClipPos(input.positionWS);
output.positionWS = input.positionWS;
// float3 faceNormal = GetMainLight().direction * tri.normalOS;
float3 faceNormal = tri.normalOS;
// output.normalWS = TransformObjectToWorldNormal(faceNormal, true);
output.normalWS = faceNormal;
output.uv = input.uv;
output.diffuseColor = input.diffuseColor;
// making pointlights work requires v.vertex
unityTransferVertexToFragmentSucksHack v;
v.vertex = output.pos;
TRANSFER_VERTEX_TO_FRAGMENT(output);
UNITY_TRANSFER_FOG(output, output.pos);
return output;
}
ENDCG
SubShader
{
Cull Off
Blend SrcAlpha OneMinusSrcAlpha // for the transparency
Pass // basic color with directional lights
{
Tags
{
"LightMode" = "ForwardBase"
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float4 frag(v2f i) : SV_Target
{
// take shadow data
float shadow = 1;
#if defined(SHADOWS_SCREEN)
shadow = (SAMPLE_DEPTH_TEXTURE_PROJ(_ShadowMapTexture, UNITY_PROJ_COORD(i._ShadowCoord)).r);
#endif
// base color by lerping 2 colors over the UVs
float4 baseColor = lerp(_BottomTint , _TopTint , saturate(i.uv.y)) * float4(i.diffuseColor, 1);
// multiply with lighting color
float4 litColor = (baseColor * _LightColor0);
// multiply with vertex color, and shadows
float4 final = litColor;
final.rgb = litColor * shadow;
// add in baseColor when lights turned off
final += saturate((1 - shadow) * baseColor * 0.2);
// add in ambient color
final += (unity_AmbientSky * baseColor * _AmbientStrength);
// add fog
UNITY_APPLY_FOG(i.fogCoord, final);
// fade the bottom based on the vertical uvs
#if FADE
float alpha = lerp(0, 1, saturate(i.uv.y * _Fade));
final.a = alpha;
#endif
return final;
}
ENDCG
}
Pass
// point lights
{
Tags
{
"LightMode" = "ForwardAdd"
}
Blend OneMinusDstColor One
ZWrite Off
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdadd_fullforwardshadows
#include "UnityCG.cginc"
float4 frag(v2f i) : SV_Target
{
UNITY_LIGHT_ATTENUATION(atten, i, i.positionWS);
// base color by lerping 2 colors over the UVs
float3 baseColor = lerp(_BottomTint , _TopTint , saturate(i.uv.y)) * i.diffuseColor;
float3 pointlights = atten * _LightColor0.rgb * baseColor;
#if FADE
float alpha = lerp(0, 1, saturate(i.uv.y * _Fade));
pointlights *= alpha;
#endif
return float4(pointlights, 1);
}
ENDCG
}
Pass // shadow pass
{
Tags
{
"LightMode" = "ShadowCaster"
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#include "UnityCG.cginc"
float4 frag(v2f i) : SV_Target
{
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}
} Fallback "VertexLit"
}
Thank you @bgolus ! I just started my shader learning journey and I already stumbled across many very helpful hints from you in the forums. Thank you so much!
I’m trying to port a geometry shader to Single Pass Instanced render mode. I’m using the macros mentioned above, also tried to use UNITY_VERTEX_OUTPUT_STEREO, UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO and UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX with no luck.
Is there a way to use geometry shader with Single Pass Instanced render mode?