I need to know what the values of the "_Projector" matrix is. In the standard projectors assets there are 2 basic shaders for projectors (blob shadows), and also around the net eg http://en.wikibooks.org/wiki/Cg_Programming/Unity/Projectors They use the (aparently) built-in matrix uniform float4x4 _Projector; I really want to know what the values are, and how unity calculates them. Despite some advice from the IRC, I cannot fathom what it's values are. For example, the most obvious matrix would be something like Code (csharp): Projector P = GetComponent<Projector>(); Matrix4x4 M = Matrix4x4.Perspective(P.fieldOfView, P.aspectRatio, P.nearClipPlane, P.farClipPlane); M *= transform.worldToLocalMatrix; P.material.SetMatrix("_ReplacementProjector", M); But that gives the second pic (First is what it's supposed to look like, using the builtin _Projector) So maybe its something fancy that cameras can do, so add a camera component and use Code (csharp): P.material.SetMatrix("_ReplacementProjector", camera.projectionMatrix); But that gives the third. So I'm proper stumped
The result is the same regardless of using shaderlab Code (csharp): Shader "Projector Shaderlab" { Properties { _ShadowTex ("Cookie", 2D) = "gray" { TexGen ObjectLinear } } Subshader { Pass { Blend Zero SrcAlpha Offset -1, -1 SetTexture [_ShadowTex] { combine texture, ONE - texture Matrix [_Projector] } } } } Or cg Code (csharp): Shader "Projector cg shader test" { Properties { _ShadowTex ("Projected Image", 2D) = "white" {} } SubShader { Pass { Blend Zero OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma debug uniform sampler2D _ShadowTex; uniform float4x4 _ReplacementProjector; struct vertexInput { float4 vertex : POSITION; float3 normal : NORMAL; }; struct vertexOutput { float4 pos : SV_POSITION; float4 posProj : TEXCOORD0; }; vertexOutput vert(vertexInput input) { vertexOutput output; output.posProj = mul(_ReplacementProjector, input.vertex); output.pos = mul(UNITY_MATRIX_MVP, input.vertex); return output; } float4 frag(vertexOutput input) : COLOR { return tex2D(_ShadowTex , float2(input.posProj) / input.posProj.w); } ENDCG } } }
Of course, this would be a rather simple task if ... Material.GetMatrix("_someMatrix"); ...would work properly (usefully) http://docs.unity3d.com/Documentation/ScriptReference/Material.GetMatrix.html
Today i tried implemeting the matrix construction according to this paper... http://csc.lsu.edu/~kooima/pdfs/gen-perspective.pdf ...and while the method is somewhat different, the result is still not appropriate to replace _Projector I would really appreciate input from somene in the know at UT, surely this is a simple question for the people that wrote this functionality?
3-Week bump I've done some other stuff, come back to this problem, still can't get it to work. I get the impression that, although the shader only take a single 4x4 matrix, its actually calculating a different matrix for every GO that the projector shines on, meaning that I can't simply calculate a single projection matrix for the projector GO, which would suck. Alot The end result I'm trying to achieve is having the projectors project using custom matrices like this So althoguh the projector is non-rotated, pointing along the world Z, by controlling the matrix as directed in the paper linked above, I control where the projector shines.
That's right. The projector matrix is function of the game object transform and the projector transform, therefore it is different for every GameObjects.
Code (CSharp): Matrix4x4 P = Matrix4x4.Perspective (projector.fieldOfView, projector.aspectRatio, projector.nearClipPlane, projector.farClipPlane); Matrix4x4 V = Matrix4x4.TRS (new Vector3 (0, 0, 0), Quaternion.identity, new Vector3 (1, 1, -2)) * projector.transform.worldToLocalMatrix; projector.material.SetMatrix("_PVMatrix", P*V); and shader Code (CSharp): Shader"Projector cg shader" { Properties { _ShadowTex ("Projected Image", 2D) = "white" {} } SubShader { Pass { Blend Zero OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag uniform sampler2D _ShadowTex; uniform float4x4 _PVMatrix; struct vertexInput { float4 vertex : POSITION; float3 normal : NORMAL; }; struct vertexOutput { float4 pos : SV_POSITION; float4 posProj : TEXCOORD0; }; vertexOutput vert(vertexInput input) { vertexOutput output; output.posProj = mul(mul(_PVMatrix,_Object2World), input.vertex); output.posProj.xy = output.posProj.xy / output.posProj.w + 0.5; output.pos = mul(UNITY_MATRIX_MVP, input.vertex); return output; } float4 frag(vertexOutput input) : COLOR { return tex2D(_ShadowTex , input.posProj.xy); } ENDCG } } }