unity URP 利用particle system制作简单的shader交互

这篇具有很好参考价值的文章主要介绍了unity URP 利用particle system制作简单的shader交互。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

首先这里制作了一个简单交互,使用shader grapgh,根据计算距离和变化数值的差实现交互后的扩散,同时计算消散遮罩让它逐渐谈去。

unity URP 利用particle system制作简单的shader交互,shader,交互

unity URP 利用particle system制作简单的shader交互,shader,交互

将他赋予材质物体,根据脚本传入位置和逐渐变化的大小后,呈现这样的效果。

unity URP 利用particle system制作简单的shader交互,shader,交互

但是,shader graph这样的工具,在做这种效果非常快的同时,也存在不少缺点,比如这里我希望我传入的位置和大小变化都是数组,使用shader graph就不太好办了。

这时候就需要把它翻译成代码,根据连线图的逻辑翻译即可,此外把传入的位置和size值替换为数组。

Shader "yourname"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _HitPos("HitPos", Vector) = (0, 0, 0, 0)
        _HitSize("HitSize", Float) = 0.001
        _HitSpread("HitSpread", Range(0, 10)) = 1
        _HitSizeMax("HitSizeMax", Float) = 0
        _DisappearSpread("DisappearSpread", Float) = 1
        _HitSpreadNoiseMulti("HitSpreadNoiseMulti", Range(0.01, 10)) = 1
        _HitSpreadNoiseScale("HitSpreadNoiseScale", Range(1, 200)) = 20
        [HideInInspector]_QueueOffset("_QueueOffset", Float) = 0
        [HideInInspector]_QueueControl("_QueueControl", Float) = -1
        [HideInInspector][NoScaleOffset]unity_Lightmaps("unity_Lightmaps", 2DArray) = "" {}
        [HideInInspector][NoScaleOffset]unity_LightmapsInd("unity_LightmapsInd", 2DArray) = "" {}
        [HideInInspector][NoScaleOffset]unity_ShadowMasks("unity_ShadowMasks", 2DArray) = "" {}


    }
    SubShader
    {

        Tags
        {
            "RenderPipeline"="UniversalPipeline"
            "RenderType"="Opaque"
            //"UniversalMaterialType" = "Lit"
            "Queue"="Geometry"
            "DisableBatching"="False"
        }

        Pass
        {

            Name "Universal Forward"
            Tags
            {
                "LightMode" = "UniversalForward"
            }
            Cull Back
            Blend One Zero
            ZTest LEqual
            ZWrite On
           
            HLSLPROGRAM
            #pragma enable_d3d11_debug_symbols  //  debug信息
            #pragma multi_compile_instancing
            #pragma target 4.0  // 默认2.5 target的详细信息 https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html
   
            #pragma vertex vert
         
            #pragma fragment frag
         
            //https://github.com/Unity-Technologies/Graphics/tree/master/Packages/com.unity.render-pipelines.universal/ShaderLibrary
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl"
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl"
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Hashes.hlsl"

      

            float Unity_SimpleNoise_ValueNoise_Deterministic_float (float2 uv)
            {
                float2 i = floor(uv);
                float2 f = frac(uv);
                f = f * f * (3.0 - 2.0 * f);
                uv = abs(frac(uv) - 0.5);
                float2 c0 = i + float2(0.0, 0.0);
                float2 c1 = i + float2(1.0, 0.0);
                float2 c2 = i + float2(0.0, 1.0);
                float2 c3 = i + float2(1.0, 1.0);
                float r0; Hash_Tchou_2_1_float(c0, r0);
                float r1; Hash_Tchou_2_1_float(c1, r1);
                float r2; Hash_Tchou_2_1_float(c2, r2);
                float r3; Hash_Tchou_2_1_float(c3, r3);
                float bottomOfGrid = lerp(r0, r1, f.x);
                float topOfGrid = lerp(r2, r3, f.x);
                float t = lerp(bottomOfGrid, topOfGrid, f.y);
                return t;
            }
        
            void Unity_SimpleNoise_Deterministic_float(float2 UV, float Scale, out float Out)
            {
                float freq, amp;
                Out = 0.0f;
                freq = pow(2.0, float(0));
                amp = pow(0.5, float(3-0));
                Out += Unity_SimpleNoise_ValueNoise_Deterministic_float(float2(UV.xy*(Scale/freq)))*amp;
                freq = pow(2.0, float(1));
                amp = pow(0.5, float(3-1));
                Out += Unity_SimpleNoise_ValueNoise_Deterministic_float(float2(UV.xy*(Scale/freq)))*amp;
                freq = pow(2.0, float(2));
                amp = pow(0.5, float(3-2));
                Out += Unity_SimpleNoise_ValueNoise_Deterministic_float(float2(UV.xy*(Scale/freq)))*amp;
            }

            void Unity_SampleGradientV1_float(Gradient Gradient, float Time, out float4 Out)
            {
                float3 color = Gradient.colors[0].rgb;
                [unroll]
                for (int c = 1; c < Gradient.colorsLength; c++)
                {
                    float colorPos = saturate((Time - Gradient.colors[c - 1].w) / (Gradient.colors[c].w - Gradient.colors[c - 1].w)) * step(c, Gradient.colorsLength - 1);
                    color = lerp(color, Gradient.colors[c].rgb, lerp(colorPos, step(0.01, colorPos), Gradient.type));
                }
            #ifdef UNITY_COLORSPACE_GAMMA
                color = LinearToSRGB(color);
            #endif
                float alpha = Gradient.alphas[0].x;
                [unroll]
                for (int a = 1; a < Gradient.alphasLength; a++)
                {
                    float alphaPos = saturate((Time - Gradient.alphas[a - 1].y) / (Gradient.alphas[a].y - Gradient.alphas[a - 1].y)) * step(a, Gradient.alphasLength - 1);
                    alpha = lerp(alpha, Gradient.alphas[a].x, lerp(alphaPos, step(0.01, alphaPos), Gradient.type));
                }
                Out = float4(color, alpha);
            }

            struct appdata
            {
                //顶点着色器语义 https://learn.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics?redirectedfrom=MSDN
                float4 vertex : POSITION;
                float3  normal  : NORMAL;
                float4  tan  : TANGENT;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                //像素着色器语义 https://learn.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics?redirectedfrom=MSDN
                float4 positionCS : SV_POSITION;
                float3  normal  : NORMAL;
                float2 uv : TEXCOORD0;
                float3 positionWS : TEXCOORD1;
            };
            //从片段着色器的返回结构,SV_Target,SV_Depth等,不知道这两个之外还有能用的不。SV_Target可以从0到7,在多渲染目标(MRT)时很有用
            struct fragOutput {
                //语义 https://learn.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics?redirectedfrom=MSDN
                float4 Emission : SV_Target;
            };


            sampler2D _MainTex;
            float4 _MainTex_ST; 

            float _HitSpreadNoiseScale;
            float _HitSpreadNoiseMulti;
            int count;
            float3 hitposarray[20];
            float hitsizearray[20];
            float hitspreadarray[20];
            float hitsizemaxarray[20];
            float disappearspreadarray[20];


            v2f vert(appdata v, uint vid : SV_VertexID)
            {
                v2f o;
                o.positionCS = TransformObjectToHClip(v.vertex);
                o.positionWS = TransformObjectToWorld(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.normal = v.normal;
                return o;
            }

            float4 CalculateCircle(v2f i, float3 _HitPos, float _HitSize, float _HitSpread, float _HitSizeMax, float _DisappearSpread)
            {
                float3 tempdis = distance(_HitPos, i.positionWS);
                float tempupmul = clamp(((tempdis - _HitSizeMax) * (-1) )/ _DisappearSpread, 0, 1);

                float noiseout = 0;
                Unity_SimpleNoise_Deterministic_float(i.uv, _HitSpreadNoiseScale, noiseout);
                noiseout = noiseout * _HitSpreadNoiseMulti;
                float temp1 = noiseout + (tempdis - _HitSize);
                float temp2 = 1 - clamp(temp1 / min(_HitSize, _HitSpread), 0, 1);
                Gradient _Gradient = NewGradient(0, 4, 2, float4(0, 0, 0, 0),float4(0.767647, 0.767647, 0.767647, 0.1058824),float4(0.6861503, 0.6861503, 0.6861503, 0.7705958),float4(0, 0, 0, 0.9647059),float4(0, 0, 0, 0),float4(0, 0, 0, 0),float4(0, 0, 0, 0),float4(0, 0, 0, 0), float2(1, 0),float2(1, 1),float2(0, 0),float2(0, 0),float2(0, 0),float2(0, 0),float2(0, 0),float2(0, 0));
                float4 gradientout = 0;
                Unity_SampleGradientV1_float(_Gradient, temp2, gradientout);

                return tempupmul * gradientout;
            }

            fragOutput frag(v2f i) : SV_Target
            {
                fragOutput o = (fragOutput)0;
                float4 tempemission = 0;
                for(int j = 0; j < count; j++){
                    tempemission += CalculateCircle(i, hitposarray[j], hitsizearray[j], hitspreadarray[j], hitsizemaxarray[j], disappearspreadarray[j]);
                };
                o.Emission = tempemission;


                return o;
            }
            ENDHLSL
        }
    }
    Fallback Off
}

