Unity FlatShadow阴影技术

2024-08-20 15:58
文章标签 技术 unity 阴影 flatshadow

本文主要是介绍Unity FlatShadow阴影技术,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

虽然不是什么新技术,但是是老技术啊,对啊,就是这么驴唇不对马嘴,就是这么的无耻,先发个招聘:

坐标山东青岛市北,招聘日系画师,spine动画师。


然后再说一下QQ群,山东手游研发聚集地335772557,进群先看公告,要是抱着我要学习的心态进群的话,那你就失望了,因为是个死群。

偶尔心情好的是时候会发个技术链接。


扯的虽然不多,但是要进入话题了。

测试来源于互联网,若侵权请告知删除。入群请不要跟我要模型贴图

由于是边写边做技术记录,所以就不先放效果图了


先说一下思路,就是在shader中重开一个pass做shadow的渲染,思路就是这么简单

第一个pass就是原来模型的渲染,这个就不说了,这个效果跟个人需求相关,我这里用了surfaceshader的standard来做测试了。

先上一下这个此事开头的shader吧 

效果图:


Shader "ShaderStore/Shadow/ShadowFlatOnPlane"
{Properties{_Color ("Color", Color) = (1,1,1,1)_MainTex ("Albedo (RGB)", 2D) = "white" {}_Glossiness ("Smoothness", Range(0,1)) = 0.5_Metallic ("Metallic", Range(0,1)) = 0.0}SubShader{Tags { "RenderType"="Opaque" "ForceNoShadowCasting"="True"}LOD 100CGPROGRAM#pragma surface surf Standard noshadow#pragma target 3.0sampler2D _MainTex;struct Input {float2 uv_MainTex;};half _Glossiness;half _Metallic;fixed4 _Color;void surf (Input IN, inout SurfaceOutputStandard o) {fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;o.Albedo = c.rgb;o.Metallic = _Metallic;o.Smoothness = _Glossiness;o.Alpha = c.a;}ENDCG}
}
接下来我们提个需求,shadow的颜色可以修改

首先需要在Properties里贴图对应的参数,方便调节

Properties{_Color ("Color", Color) = (1,1,1,1)_MainTex ("Albedo (RGB)", 2D) = "white" {}_Glossiness ("Smoothness", Range(0,1)) = 0.5_Metallic ("Metallic", Range(0,1)) = 0.0		_ShadowColor("Shadow Color",Color) = (1,0,0,1)}

然后我们继续,新增一个pass去修改模型的顶点,让模型的顶点投影到世界中,首先,shadow是平的,也就是worldposition的y要设置为0

将模型空间的顶点转到世界中去,然后把y=0,在转回模型空间。

float4 worldPos = mul(_Object2World,v.vertex);

worldPos.y = 0;

float4 localPos = mul(_World2Object,worldPos);

这样操作之后得到的结果是


Shader "ShaderStore/Shadow/ShadowFlatOnPlane"
{Properties{_Color ("Color", Color) = (1,1,1,1)_MainTex ("Albedo (RGB)", 2D) = "white" {}_Glossiness ("Smoothness", Range(0,1)) = 0.5_Metallic ("Metallic", Range(0,1)) = 0.0_ShadowColor("Shadow Color",Color) = (1,0,0,1)}SubShader{Tags { "RenderType"="Opaque" "ForceNoShadowCasting"="True"}LOD 100CGPROGRAM#pragma surface surf Standard noshadow#pragma target 3.0sampler2D _MainTex;struct Input {float2 uv_MainTex;};half _Glossiness;half _Metallic;fixed4 _Color;void surf (Input IN, inout SurfaceOutputStandard o) {fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;o.Albedo = c.rgb;o.Metallic = _Metallic;o.Smoothness = _Glossiness;o.Alpha = c.a;}ENDCG//ShadowFlatOnPlanePass{OffSet -1,-1CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex:POSITION;};struct v2f {float4 pos:SV_POSITION;};fixed4 _ShadowColor;v2f vert(appdata v){v2f o;float4 worldPos = mul(unity_ObjectToWorld,v.vertex);worldPos.y = 0;float4 localPos = mul(unity_WorldToObject,worldPos);o.pos = UnityObjectToClipPos(localPos);return o;}fixed4 frag(v2f i):SV_Target{return _ShadowColor;}ENDCG}}
}
然后新的问题出现了,阴影着实的在时间y=0的平面上,跟灯光方向无关。新需求就是希望影子投影与灯光的方向有关

(这篇博文是不是很流水账,呵呵呵,主要的意图就是招聘)


v2f vert(appdata v)
{
	v2f o;float3 lightDir = -normalize(_WorldSpaceLightPos0.xyz);loat4 worldPos = mul(unity_ObjectToWorld,v.vertex);worldPos.x -= worldPos.y/lightDir.y*lightDir.x;worldPos.z -= worldPos.y/lightDir.y*lightDir.z;worldPos.y = 0;o.pos = mul(UNITY_MATRIX_VP,worldPos);return o;
}

然后新问题:影子是不是要透明一些?



		//ShadowFlatOnPlanePass{Tags{"RenderType"="Transparent" "Queue"="Transparent"}OffSet -1,-1Blend SrcAlpha OneMinusSrcAlphaZWrite OffCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"

新问题带来的新需求,解决方案stencil



//ShadowFlatOnPlanePass{stencil{Ref 1Comp NotEqualPass Replace}
Tags{"RenderType"="Transparent" "Queue"="Transparent"}OffSet -1,-1Blend SrcAlpha OneMinusSrcAlphaZWrite OffCGPROGRAM
看似基本的效果也差不多了,我高兴的复制了一个,错了下位置,然后又有了新的问题,或许对于有些项目来说也不是个问题


怎么解决呢?还是stencil吧,不同的材质给个不同的ref



Shader "ShaderStore/Shadow/ShadowFlatOnPlane"
{Properties{_Color ("Color", Color) = (1,1,1,1)_MainTex ("Albedo (RGB)", 2D) = "white" {}_Glossiness ("Smoothness", Range(0,1)) = 0.5_Metallic ("Metallic", Range(0,1)) = 0.0_ShadowColor("Shadow Color",Color) = (1,0,0,1)_Ref("Stencil Ref",Int) = 1}
......//ShadowFlatOnPlanePass{stencil{Ref [_Ref]Comp NotEqualPass Replace}
......


现在基本上的问题都搞定了,我有兴致使然,转了下地面的plane,呵呵。。


新需求,然影子透到指定的plane平面吧,看到了哈,是平面,曲面的话我也不知道,shadowmap去干吧

.....我突然卡壳。。。这个需求过会再说吧。。。新需求,阴影从脚底到头顶有渐变过渡



		struct v2f {float4 pos:SV_POSITION;float Value:TEXCOORD0;};fixed4 _ShadowColor;v2f vert(appdata v){v2f o;float3 lightDir = -normalize(_WorldSpaceLightPos0.xyz);float4 worldPos = mul(unity_ObjectToWorld,v.vertex);worldPos.x -= worldPos.y/lightDir.y*lightDir.x;		worldPos.z -= worldPos.y/lightDir.y*lightDir.z;worldPos.y = 0;o.pos = mul(UNITY_MATRIX_VP,worldPos);o.Value = 1-worldPos.z/14.0;return o;}fixed4 frag(v2f i):SV_Target{return _ShadowColor*i.Value;}

再来说上面遗留的问题,如何投影到custom的plane上呢,把顶点转到planer,然后处理,在转回world,再mvp。。。



这个操作免不了C#的参数传入

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[ExecuteInEditMode]
public class ShadowFlatOnPlane : MonoBehaviour {public Transform ShadowPlane;public Material[] ShadowMats;// Use this for initializationvoid Start () {foreach (Material mat in ShadowMats){mat.SetMatrix("_World2Ground", ShadowPlane.GetComponent<MeshRenderer>().worldToLocalMatrix);mat.SetMatrix("_Ground2World", ShadowPlane.GetComponent<MeshRenderer>().localToWorldMatrix);}}private void Update(){Start();}
}

			struct v2f {float4 pos:SV_POSITION;float Value:TEXCOORD0;};fixed4 _ShadowColor;float4x4 _World2Ground;float4x4 _Ground2World;v2f vert(appdata v){v2f o;float3 lightDir = -normalize(_WorldSpaceLightPos0.xyz);lightDir = normalize(mul(_World2Ground,float4(lightDir,0)).xyz);float4 worldPos = mul(unity_ObjectToWorld,v.vertex);worldPos = mul(_World2Ground,worldPos);worldPos.xz -= (worldPos.y/lightDir.y)*lightDir.xz;worldPos.y = 0;worldPos = mul(_Ground2World,worldPos);worldPos = mul(unity_WorldToObject,worldPos);o.pos = UnityObjectToClipPos(worldPos);o.Value = 1-worldPos.z/14.0;return o;}

这个方案也有弊端,在效果上也有个小问题,就是过度旋转地面plane之后,影子会出现一些问题,还有就是目前写的只有Directional Light的效果,在lightDir的计算上可以加入其他光源的判定。。

有合适的人,请看博文的人给推荐推荐?







这篇关于Unity FlatShadow阴影技术的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1090517

相关文章

Qt如何实现文本编辑器光标高亮技术

《Qt如何实现文本编辑器光标高亮技术》这篇文章主要为大家详细介绍了Qt如何实现文本编辑器光标高亮技术,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录实现代码函数作用概述代码详解 + 注释使用 QTextEdit 的高亮技术(重点)总结用到的关键技术点应用场景举例示例优化建议

Java中的登录技术保姆级详细教程

《Java中的登录技术保姆级详细教程》:本文主要介绍Java中登录技术保姆级详细教程的相关资料,在Java中我们可以使用各种技术和框架来实现这些功能,文中通过代码介绍的非常详细,需要的朋友可以参考... 目录1.登录思路2.登录标记1.会话技术2.会话跟踪1.Cookie技术2.Session技术3.令牌技

Web技术与Nginx网站环境部署教程

《Web技术与Nginx网站环境部署教程》:本文主要介绍Web技术与Nginx网站环境部署教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、Web基础1.域名系统DNS2.Hosts文件3.DNS4.域名注册二.网页与html1.网页概述2.HTML概述3.

Java使用WebView实现桌面程序的技术指南

《Java使用WebView实现桌面程序的技术指南》在现代软件开发中,许多应用需要在桌面程序中嵌入Web页面,例如,你可能需要在Java桌面应用中嵌入一部分Web前端,或者加载一个HTML5界面以增强... 目录1、简述2、WebView 特点3、搭建 WebView 示例3.1 添加 JavaFX 依赖3

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

金融业开源技术 术语

金融业开源技术  术语 1  范围 本文件界定了金融业开源技术的常用术语。 本文件适用于金融业中涉及开源技术的相关标准及规范性文件制定和信息沟通等活动。

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时