Metal / Scenekit – Textura repetitiva en muestra
No estoy seguro de por qué no puedo repetir la textura al usar el shader de fragmento personalizado del cliente.
Aquí está mi fragmento:
fragment float4 bFragment( VertexOut vertexOut [[stage_in]],
texture2d<float, access::sample=""> textureInput [[texture(0)]],)
{
constexpr sampler sampler2d(coord::normalized, address::repeat, filter::linear, address::repeat);
float4 outputColor;
outputColor = textureInput.sample(sampler2d, vertexOut.texCoord);
return float4(outputColor.x , outputColor.y , outputColor.z , 1.0);
}
Así es como paso la textura:
let imageProperty = SCNMaterialProperty(contents: texture)
imageProperty.wrapS = .repeat
imageProperty.wrapT = .repeat
imageProperty.contentsTransform = SCNMatrix4MakeScale(screenRatio * numberOfRepetitionsOnX, numberOfRepetitionsOnX , 1)
node.geometry!.firstMaterial!.setValue(imageProperty, forKey: "textureInput")
La imagen no se repite, solo se sujeta al objeto, sin importar el tamaño de la textura.
Si uso la misma configuración SIN un shader personalizado:
let myMaterial = SCNMaterial()
myMaterial.lightingModel = .constant
myMaterial.diffuse.contents = texture
myMaterial.diffuse.wrapS = .repeat
myMaterial.diffuse.wrapT = .repeat
myMaterial.diffuse.contentsTransform = SCNMatrix4MakeScale(screenRatio * numberOfRepetitionsOnX, numberOfRepetitionsOnX , 1)
node.geometry!.firstMaterial! = myMaterial
La textura se repite correctamente.
Preguntas:
- ¿Qué tengo que cambiar para que sea efectivo el valor de contentsTransform también al usar el sampler en el shader de fragmento personalizado?
- Si eso no es posible, ¿cuál es la manera más fácil de lograrlo? (Escalar, repetir, volver a dibujar la textura no es una opción).
Gracias.</float,>
davy.ai
Basado en el código proporcionado, parece que el problema podría ser con el valor de
contentsTransform
. En el fragment shader personalizado, la textura se pasa comotexture2d
y el muestreador se define conaddress::repeat
tanto para las direccionesS
como para lasT
. Sin embargo, el valor decontentsTransform
solo se aplica al usarSCNMaterialProperty
en el enfoque de shader no personalizado.Para lograr el mismo efecto en el enfoque de shader personalizado, puede pasar el valor de
contentsTransform
como un uniforme y aplicarlo en el fragment shader. Aquí hay un código actualizado del fragment shader que incluye el uniformecontentsTransform
:En este código, el uniforme
contentsTransform
se pasa como un buffer con índice 1 y se aplica a la coordenada de textura antes de muestrear la textura. Los valores de escala y desplazamiento se extraen de la matriz decontentsTransform
y se aplican al valor detexCoord
.Para pasar el valor de
contentsTransform
desde el código Swift, puede agregar el siguiente código:Este código crea un
SCNMatrix4
con los valores de escala y desplazamiento deseados, lo convierte en unSCNMatrix4
, y crea un búfer con ese valor. Luego, puede establecer este búfer como eluniformBuffer
del material que está utilizando el shader personalizado:Esto debería pasar el valor de
contentsTransform
al shader personalizado y aplicarlo a las coordenadas de textura, dando como resultado una textura repetida.</float,>