Search Unity

Returning Float World Coordinates using Shaders

Discussion in 'Shaders' started by danielpsm, May 18, 2017.

  1. danielpsm

    danielpsm

    Joined:
    May 18, 2017
    Posts:
    1
    Hello, I'm new to shaders but not with Unity.
    What I'm trying to do is to get the world positions of each pixel using shaders...
    Then I am returning the result from a shader in an ARGBFloat RenderTexture and copy the values to an array.

    I think it is quite working, but even when I use a texture in float format it clamps the results of the fragment shader in [0,1] format. I came through similar threads and I did find any answer.

    Here is my shader code:

    Code (CSharp):
    1. //Shows the grayscale of the depth from the camera.
    2.  
    3. Shader "Custom/DepthShader"
    4. {
    5.     SubShader
    6.     {
    7.  
    8.         Pass
    9.     {
    10.         ZTest Always  ZWrite On
    11.         Fog{ Mode off }
    12.  
    13.         CGPROGRAM
    14. #pragma target 3.0
    15. #pragma vertex vert
    16. #pragma fragment frag
    17. #include "UnityCG.cginc"
    18.  
    19.     //uniform sampler2D _CameraDepthTexture; //the depth texture
    20.  
    21.     struct v2f
    22.     {
    23.         float4 pos : SV_POSITION;
    24.         float4 projPos : TEXCOORD0; //Screen position of pos
    25.         float4 wPos : TEXCOORD1;
    26.     };
    27.  
    28.     v2f vert(appdata_base v)
    29.     {
    30.         v2f o;
    31.         o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    32.         o.projPos = ComputeScreenPos(o.pos);
    33.         o.wPos = mul(unity_ObjectToWorld, v.vertex);
    34.  
    35.         return o;
    36.     }
    37.  
    38.    
    39.  
    40.     float4 frag(v2f i) : COLOR
    41.     {
    42.         float4 c;
    43.         float x = i.pos.x;
    44.         float y = i.pos.y;
    45.         float z = i.pos.z;
    46.        
    47.         float w = 1;
    48.  
    49.         return float4(x,y,z,1);
    50.     }
    51.  
    52.         ENDCG
    53.     }
    54.     }
    55. }
    And the code that I am using attached to the camera :

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class DepthGrayScale2 : MonoBehaviour
    6. {
    7.  
    8.     Vector3[] positions;
    9.     public float[] radiuses;
    10.     public float[] intensities;
    11.     public float[] array;
    12.  
    13.     public float[,] texture;
    14.  
    15.     public RenderTexture rTex;
    16.  
    17.     public Material mat;
    18.     //    public Material _kernelMaterial;
    19.     public int M;
    20.     public int N;
    21.     public Shader shader;
    22.     Camera mCamera;
    23.     // Use this for initialization
    24.     void Start()
    25.     {
    26.         rTex = CreateBuffer();
    27.         mat = CreateMaterial(shader);
    28.         mCamera = this.GetComponent<Camera>();
    29.         mCamera.SetReplacementShader(shader, "");
    30.         mCamera.targetTexture = rTex;
    31.         mCamera.depthTextureMode = DepthTextureMode.Depth;
    32.     }
    33.  
    34.     float[] DecodeFloatTexture()
    35.     {
    36.         Texture2D decTex = new Texture2D(rTex.width, rTex.height, TextureFormat.RGBAFloat, false);
    37.         RenderTexture.active = rTex;
    38.         decTex.ReadPixels(new Rect(0, 0, rTex.width, rTex.height), 0, 0);
    39.         decTex.Apply();
    40.         RenderTexture.active = null;
    41.         Color[] colors = decTex.GetPixels();
    42.        
    43.         float[] results = new float[colors.Length * 4];
    44.         Vector4 point = new Vector4();
    45.         for (int i = 0; i < colors.Length; i++)
    46.         {
    47.             results[i * 4] = colors[i].r;
    48.             results[i * 4 + 1] = colors[i].g;
    49.             results[i * 4 + 2] = colors[i].b;
    50.             results[i * 4 + 3] = colors[i].a;
    51.             point = new Vector4(colors[i].r, colors[i].g, colors[i].b, colors[i].a);
    52.         }
    53.         return results;
    54.     }
    55.  
    56.     float[] DecodeFloatTexture(RenderTexture tex)
    57.     {
    58.         Texture2D decTex = new Texture2D(tex.width, tex.height, TextureFormat.RGBAFloat, false);
    59.         RenderTexture.active = tex;
    60.         decTex.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0);
    61.         decTex.Apply();
    62.         RenderTexture.active = null;
    63.         Color[] colors = decTex.GetPixels();
    64.        
    65.         float[] results = new float[colors.Length * 4];
    66.         Vector4 point = new Vector4();
    67.         for (int i = 0; i < colors.Length; i++)
    68.         {
    69.             results[i * 4] = colors[i].r;
    70.             results[i * 4 + 1] = colors[i].g;
    71.             results[i * 4 + 2] = colors[i].b;
    72.             results[i * 4 + 3] = colors[i].a;
    73.             point = new Vector4(colors[i].r, colors[i].g, colors[i].b, colors[i].a);
    74.         }
    75.         return results;
    76.     }
    77.  
    78.     // Update is called once per frame
    79.     void OnRenderImage(RenderTexture source, RenderTexture destination)
    80.     {
    81.         Graphics.Blit(source, destination);
    82.         GameObject obj = GameObject.Find("SQUARE");
    83.         obj.GetComponent<Renderer>().material.mainTexture = mCamera.targetTexture;
    84.         array = DecodeFloatTexture(mCamera.targetTexture);
    85.  
    86.         float max = 0;
    87.         float min = -10;
    88.         for (int i = 0; i < array.Length; i++)
    89.         {
    90.             if (max > array[i])
    91.                 max = array[i];
    92.             if (min <= array[i] && array[i] != 0)
    93.                 min = array[i];
    94.         }
    95.  
    96.         Debug.Log("max = " + max + " min =" + min);
    97.     }
    98.  
    99.  
    100.  
    101.  
    102.  
    103.  
    104.     RenderTexture CreateBuffer()
    105.     {
    106.         var buffer = new RenderTexture(M, N, 0, RenderTextureFormat.ARGBFloat);
    107.         buffer.hideFlags = HideFlags.DontSave;
    108.         buffer.filterMode = FilterMode.Point;
    109.         buffer.wrapMode = TextureWrapMode.Repeat;
    110.      
    111.         return buffer;
    112.     }
    113.  
    114.     Material CreateMaterial(Shader shader)
    115.     {
    116.         var material = new Material(shader);
    117.         material.hideFlags = HideFlags.DontSave;
    118.         return material;
    119.     }
    120. }
    121.  
    Anyone has any idea of how to return the "full" float coordinates to the rendertexture ? Any helpThanks for the help