CustomMaterial QML Type
Componente base para crear materiales personalizados utilizados para sombrear modelos. Más...
| Import Statement: | import QtQuick3D |
| Inherits: |
Propiedades
- alwaysDirty : bool
- destinationAlphaBlend : enumeration
(since 6.7) - destinationBlend : enumeration
- fragmentShader : url
- lineWidth : real
- shadingMode : enumeration
- sourceAlphaBlend : enumeration
(since 6.7) - sourceBlend : enumeration
- vertexShader : url
Descripción detallada
El material personalizado permite utilizar código shader personalizado para un material, permitiendo la programabilidad a nivel de shader gráfico. Se puede proporcionar un sombreador de vértices, de fragmentos o ambos. Las propiedades vertexShader y fragmentShader son URLs, referenciando archivos que contienen fragmentos de shaders, y funcionan de forma muy similar a ShaderEffect o Image.source. Sólo los esquemas file y qrc son compatibles con materiales personalizados. También es posible omitir el esquema file, permitiendo especificar una ruta relativa de forma conveniente. Dicha ruta se resuelve de forma relativa a la ubicación del componente (el archivo .qml ).
Para obtener una guía de iniciación a los materiales personalizados, consulte la página Materiales programables, efectos, geometría y datos de textura.
Introducción
Considere las siguientes versiones de la misma escena. A la izquierda, el cilindro utiliza un material incorporado, no programable. Tales materiales son configurables a través de una amplia gama de propiedades, pero no hay más control sobre los shaders que se generan bajo el capó. A la derecha, el mismo cilindro se asocia ahora con un CustomMaterial que hace referencia a los fragmentos de sombreado de vértices y fragmentos proporcionados por la aplicación. Esto permite insertar lógica personalizada específica de la aplicación en el sombreador de vértices para transformar la geometría y determinar ciertas propiedades de color de forma personalizada en el sombreador de fragmentos. Como se trata de un material personalizado de shaded, el cilindro sigue participando normalmente en la iluminación de la escena.
View3D { anchors.fill: parent PerspectiveCamera { id: camera position: Qt.vector3d(0, 0, 600) } camera: camera DirectionalLight { position: Qt.vector3d(-500, 500, -100) color: Qt.rgba(0.2, 0.2, 0.2, 1.0) ambientColor: Qt.rgba(0.1, 0.1, 0.1, 1.0) } Model { source: "#Cylinder" eulerRotation: Qt.vector3d(30, 30, 0) scale: Qt.vector3d(1.5, 1.5, 1.5) materials: [ DefaultMaterial { diffuseColor: Qt.rgba(0, 1, 0, 1) } ] } } | View3D { anchors.fill: parent PerspectiveCamera { id: camera position: Qt.vector3d(0, 0, 600) } camera: camera DirectionalLight { position: Qt.vector3d(-500, 500, -100) color: Qt.rgba(0.2, 0.2, 0.2, 1.0) ambientColor: Qt.rgba(0.1, 0.1, 0.1, 1.0) } Model { source: "#Cylinder" eulerRotation: Qt.vector3d(30, 30, 0) scale: Qt.vector3d(1.5, 1.5, 1.5) materials: [ CustomMaterial { vertexShader: "material.vert" fragmentShader: "material.frag" property real uTime property real uAmplitude: 50 NumberAnimation on uTime { from: 0; to: 100; duration: 10000; loops: -1 } } ] } } |
Supongamos que los fragmentos del shader en material.vert y material.frag son los siguientes:
void MAIN()
{
VERTEX.x += sin(uTime + VERTEX.y) * uAmplitude;
} | void MAIN()
{
BASE_COLOR = vec4(0.0, 1.0, 0.0, 1.0);
} |
Observa como uTime y uAmplitude son propiedades del elemento CustomMaterial. Pueden cambiar valores y animarse normalmente, los valores serán expuestos a los shaders automáticamente sin ninguna acción adicional del desarrollador.
El resultado es un cilindro que anima sus vértices:

