2016-10-19 1 views
1

사람들이 부동 소수점 텍스처에 대해 많이 논하는 것 같지 않습니다. 몇 가지 계산을 수행 한 다음 그 결과를 다른 표면 쉐이더 (특정 변형을 얻기 위해)에 전달했습니다. 멋지다. 쉐이더에서 결과를 소화하면 CPU가 그 값을 가져와야한다. 그래서 난 부동 소수점 텍스처를 채우는 Graphics.Blit를 호출 한 직후 결과와 함께 float [] 배열을 얻습니다. 어떻게이 일을 성취 할 수 있습니까?Unity 3D에서 RGBAFloat 텍스처의 부동 소수점 값을 읽음

사이드 노트 : 지금까지이 방법을 사용하여 본 유일한 사람은 Keijiro입니다 (예 : Kvant Wall). 다른 출처가 있다면 알려 주시면 감사하겠습니다.

덧붙여서, 계산 쉐이더와 OpenCL 및 CUDA가 있음을 알고 있습니다. 이것이 지금 필요한 방법입니다.

+0

내가 누락되었지만 Texture2D.ReadPixels에서 필요한 기능을 제공하지 않습니까? – Bart

+0

@Bart 이봐, 난 그 어떤 texture2D (여전히 FloatARGB 형식)으로 RenderTexture 결과를 얻을 수 있지만, 할 ReadPixels를 사용할 수 있습니까? GetPixels을 사용할 수 없기 때문에 색상 배열을 반환하고 값이 잘릴 수 있습니다. 나는 GetRawTextureData를보고있다. 나는 그것을 가지고 어딘가에 도착할 것이라고 생각한다. – SteakOverflow

+0

흠, 나는보고를해야하지만합니다 (Color32 대안에 반대)을 전체 정밀도 부동 소수점 결과를 얻을 수 없습니다에는 getPixels합니까? – Bart

답변

0

그래서이 솔루션을 생각해 냈습니다. 우리에게 필요한 것은 플로트가 아닌 경우

float[] DecodeFloatTexture() 
{ 
    Texture2D decTex = new Texture2D(resultBuffer.width, resultBuffer.height, TextureFormat.RGBAFloat, false); 
    RenderTexture.active = resultBuffer; 
    decTex.ReadPixels(new Rect(0, 0, resultBuffer.width, resultBuffer.height), 0, 0); 
    decTex.Apply(); 
    RenderTexture.active = null; 
    Color[] colors = decTex.GetPixels(); 
    // HERE YOU CAN GET ALL 4 FLOATS OUT OR JUST THOSE YOU NEED. 
    // IN MY CASE ALL 4 VALUES HAVE A MEANING SO I'M GETTING THEM ALL. 
    float[] results = new float[colors.Length*4]; 
    for(int i=0; i<colors.Length; i++) 
    { 
     results[i * 4] = colors[i].r; 
     results[i * 4 + 1] = colors[i].g; 
     results[i * 4 + 2] = colors[i].b; 
     results[i * 4 + 3] = colors[i].a; 
    } 
    return results; 
} 

또한, GetRawTextureData을 위해 (당신이 쉐이더에서 전달하는 데이터에 약간의 유연성을 제공 System.BitConverter와 새로운 유형 바이트로 변환 다음에 사용할 수 있습니다 프래그먼트 쉐이더가 반을 출력하는 경우 예 4). 첫 번째 방법이 더 좋지만 float이 필요한 경우.

float[] DecodeFloatTexture() 
{ 
    Texture2D decTex = new Texture2D(resultBuffer.width, resultBuffer.height, TextureFormat.RGBAFloat, false); 
    RenderTexture.active = resultBuffer; 
    decTex.ReadPixels(new Rect(0, 0, resultBuffer.width, resultBuffer.height), 0, 0); 
    decTex.Apply(); 
    RenderTexture.active = null; 
    byte[] bytes = decTex.GetRawTextureData(); 
    float[] results = new float[resultBuffer.width * resultBuffer.height]; 
    for (int i = 0; i < results.Length; i++) 
    { 
     int byteIndex = i * 4; 
     byte[] localBytes = new byte[] { bytes[i], bytes[i + 1], bytes[i + 2], bytes[i + 3] }; // converts 4 bytes to a float 
     results[i] = System.BitConverter.ToSingle(localBytes, 0); 
    } 
    return results; 
}