- Home /
Setting custom camera projection matrix
Hi. I am trying to set "unity_CameraProjection" parameter of the shader for material to use different FOV but unity prevents me just setting it directly. I know i can set it to a different float4x4 and change it in vertex program but i want this to effect unity's Standart shaders too and i can't access their vertex programs.
Also tried rendering meshes with Graphics.DrawMeshNow with GL.LoadProjectionMatrix(MyCustomProjection) but DrawMeshNow doesn't calculate lightning and DrawMesh not working with GL.LoadProjectionMatrix(MyCustomProjection).
Basically I want to render specific meshes with different FOV without using custom shaders. Any ideas that my noob brain couldn't come with? Thanks.
Update: overriding in vertex program of surface shaders also works but it doesn't change lighting.
#pragma surface surf Standard fullforwardshadows vertex:vert
// ............
float4x4 custom_MatrixVP;
void vert (inout appdata_full v) {
unity_MatrixVP = custom_MatrixVP;
}
Answer by Bunny83 · Mar 01, 2021 at 11:52 PM
The Camera class is the origin for all normal mesh rendering operations. So you should set the projection matrix of your camera. Usually you only have one camera and if that is tagged Main Camera you can get that camera by Camera.main
.
Though if you want to render only certain objects with a different fov, this is kinda tricky and most likely does not work the way you think. You can use two cameras where the second one is rendering over the first one and seperate your geometry by layers and appropriate culling masks. However the result may not be what you think it is. Most lighting calculation would probably break as the two different projections are not really compatible in any way. Keep in mind that the screen only has one depth buffer, one stencil buffer and everything has to be rendered into the same screen buffer.
So your request seems kinda strange and I'm wondering what you think the endresult should look like? What you could do is apply your own additional deformation matrix in a custom shader to your objects since that's essentially what a different fov does. Keep in mind that the fov is a property of the camera and has nothing to do with the actual object being viewed. What exact problem you try to solve with your custom projection matrix and what should the endresult look like?
I already know the two cameras method but I am using stencil write/read with some objects and it just doesn't work with 2 cameras. I've tried trust me. Also it's expensive to use two cameras.
All lighting/geometry calculated on the shader of the object being rendered with using the model view and projection matrices passed to the shader by unity itself internally. And i want to override these matrices for specific objects that uses standart shaders but it seems that's not possible for some reason, unity prevents me to just set them with material.SetMatrix("unity_CameraProjection").
I have already achived the result that i want by passing a custom view * projection matrix to a custom shader and replacing ObjectToClipPos() calculation in vertex program.
I am trying to render environment with FOV 90, gun and the arms with FOV 30 so when the user changes FOV it doesn't affect how the gun looks.
Answer by NeatFreak · Mar 02, 2021 at 11:44 AM
UPDATE: Currently trying to override "UnityShaderVariables.cginc" with a custom version that changes view model matrix from unity_MatrixVP to custom_MatrixVP that is passed from custom script, but still it doesn't seems to work for some reason.
// Base forward pass (directional light, emission, lightmaps, ...)
Pass {
Name "FORWARD"
Tags { "LightMode" = "ForwardBase" }
Blend [_SrcBlend] [_DstBlend]
ZWrite [_ZWrite]
CGPROGRAM
#pragma target 3.0
// -------------------------------------
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
#pragma shader_feature _EMISSION
#pragma shader_feature_local _METALLICGLOSSMAP
#pragma shader_feature_local _DETAIL_MULX2
#pragma shader_feature_local _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature_local _SPECULARHIGHLIGHTS_OFF
#pragma shader_feature_local _GLOSSYREFLECTIONS_OFF
#pragma shader_feature_local _PARALLAXMAP
#pragma multi_compile_fwdbase
#pragma multi_compile_fog
#pragma multi_compile_instancing
// Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.
//#pragma multi_compile _ LOD_FADE_CROSSFADE
#pragma vertex vertBase
#pragma fragment fragBase
#include "OverrideUnityShaderVariables.cginc" // custom include file that overrides matrices
#include "UnityStandardCoreForward.cginc"
ENDCG
}
Also tried overriding unity_CameraProjection and unity_CameraInvProjection within custom include file. Still no results.
Another dead end. Turns out this cginc file cannot be overwritten or discarded from shaders.
it very much can, but requires the shader to be set up in a way that makes it completely independent from anything that's in there, and that usually would be done by defining the stuff you need elsewhere
afaik, certain types of shaders do require it though
Your answer
Follow this Question
Related Questions
Shader Problem 0 Answers
perform action on shader compilation/update 0 Answers
Unity 3d Sprite Shader (How do I limit Max Brightness to 1 with Multiple Lights Hitting) 0 Answers
Stretching when using world coordinates 2 Answers
Shader: How to write a shader that respects sorting order first and then depth 1 Answer