material { name : Image, parameters : [ { type : sampler2d, name : image }, { type : samplerCubemap, name : cubeMap }, { type : mat4, name : transform, precision : high }, { type : float4, name : backgroundColor }, { type : int, name : showImage }, { type : int, name : isCubeMap }, { type : int, name : cubeMapFace } ], variables : [ imageUV ], vertexDomain : device, depthWrite : false, shadingModel : unlit, variantFilter : [ skinning, shadowReceiver, vsm ], culling: none } vertex { void materialVertex(inout MaterialVertexInputs material) { material.imageUV.st = getPosition().st * 0.5 + 0.5; } } fragment { vec3 getDirectionForCubeFace(int face, vec2 uv) { vec2 st = uv * 2.0 - 1.0; // Convert [0,1] to [-1,1] if (face == 0) { // +X return normalize(vec3(1.0, -st.y, -st.x)); } else if (face == 1) { // -X return normalize(vec3(-1.0, -st.y, st.x)); } else if (face == 2) { // +Y return normalize(vec3(st.x, 1.0, st.y)); } else if (face == 3) { // -Y return normalize(vec3(st.x, -1.0, -st.y)); } else if (face == 4) { // +Z return normalize(vec3(st.x, -st.y, 1.0)); } else { // -Z (face == 5) return normalize(vec3(-st.x, -st.y, -1.0)); } } void material(inout MaterialInputs material) { prepareMaterial(material); highp vec2 uv = (materialParams.transform * vec4(saturate(variable_imageUV.st), 1.0, 1.0)).st; if (materialParams.showImage == 0 || uv.s > 1.0 || uv.s < 0.0 || uv.t < 0.0 || uv.t > 1.0) { material.baseColor = materialParams.backgroundColor; } else { vec4 color; if (materialParams.isCubeMap != 0) { // Sample cubemap using direction vector for specified face vec2 cubeUv = uv; cubeUv.t = 1.0 - cubeUv.t; // Flip V coordinate vec3 direction = getDirectionForCubeFace(materialParams.cubeMapFace, cubeUv); color = max(texture(materialParams_cubeMap, direction), 0.0); } else { // Regular 2D texture sampling uv.t = 1.0 - uv.t; color = max(texture(materialParams_image, uv.st), 0.0); } color.rgb *= color.a; // Manual, pre-multiplied srcOver with opaque destination optimization material.baseColor.rgb = color.rgb + materialParams.backgroundColor.rgb * (1.0 - color.a); } } }