У меня есть этот шейдер, который я портировал из shadertoy в металлический шейдер для iOS. Оригинальный работает отлично, но теперь я получаю странное поведение, когда я переместил его в iOS. В принципе, в течение первых нескольких секунд, когда работает шейдер, все смещается. Я думаю, что это потому, что зеркало на оси X, что верно, но вертикальные координаты также были как-то перевернуты с одной стороны. Может ли кто-нибудь сказать мне, как я должен это исправить?Решение нечетного поведения re: glsl/metal shader. (непреднамеренное преобразование координат)
Оригинал Shadertoy: https://www.shadertoy.com/view/ltl3Dj
Моя версия, превращается в металлический язык затенения:
#include <metal_stdlib>
using namespace metal;
////////////////
///CSB CONSTANTS (not required, just make sure it's handled properly at the bottom)
constant float2 resolution = (1, 1);
constant float contrast = 1.0;
constant float saturation = 1.02;
constant float brightness = 1.5;
struct FloweringQuadVertexToFragmentVariables
{
//basic Active Shader Variables
float4 position [[ position ]];
float2 textureCoordinates;
float time;
//Shader specific variables go here (not required)
};
vertex FloweringQuadVertexToFragmentVariables FloweringQuadVertexShader (constant float4 *positions [[ buffer(0) ]],
constant float2 *textureCoordinates [[ buffer(1) ]],
constant float *shaderFloatZero [[buffer(2)]],
uint vertexID [[ vertex_id ]])
{
FloweringQuadVertexToFragmentVariables output;
//basic variables output here
output.position = positions[vertexID];
output.textureCoordinates = textureCoordinates[vertexID];
output.time = *shaderFloatZero;
//additional variables here
//output
return output;
}
// Remember, can do [color(0)] etc. for rendering to attachments other than just [0]
float3 FloweringContrastSaturationBrightness(float3 color, float brt, float sat, float con)
{
// Increase or decrease theese values to adjust r, g and b color channels seperately
const float AvgLumR = 0.4;
const float AvgLumG = 0.4;
const float AvgLumB = 0.4;
const float3 LumCoeff = float3(0.2125, 0.7154, 0.0721); //luminosity coefficient
float3 AvgLumin = float3(AvgLumR, AvgLumG, AvgLumB);
float3 brtColor = color * brt;
float3 intensity = float3(dot(brtColor, LumCoeff));
float3 satColor = mix(intensity, brtColor, sat);
float3 conColor = mix(AvgLumin, satColor, con);
return conColor;
}
float4 hue(float4 color, float shift) {
const float4 kRGBToYPrime = float4 (0.299, 0.587, 0.114, 0.0);
const float4 kRGBToI = float4 (0.596, -0.275, -0.321, 0.0);
const float4 kRGBToQ = float4 (0.212, -0.523, 0.311, 0.0);
const float4 kYIQToR = float4 (1.0, 0.956, 0.621, 0.0);
const float4 kYIQToG = float4 (1.0, -0.272, -0.647, 0.0);
const float4 kYIQToB = float4 (1.0, -1.107, 1.704, 0.0);
// Convert to YIQ
float YPrime = dot (color, kRGBToYPrime);
float I = dot (color, kRGBToI);
float Q = dot (color, kRGBToQ);
// Calculate the hue and chroma
float hue = atan (Q/ I);
float chroma = sqrt (I * I + Q * Q);
// Make the user's adjustments
hue += shift;
// Convert back to YIQ
Q = chroma * sin (hue);
I = chroma * cos (hue);
// Convert back to RGB
float4 yIQ = float4 (YPrime, I, Q, 0.0);
color.r = dot (yIQ, kYIQToR);
color.g = dot (yIQ, kYIQToG);
color.b = dot (yIQ, kYIQToB);
return color;
}
float2 kale(float2 uv, float angle, float base, float spin) {
float a = atan(uv.y/uv.x)+spin;
float d = length(uv);
a = fmod(a,angle*2.0);
a = abs(a-angle);
uv.x = sin(a+base)*d;
uv.y = cos(a+base)*d;
return uv;
}
float2 rotate(float px, float py, float angle){
float2 r = float2(0);
r.x = cos(angle)*px - sin(angle)*py;
r.y = sin(angle)*px + cos(angle)*py;
return r;
}
float floweringlum(float3 c) {
return dot(c, float3(0.3, 0.59, 0.11));
}
float3 floweringclipcolor(float3 c) {
float l = floweringlum(c);
float n = min(min(c.r, c.g), c.b);
float x = max(max(c.r, c.g), c.b);
if (n < 0.0) {
c.r = l + ((c.r - l) * l)/(l - n);
c.g = l + ((c.g - l) * l)/(l - n);
c.b = l + ((c.b - l) * l)/(l - n);
}
if (x > 1.0) {
c.r = l + ((c.r - l) * (1.0 - l))/(x - l);
c.g = l + ((c.g - l) * (1.0 - l))/(x - l);
c.b = l + ((c.b - l) * (1.0 - l))/(x - l);
}
return c;
}
float3 setfloweringlum(float3 c, float l) {
float d = l - floweringlum(c);
c = c + float3(d);
return floweringclipcolor(c);
}
fragment float4 FloweringQuadFragmentShader(FloweringQuadVertexToFragmentVariables input [[ stage_in ]],
texture2d<float> fragmentTexture [[ texture(0) ]],
sampler samplr [[sampler(0) ]])
{ float timeElapsed = input.time;
float4 textureColor = fragmentTexture.sample(samplr, input.textureCoordinates);
///////
float2 iResolution = (1, 1);
float2 texCoords = input.textureCoordinates;
//float2 p = texCoords.xy/iResolution.xy;
////////
float p = 3.14159265359;
float i = timeElapsed*.5;
float2 uv = texCoords.xy/iResolution.xy*5.0-2.5;
uv = kale(uv, p/6.0,i,i*0.2);
float4 c = float4(1.0);
const float2x2 m = float2x2(float2(sin(uv.y*cos(uv.x+i)+i*0.1)*20.0, -6.0),
float2(sin(uv.x+i*1.5)*3.0,-cos(uv.y-i)*2.0));
uv = rotate(uv.x,uv.y,length(uv)+i*.4);
c.rg = cos(sin(uv.xx+uv.yy)*m-i);
c.b = sin(rotate(uv.x,uv.x,length(uv.xx)*3.0+i).x-uv.y+i);
float4 color = float4(1.0-hue(c,i).rgb,1.0);
////////
float4 finalColor;
float4 FloweringColor;
/*FloweringColor.r = (color.r+(textureColor.r*1.3))/2;
FloweringColor.g = (color.g + (textureColor.g*1.3))/2;
FloweringColor.b = (color.b + (textureColor.b*1.3))/2;
FloweringColor.a = 1.0;*/
float4 cam = textureColor;
float4 overlay = color;
FloweringColor = float4(cam.rgb * (1.0 - overlay.a) + setfloweringlum(overlay.rgb, floweringlum(cam.rgb)) * overlay.a, cam.a);
float3 csbcolor = FloweringContrastSaturationBrightness(FloweringColor.rgb, contrast, saturation, brightness);
float alpha = 1.0;
finalColor = float4(csbcolor.r, csbcolor.g, csbcolor.b, alpha);
return finalColor;//float4(textureColor.a, textureColor.a, textureColor.a, 1.0);
}
Удивительный ответ! Спасибо :) –