【Unity3D_Shader】镜面scrip的名词初步查找
来源:互联网 发布:皮鞋 知乎 编辑:程序博客网 时间:2024/04/30 23:45
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class Mirror : MonoBehaviour
{
//是否需要像素光
public bool m_DisablePixelLights = true;
//纹理大小
public int m_TextureSize = 256;
//距离mirror表面距离偏移量
public float m_ClipPlaneOffset = 0.07f;
//是否反射
public bool m_IsFlatMirror = true;
//cullMask层级
public LayerMask m_ReflectLayers = -1;
//camera哈希表
private Hashtable m_ReflectionCameras = new Hashtable();
//反射纹理层
private RenderTexture m_ReflectionTexture = null;
private int m_OldReflectionTextureSize = 0;
//保证单次渲染
private static bool s_InsideRendering = false;
public void OnWillRenderObject()
{
if( !enabled || !renderer || !renderer.sharedMaterial || !renderer.enabled )
return;
//当前用于渲染的相机
Camera cam = Camera.current;
if( !cam )
return;
if( s_InsideRendering )
return;
s_InsideRendering = true;
Camera reflectionCamera;
//camera数组中是否有currentCamera,没有的话根据currentCamera的ID创建一个赋给reflectionCamera,
//并将reflectionCamera添加进camera数组中
CreateMirrorObjects( cam, out reflectionCamera );
Vector3 pos = transform.position;
Vector3 normal;
//需要反射,法线沿表面向上
if(m_IsFlatMirror){
normal = transform.up;
}
//不需要反射,法线沿表面向下
else{
normal= transform.position - cam.transform.position ;
normal.Normalize();
}
int oldPixelLightCount = QualitySettings.pixelLightCount;
if( m_DisablePixelLights )
QualitySettings.pixelLightCount = 0;
//使reflectionCamera配置跟camera一样
UpdateCameraModes( cam, reflectionCamera );
float d = -Vector3.Dot (normal, pos) - m_ClipPlaneOffset;
Vector4 reflectionPlane = new Vector4 (normal.x, normal.y, normal.z, d);
Matrix4x4 reflection = Matrix4x4.zero;
//根据reflectionPlane计算出对称变换矩阵
CalculateReflectionMatrix (ref reflection, reflectionPlane);
Vector3 oldpos = cam.transform.position;
//flectionCamera与currentCamera关于transform.position对称
Vector3 newpos = reflection.MultiplyPoint( oldpos );
//调整reflectionCamera的worldToCameraMatrix,
//使得世界物体对于reflectionCamera的相对坐标与世界物体对于currentCamera的相对坐标相等
reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection;
//reflectionPlane在camera的坐标系的相对坐标
Vector4 clipPlane = CameraSpacePlane( reflectionCamera, pos, normal, 1.0f );
Matrix4x4 projection = cam.projectionMatrix;
//设置reflectionCamera投影矩阵的近平面为clipPlane
CalculateObliqueMatrix (ref projection, clipPlane);
reflectionCamera.projectionMatrix = projection;
//设置cullMask屏蔽对象
reflectionCamera.cullingMask = ~(1<<4) & m_ReflectLayers.value;
//将reflectionCamera看到的画面渲染到texture上
reflectionCamera.targetTexture = m_ReflectionTexture;
//关闭背面消隐,物体虚像背面能够显示
GL.SetRevertBackfacing (true);
//reflectionCamera坐标赋值
reflectionCamera.transform.position = newpos;
Vector3 euler = cam.transform.eulerAngles;
//reflectionCamera旋转角赋值
reflectionCamera.transform.position = oldpos;
//开启背面消隐,等待下一次渲染
GL.SetRevertBackfacing (false);
Material[] materials = renderer.sharedMaterials;
mat.SetTexture( "_Ref", m_ReflectionTexture );
}
if( m_DisablePixelLights )
QualitySettings.pixelLightCount = oldPixelLightCount;
s_InsideRendering = false;
}
//disable
void OnDisable()
{
if( m_ReflectionTexture ) {
DestroyImmediate( m_ReflectionTexture );
m_ReflectionTexture = null;
}
foreach( DictionaryEntry kvp in m_ReflectionCameras )
DestroyImmediate( ((Camera)kvp.Value).gameObject );
m_ReflectionCameras.Clear();
}
//使reflectionCamera配置跟camera一样(cam, reflectionCamera)
private void UpdateCameraModes( Camera src, Camera dest )
{
if( dest == null )
return;
//mirror背景颜色和是否显示天空盒与camera保持一致
dest.clearFlags = src.clearFlags;
dest.backgroundColor = src.backgroundColor;
//显示天空盒
if( src.clearFlags == CameraClearFlags.Skybox )
{
Skybox sky = src.GetComponent(typeof(Skybox)) as Skybox;
Skybox mysky = dest.GetComponent(typeof(Skybox)) as Skybox;
//没有设置天空盒
if( !sky || !sky.material )
{
mysky.enabled = false;
}
//有设置天空盒
else
{
mysky.enabled = true;
mysky.material = sky.material;
}
}
//各属性与camera保持一致
//远裁剪面
dest.farClipPlane = src.farClipPlane;
//近裁剪面
dest.nearClipPlane = src.nearClipPlane;
//正交
dest.orthographic = src.orthographic;
//视野
dest.fieldOfView = src.fieldOfView;
//视角
dest.aspect = src.aspect;
//正交大小
dest.orthographicSize = src.orthographicSize;
//渲染路径
dest.renderingPath = src.renderingPath;
}
//创建mirror,并添加到camera数组中
private void CreateMirrorObjects( Camera currentCamera, out Camera reflectionCamera )
{
reflectionCamera = null;
if( !m_ReflectionTexture || m_OldReflectionTextureSize != m_TextureSize )
{
if( m_ReflectionTexture )
DestroyImmediate( m_ReflectionTexture );
m_ReflectionTexture = new RenderTexture( m_TextureSize, m_TextureSize, 16 );
m_ReflectionTexture.name = "__MirrorReflection" + GetInstanceID();
m_ReflectionTexture.isPowerOfTwo = true;
m_ReflectionTexture.hideFlags = HideFlags.DontSave;
m_OldReflectionTextureSize = m_TextureSize;
}
//camera数组中是否存有currentCamera
reflectionCamera = m_ReflectionCameras[currentCamera] as Camera;
if( !reflectionCamera )
{
//创建currentCamera ,并且添加到camera哈希表中
GameObject go = new GameObject( "Mirror Refl Camera id" + GetInstanceID() + " for " + 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;
}
}
//sgn()取正负号
private static float sgn(float a)
{
if (a > 0.0f) return 1.0f;
if (a < 0.0f) return -1.0f;
return 0.0f;
}
//( reflectionCamera, pos, normal, 1.0f )
//reflectionPlane在camera的坐标系的相对坐标
private Vector4 CameraSpacePlane (Camera cam, Vector3 pos, Vector3 normal, float sideSign)
{
Vector3 offsetPos = pos + normal * m_ClipPlaneOffset;
Matrix4x4 m = cam.worldToCameraMatrix;
Vector3 cpos = m.MultiplyPoint( offsetPos );
Vector3 cnormal = m.MultiplyVector( normal ).normalized * sideSign;
return new Vector4( cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos,cnormal) );
}
//(ref projection, clipPlane)
//设置投影矩阵的近平面为clipPlane
private static void CalculateObliqueMatrix (ref Matrix4x4 projection, Vector4 clipPlane)
{
Vector4 q = projection.inverse * new Vector4(
sgn(clipPlane.x),
sgn(clipPlane.y),
1.0f,
1.0f
);
Vector4 c = clipPlane * (2.0F / (Vector4.Dot (clipPlane, q)));
projection[2] = c.x - projection[3];
projection[6] = c.y - projection[7];
projection[10] = c.z - projection[11];
projection[14] = c.w - projection[15];
}
//对称矩阵
private static void CalculateReflectionMatrix (ref Matrix4x4 reflectionMat, Vector4 plane)
{
reflectionMat.m00 = (1F - 2F*plane[0]*plane[0]);
reflectionMat.m01 = ( - 2F*plane[0]*plane[1]);
reflectionMat.m02 = ( - 2F*plane[0]*plane[2]);
reflectionMat.m03 = ( - 2F*plane[3]*plane[0]);
reflectionMat.m10 = ( - 2F*plane[1]*plane[0]);
reflectionMat.m11 = (1F - 2F*plane[1]*plane[1]);
reflectionMat.m12 = ( - 2F*plane[1]*plane[2]);
reflectionMat.m13 = ( - 2F*plane[3]*plane[1]);
reflectionMat.m20 = ( - 2F*plane[2]*plane[0]);
reflectionMat.m21 = ( - 2F*plane[2]*plane[1]);
reflectionMat.m22 = (1F - 2F*plane[2]*plane[2]);
reflectionMat.m23 = ( - 2F*plane[3]*plane[2]);
reflectionMat.m30 = 0F;
reflectionMat.m31 = 0F;
reflectionMat.m32 = 0F;
reflectionMat.m33 = 1F;
}
}
using System.Collections;
[ExecuteInEditMode]
public class Mirror : MonoBehaviour
{
//是否需要像素光
public bool m_DisablePixelLights = true;
//纹理大小
public int m_TextureSize = 256;
//距离mirror表面距离偏移量
public float m_ClipPlaneOffset = 0.07f;
//是否反射
public bool m_IsFlatMirror = true;
//cullMask层级
public LayerMask m_ReflectLayers = -1;
//camera哈希表
private Hashtable m_ReflectionCameras = new Hashtable();
//反射纹理层
private RenderTexture m_ReflectionTexture = null;
private int m_OldReflectionTextureSize = 0;
//保证单次渲染
private static bool s_InsideRendering = false;
public void OnWillRenderObject()
{
if( !enabled || !renderer || !renderer.sharedMaterial || !renderer.enabled )
return;
//当前用于渲染的相机
Camera cam = Camera.current;
if( !cam )
return;
if( s_InsideRendering )
return;
s_InsideRendering = true;
Camera reflectionCamera;
//camera数组中是否有currentCamera,没有的话根据currentCamera的ID创建一个赋给reflectionCamera,
//并将reflectionCamera添加进camera数组中
CreateMirrorObjects( cam, out reflectionCamera );
Vector3 pos = transform.position;
Vector3 normal;
//需要反射,法线沿表面向上
if(m_IsFlatMirror){
normal = transform.up;
}
//不需要反射,法线沿表面向下
else{
normal= transform.position - cam.transform.position ;
normal.Normalize();
}
int oldPixelLightCount = QualitySettings.pixelLightCount;
if( m_DisablePixelLights )
QualitySettings.pixelLightCount = 0;
//使reflectionCamera配置跟camera一样
UpdateCameraModes( cam, reflectionCamera );
float d = -Vector3.Dot (normal, pos) - m_ClipPlaneOffset;
Vector4 reflectionPlane = new Vector4 (normal.x, normal.y, normal.z, d);
Matrix4x4 reflection = Matrix4x4.zero;
//根据reflectionPlane计算出对称变换矩阵
CalculateReflectionMatrix (ref reflection, reflectionPlane);
Vector3 oldpos = cam.transform.position;
//flectionCamera与currentCamera关于transform.position对称
Vector3 newpos = reflection.MultiplyPoint( oldpos );
//调整reflectionCamera的worldToCameraMatrix,
//使得世界物体对于reflectionCamera的相对坐标与世界物体对于currentCamera的相对坐标相等
reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection;
//reflectionPlane在camera的坐标系的相对坐标
Vector4 clipPlane = CameraSpacePlane( reflectionCamera, pos, normal, 1.0f );
Matrix4x4 projection = cam.projectionMatrix;
//设置reflectionCamera投影矩阵的近平面为clipPlane
CalculateObliqueMatrix (ref projection, clipPlane);
reflectionCamera.projectionMatrix = projection;
//设置cullMask屏蔽对象
reflectionCamera.cullingMask = ~(1<<4) & m_ReflectLayers.value;
//将reflectionCamera看到的画面渲染到texture上
reflectionCamera.targetTexture = m_ReflectionTexture;
//关闭背面消隐,物体虚像背面能够显示
GL.SetRevertBackfacing (true);
//reflectionCamera坐标赋值
reflectionCamera.transform.position = newpos;
Vector3 euler = cam.transform.eulerAngles;
//reflectionCamera旋转角赋值
reflectionCamera.transform.eulerAngles = new Vector3(0, euler.y, euler.z);
//趁背面能够显示,渲染出物体背面
reflectionCamera.transform.position = oldpos;
//开启背面消隐,等待下一次渲染
GL.SetRevertBackfacing (false);
Material[] materials = renderer.sharedMaterials;
foreach( Material mat in materials ) {
//设置shader中的_ref属性
mat.SetTexture( "_Ref", m_ReflectionTexture );
}
if( m_DisablePixelLights )
QualitySettings.pixelLightCount = oldPixelLightCount;
s_InsideRendering = false;
}
//disable
void OnDisable()
{
if( m_ReflectionTexture ) {
DestroyImmediate( m_ReflectionTexture );
m_ReflectionTexture = null;
}
foreach( DictionaryEntry kvp in m_ReflectionCameras )
DestroyImmediate( ((Camera)kvp.Value).gameObject );
m_ReflectionCameras.Clear();
}
//使reflectionCamera配置跟camera一样(cam, reflectionCamera)
private void UpdateCameraModes( Camera src, Camera dest )
{
if( dest == null )
return;
//mirror背景颜色和是否显示天空盒与camera保持一致
dest.clearFlags = src.clearFlags;
dest.backgroundColor = src.backgroundColor;
//显示天空盒
if( src.clearFlags == CameraClearFlags.Skybox )
{
Skybox sky = src.GetComponent(typeof(Skybox)) as Skybox;
Skybox mysky = dest.GetComponent(typeof(Skybox)) as Skybox;
//没有设置天空盒
if( !sky || !sky.material )
{
mysky.enabled = false;
}
//有设置天空盒
else
{
mysky.enabled = true;
mysky.material = sky.material;
}
}
//各属性与camera保持一致
//远裁剪面
dest.farClipPlane = src.farClipPlane;
//近裁剪面
dest.nearClipPlane = src.nearClipPlane;
//正交
dest.orthographic = src.orthographic;
//视野
dest.fieldOfView = src.fieldOfView;
//视角
dest.aspect = src.aspect;
//正交大小
dest.orthographicSize = src.orthographicSize;
//渲染路径
dest.renderingPath = src.renderingPath;
}
//创建mirror,并添加到camera数组中
private void CreateMirrorObjects( Camera currentCamera, out Camera reflectionCamera )
{
reflectionCamera = null;
if( !m_ReflectionTexture || m_OldReflectionTextureSize != m_TextureSize )
{
if( m_ReflectionTexture )
DestroyImmediate( m_ReflectionTexture );
m_ReflectionTexture = new RenderTexture( m_TextureSize, m_TextureSize, 16 );
m_ReflectionTexture.name = "__MirrorReflection" + GetInstanceID();
m_ReflectionTexture.isPowerOfTwo = true;
m_ReflectionTexture.hideFlags = HideFlags.DontSave;
m_OldReflectionTextureSize = m_TextureSize;
}
//camera数组中是否存有currentCamera
reflectionCamera = m_ReflectionCameras[currentCamera] as Camera;
if( !reflectionCamera )
{
//创建currentCamera ,并且添加到camera哈希表中
GameObject go = new GameObject( "Mirror Refl Camera id" + GetInstanceID() + " for " + 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;
}
}
//sgn()取正负号
private static float sgn(float a)
{
if (a > 0.0f) return 1.0f;
if (a < 0.0f) return -1.0f;
return 0.0f;
}
//( reflectionCamera, pos, normal, 1.0f )
//reflectionPlane在camera的坐标系的相对坐标
private Vector4 CameraSpacePlane (Camera cam, Vector3 pos, Vector3 normal, float sideSign)
{
Vector3 offsetPos = pos + normal * m_ClipPlaneOffset;
Matrix4x4 m = cam.worldToCameraMatrix;
Vector3 cpos = m.MultiplyPoint( offsetPos );
Vector3 cnormal = m.MultiplyVector( normal ).normalized * sideSign;
return new Vector4( cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos,cnormal) );
}
//(ref projection, clipPlane)
//设置投影矩阵的近平面为clipPlane
private static void CalculateObliqueMatrix (ref Matrix4x4 projection, Vector4 clipPlane)
{
Vector4 q = projection.inverse * new Vector4(
sgn(clipPlane.x),
sgn(clipPlane.y),
1.0f,
1.0f
);
Vector4 c = clipPlane * (2.0F / (Vector4.Dot (clipPlane, q)));
projection[2] = c.x - projection[3];
projection[6] = c.y - projection[7];
projection[10] = c.z - projection[11];
projection[14] = c.w - projection[15];
}
//对称矩阵
private static void CalculateReflectionMatrix (ref Matrix4x4 reflectionMat, Vector4 plane)
{
reflectionMat.m00 = (1F - 2F*plane[0]*plane[0]);
reflectionMat.m01 = ( - 2F*plane[0]*plane[1]);
reflectionMat.m02 = ( - 2F*plane[0]*plane[2]);
reflectionMat.m03 = ( - 2F*plane[3]*plane[0]);
reflectionMat.m10 = ( - 2F*plane[1]*plane[0]);
reflectionMat.m11 = (1F - 2F*plane[1]*plane[1]);
reflectionMat.m12 = ( - 2F*plane[1]*plane[2]);
reflectionMat.m13 = ( - 2F*plane[3]*plane[1]);
reflectionMat.m20 = ( - 2F*plane[2]*plane[0]);
reflectionMat.m21 = ( - 2F*plane[2]*plane[1]);
reflectionMat.m22 = (1F - 2F*plane[2]*plane[2]);
reflectionMat.m23 = ( - 2F*plane[3]*plane[2]);
reflectionMat.m30 = 0F;
reflectionMat.m31 = 0F;
reflectionMat.m32 = 0F;
reflectionMat.m33 = 1F;
}
}
0 0
- 【Unity3D_Shader】镜面scrip的名词初步查找
- 【Unity3D_Shader】流水Shader的名词查找和疑问
- 【Unity3D_Shader】渐变shader的比较
- DLNA、Samba、wifi等名词的初步了解
- 技术名词面试题
- scrip----C#
- 面试题之名词比较
- 【Unity3D_Shader】笔记_1
- 【Unity3D_Shader】图形学相关
- 【Unity3D_Shader】代数相关
- 二分查找初步
- 单链表的初步实现---(转置,删除,替换,查找,添加)
- 微软面试题,查找1的个数
- 关于二分查找的面试题归类
- 面试题 -- 有序二维数组的查找
- 面试题3:二维数组的查找
- 面题3 二维数组的查找
- 面试题3-二维数组的查找
- boost::tie()和boost::variant()讲解
- makefile 编写
- 第九周项目一 do-while语句
- Java 中extends与implements使用方法
- 第九周项目一——一千以内所有偶数和
- 【Unity3D_Shader】镜面scrip的名词初步查找
- LeeCode--Two Sum
- java中Array/List/Map/Object与Json互相转换详解
- 第九周项目一--求一千以内所有偶数的和(一)
- 第九周项目一(2)求1000以内所有偶数的和
- Windows Azure云服务价格调整通知
- 第九周项目一
- 最大值2
- 小马哥-----高仿红米6582 H9T v004详细拆机图