Car Paint Shaders Asset 2.1 U3D汽車展示插件簡記

##反射面的代碼

using UnityEngine;

using System.Collections;

// This is in fact just the Water script from Pro Standard Assets,

// just with refraction stuff removed.

[ExecuteInEditMode] // Make mirror live-update even when not in play mode

public class MirrorReflectionScript : MonoBehaviour

{

public bool m_DisablePixelLights = true;

public int m_TextureSize = 256;

public float m_ClipPlaneOffset = 0.07f;

public LayerMask m_ReflectLayers = -1;

private Hashtable m_ReflectionCameras = new Hashtable(); // Camera -> Camera table

private RenderTexture m_ReflectionTexture = null;

private int m_OldReflectionTextureSize = 0;

private static bool s_InsideRendering = false;

// This is called when it's known that the object will be rendered by some

// camera. We render reflections and do other updates here.

// Because the script executes in edit mode, reflections for the scene view

// camera will just work!

public void OnWillRenderObject()

{

var rend = GetComponent();

if (!enabled || !rend || !rend.sharedMaterial || !rend.enabled)

return;

Camera cam = Camera.current;

if( !cam )

return;

// Safeguard from recursive reflections.

if( s_InsideRendering )

return;

s_InsideRendering = true;

Camera reflectionCamera;

CreateMirrorObjects( cam, out reflectionCamera );

// find out the reflection plane: position and normal in world space

Vector3 pos = transform.position;

Vector3 normal = transform.up;

// Optionally disable pixel lights for reflection

int oldPixelLightCount = QualitySettings.pixelLightCount;

if( m_DisablePixelLights )

QualitySettings.pixelLightCount = 0;

UpdateCameraModes( cam, reflectionCamera );

// Render reflection

// Reflect camera around reflection plane

float d = -Vector3.Dot (normal, pos) - m_ClipPlaneOffset;

Vector4 reflectionPlane = new Vector4 (normal.x, normal.y, normal.z, d);

Matrix4x4 reflection = Matrix4x4.zero;

CalculateReflectionMatrix (ref reflection, reflectionPlane);

Vector3 oldpos = cam.transform.position;

Vector3 newpos = reflection.MultiplyPoint( oldpos );

reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection;

// Setup oblique projection matrix so that near plane is our reflection

// plane. This way we clip everything below/above it for free.

Vector4 clipPlane = CameraSpacePlane( reflectionCamera, pos, normal, 1.0f );

//Matrix4x4 projection = cam.projectionMatrix;

Matrix4x4 projection = cam.CalculateObliqueMatrix(clipPlane);

reflectionCamera.projectionMatrix = projection;

reflectionCamera.cullingMask = ~(1<<4) & m_ReflectLayers.value; // never render water layer

reflectionCamera.targetTexture = m_ReflectionTexture;

GL.SetRevertBackfacing (true);

reflectionCamera.transform.position = newpos;

Vector3 euler = cam.transform.eulerAngles;

reflectionCamera.transform.eulerAngles = new Vector3(0, euler.y, euler.z);

reflectionCamera.Render();

reflectionCamera.transform.position = oldpos;

GL.SetRevertBackfacing (false);

Material[] materials = rend.sharedMaterials;

foreach( Material mat in materials ) {

if( mat.HasProperty("_ReflectionTex") )

mat.SetTexture( "_ReflectionTex", m_ReflectionTexture );

}

// Restore pixel light count

if( m_DisablePixelLights )

QualitySettings.pixelLightCount = oldPixelLightCount;

s_InsideRendering = false;

}

// Cleanup all the objects we possibly have created

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();

}

private void UpdateCameraModes( Camera src, Camera dest )

{

if( dest == null )

return;

// set camera to clear the same way as current 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;

}

}

// update other values to match current camera.

// even if we are supplying custom camera&projection matrices,

// some of values are used elsewhere (e.g. skybox uses far plane)

dest.farClipPlane = src.farClipPlane;

dest.nearClipPlane = src.nearClipPlane;

dest.orthographic = src.orthographic;

