Unity Shader学习笔记五使用鼠标绘制自由多边形附完整工程源码.docx

上传人:b****2 文档编号:1837588 上传时间:2022-10-24 格式:DOCX 页数:3 大小:17.46KB
下载 相关 举报
Unity Shader学习笔记五使用鼠标绘制自由多边形附完整工程源码.docx_第1页
第1页 / 共3页
Unity Shader学习笔记五使用鼠标绘制自由多边形附完整工程源码.docx_第2页
第2页 / 共3页
Unity Shader学习笔记五使用鼠标绘制自由多边形附完整工程源码.docx_第3页
第3页 / 共3页
亲,该文档总共3页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Unity Shader学习笔记五使用鼠标绘制自由多边形附完整工程源码.docx

《Unity Shader学习笔记五使用鼠标绘制自由多边形附完整工程源码.docx》由会员分享,可在线阅读,更多相关《Unity Shader学习笔记五使用鼠标绘制自由多边形附完整工程源码.docx(3页珍藏版)》请在冰豆网上搜索。

Unity Shader学习笔记五使用鼠标绘制自由多边形附完整工程源码.docx

UnityShader学习笔记五使用鼠标绘制自由多边形附完整工程源码

【UnityShader学习笔记】(五)使用鼠标绘制自由多边形(附完整工程源码)

前言

在前面的文章中,我们已经了解了怎样使用UnityShader来绘制简单的点和线,本文将延续上次的话题,讲述一下如何在场景中使用UnityShader绘制自由多边形。

本文所述的程序,支持在地图中用鼠标点击,确定多边形顶点,并且绘制多边形的边,在内部填充半透明的颜色。

先展示一下最终效果。

完整工程下载地址在本文末尾处。

1开发工具介绍

Windows10(64位)

Unity5.4.1(64位)

2建立工程

首先建立一个新工程,命名为Polygon,并创建一个Scene。

在场景中新建一个Plane,该Plane是默认带有碰撞体的,这个碰撞体必须有,因为我们在后边使用鼠标选取位置的时候,涉及到碰撞检测。

给该Plane加上贴图。

3核心代码实现

3.1Polygon.cs脚本中实现的是鼠标点击和向shader传递信息的功能

(1)为了实现鼠标点选场景中的3D位置,需要使用射线

[csharp]viewplaincopyRayray=Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHithit;if(Physics.Raycast(ray,outhit,100)){Debug.DrawLine(ray.origin,hit.point);}

(2)向shader传递顶点的位置和数量

[csharp]viewplaincopymat.SetVectorArray("Value",screenPos);//传递顶点屏幕位置信息给shadermat.SetInt("PointNum",pointNum2Shader);//传递顶点数量给shader

(3)将鼠标点击的位置转化为屏幕坐标

[csharp]viewplaincopyworldPos[currentpointNum-1]=hit.point;Vector3v3=Camera.main.WorldToScreenPoint(worldPos[currentpointNum-1]);screenPos[currentpointNum-1]=newVector4(v3.x,Screen.height-v3.y,v3.z,0);

3.2Polygon.shader中实现多边形的绘制功能

(1)计算两点之间的距离函数

[csharp]viewplaincopyfloatDis(float4v1,float4v2){returnsqrt(pow((v1.x-v2.x),2)+pow((v1.y-v2.y),2));}

(2)绘制线段的函数

