- Home /
 
How do I initialize a float texture by script?
My problem is that I want to initialize a texture with vertex positions to feed a shader. I'm thinking of trying a Texture2D with setPixel() but as the docs say there is no float format for creating a texture2D which allows me to use setPixel. Another idea is to use a init shader with a RenderTexture but in a fragment shader I can't know which pixel is being processed, so I wouldn't know which position to write in the texture. My last idea is to generate the float texture with OpenGL calls, but in the GL class docs I couldn't find anything related with glTexImage2D(). I'm new to Unity so any help will be very appreciated.
After some work, I see that the RenderTexture + fragment shader can work if I draw a X*X pixel rect and use uv coords to write to the right place. The only problem that I'm getting right now is how to draw that X*X pixel rect...
Answer by dsilvavini · Feb 11, 2013 at 04:09 AM
The RenderTexture + fragment shader approach have solved the problem. Here's the code to initialize a X*X pixel plane using an orthographic camera (cam in the snippet). The cam orthographic size must be set to dimensions.x/2 and it must render to a dimensions.x*dimensions.y RenderTexture (set in inspector).
 using UnityEngine;
 using System.Collections;
 
 public class EffectScreenQuad : MonoBehaviour
 {
     public Vector2 dimensions; //dimensions.x == dimmensions.y
     public Camera cam;
     
     // Use this for initialization
     void Start ()
     {
         Vector3[] vertices  = new Vector3[4];
         Vector3[] normals   = new Vector3[4];
         Vector2[] uv        = new Vector2[4];
         int[] triangles     = new int[6];
         
         //Create plane vertices that fill a dimensions.x*dimension.y pixels rect
         Vector3 lowerLeftPlaneScreenPos    = new Vector3(0 , 0 , 0);
         Vector3 lowerRightPlaneScreenPos= new Vector3(dimensions.x , 0 , 0);
         Vector3 upperLeftPlaneScreenPos = new Vector3(0 , dimensions.y , 0);
         
         Vector3 lowerLeftPlaneWorldPos  = cam.ScreenToWorldPoint(lowerLeftPlaneScreenPos);
         Vector3 lowerRightPlaneWorldPos = cam.ScreenToWorldPoint(lowerRightPlaneScreenPos);
         Vector3 upperLeftPlaneWorldPos = cam.ScreenToWorldPoint(upperLeftPlaneScreenPos);
         Vector3 heightDelta = (upperLeftPlaneWorldPos - lowerLeftPlaneWorldPos)/2;
         Vector3 widthDelta = (lowerRightPlaneWorldPos - lowerLeftPlaneWorldPos)/2;
         
         vertices[0] = lowerLeftPlaneWorldPos;
         vertices[1] = lowerRightPlaneWorldPos;
         vertices[2] = upperLeftPlaneWorldPos;
         vertices[3] = heightDelta + widthDelta;
         
         Vector3 normal = Vector3.Cross(widthDelta , heightDelta);
         normal.Normalize();
         for (int i = 0; i < 4; i++)
             normals[i] = normal;
 
         uv[0] = Vector2.zero;
         uv[1] = Vector2.right;
         uv[2] = Vector2.up;
         uv[3] = Vector2.right + Vector2.up;
         //Unity3D culls counterclockwise faces...
         triangles[0] = 0;
         triangles[1] = 2;
         triangles[2] = 1;
         triangles[3] = 1;
         triangles[4] = 2;
         triangles[5] = 3;
 
         MeshFilter mesh_filter        = gameObject.GetComponent("MeshFilter") as MeshFilter;
         mesh_filter.mesh = new Mesh ();
         mesh_filter.mesh.vertices     = vertices;
         mesh_filter.mesh.normals       = normals;
         mesh_filter.mesh.uv            = uv;
         mesh_filter.mesh.triangles     = triangles;
     }
     
     // Update is called once per frame
     void Update () {
     
     }
 }
 
              Your answer