unity3d rendertextureformat阴影 怎么控制方向

喜欢自由的飞翔!
Unity3D实战之移动端实时阴影技术
移动端实时阴影绘制考虑到硬件的限制,使用的实时阴影主要是对主要角色绘制的,场景的阴影渲染采用LightMap技术将其烘焙到地面上就可以了。换句话说本节实现的实时阴影主要是针对角色的,不是对场景建筑。移动端实时阴影绘制的实现方式,首先需要一个3D摄像机,将这个摄像机设置成正交摄像机,并将其放置到角色的头顶上,它主要的作用是在每一帧渲染需要加阴影的物体,渲染物体时需要一个接收面,用于接收实时阴影,为了优化效率,阴影的接收面加一个Quad四边形。如下图所示:
设置的接受层是一个Quad四边形面片,所以再设计场景时,就不要设置比较陡的斜坡,这样不利于阴影的展示,这个也是它的一个缺点,当然坡度小时没有任何问题,这个已在项目中进行过验证,下面谈谈它的技术实现。
实时阴影的前期工作已完成,接下来是实现代码的编写工作,实现的原理就是把角色头顶的Camera捕捉到的每一帧渲染到设置的面片上,首先需要把一个物体摆放到场景中,然后在角色的下面新建一个面片,同时在物体的上方设置一个相机Camera,如下图所示:
在这里面有几个地方需要注意一下:一个是需要自己建一个RenderTexture,然后将其赋值给Camera里面的参数RenderTexture项。另一个是Quad面需要挂接一个Shader,选择的是Transparent/Diffuse Shader可以渲染有Alpha通道的材质,这就要求Quad四边形的材质必须是有Alpha通道,这样角色才可以渲染到Quad四边形上,从而把阴影渲染绘制出来,当然需要调整摄像机的角度,还有其ViewPort视口的值,下面把操作步骤给大家一一讲解。
首先在模型的子节点处新建一个GameObject,将对象的名字改成Shadow,然后在其下面再建两个子节点,一个是Camera,另一个是Quad四边形,效果如下图:
下面编写一个脚本用于RenderTexture的渲染,完整的代码如下所示:using UnityE
using System.C
public class ShadowScript : MonoBehaviour {
private GameO
private RenderTexture mTex = null;
void Start()
plane = transform.FindChild("Plane").gameO
Camera ShadowCamera = transform.FindChild("Camera").GetComponent&Camera&();
obj = transform.
mTex = new RenderTexture(256, 256, 0);
mTex.name = Random.Range(0, 100).ToString();
ShadowCamera.targetTexture = mT
void Update()
plane.renderer.material.mainTexture = mT
}设置的RenderTexture效果的代码如下:
mTex = new RenderTexture(256, 256, 0)
mTex.name = Random.Range(0, 100).ToString()
ShadowCamera.targetTexture = mTex接下来介绍一下脚本的设计思路,在Start函数中new一个RenderTexture用于存放实时绘制的阴影,同时会将其赋值给ShadowCamera.targetTexture,在Update函数中每帧实时绘制,这个脚本是挂接在上面的Shadow对象上的,效果如下图:
同时设置一下对象的Layer,用于确定渲染的角色,这里设置了是aaa。然后调整Camera的大小和角度,效果图如下图:
通过上图的参数设置大家可以一目了然,非常清晰。接下来最后一步设置Quad四边形将它的摆放位置放置在角色的正中,这个四边形面片是要随着角色移动的,所以要将它挂到骨骼上。效果如下图:
整个实时阴影的前期工作就完成了,接下来运行程序看看效果,我们这里摆放了两个角色,运行效果如下图: 最后,要注意一个问题,如果角色的材质含有Alpha通道该如何处理?因为如果还使用以前的Shader渲染,二者都有Apha通道在混合时就会出现问题。这个问题的解决方案在笔者已出版的《Unity3D实战核心技术详解》电子工业出版社一书中,有详细讲解。
笔者简介:
扫码向博主提问
非学,无以致疑;非问,无以广识
擅长领域:
3D引擎架构
服务器架构
客户端架构
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!Unity3D实时阴影-Projector投影器
要在Android端做一个类似投影寻真的Demo,做一个用手电筒动态投影,但是使用Unity3D的Spotlight,各种调试参数,将PlayerSetting的Rendering
path设为Deferred Lighting,并将Camera的Rendering path设为Deferred
Lighting,在pc端能实现Spotlint的投影效果,但是移植到移动端就白瞎了,折腾了好久,使用投影器Projector实现了自己想要的效果,不废话,走起。
1、导入Projector包;
2、给投影目标物体添加一个Camera,让Camera的视觉角度和物体在一条直线上,Camera的视觉方向就是物体的投影方向(因为最后要把Camera的RenderTarget投影到墙上),并将Camera渲染剔除,只让Camera捕获目标物体;
3、创建一个空的OBJ,即:Create
Empty,然后给他添加Projector组件,让其投影方向指向要生成投影的地方;
4、创建一个RenderTexture(MyCameraRender),赋给Camera的TargetT
5、创建一个Material(MyMaterial),把步骤4中的MyCameraRender赋给MyMaterial;
6、选中步骤3中的Projector,将步骤5中的MyMaterial赋给Projector的Material属性,最后将Projector的Shader改为Projector包中自带的Light或Multiply(Shader)即可。
如此,动态投影大功告成!
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。Unity3D手游开发-移动平台实时阴影方案 - 简书
Unity3D手游开发-移动平台实时阴影方案
阴影这个东西,说来就话长了,很多年前人们就开始研究出各种阴影技术,但都存在各种瑕疵和问题,直到近几年出现了PSSM,也就是CE3的CSM,阴影技术才算有个比较完美的解决方案.Unity自带的实时阴影,也是这种技术,在电脑上很成熟的.我也是目睹了阴影技术的发展,以前也自己写过一些阴影,本来以为以后再也不用担心阴影了,结果做移动游戏以后,发现情况没那么乐观.这种基于深度的shadow map 技术,需要浮点纹理的支持,但有的移动平台不支持浮点纹理,即使支持,这种技术开销也特别大.所以我们需要重新思考,移动平台到底什么样的阴影方案比较合适.我把常见的实时阴影技术分3个大的类别,逐一分析.1. 基于模板的体积阴影基于模型边缘的,模型需要特别处理,正是由于基于模型边缘的,属于顶点级别,而不是像素级别,导致不能支持alpha test,比如主角的翅膀.放弃2. 基于投影Projector的shadow map基于投影的,投影纹理,需要RenderTexture,支持alpha test,但是这种技术也有很多问题,比如反向投影(可加一张fall of 纹理解决), 多重投影(比如桥上和桥下),等等阴影质量和RenderTexture纹理大小关闭很大,如果要一张RenderTexture纹理渲染很多角色,纹理就要大一些,要处理阴影边缘,但是用来处理单个角色,就能避免很多问题.可考虑.3. 基于深度Depth的shadow mapUnity自带的就是这种,保存深度需要浮点纹理,但是有的手机不支持,且开销很大,不考虑.通过以上分析,再结合自己游戏的实际情况,45度视角游戏,我最后定的方案是:中等画质:1.只有主角采用基于投影Projector的shadow map2.其他角色,采用最简单的阴影面片绑在脚下.(如果怪物被击浮空,就隐藏面片,落地再显示,防止穿帮)这样的好处是,既有实时阴影,又保证了效率.高画质:1.视野内全部角色基于投影Projector的shadow map实现原理:很简单,先渲染角色到RenderTexture,再用Projector投影到地面.1.投射shader:Shader "Luoyinan/Projector/ShadowCast"{Properties{_ShadowColor ("Main Color", COLOR) = (0.5, 0.5, 0.5, 1)}SubShader{Pass{Color [_ShadowColor]}}}2.接收shader:Shader "Luoyinan/Projector/ShadowReceive"{Properties{_Color ("Main Color", Color) = (1,1,1,1)_ShadowTex ("Cookie", 2D) = "" {}_MaskTex ("Mask", 2D) = "" {}}Subshader{Tags {"Queue"="Transparent"}Pass{ZWrite OffFog { Mode Off }ColorMask RGBBlend DstColor ZeroOffset -1, -1CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct v2f{float4 uvShadow : TEXCOORD0;float4 pos : SV_POSITION;};float4x4 _Pv2f vert (float4 vertex : POSITION){v2o.pos = mul (UNITY_MATRIX_MVP, vertex);o.uvShadow = mul (_Projector, vertex);}sampler2D _ShadowTsampler2D _MaskTfixed4 frag (v2f i) : SV_Target{fixed4 texM = tex2Dproj(_MaskTex, UNITY_PROJ_COORD(i.uvShadow));fixed4 texS = tex2Dproj(_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));texS.rgb += texM.return texS;}ENDCG}}}优化:1. RenderTexture尽量简单,大小最好不要超过512,格式用没alpha通道的565,关闭抗锯齿,因为只渲染单一颜色,可关闭深度,2. 阴影投射的shader尽量简单,为了效率,我的shader没用主纹理,所以不支持alpha test.如要支持,可自行修改shader.3. 阴影摄像机看到的对象比游戏主摄像机看的多一些,只让主摄像机看到的对象才产生阴影.能少渲染几个角色.用OnBecameVisible来实现.4. 为了避免反向投影穿帮,阴影方向尽量不要太斜.5. 远处的阴影边缘衰减,用一张掩码纹理:
最终效果,可以看到远处的阴影自然衰减,也能投影到斜坡上,:
Don't reinvent the wheel.
这是侑虎科技第239篇原创文章,感谢作者冯委供稿,欢迎转发分享,未经作者授权请勿转载。当然,如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:) 作者知乎:https://zhuanlan.zhihu.com/c_。同时,作...
光源的着色器 我们在《渲染13:延迟渲染》中添加了对延迟渲染路径的支持。我们所要做的只是填补G缓冲区。光源在后面的过程中会在后面渲染。那个教程简要地介绍了Unity如何添加这些光源。 这一次,我们将自己渲染这些光源。 为了测试光源,我将使用一个简单的场景,其环境强度设置为零...
什么是Shader Shader(着色器)是一段能够针对3D对象进行操作、并被GPU所执行的程序。Shader并不是一个统一的标准,不同的图形接口的Shader并不相同。OpenGL的着色语言是GLSL, NVidia开发了Cg,而微软的Direct3D使用高级着色器语言(...
【浅墨Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法&颜色、光照与材质 Babybus-u3d技术交流-【浅墨Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法&颜色、光照与材质文章链接:[[h...
这是关于渲染基础的系列教程的第二部分。这个渲染基础的系列教程的第一部分是有关矩阵的内容。在这篇文章中我们将编写我们的第一个着色器代码并导入纹理。 这个系列教程是使用Unity 5.4.0开发的,这个版本目前还是开放测试版本。我使用的是build 5.4.0b10版本。 对球...
《出轨》 目录
出轨(6) 婚后生活他觉得生活就该这样,家里油瓶倒了,和他没任何关系。父母两人退休工资加起来,还有老妈的外面上课,要7000多,老婆不上班也关系不大,反正够用了。 看着同学一个个苦逼的加班加点,夫妻俩苦哈哈的上班,赚的钱还要还房贷,一个个紧衣缩食。阿海的优...
传统意义上的设计(How it looks)往往不会成为一个项目中决定成败的因素,而更多的是那些看不见的(How it works)。设计思维并不过分强调传统意义上的设计美学或技法,而是将它看作系统(待解决的问题或是一个项目)的其中一个因素,从而让人可以跳出他固有背景或角色...
检测行业是服务经济社会发展的国家质量基础,随着人们生活水平的提高以及国际贸易壁垒的加剧,人们对环境、食品、医疗、汽车等方面的要求也越来越高,这在一定程度上推动了检验检测市场飞速发展。目前,我国检验检测行业正超速发展。国内检测行业中已经涌现出了一批优秀的民营企业。与此同时,外...
至今还记得是个雨天的夜晚,在网络世界遨游时,无意间与“简书”相识。 一下子就被简书所吸引,仿佛为我打开了另一个世界之窗,在这里我认识了许多志同道合的文友,我们以文会友,关注赞赏,我也开始了在简书的写作。 在碎片化阅读盛行的今天,简书寻求出了另一种生存发展路径。简书有着碎片化...
心好乱。好像隋唐演义里面隋炀帝驾崩前夕,象征隋朝的杨花凋零枯落一样,一片片地慢慢枯萎凋谢在地,任风吹扫,整个大隋帝国顷刻垮塌,压得喘不过气来。杨花落尽,泪池盈满,流水东去,绵延不绝。&>&Rendertexture和Projector实现的实时阴影
Rendertexture和Projector实现的实时阴影
上传大小:9.08MB
unity中基于Projector和Rendertexture实现的实时阴影,包括shader和脚本
综合评分:5
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var parentWrap = $(this).parents(".respond_box"),
q = parentWrap.find(".form1").serializeArray(),
resStr = $.trim(parentWrap.find(".res_area_r").val());
console.log(q);
//var res_area_r = $.trim($(".res_area_r").val());
if (resStr == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
//var mess = $(".res_area_r").val();
var mess = resS
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, data.com_username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click", '.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
var parentWrap = $(v).parents(".respond_box");
parentWrap.find(".res_area_r").val($.trim(parentWrap.find(".res_area").val()));
评论共有4条
非常感谢分享!!!!
Rendertexture和projector结合实现阴影
谢谢分享,观摩一下。。。。。。
VIP会员动态
CSDN下载频道资源及相关规则调整公告V11.10
下载频道用户反馈专区
下载频道积分规则调整V1710.18
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
资源所需积分/C币
当前拥有积分
当前拥有C币
输入下载码
为了良好体验,不建议使用迅雷下载
Rendertexture和Projector实现的实时阴影
会员到期时间:
剩余下载个数:
剩余积分:0
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
为了良好体验,不建议使用迅雷下载
无法举报自己的资源
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可返还被扣除的积分
被举报人:
mobilebbki399
举报的资源分:
请选择类型
资源无法下载 ( 404页面、下载失败、资源本身问题)
资源无法使用 (文件损坏、内容缺失、题文不符)
侵犯版权资源 (侵犯公司或个人版权)
虚假资源 (恶意欺诈、刷分资源)
含色情、危害国家安全内容
含广告、木马病毒资源
*详细原因:
Rendertexture和Projector实现的实时阴影网络游戏开发者
Unity3d中渲染到RenderTexture的原理,几种方式以及一些问题
本文中大部分例子将按照Opengles的实现来解释1.RenderTexture是什么
在U3D中有一种特殊的Texture类型,叫做RenderTexture,它本质上一句话是将一个FrameBufferObjecrt连接到一个server-side的Texture对象。
什么是server-sider的texture?
在渲染过程中,贴图最开始是存在cpu这边的内存中的,这个贴图我们通常称为client-side的texture,它最终要被送到gpu的存储里,gpu才能使用它进行渲染,送到gpu里的那一份被称为server-side的texture。这个tex在cpu和gpu之间拷贝要考虑到一定的带宽瓶颈。
什么是FrameBufferObject?
FrameBuffer就是gpu里渲染结果的目的地,我们绘制的所有结果(包括color depth stencil等)都最终存在这个这里,有一个默认的FBO它直接连着我们的显示器窗口区域,就是把我们的绘制物体绘制到显示器的窗口区域。但是现代gpu通常可以创建很多其他的FBO,这些FBO不连接窗口区域,这种我们创建的FBO的存在目的就是允许我们将渲染结果保存在gpu的一块存储区域,待之后使用,这是一个非常有用的东西。
当渲染的结果被渲染到一个FBO上后,就有很多种方法得到这些结果,我们能想想的使用方式就是把这个结果作为一个Texture的形式得到,通常有这样几种方式得到这个贴图:
a) 将这个FBO上的结果传回CPU这边的贴图,在gles中的实现一般是ReadPixels()这样的函数,这个函数是将当前设为可读的FBO拷贝到cpu这边的一个存储buffer,没错如果当前设为可读的FBO是那个默认FBO,那这个函数就是在截屏,如果是你自己创建的FBO,那就把刚刚绘制到上面的结果从gpu存储拿回内存。
将这个FBO上的结果拷贝到一个gpu上的texture,在gles中的实现一般是CopyTexImage2D(),它一般是将可读的FBO的一部分拷贝到存在于gpu上的一个texture对象中,直接考到server-sider就意味着可以马上被gpu渲染使用
将这个fbo直接关联一个gpu上的texture对象,这样就等于在绘制时就直接绘制到这个texure上,这样也省去了拷贝时间,gles中一般是使用FramebufferTexture2D()这样的接口。
那么unity的RenderTexture正是这种c)方式的一种实现,它定义了在server-side的一个tex对象,然后将渲染直接绘制到这个tex上。
这有什么用?
我们可以将场景的一些渲染结果渲染到一个tex上,这个tex可以被继续使用。例如,汽车的后视镜,后视镜就可以贴一个rendertex,它是从这个视角的摄像机渲染而来。
我们还可以利用这个进行一些图像处理操作,传统的图像处理在cpu中一个for循环,一次处理一个像素,如果我们渲染一个四方形,然后把原图当成tex传入进去,写一个fragment shader,将渲染的结果渲染到一个rendertex上,那么rendertex上的东西就是图像处理的结果,unity中的一些图像后处理效果(如模糊,hdr等)就是这样做的。2.渲染到RenderTexture的几种方式 1.在assets里创建一个RenderTexture,然后将其附给一个摄像机,这样这个摄像机实时渲染的结果就都在这个tex上了。 2.有的时候我们想人为的控制每一次渲染,你可以将这个摄像机disable掉,然后手动的调用一次render。 3. 有的时候我们想用一个特殊的shader去渲染这个RenderTexture,那可以调用cam的RenderWithShader这个函数,它将使用你指定的shader去渲染场景,这时候场景物体上原有的shader都将被自动替换成这个shader,而参数会按名字传递。这有什么用?比如我想得到当前场景某个视角的黑白图,那你就可以写个渲染黑白图的shader,调用这个函数。(这里还有一个replacement shader的概念,不多说,看下unity文档) 4. 我们还可以不用自己在assets下创建rendertexture,直接使用Graphics.Blit(src, target, mat)这个函数来渲染到render texture上,这里的的target就是你要绘制的render texrture,src是这个mat中需要使用的_mainTex,可以是普通tex2d,也可以是另一个rendertex,这个函数的本质是,绘制一个四方块,然后用mat这个材质,用src做maintex,然后先clear为black,然后渲染到target上。这个是一个快速的用于图像处理的方式。我们可以看到UNITY的很多后处理的一效果就是一连串的Graphics.Blit操作来完成一重重对图像的处理,如果在cpu上做那几乎是会卡死的。
3.从rendertex获取结果 大部分情况我们渲染到rt就是为了将其作为tex继续给其他mat使用。这时候我们只需把那个mat上调用settexture传入这个rt就行,这完全是在gpu上的操作。但有的时候我们想把它拷贝回cpu这边的内存,比如你想保存成图像,你想看看这个图什么样,因为直接拿着rt你并不能得到它的每个pixel的信息,因为他没有内存这一侧的信息。Texture2d之所以有,是因为对于选择了read/write属性的tex2D,它会保留一个内存这边的镜像。这种考回就是1部分写的a)方式,把rt从gpu拷贝回内存,注意这个操作不是效率很高。copy回的方法通常是这样的
Texture2D uvtexRead = new Texture2D()
RennderTexture currentActiveRT = RenderTexture.active;
// Set the supplied RenderTexture as the active one
RenderTexture.active = uvTex;
uvtexRead.ReadPixels(new Rect(0, 0, uvTexReadWidth, uvTexReadWidth), 0, 0);
RenderTexture.active = currentActiveRT;上面这段代码就是等于先把当前的fbo设为可读的对象,然后调用相关操作将其读回内存。4.其他的一些问题1.rendertexture的格式,rt的格式和普通的tex2D的格式并不是一回事,我们查阅文档,看到rt的格式支持的有很多种,最基本的ARGB32是肯定支持的,很多机器支持ARRBHALF或者ARGBFLOAT这样的格式,这种浮点格式是很有用的,想象一下你想把场景的uv信息保存在一张图上,你要保存的就不是256的颜色,而是一个个浮点数。但是使用前一定要查询当前的gpu支持这种格式2.如果你想从RenderTexture拷贝回到内存,那么rt和拷贝回来的tex的格式必须匹配,且必须是rgba32或者RGBA24这种基本类型,你把float拷贝回来应该是不行的3.rendertexture的分配和销毁,如果你频繁的要new一个rt出来,那么不要直接new,而是使用RenderTexture提供的和,它将在内部维护一个池,反复重用一些大小格式一样的rt资源,因为让gpu为你分配一个新的tex其实是要耗时间的。更重要的这里还会调用4 ()这个rendertex的接口非常重要,好的习惯是你应该尽量在每次往一个已经有内容的rt上绘制之前总是调用它的这个函数,大致得到的优化是,在一些基于tile的gpu上,rt和一些tile的内存之间要存在着各种同步, 如果你准备往一个已经有内容的rt上绘制,将触发到这种同步,而这个函数告诉gpu这块rt的内容不用管他了,我反正是要重新绘制,这样就避免了这个同步而产生的巨大开销。总之还是尽量用GetTemporray这个接口吧,它会自动为你处理这个事情可以看到虽然RenderTexture这个技术是个普遍使用的技术,但是用好它还是要理解他的底层原理和避免一些使用的问题。欢迎大家就这个问题进行更多讨论
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!}

我要回帖

更多关于 unityrendertexture 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信