[csharp]viewplaincopyboolDrawLineSegment(float4p1,float4p2,floatlineWidth,v2fi){float4center=float4((p1.x+p2.x)/2,(p1.y+p2.y)/2,0,0);//计算点到直线的距离floatd=abs((p2.y-p1.y)*i.vertex.x+(p1.x-p2.x)*i.vertex.y+p2.x*p1.y-p2.y*p1.x)/sqrt(pow(p2.y-p1.y,2)+pow(p1.x-p2.x,2));//小于或者等于线宽的一半时,属于直线范围floatlineLength=sqrt(pow(p1.x-p2.x,2)+pow(p1.y-p2.y,2));if(d<=lineWidth/2&&Dis(i.vertex,center)<lineLength/2){returntrue;}returnfalse;}

(3)绘制多边形的函数

参考:

https:

//www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html

[csharp]viewplaincopyboolpnpoly(intnvert,float4vert[6],floattestx,floattesty){inti,j;boolc=false;floatvertx[6];floatverty[6];for(intn=0;n<nvert;n++){vertx[n]=vert[n].x;verty[n]=vert[n].y;}for(i=0,j=nvert-1;i<nvert;j=i++){if(((verty[i]>testy)!

=(verty[j]>testy))&&(testx<(vertx[j]-vertx[i])*(testy-verty[i])/(verty[j]-verty[i])+vertx[i]))c=!

c;}returnc;}

4完整的C#脚本和Shader代码

Ploygon.cs

[csharp]viewplaincopyusingUnityEngine;usingSystem.Collections;[ExecuteInEditMode]publicclassPolygon:

MonoBehaviour{publicMaterialmat;//绑定材质Vector3[]worldPos;//存储获取的3D坐标Vector4[]screenPos;//存储待绘制的多边形顶点屏幕坐标intmaxPointNum=6;//多边形顶点总数intcurrentpointNum=0;//当前已经获得的顶点数intpointNum2Shader=0;//传递顶点数量给shaderboolInSelection=true;//是否处于顶点获取过程voidStart(){worldPos=newVector3[maxPointNum];screenPos=newVector4[maxPointNum];}voidUpdate(){mat.SetVectorArray("Value",screenPos);//传递顶点屏幕位置信息给shadermat.SetInt("PointNum",pointNum2Shader);//传递顶点数量给shader//使用摄像机发射一条射线,以获取要选择的3D位置Rayray=Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHithit;if(Physics.Raycast(ray,outhit,100)){Debug.DrawLine(ray.origin,hit.point);}//利用鼠标点击来获取位置信息if(Input.GetMouseButtonDown(0)&&InSelection){if(currentpointNum<maxPointNum){currentpointNum++;pointNum2Shader++;worldPos[currentpointNum-1]=hit.point;Vector3v3=Camera.main.WorldToScreenPoint(worldPos[currentpointNum-1]);screenPos[currentpointNum-1]=newVector4(v3.x,Screen.height-v3.y,v3.z,0);}else{InSelection=false;}}//实时更新已选择的3D点的屏幕位置for(inti=0;i<maxPointNum;i++){Vector3v3=Camera.main.WorldToScreenPoint(worldPos[i]);screenPos[i]=newVector4(v3.x,Screen.height-v3.y,v3.z,0);}//检测是否有3D点移动到了摄像机后面,如果有,则停止绘制for(inti=0;i<currentpointNum;i++){if(Vector3.Dot(worldPos[i]-Camera.main.transform.position,Camera.main.transform.forward)<=0){pointNum2Shader=0;break;}pointNum2Shader=currentpointNum;}}//抓取当前的渲染图像进行处理voidOnRenderImage(RenderTexturesrc,RenderTexturedest){Graphics.Blit(src,dest,mat);}}Polygon.shader

[csharp]viewplaincopyShader"Unlit/polygon"{Properties{//定义基本属性,可以从编辑器里面进行设置的变量//_MainTex("Texture",2D)="white"{}}CGINCLUDE//从应用程序传入顶点函数的数据结构定义structappdata{float4vertex:

POSITION;float2uv:

TEXCOORD0;};//从顶点函数传入片段函数的数据结构定义structv2f{float2uv:

TEXCOORD0;float4vertex:

SV_POSITION;};//定义贴图变量sampler2D_MainTex;//float4_MainTex_ST;//定义与脚本进行通信的变量vectorValue[6];intPointNum=0;//计算两点间的距离的函数floatDis(float4v1,float4v2){returnsqrt(pow((v1.x-v2.x),2)+pow((v1.y-v2.y),2));}//绘制线段boolDrawLineSegment(float4p1,float4p2,floatlineWidth,v2fi){float4center=float4((p1.x+p2.x)/2,(p1.y+p2.y)/2,0,0);//计算点到直线的距离floatd=abs((p2.y-p1.y)*i.vertex.x+(p1.x-p2.x)*i.vertex.y+p2.x*p1.y-p2.y*p1.x)/sqrt(pow(p2.y-p1.y,2)+pow(p1.x-p2.x,2));//小于或者等于线宽的一半时,属于直线范围floatlineLength=sqrt(pow(p1.x-p2.x,2)+pow(p1.y-p2.y,2));if(d<=lineWidth/2&&Dis(i.vertex,center)<lineLength/2){returntrue;}returnfalse;}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 人力资源管理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1