Skip to content

Commit 0cbbcd8

Browse files
committed
[unity] Fixes to make the pipeline work with new shaders
1 parent 0ba0ab7 commit 0cbbcd8

File tree

4 files changed

+135
-15
lines changed

4 files changed

+135
-15
lines changed

plugins/unity/runtime/src/backend/Draw.hx

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -356,17 +356,17 @@ class Draw #if !completion implements spec.Draw #end {
356356
* Adds texture coordinates to the vertex buffer.
357357
*
358358
* UV coordinates map vertices to texture pixels. The Y coordinate
359-
* is flipped (1.0 - uvY) because Unity's texture coordinate system
360-
* has Y=0 at the bottom, while Ceramic uses Y=0 at the top.
359+
* flip for Unity's coordinate system is handled in the shader's
360+
* texture sampling helper (shade_texture), not here.
361361
*
362362
* @param uvX The horizontal texture coordinate (0-1)
363-
* @param uvY The vertical texture coordinate (0-1, flipped internally)
363+
* @param uvY The vertical texture coordinate (0-1)
364364
*/
365365
#end
366366
#if !ceramic_debug_draw_backend inline #end public function putUVs(uvX:Float, uvY:Float):Void {
367367

368368
_meshVertices[_uvIndex] = uvX;
369-
_meshVertices[_uvIndex+1] = (1.0 - uvY);
369+
_meshVertices[_uvIndex+1] = uvY;
370370
_numUVs++;
371371
_uvIndex += _vertexSize;
372372

@@ -573,6 +573,20 @@ class Draw #if !completion implements spec.Draw #end {
573573

574574
}
575575

