Closed Mushe94 closed 3 years ago
no easy hookfor this, sorry.
Hi there, quick question, is there a way to make the See Through shader to only get activated when certain objects are in front? At the moment everything is getting detected which is sometimes not desired.
Thanks!
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/alelievr/HDRP-Custom-Passes/issues/17, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADYEPYCP75SGC4NAKYHL5DR7QK43ANCNFSM4PXXGBWQ.
Mm, I see. And the hard way? Or the most hacky way possible?
We are basically trying to make the Player to get renderer when a wall is on top of him (isometric perspective), but the shader is also getting applied whenever any other thing gets in the way, including the Player itself (due to it having clothing on top, helmet, etc.), including the weapons that he carries on its back/leg are getting triggered by the shader.
but the shader is also getting applied whenever any other thing gets in the way, including the Player itself (due to it having clothing on top, helmet, etc.),
Hum I see, I guess it's because these objects are not in the same layer than the player?
There might be an easy solution here, if you look at line 41 of SeeThrough.cs there is the rendering of all the blockers into the stencil buffer.
Then at line 49 we use this stencil to only render the meshes with the ShaderGraph material that have the stencil bit enabled (so that we know they are behind something).
If instead of having one layer mask for the two draw renderers you had two (one for each call), it would allow you to only put your walls into the blocker stencil while still having the other see through objects.
Wow that worked perfectly! Thank you very much!
If anyone finds this and is looking for the same solution, here is the entire SeeThrough.cs:
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using System.Collections.Generic;
class SeeThrough : CustomPass
{
public LayerMask seeThroughBlocker = 1;
public LayerMask seeThroughTarget = 1;
public Material seeThroughMaterial = null;
[SerializeField, HideInInspector]
Shader stencilShader;
Material stencilMaterial;
ShaderTagId[] shaderTags;
protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
{
if (stencilShader == null)
stencilShader = Shader.Find("Hidden/Renderers/SeeThroughStencil");
stencilMaterial = CoreUtils.CreateEngineMaterial(stencilShader);
shaderTags = new ShaderTagId[4]
{
new ShaderTagId("Forward"),
new ShaderTagId("ForwardOnly"),
new ShaderTagId("SRPDefaultUnlit"),
new ShaderTagId("FirstPass"),
};
}
protected override void Execute(ScriptableRenderContext renderContext, CommandBuffer cmd, HDCamera hdCamera, CullingResults cullingResult)
{
// We first render objects into the user stencil bit 0, this will allow us to detect
// if the object is behind another object.
stencilMaterial.SetInt("_StencilWriteMask", (int)UserStencilUsage.UserBit0);
RenderObjects(renderContext, cmd, stencilMaterial, 0, CompareFunction.LessEqual, cullingResult, hdCamera, seeThroughBlocker);
// Then we render the objects that are behind walls using the stencil buffer with Greater Equal ZTest:
StencilState seeThroughStencil = new StencilState(
enabled: true,
readMask: (byte)UserStencilUsage.UserBit0,
compareFunction: CompareFunction.Equal
);
RenderObjects(renderContext, cmd, seeThroughMaterial, seeThroughMaterial.FindPass("ForwardOnly"), CompareFunction.GreaterEqual, cullingResult, hdCamera, seeThroughTarget, seeThroughStencil);
}
public override IEnumerable<Material> RegisterMaterialForInspector() { yield return seeThroughMaterial; }
void RenderObjects(ScriptableRenderContext renderContext, CommandBuffer cmd, Material overrideMaterial, int passIndex, CompareFunction depthCompare, CullingResults cullingResult, HDCamera hdCamera, LayerMask layer, StencilState? overrideStencil = null)
{
// Render the objects in the layer blur mask into a mask buffer with their materials so we keep the alpha-clip and transparency if there is any.
RendererListDesc result = new RendererListDesc(shaderTags, cullingResult, hdCamera.camera)
{
rendererConfiguration = PerObjectData.None,
renderQueueRange = RenderQueueRange.all,
sortingCriteria = SortingCriteria.BackToFront,
excludeObjectMotionVectors = false,
overrideMaterial = overrideMaterial,
overrideMaterialPassIndex = passIndex,
layerMask = layer,
stateBlock = new RenderStateBlock(RenderStateMask.Depth){ depthState = new DepthState(true, depthCompare)},
};
if (overrideStencil != null)
{
RenderStateBlock block = result.stateBlock.Value;
block.mask |= RenderStateMask.Stencil;
block.stencilState = overrideStencil.Value;
result.stateBlock = block;
}
HDUtils.DrawRendererList(renderContext, cmd, RendererList.Create(result));
}
protected override void Cleanup()
{
// Cleanup code
}
}`
Hello, I'm back!
Is there a way to use different materials based on which layer the object is being rendered into? (Basically Player = Blue, Enemy = Red)
We tried adding a second Custom Pass Game Object but it works some of the times (sometimes both and others just one of the two). Any ideas how to do this?
You could use MaterialPropertyBlock to change some shader properties. I use it to change the color of the outline on my character (made using a custom pass) and it works perfectly.
That's a very nice idea. Thanks. I would need some pointers about how to integrate that with the current script setup because I don't really know were (and perhaps how) to integrate it.
Well I managed to fix it having 2 Custom Pass Game Objects and deleting the second camera we had for the GUI (which also gave us like 30 FPS). Now we need a way of rendering TMPro World Space on top of everything but that's out of the scope of this shader. Thanks anyways!
Hi there, quick question, is there a way to make the See Through shader to only get activated when certain objects are in front? At the moment everything is getting detected which is sometimes not desired.
Thanks!