dest.fieldOfView = src.fieldOfView;

dest.aspect = src.aspect;

dest.orthographicSize = src.orthographicSize;

}

// On-demand create any objects we need

private void CreateMirrorObjects( Camera currentCamera, out Camera reflectionCamera )

{

reflectionCamera = null;

// Reflection render texture

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 for reflection

reflectionCamera = m_ReflectionCameras[currentCamera] as Camera;

if( !reflectionCamera ) // catch both not-in-dictionary and in-dictionary-but-deleted-GO

{

GameObject go = new GameObject( "Mirror Refl Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox) );

reflectionCamera = go.GetComponent();

reflectionCamera.enabled = false;

reflectionCamera.transform.position = transform.position;

reflectionCamera.transform.rotation = transform.rotation;

reflectionCamera.gameObject.AddComponent();

go.hideFlags = HideFlags.HideAndDontSave;

m_ReflectionCameras[currentCamera] = reflectionCamera;

}

}

// Extended sign: returns -1, 0 or 1 based on sign of a

private static float sgn(float a)

{

if (a > 0.0f) return 1.0f;

if (a < 0.0f) return -1.0f;

return 0.0f;

}

// Given position/normal of the plane, calculates plane in camera space.

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) );

}

// Calculates reflection matrix around the given plane

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;

}

}

#鏡面Shader代碼

Shader "FX/MirrorReflection"

{

Properties

{

_MainTex ("Base (RGB)", 2D) = "white" {}

[HideInInspector] _ReflectionTex ("", 2D) = "white" {}

}

SubShader

{

Tags { "RenderType"="Opaque" }

LOD 100

Pass {

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

struct v2f

{

float2 uv : TEXCOORD0;

float4 refl : TEXCOORD1;

float4 pos : SV_POSITION;

};

float4 _MainTex_ST;

v2f vert(float4 pos : POSITION, float2 uv : TEXCOORD0)

{

v2f o;

o.pos = mul (UNITY_MATRIX_MVP, pos);

o.uv = TRANSFORM_TEX(uv, _MainTex);

o.refl = ComputeScreenPos (o.pos);

return o;

}

sampler2D _MainTex;

sampler2D _ReflectionTex;

fixed4 frag(v2f i) : SV_Target

{

fixed4 tex = tex2D(_MainTex, i.uv);

fixed4 refl = tex2Dproj(_ReflectionTex, UNITY_PROJ_COORD(i.refl));

return tex * refl;

}

ENDCG

}

}

}

##攝像機代碼CameraFocus

using UnityEngine;

namespace UnityStandardAssets.ImageEffects{

public sealed class CameraFocus : MonoBehaviour

{

[SerializeField]

private Camera m_camera;

[SerializeField]

private DepthOfField m_depthOfField;

[SerializeField]

private float m_focusDelay;

#region Unity core events.

private void Update()

{

Transform cameraTransform = m_camera.transform;

RaycastHit hitInfo;

if (Physics.Raycast(cameraTransform.position, cameraTransform.forward, out hitInfo))

{

m_depthOfField.focalLength = Mathf.Lerp(m_depthOfField.focalLength, hitInfo.distance, Time.deltaTime * m_focusDelay);

}

}

#endregion //Unity core events.

#region Class functions.

#endregion //Class functions.

}

}

##CameraRotate

using UnityEngine;

using System.Collections;

public class CameraRotate : MonoBehaviour

