Hey, i’m using depth blended shader as water surface shader (for the edge blending), and i’m trying to render it as reflection (using second camera and code based on Unity MirrorReflection4 script, basically doing inverted culling and custom projection matrix).
It works fine in main camera, however no matter what i do - the depth blending fails in reflected space/texture. I’m using shader replacements for other camera, and i’m feeding custom depth buffer sampler to the surface shader (instead of using _CameraDepthBuffer), but it still doesn’t work.
Do i need to multiply some matrices? Feed custom clipping space position?
Depth blended shader:
[/SIZE]
VertexOutput vert (VertexInput v) {
VertexOutput o = (VertexOutput)0;
o.uv0 = v.texcoord0;
o.pos = UnityObjectToClipPos( v.vertex );
o.projPos = ComputeScreenPos (o.pos);
COMPUTE_EYEDEPTH(o.projPos.z);
return o;
}
float4 frag(VertexOutput i) : COLOR {
float sceneZ = max(0,LinearEyeDepth (UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)))) - _ProjectionParams.g);
float partZ = max(0,i.projPos.z - _ProjectionParams.g);
float4 _WaterTexture_var = tex2D(_WaterTexture,TRANSFORM_TEX(i.uv0, _WaterTexture));
float3 emissive = saturate(( _WaterTexture_var.rgb > 0.5 ? (1.0-(1.0-2.0*(_WaterTexture_var.rgb-0.5))*(1.0-_WaterColor.rgb)) : (2.0*_WaterTexture_var.rgb*_WaterColor.rgb) ));
float3 finalColor = emissive;
return fixed4(finalColor,(_WaterTexture_var.a*saturate((sceneZ-partZ)/_WaterFeather)));
}
Mirror reflection script:
[/SIZE] private static void CAT_MirrorReflectionCalculateMatrix(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;
}
private Vector4 CAT_MirrorReflectionCameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign)
{
Vector3 offsetPos = pos + normal * CAT_MirrorReflectionClipPlaneOffset;
Matrix4x4 m = cam.worldToCameraMatrix;
Vector3 cpos = m.MultiplyPoint3x4(offsetPos);
Vector3 cnormal = m.MultiplyVector(normal).normalized * sideSign;
return new Vector4(cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos, cnormal));
}
// Use this for initialization
void OnEnable () {
Shader.SetGlobalTexture ("_MirrorReflectionTexture", CAT_MirrorReflectionDepthRTT);
CAT_MirrorReflectionCamera.transform.SetPositionAndRotation (transform.position, transform.rotation);
CAT_MirrorReflectionCamera.SetReplacementShader (CAT_UIController.instance.CAT_ReflectionCameraShader, "Mirrorable");
CAT_MirrorReflectionCamera.depthTextureMode = DepthTextureMode.DepthNormals;
CAT_MirrorReflectionCamera.SetTargetBuffers(CAT_MirrorReflectionRTT.colorBuffer, CAT_MirrorReflectionDepthRTT.depthBuffer);
CAT_MirrorReflectionPlaneWorldPosition = transform.position;
CAT_MirrorReflectionPlaneNormal = transform.up;
CAT_MirrorReflectionMagicalFloat = -Vector3.Dot (CAT_MirrorReflectionPlaneNormal, CAT_MirrorReflectionPlaneWorldPosition) - CAT_MirrorReflectionClipPlaneOffset;
CAT_MirrorReflectionMatrix = new Matrix4x4 ();
CAT_MirrorReflectionCalculateMatrix (ref CAT_MirrorReflectionMatrix, new Vector4 (CAT_MirrorReflectionPlaneNormal.x, CAT_MirrorReflectionPlaneNormal.y, CAT_MirrorReflectionPlaneNormal.z, CAT_MirrorReflectionMagicalFloat));
CAT_MirrorReflectionMaterial.SetTexture("_ReflectionTex", CAT_MirrorReflectionRTT);
}
public void OnWillRenderObject() {
// Get data
// Vector3 MirrorReflectionOldCameraPosition = CAT_XriumActiveCamera.transform.position;
CAT_MirrorReflectionCamera.fieldOfView = CAT_XriumActiveCamera.fieldOfView;
CAT_MirrorReflectionCamera.worldToCameraMatrix = CAT_XriumActiveCamera.worldToCameraMatrix * CAT_MirrorReflectionMatrix;
// Set some wiglly-woggly-jiggly-shiggly matrix magic
Vector4 MirroReflectionClipPlane = CAT_MirrorReflectionCameraSpacePlane (CAT_MirrorReflectionCamera, CAT_MirrorReflectionPlaneWorldPosition, CAT_MirrorReflectionPlaneNormal, 0.1f);
CAT_MirrorReflectionCamera.projectionMatrix = CAT_XriumActiveCamera.CalculateObliqueMatrix (MirroReflectionClipPlane);
// Render
GL.invertCulling = true;
Vector3 MirrorReflectionActiveCameraRotationEuler = CAT_XriumActiveCamera.transform.eulerAngles;
CAT_MirrorReflectionCamera.transform.position = CAT_MirrorReflectionMatrix.MultiplyPoint3x4 (CAT_XriumActiveCamera.transform.position);
CAT_MirrorReflectionCamera.transform.eulerAngles = new Vector3 (0, MirrorReflectionActiveCameraRotationEuler.y, MirrorReflectionActiveCameraRotationEuler.z);
if (!CAT_MirrorReflectionCamera.orthographic && CAT_MirrorReflectionCamera.rect.size.sqrMagnitude > 0)
CAT_MirrorReflectionCamera.Render ();
// CAT_MirrorReflectionCamera.transform.position = MirrorReflectionOldCameraPosition;
GL.invertCulling = false;
CAT_XriumController.CAT_XriumUpdateMirrorsTickets--;
}