目的:

比上一个版本更好的做法 [上一个版本](https://blog.csdn.net/qq_45253770/article/details/122034252?spm=1001.2014.3001.5501)


1.先有一个面片,这个面片的顶点需要多一点

2.(顶点阶段)构造旋转矩阵,绕z轴旋转

 float sinTheta = sin(PI * _WindDir);float cosTheta = sqrt(1 - sinTheta * sinTheta);float4x4 ZRotateM = float4x4(cosTheta,  sinTheta, 0,     0,-sinTheta, cosTheta, 0,     0,0,         0,        1,     0,0,         0,        0,     1);

3.(顶点阶段)矩阵运算后插值

 float3 localPos = mul(IN.positionOS, ZRotateM).xyz;localPos = lerp(IN.positionOS.xyz, localPos.xyz, IN.uv.y * IN.uv.y);localPos = BillBoard(localPos);

4. (片元阶段)差异化操作

 float3 worldPos = IN.positionWS * 0.01f;float2 uv  = IN.uv_noise * float2(1, 1) + _Time.xx * float2(0, -10) + float2(worldPos.x * worldPos.z, 0);

5. (片元阶段)采样噪声图

 float noise       = SAMPLE_TEXTURE2D(_NoiseMap, sampler_NoiseMap, uv).r;

6. (片元阶段)扭曲采样火焰遮罩图

__注意遮罩图的火焰尖头部分不要离顶部太近

 float distoreArea = smoothstep(0.0f, 1.0f, IN.uv.y);float offsetY     = (noise * 2 - 1);float2 offset     = float2(0, offsetY) * distoreArea * _FireStrength;float fireShape   = SAMPLE_TEXTURE2D(_FireShapeMap, sampler_FireShapeMap, IN.uv + offset).r;

7. (片元阶段)显示控制,可以用来做火焰的大小以及出现和消失

 float fireShape = SAMPLE_TEXTURE2D(_FireShapeMap, sampler_FireShapeMap, IN.uv + offset).r;fireShape = smoothstep(1 - _FireScale, 1.0f, fireShape);

8. (片元阶段)是否使用Ramp图控制颜色

 #ifdef UseRamphalf3 finalColor = SAMPLE_TEXTURE2D(_ColorRamp, sampler_ColorRamp,   float2(1 - fireShape, 0.5f)).rgb;finalColor = lerp(finalColor, finalColor * _FireColor, fireShape);half1 finalAlpha = step(0.01f, fireShape);#else half3 finalColor = _FireColor;half1 finalAlpha = fireShape;#endif

9. (片元阶段)提出透明部分,防止穿帮(深度问题导致显示错误)

 clip(finalAlpha - 0.01f);

10. 最终效果


11. shader

Shader "Fire"
{Properties {_NoiseMap       ("Noise     Texture", 2D) = "white" {}_FireShapeMap   ("FireShape Texture", 2D) = "white" {}[Toggle(UseRamp)]_MaskOn("Use Ramp?",int) = 1_ColorRamp       ("Color     Texture", 2D) = "white" {}[HDR]_FireColor ("Fire Color", Color) = (1,1,1,1)_WindDir      ("Wind Dir", Range(-0.5, 0.5)) = 0_FireStrength ("Fire Strength", Range(0, 1)) = 0_FireScale    ("Fire Scale", Range(0, 1)) = 0}SubShader {Tags { "RenderType"="Transparent" "RenderPipeline"="UniversalPipeline" "Queue"="Transparent"}Blend SrcAlpha OneMinusSrcAlphaHLSLINCLUDE#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"CBUFFER_START(UnityPerMaterial)float4 _NoiseMap_ST;half3 _FireColor;float _WindDir;float _FireStrength;float _FireScale;CBUFFER_ENDENDHLSLPass {Name "Fire"Tags { "LightMode"="UniversalForward" }ZWrite OnZTest OnCull offBlend SrcAlpha OneMinusSrcAlphaHLSLPROGRAM#pragma vertex vert#pragma fragment frag#pragma shader_feature UseRampstruct Attributes {float4 positionOS : POSITION;float3 normalOS      : NORMAL;float2 uv          : TEXCOORD0;};struct Varyings {float4 positionCS    : SV_POSITION;float2 uv         : TEXCOORD0;float2 uv_noise     : TEXCOORD1;float3 positionWS   : TEXCOORD2;};TEXTURE2D(_NoiseMap);     SAMPLER(sampler_NoiseMap);TEXTURE2D(_FireShapeMap); SAMPLER(sampler_FireShapeMap);TEXTURE2D(_ColorRamp);        SAMPLER(sampler_ColorRamp);// Billboardfloat3 BillBoard(float3 positionOS){float3 center = float3(0,0,0);float3 viewer = TransformWorldToObject(_WorldSpaceCameraPos.xyz);float3 normal = normalize(viewer - center);float3 up     = abs(normal.y > 0.999f ? float3(0, 0, 1) : float3(0, 1, 0));float3 right  = normalize(cross(up, normal));float3 centerOffset = positionOS - center;float3 billBoardPos = center + right * centerOffset.x + up * centerOffset.y + normal * centerOffset.z;return billBoardPos;}Varyings vert(Attributes IN) {Varyings OUT;// Rotatefloat sinTheta = sin(PI * _WindDir);float cosTheta = sqrt(1 - sinTheta * sinTheta);float4x4 ZRotateM = float4x4(cosTheta,  sinTheta, 0,     0,-sinTheta, cosTheta, 0,     0,0,         0,        1,     0,0,         0,        0,     1);float3 localPos = mul(IN.positionOS, ZRotateM).xyz;localPos = lerp(IN.positionOS.xyz, localPos.xyz, IN.uv.y * IN.uv.y);localPos = BillBoard(localPos);VertexPositionInputs positionInputs = GetVertexPositionInputs(localPos);OUT.positionCS = positionInputs.positionCS;OUT.positionWS  = positionInputs.positionWS;OUT.uv            = IN.uv;OUT.uv_noise   = TRANSFORM_TEX(IN.uv, _NoiseMap);return OUT;}half4 frag(Varyings IN) : SV_Target {// UVfloat3 worldPos = IN.positionWS * 0.01f;float2 uv  = IN.uv_noise * float2(1, 1) + _Time.xx * float2(0, -10) + float2(worldPos.x * worldPos.z, 0);// Shapefloat noise       = SAMPLE_TEXTURE2D(_NoiseMap, sampler_NoiseMap, uv).r;float distoreArea = smoothstep(0.0f, 1.0f, IN.uv.y);float offsetY     = (noise * 2 - 1);float2 offset     = float2(0, offsetY) * distoreArea * _FireStrength;float fireShape = SAMPLE_TEXTURE2D(_FireShapeMap, sampler_FireShapeMap, IN.uv + offset).r;fireShape = smoothstep(1 - _FireScale, 1.0f, fireShape);// Ramp #ifdef UseRamphalf3 finalColor = SAMPLE_TEXTURE2D(_ColorRamp, sampler_ColorRamp, float2(1 - fireShape, 0.5f)).rgb;finalColor = lerp(finalColor, finalColor * _FireColor, fireShape);half1 finalAlpha = step(0.01f, fireShape);#elsehalf3 finalColor = _FireColor;half1 finalAlpha = fireShape;#endifclip(finalAlpha - 0.01f);return half4(finalColor, finalAlpha);}ENDHLSL}}
}

12. 总结
__更好的美术控制,更可控的火焰效果。

unity HLSL 面片火焰Shader V0.2相关推荐

  1. unity HLSL 面片火焰Shader V0.1

    目的: 使用Unity Shader 面片火焰的实现思路 1.先有一个面片 2.uv.y的映射 3.构造火焰形状 4.采样一张噪声并添加uv动画 5.结合两个mask 6.有了上面的思路,主观调整数值 ...

  2. Unity 内置管线Shader升级到URP详细手册

    本文转载自:https://www.jianshu.com/p/3fef69e2efb6 作为技术资料记录和备份,避免遗忘或删除 //================以下为具体内容========== ...

  3. 在3dmax里仿unity的Unlit/Texture shader并渲染

    在3dmax里实现unity的texture shader并渲染 3dsmax版本:2019 首先感谢这位大哥的 Unity与3DMax效果同步--3DMaxDX Shader:https://zhu ...

  4. 一种火焰shader的实现

    火焰在我们的日常生活中十分常见,我们都知道火焰有内外焰之分,在现实世界中内外焰的颜色区别并不是十分明显,而在大多数游戏尤其是卡通渲染风格的游戏中火焰的内外焰颜色有明显的区别(我十分喜爱的一款国产游戏: ...

  5. unity 2020 怎么写shader使其接受光照?_如何在Unity中造一个PBR Shader轮子

    之前有业界大佬建议我去了解下Unity的PBR.说来惭愧,我查找了下资料才发现自己在这方面的知识居然是一片空白.经过几周的学习与尝试我对这一块算是有了初步的了解,于是写了这篇文章,一方面对自己学到的东 ...

  6. 在Unity 3D中,shader是何时编译的,在何时加载入显存中的?

    在Unity 3D中,shader是何时编译的,在何时加载入显存中的? 是某一对象在实例化时,加载其相关的material与shader还是游戏开始时? 添加评论 分享 按时间排序按投票排序 4 个回 ...

  7. unity 全息和xRay shader

    unity 全息和xRay shader 这个是网上的效果,科幻的感觉是不是很强烈. 下面是我们去实现的效果. 先看下效果图,左边的是Xray的效果,右边是全息的效果.都有着异曲同工的妙处. 全息的效 ...

  8. 关于Unity 5.x Lightmap Shader 编译过慢的分析

    关于Unity 5.x Lightmap Shader 编译过慢的分析 缘起 最近在研究Unity 5.x 的 Lightmapping 与 场景打包的相关的知识.发现坑深啊.关于怎么打包怎么用网上的 ...

  9. 【UnityShader】自定义unity粒子系统使用的shader

    前几天特效那边让改一下一个粒子系统使用的shader,说是shader的一个值希望关联上粒子的某个值. 我不假思索地就准备写个脚本挂上去传个值给shader.等脚本写好,测试的时候才突然发现,传值过去 ...

最新文章

  1. pytorch错误解决: BrokenPipeError: [Errno 32] Broken pipe
  2. [javaweb] servlet处理请求参数中文乱码的问题
  3. linux 定时运行脚本_教你如何在Linux下让Python脚本自启动和定时启动
  4. 8086CPU汇编寻址写法
  5. ts定义数组类型_ts基本数据类型
  6. 2019-03-15-算法-进化(有效的数独)
  7. 移动云11.11,钜惠High不停!
  8. java游戏怎么设置背景色_java-将背景色设置为JButton
  9. Windows-Server下加强系统安全性系列之方案【六】
  10. 别人家的公司!雷军发红包 人均39万
  11. DevExpress v17.2新版亮点——XAF篇
  12. asp.net Code学习二(使用vs 2015 update 3)
  13. 多数据源切换数据源注入为空问题
  14. 中文搜索引擎技术揭密-网络蜘蛛
  15. Oracle查询优化改写技巧与案例总结二
  16. [转载]数字全息与计算全息
  17. javaWeb图书购物商城
  18. 通信工程专业英语词汇 通信工程 专业英语
  19. 宋宝华:Linux的任督二脉——进程调度和内存管理
  20. 电脑如何接受邮件服务器,什么是传入邮件服务器?

热门文章

  1. 【日常学习笔记】2019/1/10(Oracle语句学习)
  2. 绝对适合新手的php入门教程
  3. 复合选择器之链接伪类选择器
  4. 多值依赖和第四范式的个人理解
  5. npm 查看包的所有版本号
  6. 深入分析,从产品思维到流量思维
  7. 准确率(Accuracy),精确率/查准率(Precision), 召回率/查全率(Recall)和F1-Measure
  8. 健身环大冒险 腹肌防御Best | 健身环大冒险 2162-0002 | 健身环 重新适配
  9. 【微语】第七周(12.28~2021.01.03)
  10. IIS数据库连接出错的解决方法