Unity的ios untiy 实时阴影影效率低吗

unity native2d 如何实现这种实时阴影的效果呢_unity吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:23,826贴子:
unity native2d 如何实现这种实时阴影的效果呢收藏
承办方:丽江市体育局 丽江斐瑞康网络科技有限公司
Unity5.0不用场景烘焙,支持时时阴影
如果你想阴影效果时时,你可以在物体上添加一个阴影预设,这样阴影可以时时跟随物体
登录百度帐号推荐应用购买商品:
商品价格:
价格读取中
支付方式:
请扫码进行支付
请扫码进行支付
由百度云提供技术支持
&学院APP&&
扫描微信二维码精彩活动、课程更新抢先知
下载客户端,离线视频任您学
1.&实时阴影实现方式
2.&编码实现
3.&角色透明材质解决方案
4.&角色阴影重叠解决方案
【课程类型】实战教学
【难度级别】高级
【适合人群】初级研发工程师
【课程介绍】 主要是针对移动端的手游开发对于角色的实时阴影绘制,以及解决透明材质的角色阴影绘制和阴影重叠问题。
【课程目标】 掌握实时阴影在移动端的绘制以及解决角色透明材质的阴影问题。
【课程计划】 共分为四个课时,从讲解到编码实现。
全部评价(0)
18课程287682学员5123人阅读
Unity 不显示阴影的原因:
模型尺寸太大了,镜头比较远
把模型缩小,镜头一定要拉到最近才能看到
这是我遇到的问题和解决方法,
另外一定要设置 Directional light 的 shadow type
设置 shadow type 属性为 soft shadow 或者 hard shadow
还有个无语的情况,新手们一定要注意:
如果看到编辑区一片黑啥都看不到,甚至新建场景都没用的话,那可能是 layers 显示设置的问题,
注意看看右上角有个 layers 下拉选项,选中 everything 则全都显示出来了,好大个坑~~~
折腾了一下午,另外阴影的其他可能的情况,可以参考下面的网址:
上个图吧:
一开始我的模型尺寸是比较大的,怎么都看不到阴影 好崩溃。。。
下面是缩小尺寸大概 100倍 后的效果,直接就可以看到所有模型的阴影啦。。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:613097次
积分:7609
积分:7609
排名:第2973名
原创:186篇
评论:114条
阅读:27508
(1)(2)(4)(1)(1)(4)(1)(1)(1)(2)(3)(3)(3)(2)(2)(2)(1)(3)(1)(1)(1)(5)(2)(1)(1)(1)(4)(5)(1)(4)(2)(2)(24)(96)(4)后使用快捷导航没有帐号?
只需一步,快速开始
&加载中...
查看: 5834|回复: 41
Unity实时高效阴影(实在没卷了,来赚一点点就好)
TA的其他好贴
马上注册,加入CGJOY,让你轻松玩转CGJOY。
才可以下载或查看,没有帐号?
无意间看到一篇文章,说是Unity5 demo中为了实现角色的良好阴影,单独给角色设计了一个角色阴影系统。而且使用的是比较老的技术,但效果很好。其实在很多时候,我们需要的并不是万能的阴影光照系统,而是局部能做到效果就行。
& && &&&万能的好处在于任何情况都能看上去合理,但是相对的,性能开销也大,同时为了兼顾各种情况,只能做各种效果的折中,所以我们看到了现在移动平台上,要么就是没有实时阴影,要么就是充满锯齿的实时阴影,要么就是使用2D贴图来模拟实时阴影。
& && &&&用2D贴图来模拟的效果毫无疑问是最好的,但问题在于成本太高,很多小团队资金有限,很难专门为每一个角色都让美术画一大堆阴影贴图。而这也毫无疑问会增加游戏的大小。
& && &&&我主要思考的是,在某种条件下,是否可以实现局部的良好的阴影。比如角色展台,毫无疑问只会出现一个角色,那么这个情况下,毫无疑问我们需要的是一个完美的阴影。或者说某一些游戏,视角固定,而且能看到的范围很小,那么是否只针对这个部分去实现好的阴影系统。或者一个很小的室内,我们也需要一个好的角色阴影。
& && &&&ok,那么开始思考方案,首先我们应该只需要一个平行光的阴影。一般来说需要获得这个位置看过去的深度图。我首先在这个位置上放了一个正交摄像机,注意如果你想让角色有阴影,那么必须让角色处在这个正交摄像机的范围内,那么现在第一个问题来了,如何保证角色在正交摄像机的范围内?
& && &&&方法如下:首先你要获得你主摄像机内的所有的需要阴影的物体,然后将这些物体转化到正交摄像机的坐标中,计算出这些物体的最大范围,并得出正交矩阵赋值给正交摄像机。(代码借鉴了,对这个楼主深表感谢)
& && &&&这里要注意,Unity计算出来的Z是负值,但OpenGL是正的,官方说明如下:
Matrix that transforms from world to camera space.
Use this to calculate the camera space position of objects or to provide customcamera's location that is not based on the transform.
Note that camera space matches OpenGL convention: camera's forward is the negativeZ axis. This is different from Unity's convention, where forward is the positive Zaxis.
If you change this matrix, the camera no longer updates its rendering based on its Transform.This lasts until you call ResetWorldToCameraMatrix.
#pragma strict
// Offsets camera's rendering from the transform's position.
public var offset: Vector3 = new Vector3(0, 1, 0);
var camera: C
function Start() {
& & camera = GetComponent.&Camera&();
function LateUpdate() {
& & var camoffset: Vector3 = new Vector3(-offset.x, -offset.y, offset.z);
& & var m: Matrix4x4 = Matrix4x4.TRS(camoffset, Quaternion.identity, new Vector3(1, 1, -1));
& & camera.worldToCameraMatrix = m * transform.worldToLocalM
不过实际使用过程中,我们也许并不需要正确的矩阵赋值,因为你需要的是保证所有的物体在摄像机范围内,只需要知道AABB盒,然后把相机设置在AABB盒的中心,同时增加Size即可。
public List&Transform& CharactorL
& & void CreateCameraProjecterMatrix()
& && &&&Vector3 v3MaxPosition = -Vector3.one * f;
& && &&&Vector3 v3MinPosition = Vector3.one * f;& &
& && &&&for (int vertId = 0; vertId & CharactorList.C ++vertId)
& && && && &// Light view space
& && && && &Vector3 v3Position = camera1.worldToCameraMatrix.MultiplyPoint3x4(CharactorList[vertId].position);
& && && && &if (v3Position.x & v3MaxPosition.x)
& && && && &{
& && && && && & v3MaxPosition.x = v3Position.x;
& && && && &}
& && && && &if (v3Position.y & v3MaxPosition.y)
& && && && &{
& && && && && & v3MaxPosition.y = v3Position.y;
& && && && &}
& && && && &if (v3Position.z & v3MaxPosition.z)
& && && && &{
& && && && && & v3MaxPosition.z = v3Position.z;
& && && && &}
& && && && &if (v3Position.x & v3MinPosition.x)
& && && && &{
& && && && && & v3MinPosition.x = v3Position.x;
& && && && &}
& && && && &if (v3Position.y & v3MinPosition.y)
& && && && &{
& && && && && & v3MinPosition.y = v3Position.y;
& && && && &}
& && && && &if (v3Position.z & v3MinPosition.z)
& && && && &{
& && && && && & v3MinPosition.z = v3Position.z;
& && && && &}
& && &&&Vector3 off = v3MaxPosition - v3MinP
& && &&&Vector3 sizeOff =
& && &&&sizeOff.z = 0;
& && &&&float dis = sizeOff.
& && &&&//CreateOrthogonalProjectMatrix (ref m_projMatrix, v3MaxPosition, v3MinPosition);
& && &&&//Debug.Log (v3MaxPosition.ToString() + v3MinPosition.ToString());
& && &&&//Matrix4x4 m = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1, 1, -1));
& && &&&//camera1.projectionMatrix = m * m_projM
& && &&&camera1.orthographicSize = dis / 1.8f;
& && &&&camera1.farClipPlane = off.z + 50;
& & void CreateViewMatrix(ref Matrix4x4 viewMatrix,Vector3 look,Vector3 up,Vector3 right,Vector3 pos)
& && &&&look.Normalize ();
& && &&&up.Normalize ();
& && &&&right.Normalize ();
& && &&&float x = -Vector3.Dot (right,pos);
& && &&&float y = -Vector3.Dot (up,pos);
& && &&&float z = -Vector3.Dot (look,pos);
& && &&&viewMatrix.m00 = right.x; viewMatrix.m10 = up.x; viewMatrix.m20 = look.x; viewMatrix.m30 = 0.0f;
& && &&&viewMatrix.m01 = right.y; viewMatrix.m11 = up.y; viewMatrix.m21 = look.y; viewMatrix.m31 = 0.0f;
& && &&&viewMatrix.m02 = right.z; viewMatrix.m12 = up.z; viewMatrix.m22 = look.z; viewMatrix.m32 = 0.0f;
& && &&&viewMatrix.m03 =& && & viewMatrix.m13 =& & viewMatrix.m23 =& && &viewMatrix.m33 = 1.0f;
& & void CreateOrthogonalProjectMatrix(ref Matrix4x4 projectMatrix,Vector3 v3MaxInViewSpace, Vector3 v3MinInViewSpace)
& && &&&float scaleX, scaleY, scaleZ;
& && &&&float offsetX, offsetY, offsetZ;
& && &&&scaleX = 2.0f / (v3MaxInViewSpace.x - v3MinInViewSpace.x);
& && &&&scaleY = 2.0f / (v3MaxInViewSpace.y - v3MinInViewSpace.y);
& && &&&offsetX = -0.5f * (v3MaxInViewSpace.x + v3MinInViewSpace.x) * scaleX;
& && &&&offsetY = -0.5f * (v3MaxInViewSpace.y + v3MinInViewSpace.y) * scaleY;
& && &&&scaleZ = 1.0f / (v3MaxInViewSpace.z - v3MinInViewSpace.z);
& && &&&offsetZ = -v3MinInViewSpace.z * scaleZ;
& && &&&//列矩阵
& && &&&projectMatrix.m00 = scaleX; projectMatrix.m01 = 0.0f; projectMatrix.m02 = 0.0f; projectMatrix.m03 = offsetX;
& && &&&projectMatrix.m10 = 0.0f; projectMatrix.m11 = scaleY; projectMatrix.m12 = 0.0f; projectMatrix.m13 = offsetY;
& && &&&projectMatrix.m20 = 0.0f; projectMatrix.m21 = 0.0f; projectMatrix.m22 = scaleZ; projectMatrix.m23 = offsetZ;
& && &&&projectMatrix.m30 = 0.0f; projectMatrix.m31 = 0.0f; projectMatrix.m32 = 0.0f; projectMatrix.m33 = 1.0f;
1.png (64.5 KB, 下载次数: 24)
16:42 上传
你看 所有角色都被包括在内了。当然具体适合的值你可以自己调整,这样我们就解决了第一个问题。 如果你的应用场景在室内,你可以无视第一个问题,直接手动设置一个
最合适的值就行了。
第二部,就是我们需要获得物体的剪影。就是说将物体的外轮廓给检录下来。当然复杂点就是获得物体的深度图。剪影获得很简单,我们看下深度图如何获得。因为在移动平台上不支持自动生成深度图,所以我打算自己使用片段着色器获得。
Shader &depthShader& {
& & Properties {
& & SubShader {
& &&&//Tags {&Queue&=&Transparent& &IgnoreProjector&=&True& &RenderType&=&Transparent&}
& && &&&Pass {
& && && && &CGPROGRAM
// Upgrade NOTE: excluded shader from DX11 and Xbox360; has structs without semantics (struct v2f members pos1)
#pragma exclude_renderers d3d11 xbox360
& && && && && & #pragma vertex vert
& && && && && & #pragma fragment frag
& && && && && & #include &UnityCG.cginc&
& && && && && &
& && && && && & sampler2D_float _CameraDepthT
& && && && && & struct appdata {
& && && && && && &&&float4 vertex : POSITION;
& && && && && && &&&
& && && && && & };
& && && && && & struct v2f {
& && && && && && &&&half4 pos : SV_POSITION;
& && && && && && &&&float2
& && && && && & };
& && && && && & v2f vert (appdata_base v) {
& && && && && && &&&v2
& && && && && && &&&o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
& && && && && && &&&o.depth = o.pos.
& && && && && && &&&
& && && && && & }
& && && && && &
& && && && && & fixed4 frag(v2f i) : COLOR
& && && && && & {
& && && && && && &&&float d = i.depth.x/i.depth.y;
& && && && && && &&&float flag = 0;
& && && && && && &&&if(d & 0)
& && && && && && &&&{
& && && && && && && && &d = abs(d);
& && && && && && && && &flag = 1;
& && && && && && &&&}
& && && && && && &&&float3 kEncodeMul = float3(1.0, 255.0, 65025.0);
& && && && && && &&&float kEncodeBit = 1.0/255.0;
& && && && && && &&&float3 enc = kEncodeMul *
& && && && && && &&&enc = frac (enc);
& && && && && && &&&enc -= enc.yzz * kEncodeB
& && && && && && &&&
& && && && && && &&&return fixed4(flag, enc);
& && && && && & }
& && && && &ENDCG
本来只要存储z就好了,不过很遗憾的是,有些平台的z竟然是负值,负值存储成像素是无意义的。所以我用r存储正负值,gba保存数值,但这样子性能确实会下降,毕竟在片段着色器里,考虑到后面需要照顾阴影质量,我觉得不使用深度图,而使用剪影。
剪影就简单了,连着色器都不用自己写,直接用摄像机渲染的黑图即可。这里我将摄像机设置成普通渲染模式,手动调用render,将贴图放到rendertexture中。
& && &&&camera1 = GameObject.Find (&Camera&).
& && &&&//camera1.hideFlags = HideFlags.HideAndDontS
& && &&&camera1.enabled =
& && &&&//camera1.projectionMatrix = camera.projectionM
& && &&&int textureSize = 1024;
& && &&&shadowTexture = new RenderTexture(textureSize , textureSize, 16, RenderTextureFormat.ARGB32);
& && &&&shadowTexture.name = &shadowTexture& + GetInstanceID();
& && &&&shadowTexture.isPowerOfTwo =
& && &&&shadowTexture.hideFlags = HideFlags.DontS
& && &&&camera1.targetTexture = shadowT
这样就可以看到如下贴图:
2.png (39.33 KB, 下载次数: 24)
16:42 上传
1024大小,内存6M 还算可以接受。当然,因为深度没有用,可以取消,这样会变成4M,其他格式可能会更小,但手机上不一定支持,所以暂时先这样吧。
第三个问题,就是怎么把这些东西投射到地上变成影子。
首先投射到地上已经有现成的Projector组件了,所以问题变成了坐标计算。
我们先把Projector的位置确定一下,Projector应该和主摄像机放在同一个地方,同时有同样的参数设置:
& && &&&proj = GameObject.Find (&GameObject&).GetComponent&Projector& ();
& && &&&proj.nearClipPlane = camera.nearClipP
& && &&&proj.farClipPlane = camera.farClipP
& && &&&proj.fieldOfView = camera.fieldOfV
这样就保证了视角内的物体都会出现阴影。然后就是坐标计算了,我们想一下,假设世界坐标中的点a,那么我们计算出它在正交摄像机中的坐标,然后根据坐标取出投影贴图中的点,那么假如这个点是全黑的(看你设置的是啥值了),那么就是不在阴影区的,假如不是,那么说明是阴影。
有了这个方案,我们就开始计算吧。首先我们可以轻易获得物体的坐标,问题在于怎么获得它在正交摄像机中的坐标,这个就需要使用正交摄像机的矩阵获得:
matVP = GL.GetGPUProjectionMatrix (camera1.projectionMatrix, true) * camera1.worldToCameraM
proj.material.SetMatrix(&ShadowMatrix&, matVP);
注意,我将这个计算出来的矩阵赋值给了一个材质,这个材质就是Projector使用的,因为是它需要根据坐标判断是否有阴影。
这样似乎接下来就可以直接写出着色器了:
& && && && &v2f vert (appdata_base v)
& && && && &{
& && && && && & v2
& && && && && & o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
& && && && && & float4x4 matWVP = mul (ShadowMatrix, _Object2World);
& && && && && & o.uvShadow = mul(matWVP, v.vertex);& && &&&
& && && && && &
& && && && &}
注意,顶点着色器不仅要计算出pos,同时还要获得正交相机中的坐标,也就是uvShadow.
然后就可以在片段着色器中处理了:
half2 uv = i.uvShadow.xy / i.uvShadow.w * 0.5 + 0.5;
& && && && && & #if UNITY_UV_STARTS_AT_TOP
& && && && && && &&&uv.y = 1 - uv.y;
& && && && && & #endif
& && && && && &&&fixed4 res = fixed4(0, 0, 0, 0);
& && && && && &&&fixed4 texS = tex2D(_ShadowTex, uv);
& && && && && &&&if(texS.a & 0)
& && && && && &&&{
& && && && && && && &res.a = 0.5;
& && && && && &&&}
就这么几行,阴影就出现了:
3.png (83.22 KB, 下载次数: 24)
16:42 上传
但效果似乎不那么尽如人意,让我们看下u3d自带的高品质的阴影效果:
4.png (83.41 KB, 下载次数: 23)
16:42 上传
其实已经很接近了呢,不过鉴于我开头宣称要高质量阴影,所以我打算继续优化边缘,因为你可以看到边缘部分的锯齿,当然我们可以单纯增加贴图大小,但是假如到2048,那么就要占据16M的内存了,所以我暂时打算用另外一种做法,pcf。就是通过采样,将边缘像素模糊化。
& && && && && & texS = tex2D(_ShadowTex, uv + half2(-0./pad, -0./pad));
& && && && && &&&if(texS.a & 0)
& && && && && &&&{
& && && && && && && &res.a += _S
& && && && && &&&}
& && && && && &&&
& && && && && &&&texS = tex2D(_ShadowTex, uv + half2(0./pad, -0./pad));
& && && && && &&&if(texS.a & 0)
& && && && && &&&{
& && && && && && && &res.a += _S
& && && && && &&&}
& && && && && &&&
& && && && && &&&texS = tex2D(_ShadowTex, uv + half2(-0./pad, -0./pad));
& && && && && &&&if(texS.a & 0)
& && && && && &&&{
& && && && && && && &res.a += _S
& && && && && &&&}
& && && && && &&&texS = tex2D(_ShadowTex, uv + half2(0./pad, 0./pad));
& && && && && &&&if(texS.a & 0)
& && && && && &&&{
& && && && && && && &res.a += _S
& && && && && &&&}
经过采样后效果如下:
5.png (89.53 KB, 下载次数: 24)
16:42 上传
最后 是时候做一次全面比较了,在电脑上我自己写的完爆自带的,因为我的电脑的显卡很渣,但手机显卡好一些,所以手机上的结果可能不太一样,放到手机上,开启最强模式,看看到底性能和效果对比吧。找了一台两年前的1000块钱的华为:
u3d 高质量阴影:
近距离效果:
6.jpg (506.71 KB, 下载次数: 30)
16:42 上传
再看我自己实现的效果:
2048最强模式下:
7.jpg (511.72 KB, 下载次数: 25)
16:42 上传
不过帧数下降了不少,再看看1024的吧。
8.jpg (514.65 KB, 下载次数: 24)
16:42 上传
效果也是要好上不少吧。
ok,暂时先这样吧
最后是源文件:
游客,本付费内容需要支付 2张CG券 才能下载
希望觉得有用的回复一下 顶一顶哈
如何让别人关注你?
感谢分享! 不觉明历!
本楼回复(<span id="dp_count_)
如何让别人关注你?
非常的棒,感谢楼主分享的说
本楼回复(<span id="dp_count_)
如何让别人关注你?
好好好好好好好好好
本楼回复(<span id="dp_count_)
如何让别人关注你?
本楼回复(<span id="dp_count_)
如何让别人关注你?
10万个赞!!!!
本楼回复(<span id="dp_count_)
如何让别人关注你?
mark,感谢楼主分享,正在找这个东西
本楼回复(<span id="dp_count_)
如何让别人关注你?
资源甚好,且阅且珍惜!
本楼回复(<span id="dp_count_)
如何让别人关注你?
本楼回复(<span id="dp_count_)
如何让别人关注你?
太感谢了!
本楼回复(<span id="dp_count_)
如何让别人关注你?
Powered by

我要回帖

更多关于 c4d阴影实时显示 的文章

 

随机推荐