I looked into the FrameDebugger and saw: Diffuse looks good, but my shader didn’t write anything into the specular buffer. I only found this out, because you told me about the Render Targets, so I understood what these are for:
So I changed my fragment shader to return a struct instead of a float4.
struct FragmentOutput {
float4 gBuffer0 : SV_Target0;
float4 gBuffer1 : SV_Target1;
float4 gBuffer2 : SV_Target2;
float4 gBuffer3 : SV_Target3;
};
Got this bit from here:
I’m not completely there, but the “buffer shining through mesh”-artifacts (as seen in the video I posted) are gone
So thanks for the hints @customphase
If anyone is interested:
Shader "Custom/Grass" {
Properties{
_TintColor1("Tint Color 1", Color) = (1, 1, 1)
_TintColor2("Tint Color 2", Color) = (1, 1, 1)
_ColorHeight("Color Height", Range(0, 1)) = .3
_StencilRef("Stencil Ref Value", Range(0, 100)) = 10
_StencilWriteMask("Stencil WriteMask Value", Range(0, 100)) = 14
_StencilRefDepth("Stencil Ref Value Depth", Range(0, 100)) = 8
_StencilWriteMaskDepth("Stencil WriteMask Value Depth", Range(0, 100)) = 14
_SpecularRGB("Specular Color", Color) = (1, 1, 1)
_RoughnessValue("Roughness Value", Range(0,1)) = 0.5
}
SubShader{
Pass {
Name "GBuffer"
Tags { "LightMode" = "GBuffer" }
ZWrite Off
Stencil {
Ref [_StencilRef]
WriteMask [_StencilWriteMask]
Comp Always
Pass Replace
}
HLSLPROGRAM
#pragma target 3.5
#pragma multi_compile_instancing
#include "UnityCG.cginc"
#pragma vertex DepthOnlyPassVertex
#pragma fragment DepthOnlyPassFragment
struct VertexInput {
float4 pos : POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct VertexOutput {
float4 clipPos : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
float4 _TintColor1;
float4 _TintColor2;
float _ColorHeight;
float3 _SpecularRGB;
float _RoughnessValue;
VertexOutput DepthOnlyPassVertex(VertexInput input) {
VertexOutput output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
float4 worldPos = mul(UNITY_MATRIX_M, float4(input.pos.xyz, 1.0));
output.clipPos = mul(unity_MatrixVP, worldPos);
return output;
}
struct FragmentOutput {
float4 gBuffer0 : SV_Target0;
float4 gBuffer1 : SV_Target1;
float4 gBuffer2 : SV_Target2;
float4 gBuffer3 : SV_Target3;
};
FragmentOutput DepthOnlyPassFragment(VertexOutput input) : SV_TARGET{
UNITY_SETUP_INSTANCE_ID(input);
FragmentOutput output;
float4 albedo = lerp(_TintColor1, _TintColor2, _ColorHeight);
output.gBuffer0.rgb = albedo; // Diffuse (RGB), unused (A)
float3 specular_roughness = float4(_SpecularRGB.r, _SpecularRGB.g, _SpecularRGB.b, _RoughnessValue);
output.gBuffer1.rgb = specular_roughness; // specular (RGB) Roughness (A)
output.gBuffer2.rgb = float4(0, 0, 0, 0); // world space normal?
output.gBuffer3.rgb = float4(0, 0, 0, 0); // emission + lighting + lightmaps + reflection probes buffer...
return output;
}
ENDHLSL
}
Pass {
Name "DepthOnly"
Tags { "LightMode" = "DepthOnly" "Queue" = "Geometry+0" "RenderType" = "Opaque" "RenderPipeline" = "HDRenderPipeline" }
ColorMask 0
ZWrite On
Stencil {
Ref[_StencilRefDepth]
WriteMask[_StencilWriteMaskDepth]
Comp Always
Pass Replace
}
HLSLPROGRAM
#pragma target 3.5
#pragma multi_compile_instancing
#include "UnityCG.cginc"
#pragma vertex DepthOnlyPassVertex
#pragma fragment DepthOnlyPassFragment
struct VertexInput {
float4 pos : POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct VertexOutput {
float4 clipPos : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
VertexOutput DepthOnlyPassVertex(VertexInput input) {
VertexOutput output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
float4 worldPos = mul(UNITY_MATRIX_M, float4(input.pos.xyz, 1.0));
output.clipPos = mul(unity_MatrixVP, worldPos);
return output;
}
float4 DepthOnlyPassFragment(VertexOutput input) : SV_TARGET{
UNITY_SETUP_INSTANCE_ID(input);
return 0;
}
ENDHLSL
}
}
FallBack "HDRP/Lit"
}