0

I use ARKIT to load a plane, and the plane modifies the SCNShaderModifierEntryPointFragment to display the decoded video. However, the rendered video image is too light and lighter than the video rendered using metalLayer. Why is this happening? I also tried to modify SCNShaderModifierEntryPointSurface, set the _surface.diffuse. And I also try use rgb instead of yuv. But still the same.

This should also not because of the light. I try use diffuse.content = image, and it's right.

render in metalLayer render in metalLayer

render in ar enter image description here

I have tried rendering MTLTexture using SCNProgram, shaderModifiers. Render YUV or RGB results, the color is lighter


texture2d textureY;  
texture2d textureUV;  
float3x3 coversionMatrix;  

float3 yuv;  
yuv.x = textureY.sample(textureSampler, _surface.diffuseTexcoord).r;  
yuv.yz = textureUV.sample(textureSampler, _surface.diffuseTexcoord).rg;  

float3 rgb = coversionMatrix * (yuv - offset);  
_output.color = float4(rgb, 1.0);  

//set the shaderModifiers

myMaterial.shaderModifiers = @{ SCNShaderModifierEntryPointFragment : shader};  

fanjianrong
  • 63
  • 1
  • 8

1 Answers1

1

How do you generate the Metal textures? Try to use the "_sRGB" variants of the pixel format, for instance MTLPixelFormatRGBA8Unorm_sRGB instead of MTLPixelFormatRGBA8Unorm.

Alternatively, try converting the final color (the rgb variable in your shader modifier example) to the linear color space as explained in this answer:

static float srgbToLinear(float c) {
    if (c <= 0.04045)
        return c / 12.92;
    else
        return powr((c + 0.055) / 1.055, 2.4);
}
mnuages
  • 13,049
  • 2
  • 23
  • 40
  • I use the CVMetalTextureCacheRef to create MTLTextyre. I have try to use MTLPixelFormatR8Unorm_sRGB instead of MTLPixelFormatR8Unorm, and MTLPixelFormatRG8Unorm_sRGB instead of MTLPixelFormatRG8Unorm. But it display green. – fanjianrong Aug 01 '19 at 06:32
  • It's help for me. Thanks so much – fanjianrong Aug 02 '19 at 07:56