particle system制作为在点击位置射线检测,生成粒子,并逐渐放大,最后消失。

unity URP 利用particle system制作简单的shader交互,shader,交互

弄好后关闭粒子的renderer,使其不可见。

然后创建脚本根据particle system产生的粒子位置和大小,particle system,按个数传入shader代码的数组中,按照粒子的位置和大小同步shader数组中的值以实现效果。

using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.InputSystem;
using static UnityEngine.Rendering.DebugUI;

[ExecuteAlways]
public class ForceField : MonoBehaviour
{
    //编辑器引用
    public GameObject forcefield;
    public ParticleSystem ps;
    //静态存储
    [Header("粒子系统最大数量")]
    public int psAmount = 20;
    Material material;
    Shader shader;
    Mouse mouse;
    //动态变化存储
    RaycastHit raycastHit;
    ParticleSystem.Particle[] particles;
    bool isInited = false;

    void Init()
    {
        if (material == null)
            material = forcefield.GetComponent<MeshRenderer>().sharedMaterial;
        if (shader == null)
            shader = material.shader;
        if (mouse == null)
            mouse = Mouse.current;

        particles = new ParticleSystem.Particle[psAmount];
    }

    void Update()
    {
        //编辑器模式下就要做的事情
        if (forcefield == null) return;
        if (ps == null) return;

        if (!isInited)
        {
            Init();
            isInited = true;
        }

        //运行模式下才要做的事情
        if (!Application.isPlaying) return;
        if (mouse.leftButton.wasPressedThisFrame)//Status:鼠标左键按下  运行时才有作用
        {
            Vector2 mousePos = Pointer.current.position.ReadValue();
            Ray ray = Camera.main.ScreenPointToRay(mousePos);
            Physics.Raycast(ray, out raycastHit, 1000, LayerMask.GetMask("ForceField"));
            
            if(raycastHit.collider != null)//检测有效,做以下操作
            {
                ps.transform.position = raycastHit.point;
                ps.Emit(1);
            }
        }

        ParticleSystem.MainModule psMainModule = ps.main;
        int count = ps.GetParticles(particles);
        Debug.Log(count);

        material.SetInteger("count", count);  //  激活的个数

        if(count > 0)
        {
            Vector4[] hitposs = new Vector4[20];
            float[] hitsizes = new float[20];
            float[] hitspreads = new float[20];
            float[] hitsizemaxs = new float[20];
            float[] disappearspreads = new float[20];
            for (int i = 0; i < count; i++)
            {
                hitposs[i] = new Vector4(particles[i].position.x, particles[i].position.y, particles[i].position.z, 1);
                hitsizes[i] = particles[i].GetCurrentSize(ps);
                hitspreads[i] = 1;
                hitsizemaxs[i] = psMainModule.startSize.constantMax;
                disappearspreads[i] = psMainModule.startSize.constantMax / 2;
            }
            material.SetVectorArray("hitposarray", hitposs);
            material.SetFloatArray("hitsizearray", hitsizes);
            material.SetFloatArray("hitspreadarray", hitspreads);
            material.SetFloatArray("hitsizemaxarray", hitsizemaxs);
            material.SetFloatArray("disappearspreadarray", disappearspreads);
        }

    }

}

