Unity中Shader的消融视觉效果优化smoothstep(min,max,x)

news2025/4/17 18:33:31

文章目录

  • 前言
    • Unity中Shader的消融视觉效果优化
  • 一、在clip(value) 的 基础上 用 smoothstep(min,max,x),并且增加一个渐变纹理对消融边缘进行视觉上的优化
  • 二、进行优化


前言

Unity中Shader的消融视觉效果优化

一、在clip(value) 的 基础上 用 smoothstep(min,max,x),并且增加一个渐变纹理对消融边缘进行视觉上的优化

请添加图片描述
请添加图片描述
在用噪音纹理 对 渐变纹理进行采样,让噪音纹理中黑色的地方对应 渐变纹理 黑色的地方,以实现边缘渐变的效果,在取样后 与 原本的纹理 取样的结果相加就可以

Shader "MyShader/P0_7_9"
{
    Properties
    {
        //使用这个标签,可以使外部暴露属性,有标题
        [Header(Base)]
        [NoScaleOffset]_MainTex ("Texture", 2D) = "white" {}
        _Clip("Clip",Range(0,1)) = 0

        
        //使用这个标签可以 在两行暴露属性之间加 间隙
        [Space(10)]
        [Header(Dissolve)]
        _DissolveTex("DissolveTex",2D) = "white"{}

        [NoScaleOffset]_RampTex("RampTex",2D) = "black" {}

    }
    SubShader
    {
      
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            
            sampler2D _MainTex;
            float _Clip;
            sampler2D _DissolveTex; 
           

            //这个四维向量,xyzw分别表示 Tilling 和 Offset 的 xy ,命名方式 在纹理名 后加 _ST
            float4 _DissolveTex_ST;

            sampler2D _RampTex;

            struct appdata
            {
                float4 vertex : POSITION;
                float4 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
            };

            
            

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                
                //为了减少传入的值 ,所以就不创建新变量来存储,而是把 uv 改为  四维向量 来用
                //使用 o.uv 的 xy 来存放 原人物贴图
                //使用 o.uv 的 zw 来存放 噪波贴图缩放 和 偏移 后的值
                o.uv.xy = v.uv.xy;
                //o.uv.zw = v.uv * _DissolveTex_ST.xy + _DissolveTex_ST.zw;

                o.uv.zw = TRANSFORM_TEX(v.uv,_DissolveTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col;

                fixed4 _mainTex = tex2D(_MainTex, i.uv.xy);
                col = _mainTex;
               
                //外部获取的 纹理 ,使用前都需要采样
                fixed4 dissolveTex = tex2D(_DissolveTex,i.uv.zw);
                //片段的取舍
                clip(dissolveTex.r -  _Clip);

                //进行视觉上的优化
                //smoothstep(min,max,x)
                //x < min ,y = min;
                //x > max ,y = max;
                //min < x < max,y = x;
                fixed4 rampTex = tex2D(_RampTex,smoothstep(_Clip,_Clip + 0.1,dissolveTex.r));
                col += rampTex;
                return col;
            }
            ENDCG
        }
    }
}

效果

在这里插入图片描述

二、进行优化

smoothstep函数包含的功能:

float smoothstep(min,max,x)
{
	//归一化(线性插值)
	float t = saturate(x - min) / (max - min);
	//平滑
	return t * t * (3 - 2 * t);
}

可以用下图来理解
在这里插入图片描述

t 函数是 没处理平滑前
f 函数是 处理平滑后
因为我们目前不需要平滑处理,直接用 smoothstep 比较消耗性能,所以需要优化

修改后代码:

Shader "MyShader/P0_7_9"
{
    Properties
    {
        //使用这个标签,可以使外部暴露属性,有标题
        [Header(Base)]
        [NoScaleOffset]_MainTex ("Texture", 2D) = "white" {}
        _Clip("Clip",Range(0,1)) = 0
        //使用这个标签可以 在两行暴露属性之间加 间隙
        [Space(10)]
        [Header(Dissolve)]
        _DissolveTex("DissolveTex",2D) = "white"{}

        [NoScaleOffset]_RampTex("RampTex(RGB)",2D) = "black" {}

    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            
            sampler2D _MainTex;
            float _Clip;
            sampler2D _DissolveTex; 
            //这个四维向量,xyzw分别表示 Tilling 和 Offset 的 xy ,命名方式 在纹理名 后加 _ST
            float4 _DissolveTex_ST;

            sampler2D _RampTex;

            struct appdata
            {
                float4 vertex : POSITION;
                float4 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                
                //为了减少传入的值 ,所以就不创建新变量来存储,而是把 uv 改为  四维向量 来用
                //使用 o.uv 的 xy 来存放 原人物贴图
                //使用 o.uv 的 zw 来存放 噪波贴图缩放 和 偏移 后的值
                o.uv.xy = v.uv.xy;
                //o.uv.zw = v.uv * _DissolveTex_ST.xy + _DissolveTex_ST.zw;

                o.uv.zw = TRANSFORM_TEX(v.uv,_DissolveTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv.xy);
                //外部获取的 纹理 ,使用前都需要采样
                fixed4 dissolveTex = tex2D(_DissolveTex,i.uv.zw);
                //片段的取舍
                clip(dissolveTex.r -  _Clip);

                //进行归一化
                fixed4 dissolveValue = saturate((dissolveTex.r - _Clip) / (_Clip + 0.1 - _Clip));

                fixed4 rampTex = tex2D(_RampTex,dissolveValue);

                col += rampTex;
                return col;
            }
            ENDCG
        }
    }
}


