Add markCTM to canvaskit API, use in 3D cube example
Change-Id: Id0eafdf0fd69f080e26e2bee5c7b38eb55b6a5c0 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/287897 Commit-Queue: Nathaniel Nifong <nifong@google.com> Reviewed-by: Kevin Lubick <kjlubick@google.com>
This commit is contained in:
parent
00ee8f58aa
commit
00de91c591
@ -616,30 +616,31 @@ const curves = {
|
||||
in fragmentProcessor color_map;
|
||||
in fragmentProcessor normal_map;
|
||||
|
||||
uniform float4x4 localToWorld;
|
||||
uniform float4x4 localToWorldAdjInv;
|
||||
uniform float3 lightPos;
|
||||
layout (marker=local_to_world) uniform float4x4 localToWorld;
|
||||
layout (marker=normals(local_to_world)) uniform float4x4 localToWorldAdjInv;
|
||||
|
||||
float3 convert_normal_sample(half4 c) {
|
||||
float3 n = 2 * c.rgb - 1;
|
||||
n.y = -n.y;
|
||||
return n;
|
||||
float3 n = 2 * c.rgb - 1;
|
||||
n.y = -n.y;
|
||||
return n;
|
||||
}
|
||||
|
||||
void main(float2 p, inout half4 color) {
|
||||
float3 norm = convert_normal_sample(sample(normal_map, p));
|
||||
float3 plane_norm = normalize(localToWorld * float4(norm, 0)).xyz;
|
||||
float3 norm = convert_normal_sample(sample(normal_map, p));
|
||||
float3 plane_norm = normalize(localToWorldAdjInv * float4(norm, 0)).xyz;
|
||||
|
||||
float3 plane_pos = (localToWorld * float4(p, 0, 1)).xyz;
|
||||
float3 light_dir = normalize(lightPos - plane_pos);
|
||||
float3 plane_pos = (localToWorld * float4(p, 0, 1)).xyz;
|
||||
float3 light_dir = normalize(lightPos - plane_pos);
|
||||
|
||||
float ambient = 0.2;
|
||||
float dp = dot(plane_norm, light_dir);
|
||||
float scale = min(ambient + max(dp, 0), 1);
|
||||
float ambient = 0.2;
|
||||
float dp = dot(plane_norm, light_dir);
|
||||
float scale = min(ambient + max(dp, 0), 1);
|
||||
|
||||
color = sample(color_map, p) * half4(float4(scale, scale, scale, 1));
|
||||
color = sample(color_map, p) * half4(float4(scale, scale, scale, 1));
|
||||
}
|
||||
`;
|
||||
|
||||
const fact = CanvasKit.SkRuntimeEffect.Make(prog);
|
||||
|
||||
// properties of light
|
||||
@ -723,7 +724,8 @@ const curves = {
|
||||
// as part of our "camera".
|
||||
canvas.concat(CanvasKit.SkM44.multiply(viewport, perspective));
|
||||
canvas.concat(CanvasKit.SkM44.multiply(camera, mustInvert(viewport)));
|
||||
// canvas.markCTM(...);
|
||||
// Mark the matrix to make it available to the shader by this name.
|
||||
canvas.markCTM('local_to_world');
|
||||
}
|
||||
|
||||
function setClickToWorld(canvas, matrix) {
|
||||
@ -739,9 +741,9 @@ const curves = {
|
||||
if (znormal < 0) {
|
||||
return; // skip faces facing backwards
|
||||
}
|
||||
const ltw = canvas.getLocalToWorld();
|
||||
// shader expects the 4x4 matrices in column major order.
|
||||
const uniforms = [...CanvasKit.SkM44.transpose(ltw), ...mustInvert(ltw), ...lightWorldPos];
|
||||
// Pad with space for two 4x4 matrices. Even though the shader uses a layout()
|
||||
// statement to populate them, we still have to reserve space for them.
|
||||
const uniforms = [...lightWorldPos, ...Array(32).fill(0)];
|
||||
const paint = new CanvasKit.SkPaint();
|
||||
paint.setAntiAlias(true);
|
||||
const shader = fact.makeShaderWithChildren(uniforms, true /*=opaque*/, children);
|
||||
|
@ -985,6 +985,21 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
.function("makeSurface", optional_override([](SkCanvas& self, SimpleImageInfo sii)->sk_sp<SkSurface> {
|
||||
return self.makeSurface(toSkImageInfo(sii), nullptr);
|
||||
}), allow_raw_pointers())
|
||||
.function("markCTM", optional_override([](SkCanvas& self, std::string marker) {
|
||||
self.markCTM(marker.c_str());
|
||||
}))
|
||||
.function("_findMarkedCTM", optional_override([](SkCanvas& self, std::string marker, uintptr_t /* SkScalar* */ mPtr) -> bool {
|
||||
SkScalar* sixteenMatrixValues = reinterpret_cast<SkScalar*>(mPtr);
|
||||
if (!sixteenMatrixValues) {
|
||||
return false; // matrix cannot be null
|
||||
}
|
||||
SkM44 m;
|
||||
if (self.findMarkedCTM(marker.c_str(), &m)) {
|
||||
m.getRowMajor(sixteenMatrixValues);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}))
|
||||
.function("_readPixels", optional_override([](SkCanvas& self, SimpleImageInfo di,
|
||||
uintptr_t /* uint8_t* */ pPtr,
|
||||
size_t dstRowBytes, int srcX, int srcY) {
|
||||
|
@ -200,6 +200,8 @@ var CanvasKit = {
|
||||
flush: function() {},
|
||||
getSaveCount: function() {},
|
||||
makeSurface: function() {},
|
||||
markCTM: function() {},
|
||||
findMarkedCTM: function() {},
|
||||
restore: function() {},
|
||||
restoreToCount: function() {},
|
||||
rotate: function() {},
|
||||
@ -227,6 +229,7 @@ var CanvasKit = {
|
||||
_getLocalToDevice: function() {},
|
||||
_getLocalToWorld: function() {},
|
||||
_getTotalMatrix: function() {},
|
||||
_findMarkedCTM: function() {},
|
||||
_readPixels: function() {},
|
||||
_writePixels: function() {},
|
||||
delete: function() {},
|
||||
|
@ -978,6 +978,18 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
return copy4x4MatrixFromWasm(matrPtr);
|
||||
}
|
||||
|
||||
// findMarkedCTM returns a 4x4 matrix, or null if a matrix was not found at
|
||||
// the provided marker.
|
||||
CanvasKit.SkCanvas.prototype.findMarkedCTM = function(marker) {
|
||||
var matrPtr = CanvasKit._malloc(16 * 4); // allocate space for the matrix
|
||||
// _getLocalToDevice will copy the values into the pointer.
|
||||
var found = this._findMarkedCTM(marker, matrPtr);
|
||||
if (!found) {
|
||||
return null;
|
||||
}
|
||||
return copy4x4MatrixFromWasm(matrPtr);
|
||||
}
|
||||
|
||||
// getTotalMatrix returns the current matrix as a 3x3 matrix.
|
||||
CanvasKit.SkCanvas.prototype.getTotalMatrix = function() {
|
||||
var matrPtr = CanvasKit._malloc(9 * 4); // allocate space for the matrix
|
||||
|
@ -579,6 +579,26 @@ describe('Canvas Behavior', () => {
|
||||
}
|
||||
};
|
||||
|
||||
it('can mark a CTM and retrieve it', () => {
|
||||
const canvas = new CanvasKit.SkCanvas();
|
||||
|
||||
canvas.concat(CanvasKit.SkM44.rotated([0, 1, 0], Math.PI/4));
|
||||
canvas.concat(CanvasKit.SkM44.rotated([1, 0, 1], Math.PI/8));
|
||||
canvas.markCTM('krispykreme');
|
||||
|
||||
const expected = CanvasKit.SkM44.multiply(
|
||||
CanvasKit.SkM44.rotated([0, 1, 0], Math.PI/4),
|
||||
CanvasKit.SkM44.rotated([1, 0, 1], Math.PI/8),
|
||||
);
|
||||
|
||||
expect4x4MatricesToMatch(expected, canvas.findMarkedCTM('krispykreme'));
|
||||
});
|
||||
|
||||
it('returns null for an invalid CTM marker', () => {
|
||||
const canvas = new CanvasKit.SkCanvas();
|
||||
expect(canvas.findMarkedCTM('dunkindonuts')).toBeNull();
|
||||
});
|
||||
|
||||
it('can change the 4x4 matrix on the canvas and read it back', () => {
|
||||
const canvas = new CanvasKit.SkCanvas();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user