Quantcast
Viewing all articles
Browse latest Browse all 713

Custom Post process effect creates only a triangle on the screen.

Hi! I'm new with shaders, so maybe this is a noob question, but I didn't found any solution on the web so: I wrote this edge detection shader for use it in a post process effect. It is working "fine" if I use it with a monobehaviour on the camera (pasted lower), but not if I try to use it in a custom post process effect. (code at the buttom) In that case it is creates only a triangle. I would be happy with the monobehaviour solution but in that case it is overwrites the other effects. WithMono: ![alt text][1] With Post: ![alt text][2] The shader: Shader "Hidden/EdgeDetection" { Properties { _EdgeColor("EdgeColor", COLOR) = (0,0,0,1) _SampleDistance("SampleDistance", float) = 1 _DepthSensitivity("DepthSensitivity", float) = 0.1 _NormalSensitivity("NormalSensitivity",float) = 0.1 _FadeToDistance("FadeToDistance", float) = 1 } SubShader { // No culling or depth Cull Off ZWrite Off ZTest Always Pass { CGPROGRAM #pragma vertex VertexToFragment #pragma fragment frag #include "UnityCG.cginc" //vars sampler2D _Depth; sampler2D _CameraDepthNormalsTexture; float2 _CameraDepthNormalsTexture_TexelSize; float4 _EdgeColor : COLOR; float _DepthSensitivity; float _NormalSensitivity; float _SampleDistance; sampler2D _MainTex; float _FadeToDistance; struct VertInput { float4 pos : POSITION; float2 uv : TEXCOORD0; }; struct VertexOutput { float4 clipPos : SV_POSITION; float2 uv : texcoord; }; VertexOutput VertexToFragment (VertInput input) { VertexOutput output; output.clipPos = UnityObjectToClipPos(input.pos); output.uv = input.uv; return output; } fixed4 frag (VertexOutput i) : SV_Target { fixed4 col = tex2D(_CameraDepthNormalsTexture, i.uv); fixed4 texColor = tex2D(_MainTex, i.uv); float depth; float3 normal; DecodeDepthNormal(col, depth, normal); float2 uvs[4]; float depthDistance = _SampleDistance * (1-depth*0.7); uvs[0] = i.uv + float2(_CameraDepthNormalsTexture_TexelSize.x, _CameraDepthNormalsTexture_TexelSize.y)*depthDistance; uvs[1] = i.uv + float2(_CameraDepthNormalsTexture_TexelSize.x, -_CameraDepthNormalsTexture_TexelSize.y)*depthDistance; uvs[2] = i.uv + float2(-_CameraDepthNormalsTexture_TexelSize.x, -_CameraDepthNormalsTexture_TexelSize.y)*depthDistance; uvs[3] = i.uv + float2(-_CameraDepthNormalsTexture_TexelSize.x, _CameraDepthNormalsTexture_TexelSize.y)*depthDistance; //Neighbours - get datas fixed4 nCols[4]; float nDepths[4]; float3 nNormals[4]; nCols[0] = tex2D(_CameraDepthNormalsTexture, uvs[0]); nCols[1] = tex2D(_CameraDepthNormalsTexture, uvs[1]); nCols[2] = tex2D(_CameraDepthNormalsTexture, uvs[2]); nCols[3] = tex2D(_CameraDepthNormalsTexture, uvs[3]); DecodeDepthNormal(nCols[0], nDepths[0], nNormals[0]); DecodeDepthNormal(nCols[1], nDepths[1], nNormals[1]); DecodeDepthNormal(nCols[2], nDepths[2], nNormals[2]); DecodeDepthNormal(nCols[3], nDepths[3], nNormals[3]); float avgDepth = (nDepths[0] + nDepths[1] + nDepths[2] + nDepths[3])*0.25; bool isEdge = abs(avgDepth - depth) > _DepthSensitivity*(1-depth); bool isFade = _FadeToDistance >= 0.5; //is edge by depth if (isEdge) { if (isFade) { texColor.rgb = lerp(_EdgeColor.rgb, texColor.rgb, depth); } else { texColor.rgb = _EdgeColor.rgb; } } else { //is edge by normals float3 avgNormal = nNormals[0] + nNormals[1] + nNormals[2] + nNormals[3]; avgNormal = normalize(avgNormal); float normalDif = 1-((dot(normal, avgNormal)+1)*0.5); isEdge = normalDif > _NormalSensitivity*(1+depth*10); if (isEdge) { if (isFade) { texColor.rgb = lerp(_EdgeColor.rgb, texColor.rgb, depth); } else { texColor.rgb = _EdgeColor.rgb; } } } return texColor; } ENDCG } } } The Mono: using System.Collections; using System.Collections.Generic; using UnityEngine; [ExecuteInEditMode] public class EdgeDetectEffect : MonoBehaviour { public Material postProcessingMat; private void Start() { GetComponent().depthTextureMode = DepthTextureMode.DepthNormals; } private void OnRenderImage(RenderTexture source, RenderTexture destination) { Graphics.Blit(source, destination, postProcessingMat); } } The Post Process: using System; using UnityEngine; using UnityEngine.Rendering.PostProcessing; [Serializable] [PostProcess(typeof(EdgeDetectRenderer), PostProcessEvent.BeforeStack, "Hidden/EdgeDetection")] public sealed class EdgeDetect : PostProcessEffectSettings { } public sealed class EdgeDetectRenderer : PostProcessEffectRenderer { public override DepthTextureMode GetCameraFlags() { return DepthTextureMode.DepthNormals; } public override void Render(PostProcessRenderContext context) { var sheet = context.propertySheets.Get(Shader.Find("Hidden/EdgeDetection")); context.command.BlitFullscreenTriangle(context.source, context.destination, sheet, 0); } } [1]: /storage/temp/131639-edgeon.png [2]: /storage/temp/131640-edgeoff.png

Viewing all articles
Browse latest Browse all 713

Trending Articles