最后优化:

因为 在使用渐变纹理时,只使用了 渐变纹理的 u 坐标,所以把 sampler2D 换为 sampler

修改以下两处

sampler2D _RampTex; -->sampler _RampTex;

fixed4 rampTex = tex2D(_RampTex,dissolveValue); -->fixed4 rampTex = tex1D(_RampTex,dissolveValue.r);

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/966737.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3.0 Dubbo的可扩展机制SPI源码解析

1. Dubbo SPI 架构图 2. Demo ExtensionLoader<Protocol> extensionLoader ExtensionLoader.getExt ensionLoader(Protocol.class); Protocol http extensionLoader.getExtension("dubbo"); System.out.println(http); 上⾯这个Demo就是Dubbo常⻅的写法&am…

java八股文面试[多线程]——newWorkStealingPool

newWorkStealingPool是什么&#xff1f; newWorkStealingPool简单翻译是任务窃取线程池。 newWorkStealingPool 是Java8添加的线程池。和别的4种不同&#xff0c;它用的是ForkJoinPool。 使用ForkJoinPool的好处是&#xff0c;把1个任务拆分成多个“小任务”&#xff0c;把这…

【MySQL学习笔记】(七)内置函数

内置函数 日期函数示例案例-1案例-2 字符串函数示例 数学函数其他函数 日期函数 示例 获得当前年月日 mysql> select current_date(); ---------------- | current_date() | ---------------- | 2023-09-03 | ---------------- 1 row in set (0.00 sec)获得当前时分秒…

剑指 Offer 57 - II. 和为s的连续正数序列(简单)

题目&#xff1a; class Solution { public:vector<vector<int>> findContinuousSequence(int target) { //本题使用滑动窗口&#xff08;双指针&#xff09;int i1, j1; //定义左右边界&#xff0c;一般是左闭右开int sum0; //窗口内的和vector&…

区块链技术与应用 - 学习笔记1【引言】

大家好&#xff0c;我是比特桃。本系列主要将我之前学习区块链技术时所做的笔记&#xff0c;进行统一的优化及整合。其中大量笔记源于视频课程&#xff1a;北京大学肖臻老师《区块链技术与应用》公开课。肖老师的课让我找回了求知若渴般的感觉&#xff0c;非常享受学习这门课的…

2023/9/3周报

目录 摘要 文献阅读1 1、标题和提出问题 2、物理模型对于水质预测的缺陷 3、模型框架 4、相关公式 5、结果分析 文献阅读2 1、标题和提出问题 2、问题叙述 3、模型框架 4、误差修补 5、实验结果和分析 总结 摘要 本周阅读了2篇论文&#xff0c;分别为一种基于深…

ReactNative 井字游戏 实战

效果展示 需要的插件准备 此实战项目需要用到两个插件。 react-native-snackbar 底部信息提示组件。 react-native-vector-icons 图标组件。 安装组件&#xff1a; npm i react-native-snackbar npm i react-native-vector-icons npm i types/react-native-vector-icons /…

uni-app之android离线自定义基座

一 为什么要自定义基座 1&#xff0c;基座其实就是一个app&#xff0c;然后新开发的页面可以直接在手机上面显示&#xff0c;查看效果。 2&#xff0c;默认的基座就是uniapp帮我们打包好的基座app&#xff0c;然后我们可以进行页面的调试。 3&#xff0c;自定义基座主要用来…

Python:列表推导式

相关阅读 Python专栏https://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482 列表推导式使得创建特定列表的方式更简洁。常见的用法为&#xff0c;对序列或可迭代对象中的每个元素应用某种操作&#xff0c;用生成的结果创建新的列表&#xff…

