- 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 () {
}
}