// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. CCEffect %{ techniques: - name: opaque passes: - vert: standard-vs frag: standard-fs properties: &props tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } mainColor: { value: [1.0, 1.0, 1.0, 1.0], target: albedo, linear: true, editor: { displayName: Albedo, type: color } } albedoScale: { value: [1.0, 1.0, 1.0], target: albedoScaleAndCutoff.xyz } alphaThreshold: { value: 0.5, target: albedoScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST, slide: true, range: [0, 1.0], step: 0.001 } } occlusion: { value: 0.0, target: pbrParams.x, editor: { slide: true, range: [0, 1.0], step: 0.001 } } roughness: { value: 0.8, target: pbrParams.y, editor: { slide: true, range: [0, 1.0], step: 0.001 } } metallic: { value: 0.6, target: pbrParams.z, editor: { slide: true, range: [0, 1.0], step: 0.001 } } specularIntensity: { value: 0.5, target: pbrParams.w, editor: { slide: true, range: [0.0, 1.0], step: 0.001 } } emissive: { value: [0.0, 0.0, 0.0, 1.0], linear: true, editor: { type: color } } emissiveScale: { value: [1.0, 1.0, 1.0], target: emissiveScaleParam.xyz } normalStrength: { value: 1.0, target: emissiveScaleParam.w, editor: { parent: USE_NORMAL_MAP, slide: true, range: [0, 5.0], step: 0.001 } } mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } normalMap: { value: normal } pbrMap: { value: grey } metallicRoughnessMap: { value: grey } occlusionMap: { value: white } emissiveMap: { value: grey } - &forward-add vert: standard-vs frag: standard-fs phase: forward-add propertyIndex: 0 embeddedMacros: { CC_FORWARD_ADD: true } depthStencilState: depthFunc: equal depthTest: true depthWrite: false blendState: targets: - blend: true blendSrc: one blendDst: one blendSrcAlpha: zero blendDstAlpha: one - &shadow-caster vert: shadow-caster-vs:vert frag: shadow-caster-fs:frag phase: shadow-caster propertyIndex: 0 rasterizerState: cullMode: front properties: tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } mainColor: { value: [1.0, 1.0, 1.0, 1.0], target: albedo, editor: { displayName: Albedo, type: color } } albedoScale: { value: [1.0, 1.0, 1.0], target: albedoScaleAndCutoff.xyz } alphaThreshold: { value: 0.5, target: albedoScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } } mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } - name: transparent passes: - vert: standard-vs frag: standard-fs embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } depthStencilState: depthTest: true depthWrite: false blendState: targets: - blend: true blendSrc: src_alpha blendDst: one_minus_src_alpha blendDstAlpha: one_minus_src_alpha properties: *props - *forward-add - *shadow-caster }% CCProgram shared-ubos %{ uniform Constants { vec4 tilingOffset; vec4 albedo; vec4 albedoScaleAndCutoff; vec4 pbrParams; vec4 emissive; vec4 emissiveScaleParam; }; }% CCProgram standard-vs %{ precision highp float; #include #include #include #include #include #include #include #if USE_VERTEX_COLOR in vec4 a_color; out lowp vec4 v_color; #endif #if USE_INSTANCING // when instancing is enabled in vec4 a_tilingOffset; #endif out vec3 v_position; out mediump vec3 v_normal; out vec2 v_uv; #if HAS_SECOND_UV out mediump vec2 v_uv1; #endif #if CC_RECEIVE_SHADOW out mediump vec2 v_shadowBias; #endif #if USE_NORMAL_MAP out mediump vec4 v_tangent; #endif #if HAS_SECOND_UV || CC_USE_LIGHTMAP in vec2 a_texCoord1; #endif #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD #include #endif void main () { StandardVertInput In; CCVertInput(In); mat4 matWorld, matWorldIT; CCGetWorldMatrixFull(matWorld, matWorldIT); vec4 pos = matWorld * In.position; v_position = pos.xyz; v_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz); #if CC_RECEIVE_SHADOW v_shadowBias = CCGetShadowBias(); #endif #if USE_TWOSIDE vec3 viewDirect = normalize(cc_cameraPos.xyz - v_position); v_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0; #endif #if USE_NORMAL_MAP v_tangent.xyz = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz); v_tangent.w = In.tangent.w; #endif vec4 vTilingOffset = tilingOffset; #if USE_INSTANCING // when instancing is enabled vTilingOffset = a_tilingOffset; #endif v_uv = a_texCoord * vTilingOffset.xy + vTilingOffset.zw; #if SAMPLE_FROM_RT CC_HANDLE_RT_SAMPLE_FLIP(v_uv); #endif #if HAS_SECOND_UV v_uv1 = a_texCoord1 * vTilingOffset.xy + vTilingOffset.zw; #if SAMPLE_FROM_RT CC_HANDLE_RT_SAMPLE_FLIP(v_uv1); #endif #endif #if USE_VERTEX_COLOR v_color = a_color; #endif CC_TRANSFER_FOG(pos); CC_TRANSFER_SHADOW(pos); #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD CCLightingMapCaclUV(); #endif gl_Position = cc_matProj * (cc_matView * matWorld) * In.position; } }% CCProgram standard-fs %{ precision highp float; #include #include #include #include #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD #include #endif in vec3 v_position; in vec2 v_uv; #if HAS_SECOND_UV in mediump vec2 v_uv1; #endif in mediump vec3 v_normal; #if CC_RECEIVE_SHADOW in mediump vec2 v_shadowBias; #endif #if USE_VERTEX_COLOR in lowp vec4 v_color; #endif #if USE_ALBEDO_MAP uniform sampler2D albedoMap; #pragma define-meta ALBEDO_UV options([v_uv, v_uv1]) #endif #if USE_NORMAL_MAP in mediump vec4 v_tangent; uniform sampler2D normalMap; #pragma define-meta NORMAL_UV options([v_uv, v_uv1]) #endif #pragma define-meta PBR_UV options([v_uv, v_uv1]) #if USE_PBR_MAP uniform sampler2D pbrMap; #endif #if USE_METALLIC_ROUGHNESS_MAP uniform sampler2D metallicRoughnessMap; #endif #if USE_OCCLUSION_MAP uniform sampler2D occlusionMap; #endif #if USE_EMISSIVE_MAP uniform sampler2D emissiveMap; #pragma define-meta EMISSIVE_UV options([v_uv, v_uv1]) #endif #pragma define OCCLUSION_CHANNEL r #pragma define ROUGHNESS_CHANNEL g #pragma define METALLIC_CHANNEL b #pragma define SPECULAR_INTENSITY_CHANNEL a #if USE_ALPHA_TEST #pragma define-meta ALPHA_TEST_CHANNEL options([a, r]) #endif void surf (out StandardSurface s) { vec4 baseColor = albedo; #if USE_VERTEX_COLOR baseColor.rgb *= SRGBToLinear(v_color.rgb); // use linear baseColor.a *= v_color.a; #endif #if USE_ALBEDO_MAP vec4 texColor = texture(albedoMap, ALBEDO_UV); texColor.rgb = SRGBToLinear(texColor.rgb); baseColor *= texColor; #endif s.albedo = baseColor; s.albedo.rgb *= albedoScaleAndCutoff.xyz; #if USE_ALPHA_TEST if (s.albedo.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard; #endif #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD vec4 lightColor = texture(cc_lightingMap, v_luv.xy); s.lightmap.a = lightColor.a; s.lightmap.rgb = lightColor.xyz * v_luv.z; s.lightmap_test = v_luv.z; /*lum*/ #endif s.normal = v_normal; #if CC_RECEIVE_SHADOW s.shadowBias = v_shadowBias; #endif #if USE_NORMAL_MAP vec3 nmmp = texture(normalMap, NORMAL_UV).xyz - vec3(0.5); vec3 bitangent = cross(v_normal, v_tangent.xyz) * (v_tangent.w > 0.0 ? 1.0 : -1.0); // note the cross order s.normal = (nmmp.x * emissiveScaleParam.w) * normalize(v_tangent.xyz) + (nmmp.y * emissiveScaleParam.w) * normalize(bitangent) + nmmp.z * normalize(s.normal); #endif HIGHP_VALUE_TO_STRUCT_DEFINED(v_position, s.position); vec4 pbr = pbrParams; pbr.x = 1.0; #if USE_PBR_MAP vec4 res = texture(pbrMap, PBR_UV); pbr.x *= res.OCCLUSION_CHANNEL; pbr.y *= res.ROUGHNESS_CHANNEL; pbr.z *= res.METALLIC_CHANNEL; pbr.w *= res.SPECULAR_INTENSITY_CHANNEL; #endif #if USE_METALLIC_ROUGHNESS_MAP vec4 metallicRoughness = texture(metallicRoughnessMap, PBR_UV); pbr.z *= metallicRoughness.METALLIC_CHANNEL; pbr.y *= metallicRoughness.ROUGHNESS_CHANNEL; #endif #if USE_OCCLUSION_MAP pbr.x = mix(1.0, texture(occlusionMap, PBR_UV).OCCLUSION_CHANNEL, pbrParams.x); #endif s.occlusion = pbr.x; s.roughness = pbr.y; s.metallic = pbr.z; s.specularIntensity = pbr.w; s.emissive = emissive.rgb; #if USE_EMISSIVE_MAP s.emissive = SRGBToLinear(texture(emissiveMap, EMISSIVE_UV).rgb); #endif s.emissive *= emissiveScaleParam.xyz; } CC_STANDARD_SURFACE_ENTRY() }% CCProgram shadow-caster-vs %{ precision highp float; #include #include #include #include #include #if HAS_SECOND_UV || CC_USE_LIGHTMAP in vec2 a_texCoord1; #endif #if USE_INSTANCING // when instancing is enabled in vec4 a_tilingOffset; #endif out vec2 v_uv; #if HAS_SECOND_UV out vec2 v_uv1; #endif out vec4 v_worldPos; out highp vec2 v_clip_depth; vec4 vert () { StandardVertInput In; CCVertInput(In); mat4 matWorld, matWorldIT; CCGetWorldMatrixFull(matWorld, matWorldIT); v_worldPos = matWorld * In.position; vec4 clipPos = cc_matLightViewProj * v_worldPos; vec4 vTilingOffset = tilingOffset; #if USE_INSTANCING // when instancing is enabled vTilingOffset = a_tilingOffset; #endif v_uv = a_texCoord * vTilingOffset.xy + vTilingOffset.zw; #if HAS_SECOND_UV v_uv1 = a_texCoord1 * vTilingOffset.xy + vTilingOffset.zw; #endif v_clip_depth = clipPos.zw; return clipPos; } }% CCProgram shadow-caster-fs %{ precision highp float; #include #include #include in vec2 v_uv; #if HAS_SECOND_UV in vec2 v_uv1; #endif in vec4 v_worldPos; in highp vec2 v_clip_depth; #if USE_ALBEDO_MAP uniform sampler2D albedoMap; #pragma define-meta ALBEDO_UV options([v_uv, v_uv1]) #endif #if USE_ALPHA_TEST #pragma define-meta ALPHA_TEST_CHANNEL options([a, r]) #endif vec4 frag () { vec4 baseColor = albedo; #if USE_ALPHA_TEST #if USE_ALBEDO_MAP baseColor *= texture(albedoMap, ALBEDO_UV); #endif if (baseColor.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard; #endif highp float clipDepth = v_clip_depth.x / v_clip_depth.y * 0.5 + 0.5; // spot use linear if(cc_shadowLPNNInfo.x > 0.000001 && cc_shadowLPNNInfo.x < 1.999999) { // enabled linear depth #if CC_SHADOWMAP_USE_LINEAR_DEPTH clipDepth = CCGetLinearDepth(v_worldPos.xyz); #endif } #if CC_SHADOWMAP_FORMAT == SHADOWMAP_FORMAT_RGBA8 return packDepthToRGBA(clipDepth); #else return vec4(clipDepth, 1.0, 1.0, 1.0); #endif } }%