Projector and Unity

Home Forums Syphon Syphon Implementations – User Projector and Unity

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #4598
    pymenvert
    Participant

    Hello all,

    One more thank for this amasing software.

    I have a question about Syphon inside Unity.
    Do you know if it’s possible to assign a Syphon Texture to a projector inside Unity and how ?
    I’ve try lot of solution but no way…
    It’s very important for my project.

    I’ve the last syphon framework and plugin.

    Thank you for your help.

    pym

    #4599
    Brian Chasalow
    Participant

    hey there- Brian Chasalow here, I’ve been working on the Unity implementation. i am 99% certain that you can, but you would have to modify the syphonclientbridge to get the texture ID of the projector’s material, as a projector is not a ‘standard renderer’ like most other objects.
    you’d need to use the projector.material.mainTexture i think.

    so, wherever in the syphonClientBridge it refers to mainTexture, switch it with the projector’s material instead of the renderer.material

    to get the projector’s material and native texture id: (untested code, warning)
    Projector proj = GetComponent<Projector>();
    proj.material.mainTexture.GetNativeTextureID();

    keep me updated with your progress! next week I can help you more but I’m out of town right now. good luck,
    brian

    #4600
    pymenvert
    Participant

    Thanks Brian for this way…

    I’ve modified the SyphonClientBridge like that :

    using UnityEngine;
    using System.Collections;
    using System.Runtime.InteropServices;
    
    public class SyphonClientBridge : MonoBehaviour
    {
            public int desiredWidth = 1024;
            public int desiredHeight = 768;
            private Texture2D _texture;
    
            // Frees the Syphon Server and clears our Unity Plugin's GL resources
            [DllImport ("SyphonUnityPlugin")]
    	private static extern void syphonClientDestroyResources();
    
    	// Syphon Client Update Texture takes in a texture from Unity, and populates it with the contents of a
    	// Syphon Server. This also lazily inits the server for you, ensuring the proper OpenGL context is set.
    	[DllImport ("SyphonUnityPlugin")]
    	private static extern void syphonClientUpdateTexture(int nativeTexture, int width, int height);
    
    	// Use this for initialization
    	void Awake ()
    	{
    		_texture = new Texture2D(desiredWidth, desiredHeight, TextureFormat.ARGB32, false);
    		//_texture = new Cubemap (128, TextureFormat.ARGB32, false);
    		_texture.Apply(false);
    
    		Projector proj = gameObject.GetComponent<Projector>();
    
    		proj.material.mainTexture = _texture;
    		//proj.material.mainTexture.cookie = _texture;
    	/*	if(renderer) {
    			renderer.material.mainTexture = _texture;
    			//proj.material.mainTexture = _texture;
    		}*/
    
    	}
    
    	static protected Material lineMaterial;
    	static protected void CreateLineMaterial() {
    		if( !lineMaterial ) {
    			lineMaterial = new Material( "Shader "Lines/Colored Blended" {" +
    				"SubShader { Pass { " +
    				" Blend SrcAlpha OneMinusSrcAlpha " +
    				" ZWrite Off "  +
    				"} } }" );
    			lineMaterial.hideFlags = HideFlags.HideAndDontSave;
    			lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave;
    		}
    	}        
    
            // YOU MUST USE ON RENDER OBJECT FOR UNITY CLIENT.
            void OnRenderObject ()
            {
                    // Unity 3.0 has GetNativeTextureID, which returns the texture ID.
                    // 2.x requires us to call GetInstanceID instead.
    //              #if UNITY_3     
    
                    CreateLineMaterial();
                    lineMaterial.SetPass(0);
    
                            syphonClientUpdateTexture(_texture.GetNativeTextureID(), _texture.width, _texture.height);
    //              #elif UNITY_2
    //                      syphonClientUpdateTexture(_texture.GetInstanceID());
    //              #endif
            }
    
            void OnPostRender() {
                    CreateLineMaterial();
                    lineMaterial.SetPass( 0 );
            }
    
            public void cleanup(){
                            syphonClientDestroyResources();
            }
    
            void OnDisable ()
            {
                    GL.InvalidateState();
                    Destroy(_texture);
                    cleanup();
            }
    
    }

    Now, it works with a projector’s GameObject but I don’t know if it’s a clean code.

    But, an instance of syphon client is mapped on each face of Cube.
    like this screen shot :
    http://www.heberger-image.fr/images/67697_Syphon_cube.png.html

    I won’t that.
    I would like to have one instance of Syphon Client mapped on all the structure (2 Cubes for example).

    I don’t know if the problem come from projector’s shaders or SyphonClientBridge.

    I’m trying to include mainTexture in the projector>light shaders but no way.
    Perhaps create a syphon>projector shaders…
    But I don’t understand how works the syphon shaders.

    Can you help me please..

    Thanks in advance
    pym

    #4601
    Brian Chasalow
    Participant

    there are a number of settings that make a texture repeat like that, the most obvious is the ‘repeat’ setting of the texture’s wrap mode : http://unity3d.com/support/documentation/ScriptReference/Texture-wrapMode.html

    but it also has to do with the UV’s of the model itself. the built-in cube is set up to repeat on each face like that.

    from your screenshot, it looks more like you’re using syphon to receive a texture source on the cubes, not as a projector- but it’s hard to tell what’s going on from the screenshot.
    if you can post a small example scene (in a zip file) i can take a look.

    #4602
    pymenvert
    Participant

    hi Brian,

    you can download the project here :

    http://www.megaupload.com/?d=PWIPTG0H

    thanks

    #4603
    Brian Chasalow
    Participant

    Solved- my mistake earlier, it was a bad suggestion to use mainTexture- the Projector shaders use “_ShadowTex” in their shaders instead of _MainTex, so you need to access their textures differently.

    First, use the Projector/Multiply or Projector/Light shader. Second, add the Falloff texture to the falloff texture of the shader (just like in the prefab Unity provides)

    Then do this:

    void Awake ()
    {
    _texture = new Texture2D(desiredWidth, desiredHeight, TextureFormat.ARGB32, false);
    _texture.Apply(false);
    Projector proj = gameObject.GetComponent<Projector>();
    _texture.wrapMode = TextureWrapMode.Clamp;
    proj.material.SetTexture(“_ShadowTex”, _texture);
    }

    everything else should be the same/ just work.

    #4604
    pymenvert
    Participant

    Hello,

    now, projector is working correctly.
    It just have a default ratio.
    I have tried different configuration for explain the problem.
    You can see here :
    http://www.fichier-pdf.fr/2011/02/02/issue-syphon-projector/

    and if you want, you can download a small scene here :
    http://www.megaupload.com/?d=T1AHCV3Y

    Thank you for your help

    #4605
    Brian Chasalow
    Participant

    I couldn’t pinpoint your problem, but it probably has to do with the fact that Unity internally uses power of two texture sizes for everything. What I’d suggest is, for instance, to never use 1024 x 768 as the ‘desired’ size in syphon, and instead use 1024 x 1024. it will scale to your surface, then your can resize the aspect ratio of surfaces appropriately. This may be turn out to be an issue with projectors, which do not necessarily conform to surface UV’s in the same way that regular textures do.

    From Aras : http://forum.unity3d.com/threads/18607-POT-and-NPOT-textures-problem
    “And do not worry about hardware support; we do store textures at NPOT size (to save space), but at load time we create a texture that is next power of two, and pad that texture with dummy pixels (and if original NPOT texture is DXT compressed, we blit the DXT compressed blocks and fill the rest with dummy DXT blocks – so the resulting texture is still DXT compressed). And then we do some magic so that GUI that uses that texture is still always referencing the correct portion of that “padded up” texture.”

Viewing 8 posts - 1 through 8 (of 8 total)
  • You must be logged in to reply to this topic.