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

}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容