unity3d镜面反射代码Unity3dspecularreflectioncode.docx
《unity3d镜面反射代码Unity3dspecularreflectioncode.docx》由会员分享,可在线阅读,更多相关《unity3d镜面反射代码Unity3dspecularreflectioncode.docx(9页珍藏版)》请在冰豆网上搜索。
unity3d镜面反射代码Unity3dspecularreflectioncode
unity3d镜面反射代码(Unity3dspecularreflectioncode)
unity3d镜面反射代码(Unity3dspecularreflectioncode)
Uinty3dmirrorcode
Specularreflectioncode
ThefilenameMirrorReflection.cs
UsingUnityEngine;
UsingSystem.Collections;
Thisisinfactjustthe/WaterscriptfromProStandardAssets,
Withrefractionstuffremoved.//just
[ExecuteInEditMode]MakemirrorLive-updateevenwhennot/inplaymode
PublicclassMirrorReflection:
MonoBehaviour
{
Publicboolm_DisablePixelLights=true;
Publicintm_TextureSize=256;
Publicfloatm_ClipPlaneOffset=0.07f;
PublicLayerMaskm_ReflectLayers=-1;
PrivateHashtablem_ReflectionCameras=new(Hashtable);//
Camera->Cameratable
PrivateRenderTexturem_ReflectionTexture=null;
Privateintm_OldReflectionTextureSize=0;
Privatestaticbools_InsideRendering=false;
Thisiscalledwhenit'sknown/thattheobjectwillberenderedbysome
Camera.Werenderreflectionsanddo/otherupdateshere.
Thescriptexecutesinedit/Becausemode,reflectionsforthesceneview
Willjustwork//camera!
Publicvoid(OnWillRenderObject)
{
If(enabledrenderer||||Renderer.sharedMaterialrenderer.enabled||!
)
Return;
Cameracam=Camera.current;
If(cam!
)
Return;
Fromrecursivereflections.//Safeguard
If(s_InsideRendering)
Return;
S_InsideRendering=true;
CamerareflectionCamera;
CreateMirrorObjects(camoutreflectionCamera);
Findoutthereflectionplane:
position/andnormalinworld
space
Vector3POS=transform.position;
Vector3normal=transform.up;
Disablepixellightsforreflection//Optionally
IntoldPixelLightCount=QualitySettings.pixelLightCount;
If(m_DisablePixelLights)
QualitySettings.pixelLightCount=0;
UpdateCameraModes(CAM,reflectionCamera);
Render//reflection
Cameraaroundreflectionplane//Reflect
Floatd=-Vector3.Dot(normal,POS)-m_ClipPlaneOffset;
Vector4reflectionPlane=newVector4(normal.x,normal.y,normal.z,D);
Matrix4x4reflection=Matrix4x4.zero;
CalculateReflectionMatrix(RefreflectionreflectionPlane);
Vector3oldpos=cam.transform.position;
Vector3newpos=reflection.
multiplypoint(oldpos);
reflectioncamera.worldtocameramatrix=
cam.worldtocameramatrix*反射;
/建立斜投影矩阵,使近平面成为我们的反射。
/平面。
这样我们夹以下/以上免费。
四维向量clipplane=cameraspaceplane(reflectioncamera,POS
机,正常,1.0f);
matrix4x4投影=cam.projectionmatrix;
CalculateObliqueMatrix(参考投影,clipplane);
reflectioncamera.projectionmatrix=投影;
reflectioncamera.cullingmask=~(1,,4)和m_reflectlayers.value;//从不渲染水层
reflectioncamera.targettexture=m_reflectiontexture;
gl.setrevertbackfacing(真的);
reflectioncamera.transform.position=newpos;
到cam.transform.eulerangles欧拉=;
reflectioncamera.transform.eulerangles=新到(0,欧拉,欧拉Y,Z);
reflectioncamera。
();
reflectioncamera.transform.position=oldpos;
gl.setrevertbackfacing(假);
材料[]材料=renderer.sharedmaterials;
foreach(材料材料垫){
如果(垫。
HasProperty(“_reflectiontex”))
垫。
SetTexture(“_reflectiontex”,m_reflectiontexture);
}
//矩阵变换的UV从对象空间到屏幕材质
/空间。
我们只想项目在屏幕上的反射贴图。
matrix4x4scaleoffset=matrix4x4。
TRS(
新到(0.5f,0.5f,0.5f),Quaternion.identity,新到(0.5f,0.5f,0.5f));
到transform.lossyscale规模=;
matrix4x4MTX=transform.localtoworldmatrix*matrix4x4。
规模(新Vector3(1.0f/规模。
X,Y,1.0f1.0f/规模/规模。
Z));
MTX=scaleoffset***cam.projectionmatrix
cam.worldtocameramatrixMTX;
foreach(材料材料垫){
席。
SetMatrix(“_projmatrix”,MTX);
}
/恢复像素光计数
如果(m_disablepixellights)
qualitysettings.pixellightcount=oldpixellightcount;
s_insiderendering=false;
}
//清除所有对象我们可能创造
ondisable(){void
如果(m_reflectiontexture){
destroyimmediate(m_reflectiontexture);
m_reflectiontexture=null;
}
foreach(DictionaryEntrykVpm_reflectioncameras)
destroyimmediate(((相机)值值)。
游戏对象);
m_reflectioncameras。
clear();
}
privatevoidupdatecameramodes(相机SRC,相机测试)
{
如果(dest==null)
返回;
//清除当前设置相机相机一样
dest.clearflags=src.clearflags;
dest.backgroundcolor=src.backgroundcolor;
如果(src.clearflags==cameraclearflags。
Skybox)
{
Skybox天空=SRC。
GetComponent(typeof(天空))为天空;
SkyboxMYSKY=dest.GetComponent(typeof(天空))为天空;
如果(~天空||~sky.material)
{
mysky.enabled=false;
}
其他的
{
mysky.enabled=真;
mysky.material=sky.material;
}
}
//更新其他值以匹配当前摄像机。
/即使我们提供定制的照相机和投影矩阵,
//一些值被用在其他地方(例如Skybox利用远平面)
dest.farclipplane=src.farclipplane;
dest.nearclipplane=src.nearclipplane;
dest.orthographic=src.orthographic;
dest.fieldofview=src.fieldofview;
dest.aspect=src.aspect;
dest.orthographicsize=src.orthographicsize;
}
//需求我们需要创建任何对象
privatevoidcreatemirrorobjects(相机currentcamera,相机的
reflectioncamera)
{
reflectioncamera=null;
/反射渲染纹理
如果(~m_reflectiontexture||m_oldreflectiontexturesize~=m_texturesize)
{
如果(m_reflectiontexture)
destroyimmediate(m_reflectiontexture);
m_reflectiontexture=新RenderTexture(m_texturesize,m_texturesize,16);
m_reflectiontexture.name=“__mirrorreflection”+
getinstanceid();
m_reflectiontexture.ispoweroftwo=真;
m_reflectiontexture.hideflags=hideflags.dontsave;
m_oldreflectiontexturesize=m_texturesize;
}
/反射用照相机
reflectioncamera=m_reflectioncamerascurrentcamera][照相
机;
如果(~
Reflectioncamera)//catchbothnotindictionaryandindictionary-but-deleted-go.
{
GameObjectgo=newGameObject("mirrorreflcameraID"+getinstanceid()+""+currentcamera.getinstanceid(),typeof(camera),typeof(skybox));
Reflectioncamera=go.camera;
Reflectioncamera.enabled=false;
Reflectioncamera.transform.position=transform.position;
Reflectioncamera.transform.rotation=transform.rotation;
Reflectioncamera.gameobject.addcomponent("flarelayer");
Go.hideflags=hideflags.hideanddontsave;
M_reflectioncameras[currentcamera]=reflectioncamera;
}
}
//extendedsign:
returns-1,0or1basedonsignofa
PrivatestaticfloatSGN(float)
{
If(>0.0F)return1.0F;
If(<0.0F)return-1.0f;
Return0.0F;
}
//givenposition/normaloftheplane,calculatesplaneincameraspace.
Privatevector4cameraspaceplane(cameracam,vector3POS,vector3normal,floatsidesign)
{
Vector3offsetpos=POS+normal*m_clipplaneoffset;
Matrix4x4M=cam.worldtocameramatrix;
Vector3CPOs=m.multiplypoint(offsetpos);
Vector3cnormal=m.multiplyvector(normal).Normalized*sidesign;
Returnthenewvector4(cnormal.x,cnormal.y,cnormal.z,-vector3.dot(CPOs,cnormal));
}
//adjuststhegivenprojectionmatrixsothatthenearplaneisthegivenclipplane
//clipplaneisgivenincameraspace.SeearticleinGameProgrammingGems5.
Privatestaticvoidcalculateobliquematrix(Refmatrix4x4projection,vector4clipplane)
{
Vector4q=projection.inverse*newvector4(SGN(clipplane.x),SGN(clipplane.y),1.0F,1.0F
);
Vector4C=clipplane*(2.0f/(vector4.dot(clipplane,q)));
//thirdrow=clipplanefourthrow
Projection[2]=c.xprojection[3];
Projection[6]=C.Yprojection[7];
Projection[10]=C.Zprojection[11];
Projection[14]=C.Wprojection[15];
}
//calculatesreflectionmatrixaroundthegivenplane
Privatestaticvoidcalculatereflectionmatrix(Refmatrix4x4reflectionmat,vector4plane)
{
Reflectionmat.m00=(1-2F*plane[0]*plane[0]);
Reflectionmat.m01=(-2F*plane[0]*plane[1]);
(2)reflectionmat.m02flatplane[0]*[2]).
(2)reflectionmat.m03flatplane[3]*[0]).
(2)reflectionmat.m10flatplane[1]*[0]).
reflectionmat.m11=(f-f**flatplane[1][1]).
(2)reflectionmat.m12flatplane[1]*[2]).
(2)reflectionmat.m13flatplane[3]*[1]).
(2)reflectionmat.m20flatplane[2]*[0]).
(2)reflectionmat.m21flatplane[2]*[1]).
reflectionmat.m22=(f-f**flatplane[1][2]).
(2)reflectionmat.m23flatplane[3]*[2]).
reflectionmat.m30=of.
reflectionmat.m31=of.
reflectionmat.m32=of.
reflectionmat.m33=f.
}
}
文件名mirrorreflection.shader
shader("fx/mirror."
properties(
_maintexbase(rgb),d)="white"{}
_reflectiontex("reflection",d)="white"(texgenobjectlinear}
}
////////twotexturecards:
fullthing
subshader{
pass(
settexture[_combinestexturemaintex]{}
settexture[_reflectiontex]{matrix[_projmatrix)combines
thetexture*.
}
}
////////fallback:
justhandtexture
subshader{
pass(
settexture[_combinestexturemaintex]{}
}
}
}