material { name : Grid, parameters : [ { type : float, name : maxDistance }, { type : float3, name : color } ], depthWrite : false, depthCulling : true, shadingModel : unlit, blending: opaque, variantFilter : [ skinning, shadowReceiver, vsm ], culling: none, instanced: false, vertexDomain: object } vertex { void materialVertex(inout MaterialVertexInputs material) { vec4 modelSpace = getPosition(); vec4 worldSpace = getWorldFromModelMatrix() * modelSpace; vec4 clipSpace = getClipFromWorldMatrix() * worldSpace; clipSpace.z = 0.01f; material.worldPosition = getWorldFromClipMatrix() * clipSpace; } } fragment { void material(inout MaterialInputs material) { prepareMaterial(material); // Convert world position to view space float4 viewPos = getViewFromWorldMatrix() * float4(getWorldPosition(), 1.0); // Calculate distance in view space (camera is at 0,0,0 in view space) float distance = length(viewPos.xz); // Discard fragment if it's too far from the camera if (distance > materialParams.maxDistance) { material.baseColor = float4(0.0); } else { material.baseColor = float4(materialParams.color, 1.0); // Optional: fade out as we approach maxDistance float fadeStart = materialParams.maxDistance * 0.8; if (distance > fadeStart) { float fade = 1.0 - (distance - fadeStart) / (materialParams.maxDistance - fadeStart); material.baseColor.a = fade; } } } }