576+
#if !no_backend_docs
577+
/**
578+
* Ends the current rendering frame.
579+
*
580+
* In Unity, frame finalization is handled automatically by the
581+
* rendering pipeline, so this method is empty.
582+
*/
583+
#end
584+
#if !ceramic_debug_draw_backend inline #end public function endRender():Void {
585+
586+
// Unity handles frame finalization automatically
587+
588+
}
589+
576590
#if !no_backend_docs
577591
/**
578592
* Clears the screen and applies the background color.

plugins/unity/runtime/src/backend/Materials.hx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -173,16 +173,16 @@ class Materials {
173173
if (shaderImpl.customAttributes != null) {
174174
for (i in 0...shaderImpl.customAttributes.length) {
175175
var attr = shaderImpl.customAttributes[i];
176-
var texCoord = switch i {
177-
case 0: VertexAttribute.TexCoord1;
178-
case 1: VertexAttribute.TexCoord2;
179-
case 2: VertexAttribute.TexCoord3;
180-
case 3: VertexAttribute.TexCoord4;
181-
case 4: VertexAttribute.TexCoord5;
182-
case 5: VertexAttribute.TexCoord6;
183-
case 6: VertexAttribute.TexCoord7;
184-
default: throw 'Too many custom attributes in shader: $shader (max 7)';
185-
};
176+
if (i > 6) {
177+
throw 'Too many custom attributes in shader: $shader (max 7)';
178+
}
179+
var texCoord:VertexAttribute = VertexAttribute.TexCoord1;
180+
if (i == 1) texCoord = VertexAttribute.TexCoord2;
181+
else if (i == 2) texCoord = VertexAttribute.TexCoord3;
182+
else if (i == 3) texCoord = VertexAttribute.TexCoord4;
183+
else if (i == 4) texCoord = VertexAttribute.TexCoord5;
184+
else if (i == 5) texCoord = VertexAttribute.TexCoord6;
185+
else if (i == 6) texCoord = VertexAttribute.TexCoord7;
186186
vertexBufferAttributes[3 + i] = new VertexAttributeDescriptor(
187187
texCoord, VertexAttributeFormat.Float32, attr.size, 0
188188
);

plugins/unity/tools/src/backend/tools/tasks/UnityBuild.hx

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package backend.tools.tasks;
22

3+
import haxe.Json;
34
import haxe.io.Path;
45
import sys.FileSystem;
6+
import sys.io.File;
7+
import tools.Equal;
8+
import tools.Files;
59
import tools.Helpers.*;
610
import tools.InstanceManager;
711

@@ -93,6 +97,10 @@ class UnityBuild extends tools.Task {
9397
cmdArgs.push('haxe_server=$haxeServerPort');
9498
}
9599

100+
// Haxe shaders detection
101+
cmdArgs.push('--macro');
102+
cmdArgs.push('shade.macros.ShadeMacro.initRegister(' + Json.stringify(hxmlProjectPath) + ')');
103+
96104
if (haxeServerPort != -1) {
97105
print('Run haxe compiler (server on port $haxeServerPort)');
98106
}
@@ -109,6 +117,76 @@ class UnityBuild extends tools.Task {
109117
}
110118
else {
111119
if (action == 'run' || action == 'build') {
120+
// Compile Unity shaders from Haxe shaders
121+
final shadersJsonPath = Path.join([hxmlProjectPath, 'shade', 'info.json']);
122+
final prevShadersJsonPath = Path.join([hxmlProjectPath, 'shade', 'prev-info.json']);
123+
124+
if (FileSystem.exists(shadersJsonPath)) {
125+
var shaders:Dynamic = Json.parse(File.getContent(shadersJsonPath));
126+
127+
// Read previous shade/info.json for comparison
128+
var prevShaders:Dynamic = null;
129+
if (FileSystem.exists(prevShadersJsonPath)) {
130+
prevShaders = Json.parse(File.getContent(prevShadersJsonPath));
131+
}
132+
133+
if (shaders != null && shaders.shaders != null) {
134+
final shaderReferences:Array<{
135+
pack:Array<String>,
136+
name:String,
137+
filePath:String,
138+
hash:String
139+
}> = shaders.shaders;
140+
141+
if (shaderReferences.length > 0) {
142+
// Check if shaders changed (skip if identical)
143+
var shouldSkipShaderCompilation = false;
144+
if (prevShaders != null && Equal.equal(prevShaders, shaders)) {
145+
shouldSkipShaderCompilation = true;
146+
}
147+
148+
if (!shouldSkipShaderCompilation) {
149+
// Collect unique shader files (by hash to avoid duplicates)
150+
var uniqueShaders:Map<String, String> = new Map();
151+
for (ref in shaderReferences) {
152+
if (!uniqueShaders.exists(ref.hash)) {
153+
uniqueShaders.set(ref.hash, ref.filePath);
154+
}
155+
}
156+
157+
// Build shade task arguments for Unity target
158+
var unityOutputPath = Path.join([hxmlProjectPath, 'shade', 'unity']);
159+
160+
// Delete existing unity shader folder if any
161+
if (FileSystem.exists(unityOutputPath)) {
162+
Files.deleteRecursive(unityOutputPath);
163+
}
164+
165+
// Build args for shade task
166+
var shadeArgs:Array<String> = [];
167+
for (filePath in uniqueShaders) {
168+
shadeArgs.push('--in');
169+
shadeArgs.push(filePath);
170+
}
171+
shadeArgs.push('--target');
172+
shadeArgs.push('unity');
173+
shadeArgs.push('--out');
174+
shadeArgs.push(unityOutputPath);
175+
176+
// Run shade task
177+
print('Transpile shaders to Unity ShaderLab');
178+
runTask('shade', shadeArgs);
179+
180+
// Copy shaders to Unity project
181+
copyGeneratedShadersToUnity(cwd, unityOutputPath, project);
182+
183+
// Save current info for next comparison
184+
File.saveContent(prevShadersJsonPath, File.getContent(shadersJsonPath));
185+
}
186+
}
187+
}
188+
}
189+
112190
runHooks(cwd, args, project.app.hooks, 'end build');
113191
}
114192
else if (action == 'clean') {
@@ -125,4 +203,32 @@ class UnityBuild extends tools.Task {
125203

126204
}
127205

206+
/**
207+
* Copies generated Unity ShaderLab files to the Unity project assets folder.
208+
* @param cwd Current working directory
209+
* @param sourcePath Path to generated shader files
210+
* @param project Ceramic project configuration
211+
*/
212+
function copyGeneratedShadersToUnity(cwd:String, sourcePath:String, project:tools.Project):Void {
213+
if (!FileSystem.exists(sourcePath)) return;
214+
215+
// Unity shaders go to same assets folder as other ceramic assets
216+
var dstAssetsPath = Path.join([cwd, 'project', 'unity', project.app.name, 'Assets', 'Ceramic', 'Resources', 'assets']);
217+
218+
// Ensure assets directory exists
219+
if (!FileSystem.exists(dstAssetsPath)) {
220+
FileSystem.createDirectory(dstAssetsPath);
221+
}
222+
223+
// Copy all .shader files
224+
for (file in FileSystem.readDirectory(sourcePath)) {
225+
if (file.endsWith('.shader')) {
226+
File.copy(
227+
Path.join([sourcePath, file]),
228+
Path.join([dstAssetsPath, file])
229+
);
230+
}
231+
}
232+
}
233+
128234
}

0 commit comments

Comments
 (0)