Skip to content

t1k:cocos:base:unity-shader-port

FieldValue
Modulebase
Version1.16.0
Effortmedium
Tools

Keywords: amplify, cocos, color-space, effect, fresnel, glsl, hlsl, migration, port, shader, shader-forge, unity

/t1k:cocos:base:unity-shader-port

Translating a Unity .shader into Cocos Creator 3.8.7. This skill owns the translation — reading the Unity source, mapping properties and render state, picking an archetype, and converting the fragment math. It does not own writing the .effect file: that is t1k-cocos-base-effect-authoring, which this skill hands off to.

The split matters because the include map, the verify loop, and the material schema are the same regardless of where the shader came from. Duplicating them here would mean two places to fix when the engine changes.

  • A Unity .shader (plus its .mat, and usually textures) needs a Cocos equivalent.
  • Ported materials render but the colors are wrong — see § 5.
  • Auditing an existing port for mapping mistakes.

Collect before translating:

InputWhy
The .shaderThe math and the property declarations
Every .mat using itActual authored values — the shader’s defaults are usually not what shipped
Textures referenced by those materialsSome _EmissionMap / _BumpMap refs point at deleted assets; you need to know which
ProjectSettings/PlayerSettings.asset if availablem_ColorSpace — see § 5. Frequently absent in partial checkouts.

Identifying the generator (it changes how readable the source is):

Marker in the fileGenerator
// Made with Amplify Shader Editor header, ASEBEGIN / ASEEND blocksAmplify
// Shader created with Shader Forge, SHADER_TARGET-style generated namesShader Forge
Neither, hand-readable CGPROGRAMHand-written

Generated shaders carry a lot of dead code (unused interpolators, disabled features). Translate the active path — trace from the emission/albedo output backwards — rather than every line.

  1. Read Properties { } → build the property table (references/property-mapping.md).
  2. Read Tags, Blend, ZWrite, ZTest, Cull → render state (references/state-mapping.md).
  3. Pick the Cocos archetype using the decision tree in t1k-cocos-base-effect-authoring § 1. Unity’s lighting model is the main signal: unlit/emission-only → archetype A; Blend One One + ZWrite Off → archetype C; a UI/sprite shader → archetype B.
  4. Translate the fragment math (references/formula-patterns.md). Work from the output backwards; do not translate line-by-line.
  5. List the macros — Unity #pragma shader_feature / _KEYWORD toggles become Cocos #if USE_XXX with a parent: USE_XXX property.

The deliverable is a spec, not a file. Format:

ARCHETYPE: A (3D unlit mesh) # feeds t1k-cocos-base-effect-authoring § 1
PROPERTIES:
_Color2 -> mainColor vec4, editor type: color
_Color -> rimColor vec4, editor type: color
_EmissionPower -> params.x float
_FresnelPower -> params.y float, slide 0..10
_RimPower -> params.z float
_Alpha -> params.w float, slide 0..1
_MainTex -> mainTexture sampler2D
_EmissionMap -> emissiveTexture sampler2D, parent: USE_EMISSIVE_MAP
STATE:
Blend SrcAlpha OneMinusSrcAlpha -> blendSrc: src_alpha / blendDst: one_minus_src_alpha
ZWrite On -> depthWrite: true
Cull Back -> cullMode: back
Tags{Queue=Transparent} -> technique name: transparent
MACROS:
USE_EMISSIVE_MAP (default off — see notes)
FRAGMENT (pseudo):
exponent = max(10.0 - fresnelPower, 0.001)
fresnel = pow(max(1.0 - dot(N, V), 0.0), exponent)
rim = rimColor.rgb * fresnel * rimPower
body = (tex * tint) * (tint * emissive * emissionPower)
out = vec4(rim + body, alpha)
NOTES / UNVERIFIED:
- Color space: see color-space.md. Treated as <gamma|linear|unknown>.
- _EmissionMap on materials X and Y points at a missing asset -> hardcode white.
HANDOFF: t1k-cocos-base-effect-authoring

Then invoke t1k-cocos-base-effect-authoring with that spec. It owns the includes, the file, the .mtl, and the verify loop.

Unity .mat colors are floats 0–1. Cocos .mtl colors are integers 0–255.

The conversion used by verified ports is raw ×255 with no color-space conversion:

Unity { r: 0.2784314, g: 0.16470589, b: 1 }
Cocos { "r": 71, "g": 42, "b": 255, "a": 255 }

This was checked exactly against a shipped pair of materials. It is the convention to follow unless § 5 tells you otherwise for a specific project.

5. Color space — read before trusting any port

Section titled “5. Color space — read before trusting any port”

This is the part most likely to be wrong, and the part hardest to notice.

Unity’s Built-in Render Pipeline defaults to Gamma color space, but the project can be set to Linear, and the setting lives in ProjectSettings/PlayerSettings.assetm_ColorSpace. In partial checkouts that file is often missing, which means the color space is unknowable from the source you were given.

Existing ports in the wild do the math in linear via a toLinear() / toGamma() round-trip, justified by a comment asserting “Unity renders this in linear”. Where that assertion could not be checked against m_ColorSpace, it is an assumption, not a fact.

Practical consequence, and the reason this section exists:

  • If ported colors look washed out or over-bright, deleting the linear round-trip is the first thing to try — before touching any property value.
  • Change every effect in the shared-math family together. Ports that share a source shader (a character and its props, say) must stay consistent, or the mismatch shows up as two objects lit differently in the same frame.

Full procedure, including how to verify when PlayerSettings.asset is available: references/color-space.md.

Don’tWhy
Translate HLSL line by lineGenerated shaders are 80% dead code. Trace back from the output.
Skip TagsQueue and render type decide the technique name and blend setup. Ignoring them gives correct pixels in the wrong order.
Assume a color spaceIt is knowable only from m_ColorSpace. If you can’t read it, say so in the spec’s NOTES and pick the convention already used by the project’s other ports.
Map properties the source never uses_RimPower: 0 in every material makes _Color/rimColor dead weight. Check the .mat values, not just the .shader declarations.
Copy a previous port’s property naming as if it were a standard_Color2 → mainColor is one project’s convention, not a rule. State it as a project convention in the spec.
Write the .effect hereThat is t1k-cocos-base-effect-authoring. Two copies of the include map will drift.
FileContents
references/property-mapping.mdProperties{}properties:, type mapping, packing, naming conventions
references/state-mapping.mdBlend/ZWrite/ZTest/Cull/Tags → Cocos pass state
references/color-space.mdGamma vs linear, the ×255 rule, what is verified vs assumed
references/formula-patterns.mdFresnel remap, emissive, UV scroll/distort, missing-texture handling
  • t1k-cocos-base-effect-authoring — writes the .effect/.mtl this skill specs, and owns the verify loop.
  • t1k-cocos-playable-unity-particle — ports Unity ParticleSystem prefabs. Use it for the particle module/curve/gradient data; use this skill for the material’s shader.