Unity3D The Blacksmith 角色阴影技术使用心得
这个demo放出来之后,对其中的角色阴影部分的技术十分感兴趣,我就赶紧下过来研究了一下。官方的技术博客里有对这一部分技术的介绍,链接在这里:独特的角色阴影,
其中写到只要在其他shader里添加
#pragma multi_compile _ UNIQUE_SHADOW UNIQUE_SHADOW_LIGHT_COOKIE
#include "UniqueShadow_ShadowSample.cginc"
这两行代码就能使用这个高级阴影了。 我之前也因为在做一些demo的时候发现unity默认阴影达不到理想效果,和ue4比起来还是有一定差距的。于是就想到使用这个阴影技术了。于是我兴致勃勃的把这两行代码和几个库文件加到我的shader和项目里去,一运行发现,高级阴影并没有出现。哎,看样子只能自己研究了。
既然是阴影,那么着手点就是unity里的阴影部分的代码,手动写过自定义阴影的人应该都知道,unity阴影计算:SHADOW_COORDS、TRANSFER_SHADOW、SHADOW_ATTENUATION三个函数了,unity把阴影生成的代码都写在了这三个函数里,方便调用。我看The Blacksmith的技术博客上写着: 我们发现原来有一个非常简单的方法来对常见的Unity shader所用的阴影方法进行重写。 于是我琢磨着应该是他们也用了这三个方法,于是打开 UniqueShadow_ShadowSample.cginc 文件,果不其然,在最下面找到了这么一段代码
#if defined(UNITY_PASS_FORWARDBASE) || defined(UNITY_PASS_FORWARDADD) || defined(UNIQUE_SHADOW_FORCE_REPLACE_BUILTIN) #undef SHADOW_COORDS #undef TRANSFER_SHADOW #undef SHADOW_ATTENUATION #define SHADOW_COORDS(i) UNIQUE_SHADOW_INTERP(i) #define TRANSFER_SHADOW o.uniqueShadowPos = mul(u_UniqueShadowMatrix, float4(worldPos.xyz, 1.f)); #define SHADOW_ATTENUATION(i) UNIQUE_SHADOW_SAMPLE(i);
#endif
这里的意思就是,如果判断pass的名字是
UNITY_PASS_FORWARDBASE、NITY_PASS_FORWARDADD、UNIQUE_SHADOW_FORCE_REPLACE_BUILTIN
这三个的话,就会把
SHADOW_COORDS(i) 替换成UNIQUE_SHADOW_INTERP(i),
SHADOW_ATTENUATION(i)替换成UNIQUE_SHADOW_SAMPLE(i);
TRANSFER_SHADOW的值替换成后面的 o.uniqueShadowPos
这样的话就好说了,之后只要把自己的shader里生成阴影的pass名字改成三个里的任意一个,生成阴影的代码还是按照原来的方式写就可以了。
于是我立马新建了一个Unlit Shader,添加上生成阴影的代码后,把pass的名字改成了UNITY_PASS_FORWARDBASE,代码如下
Shader "Custom/simpleSuperShadow"
{ Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { Tags{ "LightMode" = "ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdbase #include "UnityCG.cginc" #include "AutoLight.cginc" #define UNITY_PASS_FORWARDBASE
#pragma multi_compile _ UNIQUE_SHADOW UNIQUE_SHADOW_LIGHT_COOKIE
#include "UniqueShadow/UniqueShadow_ShadowSample.cginc" struct v2f { float2 uv : TEXCOORD0; float4 pos : SV_POSITION; float3 worldPos : TEXCOORD1; SHADOW_COORDS(2) }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata_full v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); o.worldPos = mul(_Object2World, v.vertex).xyz; TRANSFER_SHADOW(o); return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); fixed shadow = SHADOW_ATTENUATION(i); return col * shadow; } ENDCG } } FallBack "Diffuse"
}
点击运行之后,shader报错,提示我顶点函数里worldPos未定义,报错的地方是在TRANSFER_SHADOW(o)这一行,但是我明明在v2f里定义了这个变量,并且在上一行赋值了才对。这个提示不应该出现才对。对于这个问题,我毫无头绪,不知道自己哪里出了问题。于是我又新建了一个standard surface shader,这次我只在里面添加了
#pragma multi_compile _ UNIQUE_SHADOW UNIQUE_SHADOW_LIGHT_COOKIE
#include "UniqueShadow/UniqueShadow_ShadowSample.cginc"
两行,运行一下,居然成功了,于是我在编辑器里点开了surface shader的原始代码,通过仔细对比阴影生成的三个函数发现,surface shader在
顶点函数使用worldPos的时候,并不是直接给o.worldPos赋值的,而是先定义了一个float3的worldPos变量,计算出来以后再让o.worldPos = worldPos,这里感觉应该是一样的才是,并没有什么特别的地方啊。虽然我不是很清楚surface shader里为啥要这么写,但是抱着试一试的心情,我把自己的shader的顶点函数从原来的
v2f vert (appdata_full v)
{ v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); o.worldPos = mul(_Object2World, v.vertex).xyz; TRANSFER_SHADOW(o); return o;
}
这样,改成了
v2f vert (appdata_full v)
{ v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); float3 worldPos = mul(_Object2World, v.vertex).xyz; o.worldPos = worldPos; TRANSFER_SHADOW(o); return o;
}
这样,于是我运行一下。卧槽竟然成功了。按道理来说定义一个临时变量和直接赋值应该没有区别才是,为啥这里不定义一个就不行呢,
mul(_Object2Wrold,v.vertex).xyz返回的本来就是一个float3的变量才是,为毛非要这么做才能正确显示呢。实在是不知道要怎么解释。希望知道的大大们能够帮我解释一下。
总结一下这个高级阴影的使用方法
1.给计算阴影的pass添加
#define UNITY_PASS_FORWARDBASE
#pragma multi_compile _ UNIQUE_SHADOW UNIQUE_SHADOW_LIGHT_COOKIE
#include "UniqueShadow/UniqueShadow_ShadowSample.cginc"
这三行代码,然后在顶点函数使用TRANSFES_SHADOW的地方改成
float3 worldPos = mul(_Object2World, v.vertex).xyz;
o.worldPos = worldPos;
TRANSFER_SHADOW(o);
这样自定义的shader也能够使用这个超高分辨率的阴影了。
这里我用了一个卡通shader做测试
未使用高级阴影:
使用高级阴影:
这样就能做出媲美ue4的高级阴影来了。
Unity3D The Blacksmith 角色阴影技术使用心得相关推荐
- Unity3D游戏制作 移动平台上的角色阴影制作
本文将重点介绍两种目前在移动平台上的主流阴影制作技术,同时也会简单介绍两种移动平台上相对较为高级的动态阴影生成方法. 由于目前主流使用Unity3.x在移动平台上并不支持阴影的动态生成技术,所以目前最 ...
- Unity3D游戏开发之Unity3D中的动态阴影
http://blog.csdn.net/qinyuanpei/article/details/32355267 博主今天想和大家分享的是Unity3D中的动态阴影,昨天博主重温了一下自己喜欢的游戏& ...
- [转载]漫谈游戏中的阴影技术
学习啦~~~~~~ 原文地址:漫谈游戏中的阴影技术作者:flymemory 随着硬件的越来越高端化,各种以前可望而不可及的效果越来越多的应用到网络游戏里.本篇文章是介绍目前游戏中影子的实现方式,它们的 ...
- UnityShader17.1:ESM 阴影技术
一.奏鸣曲:基于 ShadowMapping 的软阴影技术 前面已经写过在 Unity 和 OpenGL 上实现最简单阴影的文章了: OpenGL基础52:阴影映射(上) OpenGL基础52:阴影映 ...
- 计算机科学与技术前沿讲座心得体会,技术学习心得体会范文(精选10篇)
技术学习心得体会范文(精选10篇) 有了一些收获以后,可以通过写心得体会的方式将其记录下来,这么做可以让我们不断思考不断进步.到底应如何写心得体会呢?以下是小编整理的技术学习心得体会范文(精选10篇) ...
- 游戏中的角色渲染技术之皮肤篇
原文链接https://blog.uwa4d.com/archives/Usparkle_Skin.html 这是侑虎科技第253篇原创文章,感谢作者洛城供稿,欢迎转发分享,未经作者授权请勿转载.当然 ...
- [Unity3D]Unity3D游戏开发之Unity3D中的动态阴影
大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei. 博主今天想和大家分享的是Unity3D中的动态阴影,昨天博主重温了一下自己喜欢的游戏< ...
- Unity3D引擎之高级渲染技术
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人,已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社 和<Unity3 ...
- 消息中间件的技术选型心得-RabbitMQ ActiveMQ和ZeroMQ
消息中间件的技术选型心得-RabbitMQ.ActiveMQ和ZeroMQ 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs RabbitMQ.Active ...
最新文章
- linux线程同步之互斥锁——linux的关键区域
- Java中static的作用
- 【Spring注解系列05】@Import注入原理
- 201711月04日普及组 Array
- sql注入问题-视图-事物-以及存储过程(可视化工具)
- LeetCode——双指针
- 简练软考知识点整理-控制范围
- 70. 爬楼梯 golang 斐波那契数列
- centos7部署nodejs新版
- 重读经典:《Momentum Contrast for Unsupervised Visual Representation Learning》
- html解析のBeautifulSoup
- 几款查看dll和exe信息的小工具
- 记录用vs2017安装windows driver失败的坑爹过程
- word论文各类对齐终极解决方法——制表符
- Android R 设置壁纸流程和 Launcher 闪烁问题
- 非平凡的函数依赖、平凡函数依赖
- 计算机应用基础数制试题及答案,计算机应用基础试题及答案1.doc
- Phi-divergence
- 关于新光源中我想做的事
- 1一9数字行书写法_数字1-9的标准写法-1~9的书写格式