unity urp管线扫光效果
urp管线下实现扫光效果
基本思路,还是根据深度还原世界坐标(以下简称world_pos),根据坐标的xyz判断是否在一些范围内,然后进行基于xyz两个坐标轴进行扫光
这里进行一个扩展,让扫光可以沿着任一方向进行,
就是传入一个旋转变换矩阵,对world_pos进行变换,然后判断aabb盒,这样就可以实现非xyz轴方向的扫光效果
运行效果如下:
可以沿任意方向扫光
代码如下:
shader:
Shader "lsc/screen_scan_shader"
{Properties{_MainTex("Texture", 2D) = "white" {}_scan_brush("Texture", 2D) = "white" {}}SubShader{// No culling or depthCull Off ZWrite Off ZTest AlwaysPass{HLSLPROGRAM#pragma vertex vert#pragma fragment frag#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"//sampler2D _CameraDepthTexture;float4x4 _mtx_view_inv;float4x4 _mtx_proj_inv;//float4x4 _mtx_clip_to_world;TEXTURE2D_X_FLOAT(_CameraDepthTexture);SAMPLER(sampler_CameraDepthTexture);//扫光参数float4 _scan_color;float4 _scan_box_min;float4 _scan_box_max;float4x4 _scan_box_world_mtx;TEXTURE2D_X_FLOAT(_scan_brush);SAMPLER(sampler_LinearClamp);struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;float4 screen_space : TEXCOORD1;};float4 cal_world_pos_by_dep(float ndc_dep, float2 screen_space, out float4 view_pos){// 取出非线性深度与视深度float linearDepthZ = LinearEyeDepth(ndc_dep, _ZBufferParams);// 屏幕转ndcfloat4 ndc_pos;ndc_pos.xy = screen_space * 2.0 - 1.0;ndc_pos.zw = float2(ndc_dep, 1);// 添加齐次因子ndc_pos = ndc_pos * linearDepthZ;// 转成观察与世界坐标view_pos = mul(_mtx_proj_inv, ndc_pos);float4 world_pos = mul(_mtx_view_inv, float4(view_pos.xyz, 1));return world_pos;}int is_in_box(float3 pos){//todo : need optionif (pos.x <= _scan_box_max.x &&pos.y <= _scan_box_max.y &&pos.z <= _scan_box_max.z &&pos.x >= _scan_box_min.x &&pos.y >= _scan_box_min.y &&pos.z >= _scan_box_min.z)return 1;return 0;}v2f vert (appdata v){v2f o;o.vertex = TransformObjectToHClip(v.vertex);o.uv = v.uv;// 计算屏幕空间坐标(含齐次因子)o.screen_space = ComputeScreenPos(o.vertex);return o;}sampler2D _MainTex;float4 frag (v2f i) : SV_Target{float4 col = tex2D(_MainTex, i.uv);// 插值后的屏幕坐标去除齐次因子float2 screen_space = i.screen_space.xy / i.screen_space.w;// 取出非线性深度float org_depth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, screen_space).x;// 计算世界坐标float4 view_pos;float4 world_pos = cal_world_pos_by_dep(org_depth, screen_space, view_pos);//转换到包围盒的旋转平移空间float4 box_space_pos = mul(_scan_box_world_mtx, float4(world_pos.xyz, 1));int in_box = is_in_box(box_space_pos.xyz);float2 brush_uv = float2(abs(box_space_pos.x - _scan_box_min.x) / (_scan_box_max.x - _scan_box_min.x),abs(box_space_pos.z - _scan_box_min.z) / (_scan_box_max.z - _scan_box_min.z));// 从纹理中采样渐变效果,或者也可以用xz坐标计算生成简单的渐变效果float4 scan_brush = SAMPLE_TEXTURE2D_X(_scan_brush, sampler_LinearClamp, brush_uv).x;float scan_scale = scan_brush.r * brush_uv.x * brush_uv.y;col.xyz = _scan_color.xyz * in_box * scan_scale + col.xyz;//float tmp = world_pos.y;//col.xyz = float3(tmp, tmp, tmp);return col;}ENDHLSL}}
}
render feature pass c#代码
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;public class ScreenScanRenderPassFeature : ScriptableRendererFeature
{class CustomRenderPass : ScriptableRenderPass{public Material screen_scan_material = null;public RenderTargetIdentifier render_target_color;public RenderTargetHandle temp_render_target;// This method is called before executing the render pass.// It can be used to configure render targets and their clear state. Also to create temporary render target textures.// When empty this render pass will render to the active camera render target.// You should never call CommandBuffer.SetRenderTarget. Instead call <c>ConfigureTarget</c> and <c>ConfigureClear</c>.// The render pipeline will ensure target setup and clearing happens in a performant manner.public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData){}// Here you can implement the rendering logic.// Use <c>ScriptableRenderContext</c> to issue drawing commands or execute command buffers// https://docs.unity3d.com/ScriptReference/Rendering.ScriptableRenderContext.html// You don't have to call ScriptableRenderContext.submit, the render pipeline will call it at specific points in the pipeline.public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData){//Debug.Log("Execute fog pass");if (!screen_scan_material)return;{Camera cam = renderingData.cameraData.camera;var mtx_view_inv = cam.worldToCameraMatrix.inverse;var mtx_proj_inv = cam.projectionMatrix.inverse;screen_scan_material.SetMatrix("_mtx_view_inv", mtx_view_inv);screen_scan_material.SetMatrix("_mtx_proj_inv", mtx_proj_inv);}// scan box{Vector4 box_min = new Vector4(-15, -1000, -50, 0);Vector4 box_max = new Vector4(15, 1000, 50, 0);screen_scan_material.SetVector("_scan_box_min", box_min);screen_scan_material.SetVector("_scan_box_max", box_max);screen_scan_material.SetVector("_scan_color", new Vector4(179.0f/255.0f, 224.0f / 255.0f, 230.0f / 255.0f, 1.0f));Matrix4x4 box_mtx = Matrix4x4.identity;//box_mtx = Matrix4x4.Rotate(Quaternion.Euler(0, 45 + 30 * Time.time, 0)) * Matrix4x4.Translate(new Vector3(-400, 0, -380));box_mtx = Matrix4x4.Rotate(Quaternion.Euler(0, 45 - 30 * Time.time, 0)) * Matrix4x4.Translate(new Vector3(-400, 0, -380));screen_scan_material.SetMatrix("_scan_box_world_mtx", box_mtx);}const string CommandBufferTag = "screen scan Pass";var cmd = CommandBufferPool.Get(CommandBufferTag);RenderTextureDescriptor opaqueDesc = renderingData.cameraData.cameraTargetDescriptor;opaqueDesc.depthBufferBits = 0;cmd.GetTemporaryRT(temp_render_target.id, opaqueDesc);// 通过材质,将计算结果存入临时缓冲区cmd.Blit(render_target_color, temp_render_target.Identifier(), screen_scan_material);// 再从临时缓冲区存入主纹理cmd.Blit(temp_render_target.Identifier(), render_target_color);// 执行命令缓冲区context.ExecuteCommandBuffer(cmd);// 释放命令缓存CommandBufferPool.Release(cmd);// 释放临时RTcmd.ReleaseTemporaryRT(temp_render_target.id);}// Cleanup any allocated resources that were created during the execution of this render pass.public override void OnCameraCleanup(CommandBuffer cmd){}}CustomRenderPass m_ScriptablePass;public Material screen_scan_material = null;/// <inheritdoc/>public override void Create(){m_ScriptablePass = new CustomRenderPass();// Configures where the render pass should be injected.m_ScriptablePass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques;}// Here you can inject one or multiple render passes in the renderer.// This method is called when setting up the renderer once per-camera.public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData){m_ScriptablePass.render_target_color = renderer.cameraColorTarget;m_ScriptablePass.screen_scan_material = screen_scan_material;renderer.EnqueuePass(m_ScriptablePass);}
}
unity urp管线扫光效果相关推荐
- Android控件扫光动画,完美起航-AndroidTV控件获得焦点的扫光效果
目录 前言 Android TV开发与手机开发最大的不同点就是焦点,TV常用的操作方式是遥控器,所以给用户一个醒目美观的焦点是至关重要的.很多产品经理在设计焦点的时候都会选择扫光的效果,比如小牧电视的 ...
- OneNav一为主题魔改教程(二):使用纯css增加网站Logo扫光效果--洞五洞洞幺
今日主题: 使用纯css增加网站Logo扫光效果 声明:本篇有违"魔改"这个标题:本篇只为增加收录.并且复习使用纯css给logo加上扫光效果. 效果: 可以目测 洞五洞洞幺 导航 ...
- css扫光效果总结,css文字扫光,css图片扫光
前言 今天来和大家一起探讨一下图片的扫光效果吧! 思路 其实扫光的思路都是一样的,不外乎是表层一个动态的光,从左往右进行一个动画运动! 但是这个运动的光,一般是用过伪元素来::after或者::bef ...
- Unity URP管线下多光源渲染
抓手 urp管线下,获得其他多光源的方式和内置管线的不一样. 本文会阐述具体方法,并给出源码. 具体步骤 首先要在pipeline中打开Additional lighting的设置. 然后在shade ...
- Unity URP管线的PBR材质及Tessallation Shader(Height Map高度贴图)
在使用URP管线的过程中发现默认的URP管线的shader是没有提供height map参数设置的,经过查找才知道URP管线中height map相关的功能需要自己写shader开启Tessallat ...
- 模拟楼宇扫光效果(three.js实战12)
1. demo效果 2. 实现要点 2.1 创建shader材质 这一步中主要是为了实现楼宇从下到上的扫光,而定制的着色器材质,在着色器材质中书写顶点着色器和片元着色器,具体如下 let buildi ...
- Unity URP管线设置 后处理的使用
Unity推出通用渲染管线和高清渲染管线有很长一段时间了,但是感觉使用度上不是很高,很多人不愿意尝试新的渲染管线. 我在最开始使用Unity做可视化大屏的时候,也是选择的默认渲染管线,主要是Asset ...
- unity urp 实现衣服绒毛效果
实现衣服的绒毛效果,主要就是要模拟出一根根毛发的效果.这种效果对动物身上的短毛也同样有效果.实现方式主要是多层渲染,然后再通过一张noise渐变图,根据显隐进行剔除,来模拟出来绒毛向外生长的效果. 以 ...
- php图片特效,css3实现图片头像扫光高亮效果
css3出来后,之前很多flash才能做的效果,现在甚至不用写一句js,单纯靠css3新增的属性就能轻松实现! css3实现图片头像扫光高亮效果,源码: 测试 *{margin:0;padding:0 ...
最新文章
- 103. Leetcode 213. 打家劫舍 II (动态规划-打家劫舍)
- UVA10305 Ordering Tasks
- 2021-11-18Collections
- ListGetandSetDemo 集合操作get set remove add方法
- 男科医生到底有多不正经… | 今日最佳
- Android 动画以view中心点旋转动画
- java的未检查异常有哪些_Java:检查异常与未检查异常
- LINQ to SQL之Step by Step及新手问题小结
- bzoj1031 [JSOI2007]字符加密 后缀数组改
- C++11新宠-Lambda函数学习
- swift - scrollview 判断左右移动, 以及上下两个view联动
- Gentoo解决Windows双系统时间不同步的问题
- mysql connections 作用_MySQL性能优化之max_connections配置参数浅析
- HackerRank Word Order
- w3c 整站 php源码,W3C联盟系统 v1.3
- Easy Audio CD Burner 算法分析及逆向推算(图)
- python语言是胶水语言吗_为什么只有python是胶水语言?
- 数据库设计——关系数据理论(超详细)
- 计算机二级数据透视图教程,计算机二级Office:Excel数据透视表和透视图
- 大一微积分笔记整理_大一微积分知识点总结
热门文章
- 新手入门新电脑安装配置orb slam2 一步到位不踩坑(ubutun18.04)
- 电子词典软件也能跨平台--介绍我创造的LAVA
- Linux平台下网盘客户端的设计构想
- 软件测试 - 基础理论篇
- 计算机系统结构专业是工学还是理学,理科有哪些专业和工作 理学和工学的区别解析...
- Android10.0 StatusBar之状态栏
- Oracle OCP 1z0-052 2018年9月最新考过的题库分享-3
- OpenCV—python 手写数字字体识别(使用HOG特征)
- 解决Android Studio运行编译时间久的最有效方案
- 8个最有含金量的云计算和大数据认证