unity URP 利用particle system制作简单的shader交互,shader,交互文章来源地址https://www.toymoban.com/news/detail-724975.html

到了这里,关于unity URP 利用particle system制作简单的shader交互的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Unity中Shader URP 简介

    Unity中Shader URP 简介

    在这篇文章中,我们主要介绍一下Unity中的URP(通用渲染管线)是什么 Unity帮助文档 Windows and UWP Mac and IOS Android Xbox One PlayStation4 Nintendo Switch WebGL All current VR platforms 在Unity2018以前,Unity使用的一直都是Build-in Render Pipeline(内置渲染管线) 在早期使用内置渲染管线时,Unity为了适配

    2024年01月16日
    浏览(14)
  • 利用三维内容编辑器制作VR交互课件,简单好用易上手

    利用三维内容编辑器制作VR交互课件,简单好用易上手

    随着虚拟现实技术的不断发展,越来越多的教育机构开始尝试将其应用于教育教学中。然而,要实现这一目标并不容易,需要专业的技术支持和开发团队。 为了解决这一问题, 广州华锐互动 研发了 三维内容编辑器 ,它是一种基于虚拟现实技术的教育内容编辑器,可以帮助

    2024年02月12日
    浏览(12)
  • Unity URP Shader(HLSL)踩坑日记(一)

    Unity URP Shader(HLSL)踩坑日记(一)

    最近开始转TA,刚开始学习,资料比较杂乱,其中遇到的问题和一些计算方式,记录一下,后续会一直完善补充。 注意此时Properties中的属性,如果要开启SRP合批,需要放到CBUFFER代码块中。 应用阶段准备的数据---- 顶点着色处理数据(返回值为处理后的数据)---- ------ 片元着色器

    2024年01月17日
    浏览(12)
  • Unity Shader从内置渲染管线迁移到URP

    Unity 在URP中将shader更新为了HLSL语言,使用build-in shader 无法直接在URP中使用 这里讲一下关于shader的更新方法 参考 From Built-in to URP Tags 添加 \\\"RenderPipeline\\\" = \\\"UniversalPipeline\\\" CGPROGRAM ENDCG 改变为 HLSLPROGRAM ENDHLSL #include \\\"UnityCG.cginc\\\" 更改为 #include \\\"Packages/com.unity.render-pipelines.universal/Sh

    2024年02月05日
    浏览(13)
  • Unity Spine 3.8 (URP) 踩坑(Shader报错修改)

    今天搜索spine优化,看到一篇文章项目导入多个Spine动画 合批 降低DrawCall -- UWA问答 | 游戏开发者互动问答社区 | 侑虎科技 提供了新思路,打算尝试一下URP。但美术使用的spine版本是3.8,项目用的Unity2021.3.11f1c2,直接导入spine URP包,shader报错:half4 不能转成 SurfaceData2D;遂改下

    2024年02月12日
    浏览(17)
  • Unity URP Shader “Redefinition of _Time“ error

    强烈建议先尝试阅读本文之后自行解决:https://zhuanlan.zhihu.com/p/360566324 我这里记录一下我的思路: 首先检查URP升级是否正确,主要看Asset是否设置,ShaderGraph表现是否正常 尝试排除是否是未定义宏导致的问题,主要是对比ShaderGraph自动生成的代码 确认自己的代码是否使用了

    2024年02月15日
    浏览(14)
  • unity build-in 渲染管线升级urp渲染 shader篇

            由于工作原因需要对项目进行升级,从build-in渲染管线升级到urp渲染管线,我自己对应的unity版本是2018.版本升级到2021.3.2版本,由于最近几年unity版本升级比较快,个体版本差异有所不同,如遇与版本不一致问题敬请谅解。以下是根据官网等系列网站整理的内容

    2023年04月16日
    浏览(24)
  • 《Unity的URP项目中使用自定义shader导致材质消失的解决办法》

    《Unity的URP项目中使用自定义shader导致材质消失的解决办法》

            在Unity中使用URP时,会有需求使用自定义的一些shader来实现特殊效果,这时如果我们直接使用新建材质与无光照着色器(Unlit shader),可能会发生一个对于新手而言意料之外的问题—— 物体!消失了!         打开你正在使用的的 通用渲染器(Universal Rendere

    2024年02月06日
    浏览(121)
  • Unity Shader 学习笔记(4)URP渲染管线带阴影PBR-Shader模板 -- 新增可自定义阴影颜色

    Unity Shader 学习笔记(4)URP渲染管线带阴影PBR-Shader模板 -- 新增可自定义阴影颜色

    材质面板截图 功能实现(URP渲染管线下): 1、进一步优化Shader结构和算法; 2、包含PBR材质; 3、投射和接收阴影,并升级 支持自定义阴影颜色 ; 4、支持点光源照射(但不支持点光源阴影)。 通用渲染截图 自定义阴影颜色截图 完整代码: 写在最后: 1、在我的上一篇文

    2024年02月12日
    浏览(15)
  • 【Unity】UGUI中Camera Depth,Canvas Sorting Layer、Order in Layer与Particle System渲染层级分析

    【Unity】UGUI中Camera Depth,Canvas Sorting Layer、Order in Layer与Particle System渲染层级分析

    目录   前言 一、项目需求 二、Camera 1.Clear Flags 2.Culling Mask  三、Canvas 1.Sorting Layer 2.Order in Layer 四、Particle System 1.Sorting LayerID 与Order in Layer 总结         最近在做项目的过程中,发现项目中的部分3d模型会被粒子特效所遮挡,这并不是笔者想要的效果,于是经过一番面向

    2024年02月05日
    浏览(11)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包