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

}

}

你可能感兴趣的:(Car Paint Shaders Asset 2.1 U3D汽车展示插件简记)