這個賞金已經結束。此問題的答案有資格獲得 300聲望獎勵。賞金寬限期將在10 小時后結束。 martega想引起更多人對這個問題的關注。
我正在嘗試在 iPhone 和 Apple 的 Metal API 上自學計算機圖形學的基礎知識。我正在嘗試做一些非常基本的事情,但我有點卡住了。
我想要做的只是“紋理四邊形”。基本上,我制作了一個矩形,并且我有一個覆寫矩形的影像紋理。對于影像紋理僅來自已知格式的影像的基本情況,我可以使其作業,但我無法弄清楚如何使我的代碼更通用并能夠處理不同的格式。
例如,有時影像紋理來自影像檔案,解碼后像素資料為RGB格式。有時,我的影像紋理實際上來自一個視頻幀,其中資料以 YUV 格式存盤。
理想情況下,我想創建某種“采樣器”物件或函式,它可以為特定紋理坐標回傳 RGB 顏色。在我準備渲染的代碼中,這是關于使用哪種格式的背景關系的部分,因此它將有足夠的資訊來確定應該使用哪種型別的采樣器。例如,在視頻幀的情況下,它知道它正在處理一個視頻幀,因此它創建一個 YUV 采樣器并將相關資料傳遞給它。然后從我只想讀取顏色的著色器代碼中,它可以只要求某些特定坐標處的顏色,YUV 采樣器會做適當的作業來計算正確的 RGB 顏色。如果我傳入一個 RGB 采樣器,它只會讀取 RGB 資料而不進行任何型別的計算。
我以為這會很簡單嗎?我覺得這對于處理不同格式、顏色空間或其他格式的紋理的圖形代碼來說是一個常見問題?我錯過了一些明顯的東西嗎?
您如何在不撰寫所有著色器的一堆版本的情況下做到這一點?
uj5u.com熱心網友回復:
以下是將 RGBA 轉換為 YUVA 的函式,反之亦然。
float4 rgba2yuva(float4 rgba)
{
float4 yuva = float4(0.0);
yuva.x = rgba.r * 0.299 rgba.g * 0.587 rgba.b * 0.114;
yuva.y = rgba.r * -0.169 rgba.g * -0.331 rgba.b * 0.5 0.5;
yuva.z = rgba.r * 0.5 rgba.g * -0.419 rgba.b * -0.081 0.5;
yuva.w = rgba.a;
return yuva;
}
float4 yuva2rgba(float4 yuva)
{
float4 rgba = float4(0.0);
rgba.r = yuva.x * 1.0 yuva.y * 0.0 yuva.z * 1.4;
rgba.g = yuva.x * 1.0 yuva.y * -0.343 yuva.z * -0.711;
rgba.b = yuva.x * 1.0 yuva.y * 1.765 yuva.z * 0.0;
rgba.a = yuva.a;
return rgba;
}
我從這里修改了代碼:https : //github.com/libretro/glsl-shaders/blob/master/nnedi3/shaders/
簡單的 OpenGL 著色器很容易移植到 Metal。我幾乎只是將資料型別更改vec4為float4. 如果你想有一個半版,剛剛替補float4了half4。
uj5u.com熱心網友回復:
金屬著色器功能ARK,現在您可以使用@Jeshua Lacock 在兩者之間進行轉換。
// tweak your color offsets as desired
#include <metal_stdlib>
using namespace metal;
kernel void YUVColorConversion(texture2d<uint, access::read> yTexture [[texture(0)]],
texture2d<uint, access::read> uTexture [[texture(1)]],
texture2d<uint, access::read> vTexture [[texture(2)]],
texture2d<float, access::write> outTexture [[texture(3)]],
uint2 gid [[thread_position_in_grid]])
{
float3 colorOffset = float3(0, -0.5, -0.5);
float3x3 colorMatrix = float3x3(
float3(1, 1, 1),
float3(0, -0.344, 1.770),
float3(1.403, -0.714, 0)
);
uint2 uvCoords = uint2(gid.x / 2, gid.y / 2);
float y = yTexture.read(gid).r / 255.0;
float u = uTexture.read(uvCoords).r / 255.0;
float v = vTexture.read(uvCoords).r / 255.0;
float3 yuv = float3(y, u, v);
float3 rgb = colorMatrix * (yuv colorOffset);
outTexture.write(float4(float3(rgb), 1.0), gid);
}
這里有很好的參考,然后你可以構建管道或變體來專門處理你需要的東西,比如這里
#include <metal_stdlib>
#include <simd/simd.h>
#include <metal_texture>
#include <metal_matrix>
#include <metal_geometric>
#include <metal_math>
#include <metal_graphics>
#include "AAPLShaderTypes.h"
using namespace metal;
// Variables in constant address space.
constant float3 lightPosition = float3(0.0, 1.0, -1.0);
// Per-vertex input structure
struct VertexInput {
float3 position [[attribute(AAPLVertexAttributePosition)]];
float3 normal [[attribute(AAPLVertexAttributeNormal)]];
half2 texcoord [[attribute(AAPLVertexAttributeTexcoord)]];
};
// Per-vertex output and per-fragment input
typedef struct {
float4 position [[position]];
half2 texcoord;
half4 color;
} ShaderInOut;
// Vertex shader function
vertex ShaderInOut vertexLight(VertexInput in [[stage_in]],
constant AAPLFrameUniforms& frameUniforms [[ buffer(AAPLFrameUniformBuffer) ]],
constant AAPLMaterialUniforms& materialUniforms [[ buffer(AAPLMaterialUniformBuffer) ]]) {
ShaderInOut out;
// Vertex projection and translation
float4 in_position = float4(in.position, 1.0);
out.position = frameUniforms.projectionView * in_position;
// Per vertex lighting calculations
float4 eye_normal = normalize(frameUniforms.normal * float4(in.normal, 0.0));
float n_dot_l = dot(eye_normal.rgb, normalize(lightPosition));
n_dot_l = fmax(0.0, n_dot_l);
out.color = half4(materialUniforms.emissiveColor n_dot_l);
// Pass through texture coordinate
out.texcoord = in.texcoord;
return out;
}
// Fragment shader function
fragment half4 fragmentLight(ShaderInOut in [[stage_in]],
texture2d<half> diffuseTexture [[ texture(AAPLDiffuseTextureIndex) ]]) {
constexpr sampler defaultSampler;
// Blend texture color with input color and output to framebuffer
half4 color = diffuseTexture.sample(defaultSampler, float2(in.texcoord)) * in.color;
return color;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/399073.html
