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 - 板砖日志 - 简单的树、草 等植物的 随风飘扬 动画 -> 正文阅读

[游戏开发]Unity Shader - 板砖日志 - 简单的树、草 等植物的 随风飘扬 动画


目的

便于后续自己的 CTRL+C,V的面向复制、粘贴编程


思路

非常简单:可以使用 perlin noise,simple noise 或是其他的 noise 函数,又或是 noise tex 来提取顶点 xyz 的偏移

然后 vs 里便宜就好了,需要阴影跟随飘动的投影就加上 “LightMode”=“ShadowCaster” 的 pass


Script


include cginc

#ifndef __WIND_COMMON_H__
#define __WIND_COMMON_H__

// jave.lin 2021/04/13

#include "UnityCG.cginc"

#if defined(_WIND_ON)

half	_WindSpeed;
half	_WindWavesScale;
half	_WindForce;
half4	_WindDir;
half	_MoveHeight;
half	_MoveHeightPow;

float3 mod3D289(float3 x) { return x - floor(x / 289.0) * 289.0; }

float4 mod3D289(float4 x) { return x - floor(x / 289.0) * 289.0; }

float4 permute(float4 x) { return mod3D289((x * 34.0 + 1.0) * x); }

float4 taylorInvSqrt(float4 r) { return 1.79284291400159 - r * 0.85373472095314; }