Dos tipos de materiales personalizados
Hay dos tipos principales de materiales personalizados. Esto se especifica mediante la propiedad shadingMode. En los materiales personalizados unshaded el sombreador de fragmentos produce un único color vec4, ignorando luces, sondas de luz y sombras en la escena. En los materiales de shaded se espera que el shader implemente ciertas funciones y trabaje con variables incorporadas para tener en cuenta la contribución de la iluminación y las sombras.
La elección por defecto suele ser un material sombreado, esto se refleja en el valor por defecto de la propiedad shadingMode. Esto se ajusta a los materiales que necesitan transformar vértices u otros datos entrantes de la geometría, o determinar valores como BASE_COLOR o EMISSIVE_COLOR de forma personalizada, quizás muestreando SCREEN_TEXTURE o DEPTH_TEXTURE, mientras siguen recibiendo contribuciones de luz y sombra de la escena. Además, estos materiales también pueden anular y reimplementar las ecuaciones utilizadas para calcular las contribuciones de las luces direccionales, puntuales y otras. Los fragmentos de sombreado proporcionados por la aplicación son modificados en gran medida por el motor 3D de Qt Quick con el fin de proporcionar las características, como la iluminación, que tienen los materiales estándar.
Los materiales sin sombreado son útiles cuando el aspecto del objeto viene determinado completamente por el código de sombreado personalizado. Los shaders para tales materiales reciben adiciones mínimas por el motor, y por lo tanto es completamente hasta el shader para determinar el color del fragmento final. Esto da más libertad, pero también limita las posibilidades de integración con otros elementos de la escena, como las luces.
Nota: El código del sombreador siempre se proporciona utilizando GLSL al estilo Vulkan, independientemente de la API gráfica utilizada por Qt en tiempo de ejecución.
Nota: El código de sombreado de vértices y fragmentos proporcionado por el material no son sombreadores GLSL completos por sí mismos. Más bien, proporcionan un conjunto de funciones, que luego son modificadas con más código shader por el motor.
Exposición de datos a los sombreadores
Las propiedades dinámicas del CustomMaterial se pueden cambiar y animar utilizando QML y Qt Quick, y los valores se exponen automáticamente a los shaders. Esto en la práctica es muy similar ShaderEffect. La siguiente lista muestra cómo se asignan las propiedades:
- bool, int, real -> bool, int, float
- QColor color -> vec4, y el color se convierte a lineal, asumiendo el espacio sRGB para el valor de color especificado en QML. Los colores Qt incorporados, como también están en espacio de color sRGB, y la misma conversión se realiza para todas las propiedades de color de DefaultMaterial y , por lo que este comportamiento de CustomMaterial coincide con ellos. A diferencia de , para la linealización 3D es esencial ya que normalmente se realizará tonemapping en la escena 3D.
"green"PrincipledMaterial Qt Quick Qt Quick - QRect QRectF, -> vec4 rect
- QPoint QPointF, , , , -> vec2 point QSize QSizeF size
- QVector2D vector2d -> vec2
- QVector3D, vector3d -> vec3
- QVector4D, vector4d -> vec4
- QMatrix4x4, matrix4x4 -> mat4
- QQuaternion, quaternion -> vec4, valor escalar es
w - TextureInput -> sampler2D o samplerCube, dependiendo de si se utiliza Texture o CubeMapTexture en la propiedad texture del TextureInput. Establecer la propiedad enabled a false lleva a exponer una textura ficticia al shader, lo que significa que los shaders siguen siendo funcionales pero muestrearán una textura con contenido de imagen negra opaca. Presta atención al hecho de que las propiedades para los muestreadores siempre deben hacer referencia a un objeto TextureInput, no a un Texture directamente. En lo que respecta a las propiedades de Texture, las relacionadas con la fuente, el mosaico y el filtrado son las únicas que se tienen en cuenta de forma implícita con los materiales personalizados, ya que el resto (como las transformaciones UV) depende de los sombreadores personalizados para que las implementen como consideren oportuno.
Nota: Cuando un uniforme referenciado en el código del shader no tiene una propiedad correspondiente, causará un error de compilación del shader al procesar el material en tiempo de ejecución. Hay algunas excepciones a esto, como los uniformes sampler, que obtienen una textura ficticia cuando no hay una propiedad QML correspondiente, pero como regla general, todos los uniformes y samplers deben tener una propiedad correspondiente declarada en el objeto CustomMaterial.
Materiales personalizados sin sombreado
A continuación se muestra un ejemplo de material personalizado unshaded.
CustomMaterial { // These properties are automatically exposed to the shaders property real time: 0.0 property real amplitude: 5.0 property real alpha: 1.0 property TextureInput tex: TextureInput { enabled: true texture: Texture { source: "image.png" } } shadingMode: CustomMaterial.Unshaded sourceBlend: alpha < 1.0 ? CustomMaterial.SrcAlpha : CustomMaterial.NoBlend destinationBlend: alpha < 1.0 ? CustomMaterial.OneMinusSrcAlpha : CustomMaterial.NoBlend cullMode: CustomMaterial.BackFaceCulling vertexShader: "customshader.vert" fragmentShader: "customshader.frag" }
Con el ejemplo anterior, los fragmentos de sombreado de vértices y fragmentos de unshaded podrían tener el siguiente aspecto. Nótese como los shaders no declaran, ni deben declarar, uniformes o entradas de vértices ya que de eso se encarga Qt al ensamblar el código final del shader.
VARYING vec3 pos;
VARYING vec2 texcoord;
void MAIN()
{
pos = VERTEX;
pos.x += sin(time * 4.0 + pos.y) * amplitude;
texcoord = UV0;
POSITION = MODELVIEWPROJECTION_MATRIX * vec4(pos, 1.0);
}VARYING vec3 pos;
VARYING vec2 texcoord;
void MAIN()
{
vec4 c = texture(tex, texcoord);
FRAGCOLOR = vec4(pos.x * 0.02, pos.y * 0.02, pos.z * 0.02, alpha) * c;
}Están disponibles las siguientes palabras clave especiales en mayúsculas:
- MAIN -> el nombre del punto de entrada en el fragmento de sombreado de vértices o fragmentos debe ser siempre
MAIN. Proporcionar esta función es obligatorio en los fragmentos de shaders para materiales personalizados sin sombreado. - VARYING -> declara una salida del vertex shader o una entrada al fragment shader
- POSITION -> vec4, la salida del vertex shader
- FRAGCOLOR -> vec4, la salida del fragment shader. Disponible sólo para materiales personalizados sin sombreado.
- VERTEX -> vec3, la posición del vértice en el sombreador de vértices.
- NORMAL -> vec3, la normal del vértice en el sombreador de vértices. Cuando la malla del modelo asociado no proporciona normales, el valor es vec3(0.0).
- UV0 -> vec2, el primer conjunto de coordenadas de textura en el sombreador de vértices. Cuando la malla del modelo asociado no proporciona coordenadas de textura, el valor es vec2(0.0).
- UV1 -> vec2, el segundo conjunto de coordenadas de textura en el sombreador de vértices. Cuando la malla del modelo asociado no proporciona un segundo conjunto de coordenadas de textura, el valor es vec2(0.0).
- COLOR -> vec4, el color del vértice en el sombreador de vértices. Cuando la malla del modelo asociado no proporciona colores por vértice, el valor es vec4(1.0).
- TANGENT -> vec3, tangente en el sombreador de vértices. Cuando la malla del modelo asociado no proporciona datos tangentes, el valor es vec3(0.0).
- BINORMAL -> vec3, binormal en el sombreador de vértices. Cuando la malla del modelo asociado no proporciona datos binormales, el valor es vec3(0.0).
- JOINTS -> ivec4, índices de juntas en el sombreador de vértices. Cuando la malla para el modelo asociado no proporciona datos de índices de articulaciones, el valor es ivec4(0).
- PESOS -> vec4, pesos de las juntas en el sombreador de vértices. Cuando la malla para el modelo asociado no proporciona datos de pesos de articulaciones, el valor es vec4(0.0).
- MORPH_POSITION(n) -> vec3, la n+1ªposición del objetivo morph en el sombreador de vértices. El modelo asociado debe proporcionar los datos apropiados.
- MORPH_NORMAL(n) -> vec3, la n+1ªnormal del objetivo morph en el sombreador de vértices. El modelo asociado debe proporcionar los datos apropiados.
- MORPH_TANGENT(n) -> vec3, el n+1ºobjetivo morph tangente en el sombreador de vértices. El modelo asociado debe proporcionar los datos apropiados.
- MORPH_BINORMAL(n) -> vec3, el n+1ºobjetivo morph binormal en el sombreador de vértices. El modelo asociado debe proporcionar los datos apropiados.
- MODELVIEWPROJECTION_MATRIX -> mat4, la matriz modelo-vista-proyección. Las matrices de proyección siempre siguen las convenciones de OpenGL, con una transformación incorporada para la dirección del eje Y y la profundidad del clip, dependiendo de la API gráfica utilizada en tiempo de ejecución.
- VIEWPROJECTION_MATRIX -> mat4, la matriz de proyección de la vista
- PROJECTION_MATRIX -> mat4, la matriz de proyección
- INVERSE_PROJECTION_MATRIX -> mat4, la matriz de proyección inversa
- VIEW_MATRIX -> mat4, la matriz de vista (cámara)
- MODEL_MATRIX -> mat4, la matriz del modelo (mundo)
- NORMAL_MATRIX -> mat3, la matriz normal (la transpuesta de la inversa de la parte superior izquierda 3x3 de la matriz del modelo)
- BONE_TRANSFORMS -> mat4[], la matriz de las matrices de los huesos del modelo
- BONE_NORMAL_TRANSFORMS -> mat3[], el array de las matrices normales de los huesos del modelo (la transpuesta de la inversa de la parte superior izquierda 3x3 de las matrices de cada hueso)
- MORPH_WEIGHTS -> float[], el array de los pesos morph. El modelo asociado debe proporcionar los datos adecuados. Por seguridad, QT_MORPH_MAX_COUNT se define al tamaño de este array.
- CAMERA_POSITION -> vec3, la posición de la cámara en el espacio global
- CAMERA_DIRECTION -> vec3, el vector de direccion de la camara
- CAMERA_PROPERTIES -> vec2, los valores del clip cercano y lejano de la cámara
- POINT_SIZE -> float, sólo escribible en el sombreador de vértices. Cuando se renderiza geometría con una topología de puntos, el sombreador de vértices personalizado debe establecerlo en 1.0 u otro valor, tanto en materiales personalizados sombreados como no sombreados. Consulte PrincipledMaterial::pointSize para obtener más información sobre la compatibilidad con tamaños distintos de 1.
Materiales personalizados sombreados
Un material shaded augments el código shader que sería generado por un PrincipledMaterial. A diferencia de los materiales sin sombrear, que proporcionan casi toda la lógica para las funciones principales del vertex y fragment shader por sí mismos, evitando añadir código generado para iluminación, sombreado, iluminación global, etc., los materiales sombreados permiten que la generación de shaders se produzca normalmente, como si el CustomMaterial fuera un PrincipledMaterial. Se espera que los fragmentos de shaders de vértices y fragmentos proporcionen funciones opcionales que luego se invocan en determinados puntos, dándoles la posibilidad de personalizar los colores y otros valores que luego se utilizan para calcular la iluminación y el color final del fragmento.
En lugar de implementar sólo una función MAIN, el sombreador de fragmentos de un material personalizado sombreado puede implementar múltiples funciones. Todas las funciones, incluida MAIN, son opcionales en los materiales sombreados personalizados. Un fragmento de sombreado vacío o, incluso, no especificar las propiedades vertexShader o fragmentShader también puede ser perfectamente válido.
Fragmentos de sombreado de vértices en un material personalizado sombreado
Las siguientes funciones pueden implementarse en un fragmento de sombreador de vértices:
void MAIN()Cuando está presente, esta función es llamada para establecer el valor dePOSITION, la salida vec4 del sombreador de vértices, y, opcionalmente, para modificar los valores deVERTEX,COLOR,NORMAL,UV0,UV1,TANGENT,BINORMAL,JOINTS, yWEIGHTS. A diferencia de los materiales no sombreados, escribir en ellos tiene sentido porque los valores modificados se tienen en cuenta en el resto del código del sombreador generado (mientras que para los materiales no sombreados no se genera código de sombreado adicional). Por ejemplo, si el sombreador de vértices personalizado desplaza los vértices o las normales, querrá almacenar los valores modificados enVERTEXoNORMAL, para conseguir después cálculos de iluminación correctos. Adicionalmente, la función puede escribir en variables definidas conVARYINGpara pasar datos interpolados al fragment shader. Cuando esta función o una redefinición dePOSITIONno está presente,POSITIONse calcula basándose enVERTEXyMODELVIEWPROJECTION_MATRIX, tal y como haría un PrincipledMaterial.Ejemplo, confiando tanto en propiedades QML expuestas como uniformes, y también pasando datos al fragment shader:
VARYING vec3 vNormal; VARYING vec3 vViewVec; void MAIN() { VERTEX.x += sin(uTime * 4.0 + VERTEX.y) * uAmplitude; vNormal = normalize(NORMAL_MATRIX * NORMAL); vViewVec = CAMERA_POSITION - (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; POSITION = MODELVIEWPROJECTION_MATRIX * vec4(VERTEX, 1.0); }Nota: En el ejemplo anterior, asignar un valor a
POSITIONes opcional, ya que el uso en este caso es idéntico al comportamiento por defecto.
Nota: Para pasar datos sin interpolación del vértice a la etapa de fragmento, añada la palabra clave flat antes del tipo en las declaraciones de VARYING.
Fragmentos de sombreado de fragmentos en un material personalizado sombreado
Las siguientes funciones pueden implementarse en un fragmento de sombreado de fragmentos:
void MAIN()Cuando está presente, esta función es llamada para establecer los valores de las variables especiales escribiblesBASE_COLOR,METALNESS,ROUGHNESS,SPECULAR_AMOUNT, NORMAL, CLEARCOAT_FRESNEL_POWER, CLEARCOAT_FRESNEL_SCALE, CLEARCOAT_FRESNEL_BIAS, CLEARCOAT_AMOUNT, CLEARCOAT_ROUGHNESS, CLEARCOAT_NORMAL, FRESNEL_BIAS, FRESNEL_SCALE, FRESNEL_POWER, IOR,TRANSMISSION_FACTOR, THICKNESS_FACTOR, ATTENUATION_COLOR, ATTENUATION_DISTANCE yOCCLUSION_AMOUNT.Un caso de uso común es establecer el valor de
BASE_COLORbasándose en el muestreo de una textura, ya sea un mapa de color base,SCREEN_TEXTURE, o algún otro tipo de fuente. Esto puede ser relevante y conveniente especialmente cuando no se implementan funciones personalizadas del procesador de luz. EstablecerBASE_COLOR.aa algo distinto del valor por defecto 1.0 permite afectar al valor alfa final del fragmento. (tenga en cuenta que esto a menudo requerirá también activar la mezcla alfa en sourceBlend y destinationBlend)Otro escenario es cuando no hay una función personalizada
SPECULAR_LIGHTproporcionada, o cuando hay una sonda de luz establecida en el SceneEnvironment. El metal, la rugosidad, y otros valores que afectan el cálculo de la contribución especular se pueden establecer enMAINa sus valores personalizados deseados.La función puede escribir en las siguientes variables especiales. Los valores que se escriben en ellas normalmente se codifican o se calculan basándose en propiedades QML asignadas a uniformes. La semántica es idéntica a la de PrincipledMaterial.
- vec4
BASE_COLOR- El color base y el valor alfa del material. Corresponde a built-in materials' color property. Cuando las funciones del procesador de luz no están implementadas, puede ser conveniente establecer un color base personalizado enMAINporque entonces se tiene en cuenta en los cálculos de iluminación por defecto. El valor por defecto esvec4(1.0), es decir, blanco con un alfa de 1.0. El valor alfa afecta al alfa final del fragmento. El valor alfa final es la opacidad del objeto (modelo) multiplicada por el color base alfa. Cuando se especifica el valor directamente en el código del shader, sin depender de los valores uniformes expuestos desde las propiedades de color en QML, tenga en cuenta que depende del shader realizar la conversión de sRGB a lineal, si es necesario. Por ejemplo, suponiendo unvec3 coloryfloat alphaesto se puede lograr de la siguiente manera:float C1 = 0.305306011; vec3 C2 = vec3(0.682171111, 0.682171111, 0.682171111); vec3 C3 = vec3(0.012522878, 0.012522878, 0.012522878); BASE_COLOR = vec4(rgb * (rgb * (rgb * C1 + C2) + C3), alpha);
- vec3
EMISSIVE_COLOR- El color de la auto-iluminación. Corresponde al color emisivo de los materiales incorporados que es combinado por built-in materials's emissiveFactor property y built-in materials's emissiveMap property. El valor por defecto esvec3(0.0). Al especificar el valor directamente en el código del shader, sin depender de los valores uniformes expuestos desde las propiedades de color en QML, tenga en cuenta que depende del shader realizar la conversión de sRGB a lineal, si es necesario. - float
IOREspecifica el índice de refracción del material. Un valor típico, y también el predeterminado, es1.5, ya que es el que utilizaría PrincipledMaterial. - float
TRANSMISSION_FACTOREspecifica la cantidad de translucidez. Un valor típico, sería1.0y también el valor por defecto, es0.0ya que es lo que usaría un PrincipledMaterial. - float
THICKNESS_FACTOREspecifica la cantidad de grosor del material translúcido. Un valor típico, sería10.0y también el valor por defecto, es0.0ya que es lo que usaría un PrincipledMaterial. - vec3
ATTENUATION_COLOREspecifica el cambio de color del material translúcido por distancia. Un valor típico, seríavec3(1.0, 0.0, 0.0)y también el valor por defecto, esvec3(1.0)ya que es lo que usaría un PrincipledMaterial. - float
ATTENUATION_DISTANCEEspecifica la atenuación por distancia del cambio de color del material translúcido. Un valor típico, sería100.0y también el valor por defecto, es0.0ya que es lo que usaría un PrincipledMaterial. - float
METALNESSCantidad de metalness en el rango 0.0 - 1.0. El valor por defecto es 0. Debe establecerse en un valor distinto de cero para que tenga efecto. - float
ROUGHNESSValor de rugosidad en el rango 0.0 - 1.0. El valor por defecto es 0. - float
CLEARCOAT_FRESNEL_POWEREspecifica el poder fresnel de la capa de barniz. Un valor típico, y también el valor por defecto, es5.0ya que es el que utilizaría un PrincipledMaterial. - float
CLEARCOAT_FRESNEL_SCALEEspecifica la escala de fresnel de la capa de barniz. Un valor típico, y también el predeterminado, es1.0, ya que es el que utilizaría PrincipledMaterial. - float
CLEARCOAT_FRESNEL_BIASEspecifica el sesgo de fresnel de la capa de barniz. Un valor típico, y también el predeterminado, es0.0, ya que es el que utilizaría PrincipledMaterial. - float
CLEARCOAT_AMOUNTEspecifica la cantidad de capa de barniz sobre el material. Un valor típico, sería1.0y también el valor por defecto, es0.0ya que es lo que usaría un PrincipledMaterial. - float
CLEARCOAT_ROUGHNESSEspecifica la rugosidad de la capa de barniz. Un valor típico, sería1.0para una capa de barniz totalmente borrosa y también el valor por defecto, es0.0ya que es lo que utilizaría un PrincipledMaterial. - vec3
CLEARCOAT_NORMAL- La normal de la capa transparente que proviene del sombreador de vértices en el espacio global. Aunque esta propiedad tiene el mismo valor inicial queVAR_WORLD_NORMAL, sólo cambiar el valor deCLEARCOAT_NORMALtendrá efecto sobre la normal de la capa de capa transparente. - float
FRESNEL_POWEREspecifica la potencia de fresnel. Un valor típico, y también el predeterminado, es5.0ya que es el que utilizaría PrincipledMaterial. - float
FRESNEL_SCALEEspecifica la escala de fresnel. Un valor típico, y también el predeterminado, es1.0, ya que es el que utilizaría PrincipledMaterial. - float
FRESNEL_BIASEspecifica el sesgo de fresnel. Un valor típico, y también el predeterminado, es0.0, ya que es el que utilizaría PrincipledMaterial. - float
SPECULAR_AMOUNTCantidad especular en el rango 0.0 - 1.0. El valor por defecto es0.5, que coincide con PrincipledMaterial::specularAmount. Debe establecerse en un valor distinto de cero para que tenga efecto. - float
OCCLUSION_AMOUNTEspecifica el factor AO. Un valor típico, y también el predeterminado, es1.0ya que es el que utilizaría PrincipledMaterial. - vec3
NORMAL- La normal que proviene del sombreador de vértices en el espacio del mundo. Aunque esta propiedad tiene el mismo valor inicial queVAR_WORLD_NORMAL, sólo cambiando el valor deNORMALtendrá efecto sobre la iluminación. - vec3
TANGENT- La tangente que proviene del sombreador de vértices en el espacio global. Este valor se ajusta potencialmente para la doble cara. - vec3
BINORMAL- La binormal que proviene del sombreador de vértices en el espacio global. Este valor está potencialmente ajustado para doble cara. - vec2
UV0- El primer conjunto de coordenadas de textura del sombreador de vértices. Esta propiedad es de solo lectura en el fragment shader. - vec2
UV1- El segundo conjunto de coordenadas de textura del sombreador de vértices. Esta propiedad es de sólo lectura en el sombreador de fragmentos.
Nota: A diferencia de los materiales no sombreados, el fragmento
MAINpara un material sombreado no tiene control directo sobreFRAGCOLOR. Más bien, son los valoresDIFFUSEySPECULARescritos en las funciones del procesador de luz los que deciden cual es el color final del fragmento. Cuando no se implementa una función de procesador de luz, los cálculos de sombreado por defecto pertinentes se realizan como con un PrincipledMaterial, teniendo en cuentaBASE_COLORy otros valores de la lista anterior.Un ejemplo de sombreador de material personalizado sencillo y metálico podría ser el siguiente:
void MAIN() { METALNESS = 1.0; ROUGHNESS = 0.5; FRESNEL_POWER = 5.0; }Otro ejemplo, donde el color base y el alfa se establecen muestreando una textura:
VARYING vec2 texcoord; void MAIN() { BASE_COLOR = texture(uColorMap, texcoord); }- vec4
void AMBIENT_LIGHT()Cuando está presente, esta función es llamada una vez por cada fragmento. La tarea de la función es añadir la contribución total del ambiente a una variable especial escribibleDIFFUSE. Por supuesto, se puede optar por calcular un valor diferente, o no tocarDIFFUSEen absoluto (para ignorar por completo la iluminación ambiental). Cuando esta función no está presente en absoluto, la contribución ambiental se calcula normalmente, como lo haría un PrincipledMaterial.La función puede escribir en las siguientes variables especiales:
- vec3
DIFFUSEAcumula las contribuciones de luz difusa, por fragmento. Las funciones del procesador de luz normalmente le añadirán (+=), ya que sobrescribiendo el valor se perdería la contribución de otras luces.
La función puede leer las siguientes variables especiales, además de las matrices (como,
MODEL_MATRIX) y vectores (como,CAMERA_POSITION) uniformes de la tabla anterior:- vec3
TOTAL_AMBIENT_COLORLa contribución ambiental total en la escena.
Ejemplo:
void AMBIENT_LIGHT() { DIFFUSE += TOTAL_AMBIENT_COLOR; }- vec3
void DIRECTIONAL_LIGHT()Cuando está presente, esta función es llamada para cada luz direccional activa en la escena para cada fragmento. La tarea de la función es añadir la contribución difusa a una variable especial escribibleDIFFUSE. La función también puede elegir no hacer nada, en cuyo caso se ignoran las contribuciones difusas de las luces direccionales. Cuando la función no está presente en absoluto, las contribuciones difusas de las luces direccionales se acumulan normalmente, como haría un PrincipledMaterial.La función puede escribir en las siguientes variables especiales:
- vec3
DIFFUSEAcumula las contribuciones difusas de la luz, por fragmento.
- Las funciones del procesador de luz normalmente le añadirán (
+=
- , ya que sobreescribiendo el valor se perdería la contribución de otras luces.
La función puede leer las siguientes variables especiales, además de las matriciales (como,
)MODEL_MATRIXy vectoriales (como,
)CAMERA_POSITIONuniformes de la tabla anterior:
- vec3
LIGHT_COLORColor de luz difusa. - float
SHADOW_CONTRIBContribución de sombra, ó 1.0 si no hay sombra en absoluto o no recibe sombras. - vec3
TO_LIGHT_DIRVector que apunta hacia la fuente de luz. - vec3
NORMALEl vector normal en el espacio del mundo. - vec4
BASE_COLOREl color base y el valor alfa del material. - float
METALNESSLa cantidad de Metalness. - float
ROUGHNESSLa cantidad de Roughness.
Ejemplo:
void DIRECTIONAL_LIGHT() { DIFFUSE += LIGHT_COLOR * SHADOW_CONTRIB * vec3(max(0.0, dot(normalize(VAR_WORLD_NORMAL), TO_LIGHT_DIR))); }- vec3
void POINT_LIGHT()Cuando está presente, esta función es llamada para cada punto de luz activo en la escena para cada fragmento. La tarea de la función es añadir la contribución difusa a una variable especial escribibleDIFFUSE. La función también puede elegir no hacer nada, en cuyo caso se ignoran las contribuciones difusas de las luces puntuales. Cuando la función no está presente en absoluto, las contribuciones difusas de las luces puntuales se acumulan normalmente, como lo haría un PrincipledMaterial.La función puede escribir en las siguientes variables especiales:
- vec3
-
DIFFUSEAcumula las contribuciones de luz difusa, por fragmento
. La función puede leer las siguientes variables especiales, además de los uniformes matriciales (como,
)MODEL_MATRIXy vectoriales (como,
)CAMERA_POSITIONde la tabla anterior:
- vec3
LIGHT_COLORColor de luz difusa. - float
- Atenuación de la luz.
- float
SHADOW_CONTRIBContribución de sombra, o 1.0 si no hay ninguna sombra o no recibe sombras. vec3
- Vector que apunta hacia la fuente de luz.
- vec3
NORMALEl vector normal en el espacio del mundo. - vec4
BASE_COLOREl color base y el valor alfa del material. - float
METALNESSLa cantidad de Metalness. - float
ROUGHNESSLa cantidad de Roughness.
Ejemplo:
void POINT_LIGHT() { DIFFUSE += LIGHT_COLOR * LIGHT_ATTENUATION * SHADOW_CONTRIB * vec3(max(0.0, dot(normalize(VAR_WORLD_NORMAL), TO_LIGHT_DIR))); }void SPOT_LIGHT()Cuando está presente, esta función es llamada para cada foco de luz activo en la escena para cada fragmento. La tarea de la función es añadir la contribución difusa a una variable especial escribibleDIFFUSE. La función también puede elegir no hacer nada, en cuyo caso las contribuciones difusas de los focos se ignoran. Cuando la función no está presente en absoluto, las contribuciones difusas de las luces puntuales se acumulan normalmente, como haría un PrincipledMaterial.La función puede escribir en las siguientes variables especiales:
- vec3
-
DIFFUSEAcumula las contribuciones de luz difusa, por fragmento
. La función puede leer las siguientes variables especiales, además de los uniformes matriciales (como,
)MODEL_MATRIXy vectoriales (como,
)CAMERA_POSITIONde la tabla anterior:
- vec3
LIGHT_COLORColor de luz difusa. - float
- Atenuación de la luz.
- float
SHADOW_CONTRIBContribución de sombra, o 1.0 si no hay sombra en absoluto o no recibe sombras. - vec3
TO_LIGHT_DIRVector que apunta hacia la fuente de luz. - float
SPOT_FACTORFactor de luz puntual. - vec3
NORMALEl vector normal en el espacio del mundo. - vec4
BASE_COLOREl color base y el valor alfa del material. - float
METALNESSLa cantidad de Metalness. - float
ROUGHNESSLa cantidad de Roughness.
Ejemplo:
void SPOT_LIGHT() { DIFFUSE += LIGHT_COLOR * LIGHT_ATTENUATION * SPOT_FACTOR * SHADOW_CONTRIB * vec3(max(0.0, dot(normalize(VAR_WORLD_NORMAL), TO_LIGHT_DIR))); }void SPECULAR_LIGHT()Cuando está presente, esta función es llamada para cada luz activa en la escena para cada fragmento. La tarea de la función es añadir la contribución especular a una variable especial escribibleSPECULAR. La función también puede elegir no hacer nada, en cuyo caso se ignoran las contribuciones especulares de las luces. Cuando la función no está presente en absoluto, las contribuciones especulares de las luces se acumulan normalmente, como lo haría un PrincipledMaterial.La función puede escribir en las siguientes variables especiales:
- vec3
SPECULARAcumula las contribuciones especulares de la luz, por framento.
- Las funciones del procesador de luz normalmente le añadirán (
+=
- , ya que sobreescribiendo el valor se perdería la contribución de otras luces.
La función puede leer las siguientes variables especiales, además de los uniformes matriciales (como,
)MODEL_MATRIXy vectoriales (como,
CAMERA_POSITION) de la tabla anterior:- vec3
LIGHT_COLORColor de luz especular. - float
LIGHT_ATTENUATIONAtenuación de luz. Para luces direccionales el valor es 1.0. - Para luces puntuales el valor es el mismo que
LIGHT_ATTENUATION * SPOT_FACTORdevoid SPOT_LIGHT(). - float
SHADOW_CONTRIBContribución de sombra, o 1.0 si no hay sombra en absoluto o no recibe sombras. vec3
- vec3
- Contribución Fresnel del cálculo Fresnel incorporado.
- vec3
TO_LIGHT_DIRVector apuntando hacia la fuente de luz. - vec3
NORMALEl vector normal en el espacio del mundo. - vec4
BASE_COLOREl color base y el valor alpha del material. - float
METALNESSLa cantidad de Metalness. - float
ROUGHNESSLa cantidad de Roughness. - float
SPECULAR_AMOUNTLa cantidad especular. Este valor estará entre 0.0 y 1.0 será el mismo valor establecido en la función personalizadaMAIN. Este valor será útil para calcular las contribuciones de Fresnel cuando no se utilice la contribución de Fresnel incorporada proporcionada porFRESNEL_CONTRIB
.void SPECULAR_LIGHT() { vec3 H = normalize(VIEW_VECTOR + TO_LIGHT_DIR); float cosAlpha = max(0.0, dot(H, normalize(NORMAL))); float shine = pow(cosAlpha, exp2(15.0 * (1.0 - ROUGHNESS) + 1.0) * 0.25); SPECULAR += shine * LIGHT_COLOR * FRESNEL_CONTRIB * SHADOW_CONTRIB * LIGHT_ATTENUATION; }void POST_PROCESS()Cuando está presente, esta función se llama al final de la tubería de fragmentos. La tarea de la función es finalizarCOLOR_SUMcon los términos difusos, especulares y emisivos finales. A diferencia deFRAGCOLORpara un material sin sombreado,COLOR_SUMserá automáticamente tonemapped antes de ser escrito en el framebuffer. Para propósitos de depuración a veces es útil dar salida a un valor que no debe ser tratado como un color. Para evitar que el tonemapping distorsione este valor se puede desactivar estableciendo la propiedad tonemapMode aTonemapModeNoneLa función puede escribir en las siguientes variables especiales:
- vec4
COLOR_SUMla salida del fragment shader.
- El valor por defecto es vec4(DIFFUSE.rgb + SPECULAR + EMISSIVE, DIFFUSE.a)
La función puede leer las siguientes variables especiales.
- vec4
DIFFUSEEl término difuso - final del fragment pipeline. vec3
SPECULAREl término especular final del fragment pipeline. - vec3
EMISSIVEEl término emisivo final del fragment pipeline. vec
-
UV0- El primer - conjunto de coordenadas de textura del sombreador de vértices
- .
- vec2
UV1- El segundo conjunto de coordenadas de textura del sombreador de vértices.
void POST_PROCESS() { float center_x = textureSize(SCREEN_TEXTURE, 0).x * 0.5; if (gl_FragCoord.x > center_x) COLOR_SUM = DIFFUSE; else COLOR_SUM = vec4(EMISSIVE, DIFFUSE.a); }- vec4
void IBL_PROBE()Cuando está presente, esta función es llamada para IBL (Iluminación Basada en Imágenes). La tarea de la función es añadir las contribuciones difusa y especular de IBL a las variables especiales escribiblesDIFFUSEySPECULAR. La función puede escribir en las siguientes variables especiales:
- vec3
DIFFUSEAcumula las contribuciones de luz difusa, por fragmento. - vec3
SPECULARAcumula las contribuciones de luz especular, por fragmento.
La función puede leer las siguientes variables especiales.
- vec4
BASE_COLOREl color base y el valor alfa del material. - float
AO_FACTOREl factor de oclusión en el espacio de la pantalla. - float
SPECULAR_AMOUNTLa cantidad especular. - float
ROUGHNESSEl término emisivo final de la canalización del fragmento. - vec3
NORMALEl vector normal en el espacio del mundo. - vec3
VIEW_VECTORApunta hacia la cámara. - mat3
IBL_ORIENTATIONLa orientación de la sonda de luz. Proviene de SceneEnvironment::probeOrientation
.- vec3
void IBL_PROBE() { vec3 smpDir = IBL_ORIENTATION * NORMAL; DIFFUSE += AO_FACTOR * BASE_COLOR.rgb * textureLod(IBL_TEXTURE, smpDir, IBL_MAXMIPMAP).rgb; }
LIGHT_ATTENUATION TO_LIGHT_DIR LIGHT_ATTENUATION FRESNEL_CONTRIB Variables personalizadas entre funciones
Variables adicionales pueden ser entregadas desde la función PRINCIPAL a las otras. La palabra clave SHARED_VARS puede utilizarse para definir nuevas variables personalizadas. Se puede acceder a estas variables definidas por el usuario con SHARED.<nombre de variable>.
Por ejemplo, un material personalizado sombreado puede obtener un valor compartido en la función PRINCIPAL y utilizarlo en otras funciones.
SHARED_VARS {
vec3 colorThreshold;
};
void MAIN()
{
BASE_COLOR = texture(baseColorMap, UV0);
SHARED.colorThreshold = texture(thresholdMap, UV0).rgb;
}
void DIRECTIONAL_LIGHT()
{
if (DIFFUSE >= SHARED.colorThreshold) {
DIFFUSE = SHARED.colorThreshold;
return;
}
DIFFUSE += LIGHT_COLOR * SHADOW_CONTRIB;
}Nota: SHARED puede ser escrito en todas las funciones sin POST_PROCESS pero es seguro escribirlo en MAIN y leerlo en las otras funciones.
Nota: Un caso de uso recomendado para escribir SHARED en funciones LIGHT es resetearlo primero en MAIN y luego acumularlo en cada función LIGHT.
SHARED_VARS {
float sheenIntensity;
float sheenRoughness;
vec3 sheenColor;
vec3 outSheenColor;
};
void MAIN()
{
...
vec4 tex = texture(uSheenMap, UV0);
SHARED.sheenColor = tex.rgb;
SHARED.sheenIntensity = tex.a;
SHARED.sheenRoughness = uSheenRoughness;
SHARED.outSheenColor = vec3(0.0);
}
void SPECULAR_LIGHT()
{
SHARED.outSheenColor += ...;
}
void POST_PROCESS()
{
COLOR_SUM = DIFFUSE + SPECULAR + EMISSIVE + SHARED.outSheenColor;
}Nota: MAIN se llama antes que otras, y POST_PROCESS después de todas las demás, pero no hay garantía de ningún otro orden para procesadores ligeros.
Palabras clave especiales adicionales
El código del sombreador de fragmentos personalizado puede acceder libremente a los uniformes (como, CAMERA_DIRECTION o CAMERA_POSITION), y a las variaciones pasadas desde el sombreador de vértices personalizado. Además, hay una serie de variaciones incorporadas disponibles como palabras clave especiales. Algunas de ellas son opcionales, en el sentido de que un sombreador de vértices MAIN puede calcularlas y transferirlas por sí mismo, pero para reducir la duplicación de datos, los sombreadores de fragmentos también pueden basarse en ellas. Estas funciones están disponibles en las funciones del procesador de luz y en el fragment MAIN.
- vec3
VAR_WORLD_NORMAL- Normal interpolada transformada porNORMAL_MATRIX. - vec3
VAR_WORLD_TANGENT- Tangente interpolada transformada porMODEL_MATRIX. - vec3
VAR_WORLD_BINORMAL- Binormal interpolada transformada porMODEL_MATRIX - vec3
NORMAL- A diferencia deVAR_WORLD_NORMAL, que es la normal interpolada tal cual, este valor se ajusta potencialmente para la doble cara: al renderizar con el culling desactivado, la normal se invertirá según sea necesario. Por lo tanto, se recomienda utilizarNORMALen lugar deVAR_WORLD_NORMALpara que la iluminación y otros cálculos se comporten correctamente con todos los modos de culling. - vec3
TANGENT- Al igual queNORMAL, este valor se ajusta potencialmente para la doble cara: cuando se renderiza con el culling desactivado, la tangente se invertirá según sea necesario. - vec3
BINORMAL- Al igual queNORMAL, este valor se ajusta potencialmente a la doble cara: cuando se renderiza con la función de selección desactivada, la binormal se invierte según sea necesario. - vec3
VAR_WORLD_POSITION- Posición interpolada del vértice en el espacio global ((MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz) - vec4
VAR_COLOR- El color interpolado del vértice cuando se proporcionan colores en la malla.vec4(1.0)en caso contrario. - vec3
VIEW_VECTOR- Apunta hacia la cámara. Se trata del vectorCAMERA_POSITION - VAR_WORLD_POSITIONnormalizado. - vec4
FRAGCOORD- Contiene las coordenadas relativas a la ventana del fragmento actual. - float
FRAMEBUFFER_Y_UP- El valor es1cuando el eje Y apunta hacia arriba en el sistema de coordenadas para framebuffers (texturas), lo que significa que(0, 0)es la esquina inferior izquierda. El valor es-1cuando el eje Y apunta hacia abajo, siendo(0, 0)la esquina superior izquierda. Estas diferencias en las API gráficas subyacentes no afectan a la mayoría de los materiales personalizados. Una excepción notable es el muestreo deSCREEN_TEXTUREcon coordenadas de textura no basadas enFRAGCOORD. Dado que la orientación deSCREEN_TEXTUREestá ligada a la API gráfica subyacente por naturaleza, el uso de coordenadas de textura de una malla puede necesitar ajustes apropiados en la coordenada Y.Por ejemplo, el siguiente fragment shader, adecuado para mallas Rectangle o Cube, mostrará los objetos opacos de la escena en el modelo:
VARYING vec2 texcoord; void MAIN() { vec2 screencoord = texcoord; if (FRAMEBUFFER_Y_UP < 0.0) // effectively: if not OpenGL screencoord.y = 1.0 - screencoord.y; BASE_COLOR = texture(SCREEN_TEXTURE, screencoord); }Cuando se muestrean texturas distintas de
SCREEN_TEXTURE, yDEPTH_TEXTURE, o cuando se utilizaFRAGCOORDpara calcular la coordenada de textura (que sería el caso de uso típico para acceder a las texturas de pantalla y profundidad), no es necesario realizar dicho ajuste. - float
NDC_Y_UP- El valor es1cuando el eje Y apunta hacia arriba en el espacio de coordenadas normalizado del dispositivo, y-1cuando el eje Y apunta hacia abajo. Y apuntando hacia abajo es el caso cuando el renderizado ocurre con Vulkan. La mayoría de los materiales no necesitan preocuparse por esto, pero ser capaz de bifurcarse basándose en esto puede ser útil en ciertos casos de uso avanzados. - float
NEAR_CLIP_VALUE- El valor es-1para cuando el rango del plano de recorte empieza en-1y va hasta1. Esto es así cuando se utiliza OpenGL para el renderizado. Para otros backends de renderizado el valor de esta propiedad será0lo que significa que el rango del plano de recorte es de0a1. Este valor es útil con ciertas técnicas que involucran elDEPTH_TEXTUREPor ejemplo, el siguiente fragment shader demuestra una técnica para reconstruir la posición de un valor desde el buffer de profundidad para determinar la distancia desde la posición actual que se está renderizando. Cuando se utiliza en combinación con
INVERSE_PROJECTION_MATRIXel valor de profundidad necesita estar en coordenadas de dispositivo normalizadas por lo que es importante asegurarse de que el rango del valor de profundidad refleja eso. CuandoNEAR_CLIP_VALUEes-1entonces el valor de profundidad se escala para estar entre-1y1.void MAIN() { vec2 screen_uv = FRAGCOORD.xy / vec2(textureSize(SCREEN_TEXTURE, 0)); float depth = texture(DEPTH_TEXTURE, screen_uv).r; if (NEAR_CLIP_VALUE < 0.0) // effectively: if opengl depth = depth * 2.0 - 1.0; vec4 unproject = INVERSE_PROJECTION_MATRIX * vec4(screen_uv, depth, 1.0); depth = (unproject.xyz / unproject.w).z; float viewVectorZ = (VIEW_MATRIX * vec4(VAR_WORLD_POSITION, 1.0)).z; depth = viewVectorZ - depth; BASE_COLOR = vec4(depth, depth, depth, 1.0); } - float
IBL_EXPOSE- La cantidad de luz emitida por la sonda de luz. Proviene de SceneEnvironment::probeExposure.DIFFUSE += AO_FACTOR * IBL_EXPOSE * BASE_COLOR.rgb * textureLod(IBL_TEXTURE, NORMAL, IBL_MAXMIPMAP).rgb;
- float
IBL_HORIZON- El valor de corte horizontal de las reflexiones del entorno de la mitad inferior. Proviene de Horizon Cut-Off pero remapeado a [-1, 0).vec3 diffuse += AO_FACTOR * IBL_EXPOSE * BASE_COLOR.rgb * textureLod(IBL_TEXTURE, NORMAL, IBL_MAXMIPMAP).rgb; if (IBL_HORIZON > -1.0) { float ctr = 0.5 + 0.5 * IBL_HORIZON; float vertWt = smoothstep(ctr * 0.25, ctr + 0.25, NORMAL.y); float wtScaled = mix(1.0, vertWt, IBL_HORIZON + 1.0); diffuse *= wtScaled; } - float
IBL_MAXMIPMAP- El nivel máximo de mipmap de IBL_TEXTURE.
Instanciación
Cuando se realiza un renderizado en instancias, algunas de las palabras clave anteriores no se aplican. Las siguientes palabras clave sólo están disponibles con instanciación:
INSTANCE_MODEL_MATRIX-> mat4, sustitución deMODEL_MATRIX, incluida la transformación de instanciación.INSTANCE_MODELVIEWPROJECTION_MATRIX-> mat4, reemplazo deMODELVIEWPROJECTION_MATRIX, incluida la transformación de instanciación.INSTANCE_COLOR-> vec4, el color de la instancia: debe combinarse conCOLOR.INSTANCE_DATA-> vec4, los datos personalizados de la instancia.INSTANCE_INDEX-> int, el número de instancia y el índice de la tabla de instanciación.
Pantalla, profundidad y otras texturas
El pipeline de renderizado puede exponer un número de texturas a los shaders de materiales personalizados con contenido de pases de renderizado especiales. Esto se aplica tanto a los materiales personalizados sombreados como a los no sombreados.
Por ejemplo, un shader puede querer acceder a una textura de profundidad que contenga el contenido del buffer de profundidad para los objetos opacos de la escena. Esto se consigue muestreando DEPTH_TEXTURE. Tal textura no se genera normalmente, a menos que haya una necesidad real para ello. Por lo tanto, la presencia de las siguientes palabras clave en el sombreador de vértices o fragmentos también actúa como un interruptor para optar por los pases -potencialmente caros- para generar la textura en cuestión. (por supuesto, podría ser que algunas de estas ya estuvieran habilitadas debido a otros ajustes, como los parámetros de oclusión ambiental en SceneEnvironment o debido a un efecto de post-procesado que dependa de la textura de profundidad, en cuyo caso las texturas en cuestión se generan independientemente del material personalizado y por lo tanto el muestreo de estas texturas especiales en el material no tiene ningún coste adicional aparte del acceso a la textura en sí)
SCREEN_TEXTURE- Cuando está presente, una textura (sampler2Dosampler2DArray) con el buffer de color de un pase de renderizado que contiene el contenido de la escena excluyendo cualquier material transparente o cualquier material que también utilice el SCREEN_TEXTURE se expone al shader bajo este nombre. La textura se puede utilizar para técnicas que requieren el contenido del framebuffer en el que se están renderizando. La textura SCREEN_TEXTURE utiliza el mismo modo de borrado que View3D. El tamaño de estas texturas coincide con el tamaño de View3D en píxeles. Por ejemplo, un fragment shader podría contener lo siguiente:vec2 uv = FRAGCOORD.xy / vec2(textureSize(SCREEN_TEXTURE, 0)); vec2 displace = vec2(0.1); vec4 c = texture(SCREEN_TEXTURE, uv + displace);
Ten en cuenta que el uso de
SCREEN_TEXTURErequiere un diseño apropiado y consciente de la escena. Los objetos que utilizan este tipo de materiales tienen que ser colocados cuidadosamente, por lo general por encima de todos los demás objetos que se espera que sean visibles en la textura. Los objetos que emplean semitransparencia de alguna forma nunca forman parte deSCREEN_TEXTURE. A menudoSCREEN_TEXTUREse utilizará en combinación conBASE_COLORenMAIN. Por ejemplo, el siguiente sombreador de fragmentos personalizado aplica un efecto de relieve, mientras mantiene transparentes los fragmentos no tocados por objetos opacos.Esto supone que el objeto con el material se coloca en la parte delantera, y que tiene la mezcla activada.
void MAIN() { vec2 size = vec2(textureSize(SCREEN_TEXTURE, 0)); vec2 uv = FRAGCOORD.xy / size; // basic emboss effect vec2 d = vec2(1.0 / size.x, 1.0 / size.y); vec4 diff = texture(SCREEN_TEXTURE, uv + d) - texture(SCREEN_TEXTURE, uv - d); float c = (diff.x + diff.y + diff.z) + 0.5; float alpha = texture(SCREEN_TEXTURE, uv).a; BASE_COLOR = vec4(vec3(c), alpha); }Con el renderizado multivista,
SCREEN_TEXTUREes unasampler2DArray. UtiliceVIEW_INDEXpara seleccionar la capa a utilizar. Para aplicaciones VR/AR que deseen soportar ambos tipos de renderizado, la aproximación portable es la siguiente:#if QSHADER_VIEW_COUNT >= 2 vec4 c = texture(SCREEN_TEXTURE, vec3(uv, VIEW_INDEX)); #else vec4 c = texture(SCREEN_TEXTURE, uv); #endifSCREEN_MIP_TEXTURE- Idéntica aSCREEN_TEXTUREen la mayoría de los aspectos, la diferencia es que esta textura tiene mipmaps generados. Esto puede ser una característica costosa en cuanto a rendimiento, dependiendo del tamaño de la pantalla, y debido a tener que generar los mipmaps cada vez que se renderiza la escena. Por lo tanto, es preferible utilizar siempreSCREEN_TEXTURE, a menos que el material personalizado implemente una técnica que dependa de los niveles mip de la textura (por ejemplo, utilizandotextureLoden el shader).DEPTH_TEXTURE- Cuando está presente, una textura (sampler2Dosampler2DArray) con el contenido del búfer de profundidad (no linealizado) se expone al shader con este nombre. Sólo se incluyen los objetos opacos. Por ejemplo, un fragment shader podría contener lo siguiente:ivec2 dtSize = textureSize(DEPTH_TEXTURE, 0); vec2 dtUV = (FRAGCOORD.xy) / vec2(dtSize); vec4 depthSample = texture(DEPTH_TEXTURE, dtUV); float zNear = CAMERA_PROPERTIES.x; float zFar = CAMERA_PROPERTIES.y; float zRange = zFar - zNear; float z_n = 2.0 * depthSample.r - 1.0; float d = 2.0 * zNear * zFar / (zFar + zNear - z_n * zRange); d /= zFar;
Con renderizado multivista,
DEPTH_TEXTUREes unsampler2DArray. UtilizaVIEW_INDEXpara seleccionar la capa a utilizar. Para aplicaciones VR/AR que deseen soportar ambos tipos de renderizado, el enfoque portable es el siguiente:#if QSHADER_VIEW_COUNT >= 2 vec4 depthSample = texture(DEPTH_TEXTURE, vec3(uv, VIEW_INDEX)); #else vec4 depthSample = texture(DEPTH_TEXTURE, uv); #endifNORMAL_ROUGHNESS_TEXTURE- Cuando está presente, una textura (sampler2D) con las normales del espacio-mundo y la rugosidad del material se expone al shader bajo este nombre. Sólo se incluyen los objetos opacos. La rugosidad se almacena en el canal alfa. Por ejemplo, un sombreador de fragmentos podría contener lo siguiente:vec3 N = normalize(texture(NORMAL_ROUGHNESS_TEXTURE, uv).rgb);
-
AO_TEXTURE- Cuando está presente y la oclusión ambiental en el espacio de pantalla está activada (es decir, cuando la fuerza y la distancia AO son ambas distintas de cero) en SceneEnvironment, la textura SSAO (sampler2Dosampler2DArray) se expone al sombreador bajo este nombre. El muestreo de esta textura puede ser útil en materiales no sombreados. Los materiales sombreados tienen soporte de oclusión ambiental incorporado. Esto significa que el factor de oclusión ambiental se tiene en cuenta automáticamente. Mientras que en un fragment shader para un material no sombreado se podría escribir lo siguiente para lograr lo mismo:ivec2 aoSize = textureSize(AO_TEXTURE, 0); vec2 aoUV = (FRAGCOORD.xy) / vec2(aoSize); float aoFactor = texture(AO_TEXTURE, aoUV).x;
Con el renderizado multivista,
AO_TEXTUREes unsampler2DArray. UtilizaVIEW_INDEXpara seleccionar la capa a utilizar. Para aplicaciones VR/AR que deseen soportar ambos tipos de renderizado, el enfoque portable es el siguiente:#if QSHADER_VIEW_COUNT >= 2 ivec2 aoSize = textureSize(AO_TEXTURE, 0).xy; vec2 aoUV = (FRAGCOORD.xy) / vec2(aoSize); float aoFactor = texture(AO_TEXTURE, vec3(aoUV, VIEW_INDEX)).x; #else ivec2 aoSize = textureSize(AO_TEXTURE, 0); vec2 aoUV = (FRAGCOORD.xy) / vec2(aoSize); float aoFactor = texture(AO_TEXTURE, aoUV).x; #endif IBL_TEXTURE- No habilitará ningún pase de renderizado especial, pero puede utilizarse cuando el material tenga Material::lightProbe o el modelo esté en el ámbito de SceneEnvironment::lightProbe.void IBL_PROBE() { DIFFUSE += AO_FACTOR * BASE_COLOR.rgb * textureLod(IBL_TEXTURE, NORMAL, IBL_MAXMIPMAP).rgb; }MOTION_VECTOR_TEXTURE- Activa un pase de renderizado dedicado que calcula vectores de movimiento por objeto para la escena. La salida es una textura de cuatro canales: los componentes R y G contienen los vectores de movimiento escalados de los modelos, mientras que los componentes B y A almacenan los vectores de movimiento no escalados.VIEW_INDEX- Cuando se utiliza en el código de sombreado personalizado, se trata de una variable uint (no interpolada). Cuando no se utiliza el renderizado multivista, el valor es siempre 0. Con renderizado multivista, el valor es el índice de la vista actual (por ejemplo, gl_ViewIndex). Útil en particular en combinación conDEPTH_TEXTUREy similares cuando el renderizado multivista está activado.
Véase también SceneEnvironment::tonemapMode, Uso de la iluminación basada en imágenes, Qt Quick 3D - Ejemplo de sombreadores personalizados, Qt Quick 3D - Ejemplo de materiales personalizados, y Materiales, efectos, geometría y datos de textura programables.
Documentación de propiedades
alwaysDirty : bool
Especifica que el estado del material es siempre sucio, lo que indica que el material necesita ser refrescado cada vez que es utilizado por el QtQuick3D.
destinationAlphaBlend : enumeration [since 6.7]
Especifica el factor de mezcla alfa de destino. El valor por defecto es CustomMaterial.NoBlend. Este valor sólo se utiliza activamente si sourceBlend y destinationBlend tienen un valor distinto del predeterminado.
| Constante | Valor |
|---|---|
CustomMaterial.NoBlend | |
CustomMaterial.Zero | |
CustomMaterial.One | |
CustomMaterial.SrcColor | |
CustomMaterial.OneMinusSrcColor | |
CustomMaterial.DstColor | |
CustomMaterial.OneMinusDstColor | |
CustomMaterial.SrcAlpha | |
CustomMaterial.OneMinusSrcAlpha | |
CustomMaterial.DstAlpha | |
CustomMaterial.OneMinusDstAlpha | |
CustomMaterial.ConstantColor | |
CustomMaterial.OneMinusConstantColor | |
CustomMaterial.ConstantAlpha | |
CustomMaterial.OneMinusConstantAlpha | |
CustomMaterial.SrcAlphaSaturate |
Nota: A efectos de compatibilidad con versiones anteriores, si se deja con su valor predeterminado, se le asignará el mismo valor que destinationBlend cuando sourceBlend y destinationBlend se establezcan en valores no predeterminados.
Esta propiedad se introdujo en Qt 6.7.
Véase también destinationBlend.
destinationBlend : enumeration
Especifica el factor de mezcla de destino. El valor por defecto es CustomMaterial.NoBlend.
| Constante | Valor |
|---|---|
CustomMaterial.NoBlend | |
CustomMaterial.Zero | |
CustomMaterial.One | |
CustomMaterial.SrcColor | |
CustomMaterial.OneMinusSrcColor | |
CustomMaterial.DstColor | |
CustomMaterial.OneMinusDstColor | |
CustomMaterial.SrcAlpha | |
CustomMaterial.OneMinusSrcAlpha | |
CustomMaterial.DstAlpha | |
CustomMaterial.OneMinusDstAlpha | |
CustomMaterial.ConstantColor | |
CustomMaterial.OneMinusConstantColor | |
CustomMaterial.ConstantAlpha | |
CustomMaterial.OneMinusConstantAlpha | |
CustomMaterial.SrcAlphaSaturate |
Nota: Tanto sourceBlend como destinationBlend deben tener un valor distinto del predeterminado antes de que se active la mezcla.
Véase también sourceBlend.
fragmentShader : url
Especifica el archivo con el fragmento de código del fragment shader personalizado.
El valor es una URL y debe ser un archivo local o utilizar el esquema qrc para acceder a archivos incrustados a través del sistema de recursos de Qt. También se aceptan rutas de archivo relativas (sin esquema), en cuyo caso el archivo se trata como relativo al componente (el archivo .qml ).
Advertencia: Se supone que los fragmentos de sombreado son contenido de confianza. Se recomienda a los desarrolladores de aplicaciones que consideren detenidamente las posibles implicaciones antes de permitir la carga de contenido proporcionado por el usuario que no forme parte de la aplicación.
Véase también vertexShader.
lineWidth : real
Esta propiedad determina el ancho de las líneas renderizadas, cuando la geometría está utilizando un tipo primitivo de líneas o tiras de líneas. El valor por defecto es 1.0. Esta propiedad no es relevante cuando se renderizan otros tipos de geometría, como por ejemplo, mallas triangulares.
Atención: Los anchos de línea distintos de 1 pueden no estar soportados en tiempo de ejecución, dependiendo de la API gráfica subyacente. En tal caso, se ignorará la solicitud de cambio de anchura. Por ejemplo, no es de esperar que ninguna de las siguientes API admita líneas anchas: Direct3D, Metal, OpenGL con contextos de perfil de núcleo.
Nota: A diferencia de la anchura de línea, cuyo valor forma parte del objeto de canalización gráfica, el tamaño de punto para geometrías con una topología de puntos está controlado por el sombreador de vértices (cuando es compatible) y, por tanto, no tiene una propiedad QML correspondiente.
shadingMode : enumeration
Especifica el tipo de material. El valor por defecto es Sombreado.
| Constante | Valor |
|---|---|
CustomMaterial.Unshaded | |
CustomMaterial.Shaded |
sourceAlphaBlend : enumeration [since 6.7]
Especifica el factor de mezcla alfa fuente. El valor por defecto es CustomMaterial.NoBlend. Este valor sólo se utiliza activamente si sourceBlend y destinationBlend tienen un valor distinto del predeterminado.
| Constante | Valor |
|---|---|
CustomMaterial.NoBlend | |
CustomMaterial.Zero | |
CustomMaterial.One | |
CustomMaterial.SrcColor | |
CustomMaterial.OneMinusSrcColor | |
CustomMaterial.DstColor | |
CustomMaterial.OneMinusDstColor | |
CustomMaterial.SrcAlpha | |
CustomMaterial.OneMinusSrcAlpha | |
CustomMaterial.DstAlpha | |
CustomMaterial.OneMinusDstAlpha | |
CustomMaterial.ConstantColor | |
CustomMaterial.OneMinusConstantColor | |
CustomMaterial.ConstantAlpha | |
CustomMaterial.OneMinusConstantAlpha | |
CustomMaterial.SrcAlphaSaturate |
Nota: Por motivos de compatibilidad con versiones anteriores, si se deja en su valor predeterminado, se le asignará el mismo valor que sourceBlend cuando sourceBlend y destinationBlend se establezcan en valores no predeterminados.
Esta propiedad se introdujo en Qt 6.7.
Véase también sourceBlend.
sourceBlend : enumeration
Especifica el factor de mezcla de origen. El valor por defecto es CustomMaterial.NoBlend.
| Constante | Valor |
|---|---|
CustomMaterial.NoBlend | |
CustomMaterial.Zero | |
CustomMaterial.One | |
CustomMaterial.SrcColor | |
CustomMaterial.OneMinusSrcColor | |
CustomMaterial.DstColor | |
CustomMaterial.OneMinusDstColor | |
CustomMaterial.SrcAlpha | |
CustomMaterial.OneMinusSrcAlpha | |
CustomMaterial.DstAlpha | |
CustomMaterial.OneMinusDstAlpha | |
CustomMaterial.ConstantColor | |
CustomMaterial.OneMinusConstantColor | |
CustomMaterial.ConstantAlpha | |
CustomMaterial.OneMinusConstantAlpha | |
CustomMaterial.SrcAlphaSaturate |
Nota: Tanto sourceBlend como destinationBlend deben tener un valor distinto del predeterminado antes de que se active la mezcla.
Véase también destinationBlend.
vertexShader : url
Especifica el archivo con el fragmento de código del sombreador de vértices personalizado.
El valor es una URL y debe ser un archivo local o utilizar el esquema qrc para acceder a archivos incrustados a través del sistema de recursos de Qt. También se aceptan rutas de archivo relativas (sin esquema), en cuyo caso el archivo se trata como relativo al componente (el archivo .qml ).
Advertencia: Se supone que los fragmentos de sombreado son contenido de confianza. Se recomienda a los desarrolladores de aplicaciones que consideren detenidamente las posibles implicaciones antes de permitir la carga de contenido proporcionado por el usuario que no forme parte de la aplicación.
Véase también fragmentShader.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.