VSC++: 奇怪的风吹

void 奇怪的风吹() {//缘由https://ask.csdn.net/questions/1062454int aa[]{15, 30, 12, 36, 11, 20, 19, 17, 16, 18, 38, 15, 30, 12, 36, 11, 20, 19, 17, 16, 18, 38, -1},j 0, a 0, y 0, z 0;while (aa[j] > 0){if (j && aa[j] > 35 || aa[j] < 15)…

CXL.cache D2H Message 释义

&#x1f525;点击查看精选 CXL 系列文章&#x1f525; &#x1f525;点击进入【芯片设计验证】社区&#xff0c;查看更多精彩内容&#x1f525; &#x1f4e2; 声明&#xff1a; &#x1f96d; 作者主页&#xff1a;【MangoPapa的CSDN主页】。⚠️ 本文首发于CSDN&#xff0c…

记录一下自己对linux分区挂载的理解

一直狠模糊&#xff0c;分两个区&#xff0c;一个挂载/, 一个挂载/home 两者是什么关系 实测 先看挂载的内容 然后umount /home后创建一个新文件 再挂载回去 发现旧分区又回来了&#xff0c;说明路径只是个抽象的概念&#xff0c;分区挂载&#xff0c;互相之间数据是不影响…

只有一个线程的程序(main函数)

C并发编程入门 目录 只有一个线程的程序 就是main函数所在的线程。 这个线程无需我们手动创建&#xff0c;main函数就是这个线程的执行体。 运行main函数&#xff0c;就是执行只有一个线程的程序。 线程是进程内正在执行的代码所在的函数 代码示例 #include <iostream&…

弹性盒子的使用

一、定义 弹性盒子是一种用于按照布局元素的一维布局方法&#xff0c;它可以简便、完整、响应式地实现各种页面布局。 容器中存在两条轴&#xff0c;主轴和交叉轴(相当于我们坐标轴的x轴和y轴)。我们可以通过flex-direction来决定主轴的方向。 主轴&#xff08;main axis&am…

CentOS 7.6源码安装gdb 12.1

参考文章&#xff1a;《GDB调试-从安装到使用》 gdb --version看一下当前gdb的版本&#xff0c;可以看到是7.6.1-120.el7。 https://www.sourceware.org/gdb/download/可以下载gdb源码。 sudo nohup wget https://sourceware.org/pub/gdb/releases/gdb-12.1.tar.xz &下…

CXL.cache H2D Message 释义

&#x1f525;点击查看精选 CXL 系列文章&#x1f525; &#x1f525;点击进入【芯片设计验证】社区&#xff0c;查看更多精彩内容&#x1f525; &#x1f4e2; 声明&#xff1a; &#x1f96d; 作者主页&#xff1a;【MangoPapa的CSDN主页】。⚠️ 本文首发于CSDN&#xff0c…

CXL Memory Cache 分类及 Cacheline 归属问题

&#x1f525;点击查看精选 CXL 系列文章&#x1f525; &#x1f525;点击进入【芯片设计验证】社区&#xff0c;查看更多精彩内容&#x1f525; &#x1f4e2; 声明&#xff1a; &#x1f96d; 作者主页&#xff1a;【MangoPapa的CSDN主页】。⚠️ 本文首发于CSDN&#xff0c…

【原创】鲲鹏ARM构架openEuler操作系统安装Oracle 19c

作者:einyboy 【原创】鲲鹏ARM构架openEuler操作系统安装Oracle 19c | 云非云计算机科学、自然科学技术科谱http://www.nclound.com/index.php/2023/09/03/%E3%80%90%E5%8E%9F%E5%88%9B%E3%80%91%E9%B2%B2%E9%B9%8Farm%E6%9E%84%E6%9E%B6openeuler%E6%93%8D%E4%BD%9C%E7%B3%BB%…

进程、操作系统

文章目录 一、冯诺依曼体系&#xff08;Von Neumann Architecture&#xff09;1. 概述2. CPU 二、操作系统&#xff08;Operating System&#xff09;三、进程(process)/任务(task) 一、冯诺依曼体系&#xff08;Von Neumann Architecture&#xff09; 1. 概述 分类 CPU 中央处…

自建音乐播放器之一

这里写自定义目录标题 1.1 官方网站 2. Navidrome 简介2.1 简介2.2 特性 3. 准备工作4. 视频教程5. 界面演示5.1 初始化页5.2 专辑页 前言 之前给大家介绍过 Koel 音频流服务&#xff0c;就是为了解决大家的这个问题&#xff1a;下载下来的音乐&#xff0c;只能在本机欣赏&…