float snoise(float3 v)
{
	const float2 C = float2(1.0 / 6.0, 1.0 / 3.0);
	float3 i = floor(v + dot(v, C.yyy));
	float3 x0 = v - i + dot(i, C.xxx);
	float3 g = step(x0.yzx, x0.xyz);
	float3 l = 1.0 - g;
	float3 i1 = min(g.xyz, l.zxy);
	float3 i2 = max(g.xyz, l.zxy);
	float3 x1 = x0 - i1 + C.xxx;
	float3 x2 = x0 - i2 + C.yyy;
	float3 x3 = x0 - 0.5;
	i = mod3D289(i);
	float4 p = permute(permute(permute(i.z + float4(0.0, i1.z, i2.z, 1.0)) + i.y + float4(0.0, i1.y, i2.y, 1.0)) + i.x + float4(0.0, i1.x, i2.x, 1.0));
	float4 j = p - 49.0 * floor(p / 49.0);  // mod(p,7*7)
	float4 x_ = floor(j / 7.0);
	float4 y_ = floor(j - 7.0 * x_);  // mod(j,N)
	float4 x = (x_ * 2.0 + 0.5) / 7.0 - 1.0;
	float4 y = (y_ * 2.0 + 0.5) / 7.0 - 1.0;
	float4 h = 1.0 - abs(x) - abs(y);
	float4 b0 = float4(x.xy, y.xy);
	float4 b1 = float4(x.zw, y.zw);
	float4 s0 = floor(b0) * 2.0 + 1.0;
	float4 s1 = floor(b1) * 2.0 + 1.0;
	float4 sh = -step(h, 0.0);
	float4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
	float4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
	float3 g0 = float3(a0.xy, h.x);
	float3 g1 = float3(a0.zw, h.y);
	float3 g2 = float3(a1.xy, h.z);
	float3 g3 = float3(a1.zw, h.w);
	float4 norm = taylorInvSqrt(float4(dot(g0, g0), dot(g1, g1), dot(g2, g2), dot(g3, g3)));
	g0 *= norm.x;
	g1 *= norm.y;
	g2 *= norm.z;
	g3 *= norm.w;
	float4 m = max(0.6 - float4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
	m = m * m;
	m = m * m;
	float4 px = float4(dot(x0, g0), dot(x1, g1), dot(x2, g2), dot(x3, g3));
	return 42.0 * dot(m, px);
}

void windNoiseHandle(inout float4 posOS, float modelY, float uv_v)
{
	if (_MoveHeight <= 0) return;

	 jave.lin 2021/12/13 : 新版本的方式,目前暂时没用上 uv
	//float hT = modelY / _MoveHeight;

	//float3 positionOS = posOS;
	//float windSpeed = _Time.y * (_WindSpeed * 5);
	//float3 noisePos = (positionOS + windSpeed) * _WindWavesScale;
	//float windNoise = snoise(noisePos) * (_WindForce * 30);
	//windNoise *= hT;
	//windNoise *= pow(hT, _MoveHeightPow);
	//posOS.xyz = positionOS + _WindDir.xyz * windNoise;

	// jave.lin : 旧版本的方式
	float3 positionOS = posOS;
	float windSpeed = _Time.y * (_WindSpeed * 5);
	float windNoise = snoise((mul(unity_ObjectToWorld, posOS) + windSpeed) * _WindWavesScale);
	windNoise = (windNoise * 0.01);
	//#ifdef _FIXTHEBASEOFFOLIAGE_ON
	//	windNoise = (windNoise * pow(uv_v, 2.0));
	//#endif
	//windNoise = (windNoise * pow(uv_v, 2.0));
	windNoise = (windNoise * pow(modelY / _MoveHeight, _MoveHeightPow));
	windNoise = (windNoise * (_WindForce * 30));
	posOS.xyz += (_WindDir.xyz * windNoise) * (1 + (sin(_Time.y * 0.5) * 0.5 + 0.5));
}

#define VERT_WIND(wpos, modelY, uv_v) windNoiseHandle(wpos, modelY, uv_v);

#else
#define VERT_WIND(wpos, modelY, uv_v)
#endif


#endif


appled shader

// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)

Shader "OnePiece/Legacy Shaders/Transparent/Cutout/Diffuse_DoubleSide_Wind" {
Properties {
    _Color ("Main Color", Color) = (1,1,1,1)
    _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}

SubShader {
    Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    LOD 200
	Cull Off



CGPROGRAM
#define _WIND_ON
#pragma surface surf Lambert fullforwardshadows addshadow alphatest:_Cutoff vertex:vert

// include 引入
#include "Includes/CG/WindCommon.cginc"

sampler2D _MainTex;
fixed4 _Color;

struct Input {
    float2 uv_MainTex;
};

void vert(inout appdata_full v)
{
	// 应用
	VERT_WIND(v.vertex, v.vertex.y, v.texcoord.y)
}

void surf (Input IN, inout SurfaceOutput o) {
    fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    o.Albedo = c.rgb;
    o.Alpha = c.a;
}
ENDCG
}

Fallback "Legacy Shaders/Transparent/Cutout/VertexLit"
}


csharp

// jave.lin 2021/04/13

using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;
#endif

[ExecuteInEditMode]
public class WindArgsController : MonoBehaviour
{
    private static int _WindForce = Shader.PropertyToID("_WindForce");
    private static int _WindWavesScale = Shader.PropertyToID("_WindWavesScale");
    private static int _WindSpeed = Shader.PropertyToID("_WindSpeed");
    private static int _WindStrengthen = Shader.PropertyToID("_WindStrengthen");
    private static int _WindDir = Shader.PropertyToID("_WindDir");
    private static int _MoveHeight = Shader.PropertyToID("_MoveHeight");
    private static int _MoveHeightPow = Shader.PropertyToID("_MoveHeightPow");

    public bool windToggle = true;
    private bool lastWindToggle = false;

    [Range(0.0f, 1.0f)]
    public float WindSpeed = 0.3f;
    private float lastWindSpeed;

    [Range(0.0f, 1.0f)]
    public float WindStrengthen = 1;
    private float lastWindStrengthen = 1;

    [Range(0.0f, 1.0f)]
    public float WindWavesScale = 0.25f;
    private float lastWindWavesScale;

    [Range(0.0f, 1.0f)]
    public float WindForce = 0.5f;
    private float lastWindForce;

    public bool DirFromForward = true;
    public Vector4 WindDir = new Vector4(1, 0, 0, 0);
    private Vector4 lastWindDir;

    public float MoveHeight = 5.0f;
    private float lastMoveHeight;

    [Range(0.001f, 5.0f)]
    public float MoveHeightPow = 1.0f;
    private float lastMoveHeightPow;

#if UNITY_EDITOR
    public float GizmosDirLineSize = 8.0f;
    public Color GizmosDirLineColor = Color.green;
    public Color GizmosCircleColor = Color.red;
    public int GizmosDirHeadCircleLineSegmentNum = 12;
    public int GizmosDirHeadCircleLineRadius = 2;
#endif

    private void Start()
    {
        WindDir = transform.forward;

        if (windToggle)
            Shader.EnableKeyword("_WIND_ON");
        else
            Shader.DisableKeyword("_WIND_ON");

        Shader.SetGlobalFloat(_WindSpeed, WindSpeed);
        Shader.SetGlobalFloat(_WindWavesScale, WindWavesScale);
        Shader.SetGlobalFloat(_WindForce, WindForce);
        Shader.SetGlobalVector(_WindDir, WindDir);
        Shader.SetGlobalFloat(_MoveHeight, MoveHeight);
        Shader.SetGlobalFloat(_MoveHeightPow, MoveHeightPow);
    }

    private void Update()
    {
        if (lastWindToggle != windToggle)
        {
            lastWindToggle = windToggle;
            if (windToggle)
                Shader.EnableKeyword("_WIND_ON");
            else
                Shader.DisableKeyword("_WIND_ON");
        }

        if (lastWindSpeed != WindSpeed)
        {
            lastWindSpeed = WindSpeed;
            Shader.SetGlobalFloat(_WindSpeed, WindSpeed);
        }

        if (lastWindStrengthen != WindStrengthen)
        {
            lastWindStrengthen = WindStrengthen;
            Shader.SetGlobalFloat(_WindStrengthen, WindStrengthen);
        }

        if (lastWindWavesScale != WindWavesScale)
        {
            lastWindWavesScale = WindWavesScale;
            Shader.SetGlobalFloat(_WindWavesScale, WindWavesScale);
        }

        if (lastWindForce != WindForce)
        {
            lastWindForce = WindForce;
            Shader.SetGlobalFloat(_WindForce, WindForce);
        }

        if (DirFromForward)
        {
            WindDir = transform.forward;
        }
        if (!lastWindDir.Equals(WindDir))
        {
            lastWindDir = WindDir;
            Shader.SetGlobalVector(_WindDir, WindDir);
        }

        if (lastMoveHeight != MoveHeight)
        {
            lastMoveHeight = MoveHeight;
            Shader.SetGlobalFloat(_MoveHeight, MoveHeight);
        }

        if (lastMoveHeightPow != MoveHeightPow)
        {
            lastMoveHeightPow = MoveHeightPow;
            Shader.SetGlobalFloat(_MoveHeightPow, MoveHeightPow);
        }
    }

#if UNITY_EDITOR
    private void OnDrawGizmos()
    {
        // jave.lin 2021/12/13 - 添加实现 风向 显示的 Gizmos
        var transWPos = transform.position;
        Vector3 transForward;

        if (DirFromForward)
        {
            transForward = transform.forward;
        }
        else
        {
            transForward = WindDir;
        }

        // back up gizmos col
        var srcCol = Gizmos.color;
        int count = GizmosDirHeadCircleLineSegmentNum;
        float curAngle = 0;
        float perIterateAngle = (2.0f * Mathf.PI) / count;

        // center line
        Gizmos.color = GizmosCircleColor;
        Gizmos.DrawLine(transWPos, transWPos + transForward * GizmosDirLineSize);

        // local to world mat
        var L2WMat = transform.localToWorldMatrix;

        for (int i = 0; i < count; i++)
        {
            // draw circle
            Gizmos.color = GizmosCircleColor;

            var cx = Mathf.Cos(curAngle);
            var cy = Mathf.Sin(curAngle);
            var cv = new Vector3(cx, cy, 0) * GizmosDirHeadCircleLineRadius;
            cv = L2WMat.MultiplyVector(cv);

            curAngle += perIterateAngle;
            var nx = Mathf.Cos(curAngle);
            var ny = Mathf.Sin(curAngle);
            var nv = new Vector3(nx, ny, 0) * GizmosDirHeadCircleLineRadius;
            nv = L2WMat.MultiplyVector(nv);

            Gizmos.DrawLine(transWPos + cv, transWPos + nv);

            // draw dir line
            Gizmos.color = GizmosDirLineColor;
            Gizmos.DrawLine(transWPos + cv, transWPos + cv + transForward * GizmosDirLineSize);
        }

        // recovery gizmos color
        Gizmos.color = srcCol;
    }
#endif
}


效果

在这里插入图片描述

  游戏开发 最新文章
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-12-15 18:37:41  更:2021-12-15 18:39:37 
 
开发: 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年11日历 -2024/11/27 20:28:13-

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