Question by
Listless_ · Oct 12, 2020 at 07:15 AM ·
unity5bug-perhaps
Trying To Implement Sonar Effect in Universal Rendering Pipeline
Hello, I'm pretty new to unity
So, I was browsing youtube, and i stumble across the sonar effect
I tried doing what he says in URP, however it doesn't work because of OnRenderImage lifecycle is discontinued. So here's what i did
-
1. On the Forward Renderer Setting I add Blit on the render features from Unity Universal Rendering Pipeline Examples ( Because he was using ImageEffect shader )
-
2. I tried to change his code like this:
ScannerEffectDemo.cs
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class ScannerEffectDemo : MonoBehaviour
{
public Transform ScannerOrigin;
public Material EffectMaterial;
public float ScanDistance;
public float ScanSpeed = 50;
public Shader ScannerShader;
public Camera _textureCamera;
public RenderTexture _renderTexture;
// Demo Code
public bool _scanning;
void Start()
{
Debug.Log("START");
_textureCamera.enabled = true;
_textureCamera.targetTexture = null;
SetupRenderTexture();
}
void Update()
{
if (_scanning)
{
ScanDistance += Time.deltaTime * ScanSpeed;
}
if (Input.GetKeyDown(KeyCode.C))
{
_scanning = true;
ScanDistance = 0;
}
if (Input.GetMouseButtonDown(0))
{
Ray ray = _textureCamera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
_scanning = true;
ScanDistance = 0;
ScannerOrigin.position = hit.point;
}
}
UpdateMaterial();
}
// End Demo Code
void OnEnable()
{
_textureCamera = GetComponent<Camera>();
_textureCamera.depthTextureMode = DepthTextureMode.Depth;
}
private void OnDisable()
{
_textureCamera.ResetReplacementShader();
}
void UpdateMaterial()
{
EffectMaterial.SetVector("_WorldSpaceScannerPos", ScannerOrigin.position);
EffectMaterial.SetFloat("_ScanDistance", ScanDistance);
EffectMaterial.SetPass(0);
Debug.Log("World_Scanner_Pos" + ScannerOrigin.position.ToString("f") + "; Scan Distance: " + ScanDistance.ToString("f"));
}
IEnumerator UpdateCameraTexture()
{
yield return new WaitForEndOfFrame();
Debug.Log("Camera Texture");
Texture2D texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGBA32, false);
texture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0, false);
texture.Apply();
EffectMaterial.SetTexture("_MainTex", texture);
}
IEnumerator UpdateRenderTexture()
{
yield return new WaitForEndOfFrame();
_renderTexture = new RenderTexture(Screen.width, Screen.height, 24);
_textureCamera.targetTexture = _renderTexture;
RenderTexture.active = _renderTexture;
_textureCamera.Render();
_textureCamera.targetTexture = null;
RenderTexture.active = null;
EffectMaterial.SetTexture("_MainTex", _renderTexture);
}
void SetupRenderTexture()
{
_renderTexture = new RenderTexture(Screen.width, Screen.height, 24);
_textureCamera.targetTexture = _renderTexture;
EffectMaterial.SetTexture("_MainTex", _renderTexture);
}
}
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class ScannerEffectDemo : MonoBehaviour
{
public Transform ScannerOrigin;
public Material EffectMaterial;
public float ScanDistance;
public float ScanSpeed = 50;
public Shader ScannerShader;
public Camera _textureCamera;
public RenderTexture _renderTexture;
// Demo Code
public bool _scanning;
void Start()
{
Debug.Log("START");
_textureCamera.enabled = true;
_textureCamera.targetTexture = null;
SetupRenderTexture();
}
void Update()
{
if (_scanning)
{
ScanDistance += Time.deltaTime * ScanSpeed;
}
if (Input.GetKeyDown(KeyCode.C))
{
_scanning = true;
ScanDistance = 0;
}
if (Input.GetMouseButtonDown(0))
{
Ray ray = _textureCamera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
_scanning = true;
ScanDistance = 0;
ScannerOrigin.position = hit.point;
}
}
UpdateMaterial();
}
// End Demo Code
void OnEnable()
{
_textureCamera = GetComponent<Camera>();
_textureCamera.depthTextureMode = DepthTextureMode.Depth;
}
private void OnDisable()
{
_textureCamera.ResetReplacementShader();
}
void UpdateMaterial()
{
EffectMaterial.SetVector("_WorldSpaceScannerPos", ScannerOrigin.position);
EffectMaterial.SetFloat("_ScanDistance", ScanDistance);
EffectMaterial.SetPass(0);
Debug.Log("World_Scanner_Pos" + ScannerOrigin.position.ToString("f") + "; Scan Distance: " + ScanDistance.ToString("f"));
}
IEnumerator UpdateCameraTexture()
{
yield return new WaitForEndOfFrame();
Debug.Log("Camera Texture");
Texture2D texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGBA32, false);
texture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0, false);
texture.Apply();
EffectMaterial.SetTexture("_MainTex", texture);
}
IEnumerator UpdateRenderTexture()
{
yield return new WaitForEndOfFrame();
_renderTexture = new RenderTexture(Screen.width, Screen.height, 24);
_textureCamera.targetTexture = _renderTexture;
RenderTexture.active = _renderTexture;
_textureCamera.Render();
_textureCamera.targetTexture = null;
RenderTexture.active = null;
EffectMaterial.SetTexture("_MainTex", _renderTexture);
}
void SetupRenderTexture()
{
_renderTexture = new RenderTexture(Screen.width, Screen.height, 24);
_textureCamera.targetTexture = _renderTexture;
EffectMaterial.SetTexture("_MainTex", _renderTexture);
}
}
<hr>
ScannerEffect.shader
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "ScanProto/ScannerEffectOne"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_DetailTex("Texture", 2D) = "white" {}
_ScanDistance("Scan Distance", float) = 0
_ScanWidth("Scan Width", float) = 10
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct VertIn
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 ray : TEXCOORD1;
};
struct VertOut
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uv_depth : TEXCOORD1;
float4 interpolatedRay : TEXCOORD2;
float3 worldPos :TEXCOORD3;
};
float4 _MainTex_TexelSize;
float4 _CameraWS;
VertOut vert(VertIn v)
{
VertOut o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
o.uv = v.uv.xy;
o.uv_depth = v.uv.xy;
o.interpolatedRay = v.ray;
return o;
}
sampler2D _MainTex;
sampler2D _CameraDepthTexture;
float4 _WorldSpaceScannerPos;
float _ScanDistance;
float _ScanWidth;
half4 frag (VertOut i) : SV_Target
{
half4 col = tex2D(_MainTex, i.uv);
half4 depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, i.uv));
float rawDepth = DecodeFloatRG(tex2D(_CameraDepthTexture, i.uv_depth));
float linearDepth = Linear01Depth(rawDepth);
float4 wsDir = linearDepth * i.interpolatedRay;
float3 wsPos = _WorldSpaceCameraPos + wsDir;
half4 scannerCol = half4(0, 0, 0, 0);
float eyeDepth = LinearEyeDepth(depth);
float3 worldSpaceEye = wsDir * eyeDepth + _WorldSpaceCameraPos;
float dist = distance(wsPos, _WorldSpaceScannerPos);
float distance2 = distance(i.worldPos, _WorldSpaceScannerPos);
float eyeDistance = distance(worldSpaceEye, _WorldSpaceScannerPos);
float usedDistance = eyeDistance;
if (usedDistance < _ScanDistance && usedDistance > _ScanDistance - _ScanWidth)
{
float diff = 1 - (_ScanDistance - dist) / (_ScanWidth);
if(diff <= 0) diff = 0;
diff = 1;
scannerCol += diff;
}
return col + scannerCol;
}
ENDCG
}
}
}
I changed it, It sort of works, but I was curious why the ring doesn't originate from the origin object, rather from outside the game view so i don't know where it starts.
I thought originally I was because the PixelToWorldSpace technique is wrong
I tinker further then I noticed that the shader didn't quite draw the ring properly.
I'm not sure why it draws outside, can anyone please help me?
screenshot-2020-10-12-140911.png
(78.0 kB)
screenshot-2020-10-12-135125.png
(70.3 kB)
Comment
Your answer
Follow this Question
Related Questions
Debug.Log not working 1 Answer
Every object I drag into the scene turns yellow 0 Answers
Unity playmode bug 0 Answers
What is my parsing error? 0 Answers