Hello everyone, I’m new here in the forum, and new to shaders too
I was reading a post about Custom Projection Matrix: First Person Rendering in Unity 5 (writeup) - Unity Engine - Unity Discussions and I thought it’s a great solution for a big problem for everyone trying to develop an FPS on Unity.
This tutorial was written for an older version of Unity (5.4), and I tried to redo it on Unity 5.6, but I’m having several problems that I can not understand why and how to solve
Firstly I edited UnityShaderUtilities.cginc and I added it in my shaders folder
#ifndef UNITY_SHADER_UTILITIES_INCLUDED
#define UNITY_SHADER_UTILITIES_INCLUDED
#include "UnityShaderVariables.cginc"
float4x4 _CustomProjMatrix;
#if defined(FIRST_PERSON)
// Tranforms position from object to homogenous space
inline float4 UnityObjectToClipPos(in float3 pos)
{
float4x4 mvp = mul(mul(_CustomProjMatrix, UNITY_MATRIX_V ), unity_ObjectToWorld);
float4 ret = mul(mvp, float4(pos, 1.0));
//hack to fix vertically flipped vertices post-projection
ret.y *= -1;
//hack to offset depth value to avoid scene geometry intersection
//todo: check if it works in OpenGL?
ret.z *= 0.5;
return ret;
}
#else
// Tranforms position from object to homogenous space
inline float4 UnityObjectToClipPos(in float3 pos)
{
// More efficient than computing M*VP matrix product
return mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, float4(pos, 1.0)));
}
#endif
inline float4 UnityObjectToClipPos(float4 pos) // overload for float4; avoids "implicit truncation" warning for existing shaders
{
return UnityObjectToClipPos(pos.xyz);
}
#endif
And then I added this to the example shader:
#pragma multi_compile __ FIRST_PERSON
Then I followed the steps to define the custom projection matrix
using UnityEngine;
public class SetWeaponProjectionMatrix : MonoBehaviour
{
public Camera sourceCam;
void LateUpdate ()
{
Shader.SetGlobalMatrix("_CustomProjMatrix", sourceCam.projectionMatrix);
}
}
And then for each mesh that uses my custom shader, I’ve added the following script to enable the shader keyword FIRST_PERSON
using UnityEngine;
public class EnableFirstPersonShaderVariant : MonoBehaviour
{
void Awake ()
{
GetComponent<Renderer>().material.EnableKeyword("FIRST_PERSON");
}
}
Following these steps, I should get the same result as in the original post video, but instead I get those results:
The shader is rendering the inside of the weapon, but from the tests I’ve done, it seems to be some problem with the projection matrix (when I remove the keyword “FIRST_PERSON” from the shader, it works normally).
I’d appreciate your help! Thank’s for your time!