Files
cup_edit/example/assets/ubershader_gpu.mat.in

186 lines
8.4 KiB
Plaintext

material {
name : ubershader_gpu,
requires : [ uv0, uv1, color ],
shadingModel : lit,
blending : transparent,
depthWrite : true,
doubleSided : true,
flipUV : false,
specularAmbientOcclusion : simple,
specularAntiAliasing : true,
clearCoatIorChange : false,
vertexDomain: world,
parameters : [
{ type : float3, name : specularFactor },
{ type : float, name : glossinessFactor },
// Base Color
{ type : int, name : baseColorIndex },
{ type : float4, name : baseColorFactor },
{ type : sampler2d, name : baseColorMap },
{ type : mat3, name : baseColorUvMatrix, precision: high },
// Metallic-Roughness Map
{ type : int, name : metallicRoughnessIndex },
{ type : float, name : metallicFactor },
{ type : float, name : roughnessFactor },
{ type : sampler2d, name : metallicRoughnessMap },
{ type : mat3, name : metallicRoughnessUvMatrix, precision: high },
// Normal Map
{ type : int, name : normalIndex },
{ type : float, name : normalScale },
{ type : sampler2d, name : normalMap },
{ type : mat3, name : normalUvMatrix, precision: high },
// Ambient Occlusion
{ type : int, name : aoIndex },
{ type : float, name : aoStrength },
{ type : sampler2d, name : occlusionMap },
{ type : mat3, name : occlusionUvMatrix, precision: high },
// Emissive Map
{ type : int, name : emissiveIndex },
{ type : float3, name : emissiveFactor },
{ type : sampler2d, name : emissiveMap },
{ type : mat3, name : emissiveUvMatrix, precision: high },
// Cleat coat
{ type : float, name : clearCoatFactor },
{ type : float, name : clearCoatRoughnessFactor },
{ type : int, name : clearCoatIndex },
{ type : sampler2d, name : clearCoatMap },
{ type : mat3, name : clearCoatUvMatrix, precision: high },
{ type : int, name : clearCoatRoughnessIndex },
{ type : sampler2d, name : clearCoatRoughnessMap },
{ type : mat3, name : clearCoatRoughnessUvMatrix, precision: high },
{ type : int, name : clearCoatNormalIndex },
{ type : sampler2d, name : clearCoatNormalMap },
{ type : mat3, name : clearCoatNormalUvMatrix, precision: high },
{ type : float, name : clearCoatNormalScale },
// Reflectance
{ type : float, name : reflectance },
{ type : int3, name: dimensions },
{ type : float[255], name:"morphTargetWeights" },
{ type: sampler2dArray, format: float, name:"morphTargets" }
],
}
fragment {
void material(inout MaterialInputs material) {
highp float2 uvs[2];
uvs[0] = getUV0();
uvs[1] = getUV1();
if (materialParams.normalIndex > -1) {
highp float2 uv = uvs[materialParams.normalIndex];
uv = (vec3(uv, 1.0) * materialParams.normalUvMatrix).xy;
material.normal = texture(materialParams_normalMap, uv).xyz * 2.0 - 1.0;
material.normal.xy *= materialParams.normalScale;
}
if (materialParams.clearCoatNormalIndex > -1) {
highp float2 uv = uvs[materialParams.clearCoatNormalIndex];
uv = (vec3(uv, 1.0) * materialParams.clearCoatNormalUvMatrix).xy;
material.clearCoatNormal = texture(materialParams_clearCoatNormalMap, uv).xyz * 2.0 - 1.0;
material.clearCoatNormal.xy *= materialParams.clearCoatNormalScale;
}
prepareMaterial(material);
material.baseColor = materialParams.baseColorFactor;
if (materialParams.baseColorIndex > -1) {
highp float2 uv = uvs[materialParams.baseColorIndex];
uv = (vec3(uv, 1.0) * materialParams.baseColorUvMatrix).xy;
material.baseColor *= texture(materialParams_baseColorMap, uv);
}
material.baseColor *= getColor();
material.baseColor.rgb *= material.baseColor.a;
material.roughness = materialParams.roughnessFactor;
material.metallic = materialParams.metallicFactor;
// KHR_materials_clearcoat forbids clear coat from
// being applied in the specular/glossiness model
material.clearCoat = materialParams.clearCoatFactor;
material.clearCoatRoughness = materialParams.clearCoatRoughnessFactor;
if (materialParams.clearCoatIndex > -1) {
highp float2 uv = uvs[materialParams.clearCoatIndex];
uv = (vec3(uv, 1.0) * materialParams.clearCoatUvMatrix).xy;
material.clearCoat *= texture(materialParams_clearCoatMap, uv).r;
}
if (materialParams.clearCoatRoughnessIndex > -1) {
highp float2 uv = uvs[materialParams.clearCoatRoughnessIndex];
uv = (vec3(uv, 1.0) * materialParams.clearCoatRoughnessUvMatrix).xy;
material.clearCoatRoughness *= texture(materialParams_clearCoatRoughnessMap, uv).g;
}
material.emissive = vec4(materialParams.emissiveFactor.rgb, 0.0);
if (materialParams.metallicRoughnessIndex > -1) {
highp float2 uv = uvs[materialParams.metallicRoughnessIndex];
uv = (vec3(uv, 1.0) * materialParams.metallicRoughnessUvMatrix).xy;
vec4 mr = texture(materialParams_metallicRoughnessMap, uv);
material.roughness *= mr.g;
material.metallic *= mr.b;
}
if (materialParams.aoIndex > -1) {
highp float2 uv = uvs[materialParams.aoIndex];
uv = (vec3(uv, 1.0) * materialParams.occlusionUvMatrix).xy;
material.ambientOcclusion = texture(materialParams_occlusionMap, uv).r *
materialParams.aoStrength;
}
if (materialParams.emissiveIndex > -1) {
highp float2 uv = uvs[materialParams.emissiveIndex];
uv = (vec3(uv, 1.0) * materialParams.emissiveUvMatrix).xy;
material.emissive.rgb *= texture(materialParams_emissiveMap, uv).rgb;
}
}
}
vertex {
vec3 getMorphTarget(int vertexIndex, int morphTargetIndex) {
// our texture is laid out as (x,y,z) where y is 1, z is the number of morph targets, and x is the number of vertices * 2 (multiplication accounts for position + normal)
// UV coordinates are normalized to (-1,1), so we divide the current vertex index by the total number of vertices to find the correct coordinate for this vertex
vec3 uv = vec3(
(float(vertexIndex) + 0.5) / float(materialParams.dimensions.x),
0.0f,
//(float(morphTargetIndex) + 0.5f) / float(materialParams.dimensions.z));
float(morphTargetIndex));
return texture(materialParams_morphTargets, uv).xyz;
}
void materialVertex(inout MaterialVertexInputs material) {
// for every morph target
for(int morphTargetIndex = 0; morphTargetIndex < materialParams.dimensions.z; morphTargetIndex++) {
// get the weight to apply
float weight = materialParams.morphTargetWeights[morphTargetIndex];
// get the ID of this vertex, which will be the x-offset of the position attribute in the texture sampler
int vertexId = getVertexIndex();
// get the position of the target for this vertex
vec3 morphTargetPosition = getMorphTarget(vertexId, morphTargetIndex);
// update the world position of this vertex
material.worldPosition.xyz += (weight * morphTargetPosition);
// increment the vertexID by half the size of the texture to get the x-offset of the normal (all positions stored in the first half, all normals stored in the second half)
vertexId += (materialParams.dimensions.x / 2);
// get the normal of this target for this vertex
vec3 morphTargetNormal = getMorphTarget(vertexId, morphTargetIndex);
material.worldNormal += (weight * morphTargetNormal);
}
mat4 transform = getWorldFromModelMatrix();
material.worldPosition = mulMat4x4Float3(transform, material.worldPosition.xyz);
}
}