{

public Transform targetObject;

public Vector3 targetOffset;

public float averageDistance = 5.0f;

public float maxDistance = 20;

public float minDistance = .6f;

public float xSpeed = 200.0f;

public float ySpeed = 200.0f;

public int yMinLimit = -80;

public int yMaxLimit = 80;

public int zoomSpeed = 40;

public float panSpeed = 0.3f;

public float zoomDampening = 5.0f;

public float rotateOnOff = 1;

private float xDeg = 0.0f;

private float yDeg = 0.0f;

private float currentDistance;

private float desiredDistance;

private Quaternion currentRotation;

private Quaternion desiredRotation;

private Quaternion rotation;

private Vector3 position;

private float idleTimer = 0.0f;

private float idleSmooth = 0.0f;

void Start() { Init(); }

void OnEnable() { Init(); }

public void Init()

{

if (!targetObject)

{

GameObject go = new GameObject("Cam Target");

go.transform.position = transform.position + (transform.forward * averageDistance);

targetObject = go.transform;

}

currentDistance = averageDistance;

desiredDistance = averageDistance;

position = transform.position;

rotation = transform.rotation;

currentRotation = transform.rotation;

desiredRotation = transform.rotation;

xDeg = Vector3.Angle(Vector3.right, transform.right );

yDeg = Vector3.Angle(Vector3.up, transform.up );

position = targetObject.position - (rotation * Vector3.forward * currentDistance + targetOffset);

}

void LateUpdate()

{

if (Input.GetMouseButton(2) && Input.GetKey(KeyCode.LeftAlt) && Input.GetKey(KeyCode.LeftControl))

{

desiredDistance -= Input.GetAxis("Mouse Y") * 0.02f??* zoomSpeed*0.125f * Mathf.Abs(desiredDistance);

}

else if (Input.GetMouseButton(0) )

{

xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f;

yDeg -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;

yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);

desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);

currentRotation = transform.rotation;

rotation = Quaternion.Lerp(currentRotation, desiredRotation, 0.02f??* zoomDampening);

transform.rotation = rotation;

idleTimer=0;

idleSmooth=0;

}else{

idleTimer+=0.02f ;

if(idleTimer > rotateOnOff && rotateOnOff > 0){

idleSmooth+=(0.02f +idleSmooth)*0.005f;

idleSmooth = Mathf.Clamp(idleSmooth, 0, 1);

xDeg += xSpeed * 0.001f * idleSmooth;

}

yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);

desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);

currentRotation = transform.rotation;

rotation = Quaternion.Lerp(currentRotation, desiredRotation, 0.02f??* zoomDampening*2);

transform.rotation = rotation;

}

desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * 0.02f??* zoomSpeed * Mathf.Abs(desiredDistance);

desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);

currentDistance = Mathf.Lerp(currentDistance, desiredDistance, 0.02f??* zoomDampening);

position = targetObject.position - (rotation * Vector3.forward * currentDistance + targetOffset);

transform.position = position;

}

private static float ClampAngle(float angle, float min, float max)

{

if (angle < -360)

angle += 360;

if (angle > 360)

angle -= 360;

return Mathf.Clamp(angle, min, max);

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末朴爬,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子涛癌,更是在濱河造成了極大的恐慌滓玖,老刑警劉巖续徽,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異却紧,居然都是意外死亡陌僵,警方通過查閱死者的電腦和手機悴务,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門睹限,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人讯檐,你說我怎么就攤上這事羡疗。” “怎么了别洪?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵叨恨,是天一觀的道長。 經(jīng)常有香客問我挖垛,道長痒钝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任痢毒,我火速辦了婚禮送矩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘哪替。我一直安慰自己栋荸,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布凭舶。 她就那樣靜靜地躺著晌块,像睡著了一般。 火紅的嫁衣襯著肌膚如雪帅霜。 梳的紋絲不亂的頭發(fā)上匆背,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音身冀,去河邊找鬼钝尸。 笑死,一個胖子當著我的面吹牛搂根,可吹牛的內(nèi)容都是我干的珍促。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼兄墅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了澳叉?” 一聲冷哼從身側(cè)響起隙咸,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤沐悦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后五督,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體藏否,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年充包,在試婚紗的時候發(fā)現(xiàn)自己被綠了副签。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡基矮,死狀恐怖淆储,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情家浇,我是刑警寧澤本砰,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站钢悲,受9級特大地震影響点额,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜莺琳,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一还棱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惭等,春花似錦珍手、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至凭豪,卻和暖如春焙蹭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嫂伞。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工孔厉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人帖努。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓撰豺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親拼余。 傳聞我的和親對象是個殘疾皇子污桦,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容