IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity学习shader笔记[四十]简单熔岩下落shader -> 正文阅读

[游戏开发]Unity学习shader笔记[四十]简单熔岩下落shader

这次的效果是仿原神的熔岩流下效果,代码是内置管线的

在这里插入图片描述

最终效果如下,高仿熔岩效果需要开启HDR颜色和Bloom效果,用postprocessing或者URP的设置或者自己写Bloom在这里插入图片描述

视频效果的特点及思路

  1. 镂空部分只有在岩浆下半部分以下出现 渐变图来控制 镂空程度要用渐变图的灰度值来lerp 渐变图控制镂空的起始位置

  2. 镂空部分随着向下流动而变大 思路是 镂空阈值随着顶点的U值或者V值的单方向变化而变小
    举个例子 镂空图的同样的一块黑班在U值较小时 只有一小部分能做到镂空 但是在U值较大时 镂空的部分就变大了

  3. 镂空口部分是往下扩大,上面部分基本不扩大。
    思路:
    因为单方向的UV是0-1的小数,尝试用pow的方式去做
    0-1 之间的数, pow 函数指数越大 图像越陡
    0-0.5部分会被压缩到小的区域 0.5-1时候会陡增
    这个pow函数线条代表了阈值随着UV的U或者V的变大的变化,
    然后最后阈值 = 1-阈值,这样V或者U变大的时候,最后阈值极速减小,并且变大的方向与向下流动的方向一致,就下方部分极速镂空。

  4. 视频中镂空不存在半透明的部分 应该使用裁切的方式 不能用透明度渐变来做

  5. 镂空部分一般不出现断节 以及消失:做法 阈值做个最大限制
    float hollowThresholdClamp = clamp(hollowThreshold, 0, threshold);
    threshold是 0.6f效果较好。

  6. 为了不让镂空边缘扩大的动效显得那么生硬 镂空图应该用模糊处理 这样扩大效果会好一些,因为没有模糊的图片,黑白过渡部分可能会出现明显的跳动,比如这个像素的灰度值是0.3,隔壁的突然变成了0.8,这样随着阈值减小时,镂空扩大会变得有时激进有时缓慢,不符合实际生活中熔岩扩大的渐进效果

  7. 自己在熔岩的底部再添加了读取渐变图让透明度渐变消失

注意点:

  1. 底部的渐变消失存在像素浮点精度运算问题,表现是底部有一条细丝,这是因为UV算到1的时候因为精度超出了范围变成1.xx,然后超出范围如果图片设置为repeat会自动取余读取图片靠近0时候的部分,这时最下方就是为0,按照shader的逻辑就透明度变成了1,于是就出现了最底部的一条横线。
    在这里插入图片描述

  2. 尝试过用UV拉伸噪声图的方式来模拟熔岩镂空下扩,但是用UV拉伸的方式太不可控,做了一些尝试发现一些特点

  • 首先UV本身是用time去控制流动的,这样改变了的UV会重新从顶点函数传入回来,也就是说,用时间叠加之后,位于模型部位的相同的顶点,在不同时刻被赋予的UV是不一样的。
  • UV乘以0到1的小数可以被不同程度的拉伸 在第一条的基础上用片源去采样渐变图,将灰度值作为UV的拉伸值,实现不同部位不同程度的拉伸,但是这样还是会有不正常的现象产生。

Shader代码:

Shader "Test/Lava"
{

    Properties
    {
        _mainTex ("主贴图", 2D) = "white" {}
        _flowSpeed("流动速度",Range(0,0.5)) = 0.02
        _color("颜色", Color) = (1,0,0,1)
        _maskTex ("镂空图", 2D) = "white" {}
        _gradientTex ("交界图", 2D) = "white" {}
        
        _clipStrength("镂空速度",Range(0.5, 1)) = 0.5
        _clipStrengthPower("镂空倍速",Range(1, 3)) = 0.5

        _clampRange("镂空阈值",Range(0, 1)) = 0.6
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

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

            struct v2f
            {
                float2 mainTexUV : TEXCOORD0;
                float2 maskTexUV : TEXCOORD1;
                float2 gradientTexUV : TEXCOORD2;
                float2 originUV : TEXCOORD4;

                
                float4 vertex : SV_POSITION;
            };

            sampler2D _mainTex;
            float4 _mainTex_ST;
            
            float _flowSpeed;
            float4 _color;
            
            sampler2D _maskTex;
            float4 _maskTex_ST;

            sampler2D _gradientTex;
            float4 _gradientTex_ST;

            float _clipStrength;
            float _clipStrengthPower;
            float _clampRange;

            
            
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.mainTexUV = TRANSFORM_TEX(v.uv, _mainTex);
                o.maskTexUV = TRANSFORM_TEX(v.uv, _maskTex);
                o.gradientTexUV = TRANSFORM_TEX(v.uv, _gradientTex);

                o.mainTexUV.x += _Time.y * _flowSpeed;
                o.maskTexUV.x += _Time.y * _flowSpeed;

                 o.originUV = v.uv;
   
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                
                // return float4(i.originUV.x, i.originUV.x, i.originUV.x, 1) ;

                fixed4 mainTexColor = tex2D(_mainTex, i.mainTexUV);

                fixed4 maskValue = tex2D(_maskTex, i.maskTexUV);
                
                fixed borderValue = tex2D(_gradientTex, i.gradientTexUV).r;


                // return  borderValue;

                float uvXReverse = (1 - i.originUV.x) ;

                // return  uvXReverse;


                
                // float hollowThreshold = uvXReverse * _clipStrength ;
                float hollowThreshold = pow(uvXReverse, _clipStrengthPower) ;

                // return  hollowThreshold;

                float hollowThresholdClamp = clamp(hollowThreshold, 0, _clampRange);
                

                // return  hollowThresholdClamp;

                
                float alpha = lerp(1, maskValue.r , borderValue);

                
                
                clip(alpha - hollowThresholdClamp);
                
                
                fixed4 finalColor = fixed4(mainTexColor.rgb * _color.rgb, alpha);
                
                return finalColor;
            }
            ENDCG
        }
    }
}

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-09-07 11:09:07  更:2021-09-07 11:09:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/21 20:24:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码