How Can I Get UV(TEXCOORD) by Mirrored Camera in Reflection Effect( inverted image) on Water?
Here is the Script to Mirror Camera by Water Plane
public class MirrorCamera : MonoBehaviour
{
public Camera original_camera;
public Camera target_camera;
Vector3 eye;
Vector3 up;
Vector3 right;
Vector3 lookat;
Vector3 m;
Matrix4x4 matrix = new Matrix4x4();
void Start()
{
}
// Update is called once per frame
void Update()
{
print(target_camera.transform.forward);
//RaycastHit hitpoint;
//Physics.Raycast(original_camera.transform.position, original_camera.transform.forward, out hitpoint);
eye = GetMirrorPoint(this.gameObject.transform.up, original_camera.transform.position, this.gameObject.transform.position);
up = GetMirrorPoint(this.gameObject.transform.up, original_camera.transform.up, this.gameObject.transform.position);
lookat = GetMirrorPoint(this.gameObject.transform.up, original_camera.transform.forward, this.gameObject.transform.position);
Vector3 z = lookat.normalized;
Vector3 x = Vector3.Cross(up.normalized, z);
Vector3 y = Vector3.Cross(z, x);
matrix.SetColumn(0, x);
matrix.SetColumn(1, y);
matrix.SetColumn(2, z);
matrix.SetColumn(3, new Vector4(eye.x, eye.y, eye.z, 1));
print(matrix);
target_camera.transform.position = eye;
target_camera.transform.rotation = matrix.rotation;
Shader.SetGlobalMatrix("_MirrorCameraMatrix", matrix.inverse);
}
Vector3 GetMirrorPoint(Vector3 pn, Vector3 cp, Vector3 pp)
{
Vector3 d1 = cp - Vector3.ProjectOnPlane(cp, pn);
Vector3 d2 = pp - Vector3.ProjectOnPlane(pp,pn);
float direct= Vector3.Dot(d1, pn) * Vector3.Dot(d2, pn);
Vector3 d0 ;
if (Vector3.Dot(pn, d1) > 0)
{
if (d1.magnitude - d2.magnitude > 0)
{
d0 = d1 - d2;
m = cp - 2 * d0.magnitude * pn;
}
else
{
d0 = d2 - d1;
m = cp + 2 * d0.magnitude * pn;
}
}
else
{
if (d1.magnitude - d2.magnitude > 0)
{
d0 = d1 - d2;
m = cp + 2 * d0.magnitude * pn;
}
else
{
d0 = d2 - d1;
m = cp - 2 * d0.magnitude * pn;
}
}
return m;
}
}
the reflection Water Shader is below:
Properties
{
_ReflectMap("Reflect Map", 2D) = "white" {}
[Header(BaseColor)]
_DepthGradientShallow("Depth Gradient Shallow", Color) = (0.325, 0.807, 0.971, 0.725)
_DepthGradientDeep("Depth Gradient Deep", Color) = (0.086, 0.407, 1, 0.749)
_DepthMaxDistance("Depth Maximum Distance", Float) = 1
[Header(Wave)]
_WaveLen("WaveLen", range(0.0,3.2)) = 1.0
_Speed("Speed", range(0.0,10.0)) = 1.0
_Height("Height", range(0.0,1.0)) = 0.2
_deepcolor("deepcolor", range(0.0,1.0)) = 0.47
_horizontal_thrill("horizontal_thrill", range(0.0,1.0)) = 0.3
_Z_Offset("Z-Offset", range(-1.0,1.0)) = 0.4
[Header(Caustics)]
_CausticsColor("Caustics Color", Color) = (1,1,1,1)
_CausticsMap("Caustics Map", 2D) = "white" {}
_CausticsCutoff("Caustics Cutoff", Range(0, 1)) = 0.777
_CausticsScroll_X("Caustics Scroll X",Float) = 0.03
_CausticsScroll_Y("Caustics Scroll Y",Float) = 0.03
_CausticsDistortion("Caustics Distortion", 2D) = "white" {}
_CausticsDistortionAmount("Caustics Distortion Amount", Range(0, 1)) = 0.27
[Header(Foam)]
_FoamColor("Foam Color", Color) = (1,1,1,1)
_SurfaceNoise("Surface Noise", 2D) = "white" {}
_SurfaceNoiseCutoff("Surface Noise Cutoff", Range(0, 1)) = 0.777
_FoamMaxDistance("Foam Maximum Distance", Float) = 0.4
[MaterialToggle] _hasSurfaceFoam("SurfaceFoam", Float) = 0
_SurfaceFoamDenSity("SurfaceFoamDenSity", Range(0, 2.0)) = 1.0
_SurfaceNoiseScroll_X("Surface Noise Scroll X",Float) = 0.03
_SurfaceNoiseScroll_Y("Surface Noise Scroll Y",Float) = 0.03
_SurfaceDistortion("Surface Distortion", 2D) = "white" {}
_SurfaceDistortionAmount("Surface Distortion Amount", Range(0, 1)) = 0.27
}
SubShader
{
Tags
{
"Queue" = "Transparent"
}
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
CGPROGRAM
#define SMOOTHSTEP_AA 0.02
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _CameraDepthTexture;
float _Height;
float _horizontal_thrill;
float _Z_Offset;
float _Speed;
float _WaveLen;
float _deepcolor;
sampler2D _ReflectMap;
float4 _ReflectMap_ST;
float4 _CausticsColor;
sampler2D _CausticsMap;
float4 _CausticsMap_ST;
float _CausticsCutoff;
float _CausticsScroll_X;
float _CausticsScroll_Y;
sampler2D _CausticsDistortion;
float4 _CausticsDistortion_ST;
float _CausticsDistortionAmount;
float4 _FoamColor;
float4 _DepthGradientShallow;
float4 _DepthGradientDeep;
float _DepthMaxDistance;
sampler2D _SurfaceNoise;
float4 _SurfaceNoise_ST;
float _SurfaceNoiseCutoff;
float _SurfaceNoiseScroll_X;
float _SurfaceNoiseScroll_Y;
float _hasSurfaceFoam;
sampler2D _SurfaceDistortion;
float4 _SurfaceDistortion_ST;
float _SurfaceDistortionAmount;
float _FoamMaxDistance;
float _SurfaceFoamDenSity;
fixed4 _UnifyMapColor;
float4x4 _MirrorCameraMatrix;
float4 alphaBlend(float4 top, float4 bottom)
{
float3 color = (top.rgb * top.a) + (bottom.rgb * (1 - top.a));
float alpha = top.a + bottom.a * (1 - top.a);
return float4(color, alpha);
}
struct appdata
{
float4 vertex : POSITION;
float4 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float4 vertex : SV_POSITION;
float4 vertex_mirror : TEXCOORD5;
float4 screenPosition : TEXCOORD2;
float2 noiseUV : TEXCOORD0;
float2 distortUV : TEXCOORD1;
float2 CausticsUV : TEXCOORD3;
float2 CausticsdistortUV :TEXCOORD4;
float3 viewNormal : NORMAL;
float4 cc:COLOR;
};
inline fixed4 PointToPlaneDistance(fixed4 c_point,fixed n_plane)
{
return dot(c_point, n_plane);
}
inline fixed4 MirrorPoint(fixed4 c_point, fixed n_plane)
{
fixed4 m_point;
fixed d = PointToPlaneDistance(c_point, n_plane)[0];
m_point = c_point - (2 * d)*n_plane;
return m_point;
}
v2f vert (appdata v)
{
v2f o;
float new_x = (v.vertex.x *_WaveLen + _Time.z*_Speed);
float hh = sin(new_x + _Z_Offset * v.vertex.z)*_Height*v.vertex.x;
float dd = sin(new_x)*_Height*v.vertex.x;
float3 pp = v.vertex.xyz;
pp.y += hh;
pp.z += _horizontal_thrill * dd;
o.vertex = UnityObjectToClipPos(float4(pp, 1.0));
o.cc = (_deepcolor*pp.y) + 1.0;
o.screenPosition = ComputeScreenPos(o.vertex);
o.noiseUV = TRANSFORM_TEX(v.uv, _SurfaceNoise);
o.distortUV = TRANSFORM_TEX(v.uv, _SurfaceDistortion);
o.CausticsUV = TRANSFORM_TEX(v.uv, _CausticsMap);
o.CausticsdistortUV = TRANSFORM_TEX(v.uv,_CausticsDistortion);
o.viewNormal = COMPUTE_VIEW_NORMAL;
float4x4 mirror_m = unity_ObjectToWorld * _MirrorCameraMatrix * UNITY_MATRIX_P;
o.vertex_mirror = mul(mirror_m, float4(pp, 1.0));
return o;
}
float4 frag (v2f i) : SV_Target
{
float foamDistance = _FoamMaxDistance;
float existingDepth01 = tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPosition)).r;
float existingDepthLinear = LinearEyeDepth(existingDepth01);
float depthDifference = existingDepthLinear - i.screenPosition.w;
float2 CausticsdistortSample = (tex2D(_CausticsDistortion, i.CausticsdistortUV).xy /* 2 - 1*/) * _CausticsDistortionAmount;
float2 myCausticsUV = float2(i.CausticsUV.x + _Time.y *_CausticsScroll_X + CausticsdistortSample.x, i.CausticsUV.y + _Time.y *_CausticsScroll_Y + CausticsdistortSample.y);
float4 CausticsMap = tex2D(_CausticsMap,myCausticsUV);
CausticsMap.rgb *= _CausticsColor.rgb;
//case1
// fixed4 r = tex2D(_ReflectMap, float2(1-((i.vertex.x)/ _ScreenParams.x), (i.vertex.y )/ _ScreenParams.y));
//case2
fixed4 r = tex2D(_ReflectMap, float2(((i.vertex_mirror.x / i.vertex_mirror.w)*0.5 + 0.5), ((i.vertex_mirror.y / i.vertex_mirror.w)*0.5 + 0.5)));
float waterDepthDifference01 = saturate(depthDifference / _DepthMaxDistance);
float4 waterColor = (lerp(_DepthGradientShallow, _DepthGradientDeep, waterDepthDifference01))*i.cc*r;
waterColor.rgb = lerp(waterColor.rgb, CausticsMap.rgb, (CausticsMap.a > _CausticsCutoff ? 1 : 0)*_CausticsColor.a);
float2 distortSample = (tex2D(_SurfaceDistortion, i.distortUV).xy /* 2 - 1*/) * _SurfaceDistortionAmount;
float2 noiseUV = float2(i.noiseUV.x + _Time.y *_SurfaceNoiseScroll_X +distortSample.x, i.noiseUV.y + _Time.y *_SurfaceNoiseScroll_Y +distortSample.y);
float surfaceNoiseSample = tex2D(_SurfaceNoise, noiseUV).r;
float foamDepthDifference01 = saturate(depthDifference / foamDistance);
float surfaceNoiseCutoff = foamDepthDifference01 /* _SurfaceNoiseCutoff*/;
if (_hasSurfaceFoam > 0)surfaceNoiseCutoff *= (_SurfaceNoiseCutoff *_SurfaceFoamDenSity);
float surfaceNoise = smoothstep(surfaceNoiseCutoff - SMOOTHSTEP_AA, surfaceNoiseCutoff + SMOOTHSTEP_AA, surfaceNoiseSample);
float4 surfaceNoiseColor = _FoamColor;
surfaceNoiseColor.a *= surfaceNoise;
//return float4 (existingNormal,1.0);
return alphaBlend(surfaceNoiseColor, waterColor)*_UnifyMapColor;
}
ENDCG
}
}
How can I get Correct UV to assign to _ReflectMap?
//case1 is near but not correct
fixed4 r = tex2D(_ReflectMap, float2(1-((i.vertex.x)/ _ScreenParams.x), (i.vertex.y )/ _ScreenParams.y));
//case2 is totally not correct
fixed4 r = tex2D(_ReflectMap, float2(1 - ((i.vertex_mirror.x / i.vertex_mirror.w)*0.5 + 0.5), 1 - ((i.vertex_mirror.y / i.vertex_mirror.w)*0.5 + 0.5)));
