diff --git a/src/lib/scene/mesh.ts b/src/lib/scene/mesh.ts index 6496c3f..aac71b5 100644 --- a/src/lib/scene/mesh.ts +++ b/src/lib/scene/mesh.ts @@ -178,7 +178,7 @@ export class OBJ extends Mesh { finalVertices.push(pos[0], pos[1], pos[2], nor[0], nor[1], nor[2], uv[0], uv[1], 1); - vertexMap.set(key, finalVertices.length / 8 - 1); + vertexMap.set(key, finalVertices.length / 9 - 1); } faceVertices.push(vertexMap.get(key)!); diff --git a/src/lib/shaders/instance_points.cs.wgsl b/src/lib/shaders/instance_points.cs.wgsl index 7dadcb3..31245b4 100644 --- a/src/lib/shaders/instance_points.cs.wgsl +++ b/src/lib/shaders/instance_points.cs.wgsl @@ -85,11 +85,22 @@ fn main(@builtin(global_invocation_id) id: vec3) { let height = mix(mix(h_bl, h_br, fx), mix(h_tl, h_tr, fx), fz); let normal = normalize(mix(mix(nor_bl, nor_br, fx), mix(nor_tl, nor_tr, fx), fz)); + // rotate in a random direction + let rnd = hash11(f32(id.x) + 1234.0); + let angle = rnd * 6.2831853; + let c = cos(angle); + let t = tan(angle); + // do all the annoying calc in here, then store it in instance_pts... let helper = select(vec3f(0.0, 1.0, 0.0), vec3f(1.0, 0.0, 0.0), abs(normal.y) > 0.99); let T = normalize(cross(helper, normal)); let B = cross(normal, T); - let rot = mat3x3f(T, B, normal); + + let T_rot = normalize(T * c + B * t); + let B_rot = normalize(cross(normal, T_rot)); + let rot = mat3x3f(T_rot, B_rot, normal); + //let rot = mat3x3f(T, B, normal); + instance_pts[id.x].pos = vec3(x, height, z); instance_pts[id.x].nor = vec3(normal.x, normal.y, normal.z); diff --git a/src/lib/shaders/instancing.wgsl b/src/lib/shaders/instancing.wgsl index 9723a01..5d939fe 100644 --- a/src/lib/shaders/instancing.wgsl +++ b/src/lib/shaders/instancing.wgsl @@ -33,18 +33,28 @@ struct VertexOut { @location(4) @interpolate(flat) used: u32, }; +fn hash11(n: f32) -> f32 { + let x = fract(sin(n) * 43758.5453123); + return x; +} + +fn rotateAroundAxis(v: vec3f, axis: vec3f, angle: f32) -> vec3f { + let cosA = cos(angle); + let sinA = sin(angle); + return v * cosA + + cross(axis, v) * sinA + + axis * dot(axis, v) * (1.0 - cosA); +} + @vertex fn vs_main(in : VertexIn) -> VertexOut { var out : VertexOut; let vOffset = in.instance_index * 9u; - // get point position + // get point data var pos = instance_pts[in.instance_index].pos; - - // point nor for testing... var nor = normalize(instance_pts[in.instance_index].nor); - var used = instance_pts[in.instance_index].used; let idx = indices[in.vertex_index]; @@ -64,9 +74,12 @@ fn vs_main(in : VertexIn) -> VertexOut { // do transformations let rot = instance_pts[in.instance_index].rotMat; - let rotated = rot * local; - let world = transform_matrix * vec4(pos + rotated, 1.0); - let world_pos = camera.viewProjMat * world; + let rotatedLocal = rot * local; + let transformedLocal = (transform_matrix * vec4(rotatedLocal, 0.0)).xyz; + + // translate + let worldPos = pos + transformedLocal; + let clipPos = camera.viewProjMat * vec4(worldPos, 1.0); // transform normals too let normal_matrix = mat3x3( @@ -74,13 +87,13 @@ fn vs_main(in : VertexIn) -> VertexOut { transform_matrix[1].xyz, transform_matrix[2].xyz ); - let transformed_nor = rot * vert_nor; - let new_nor = normalize(normal_matrix * transformed_nor); + let transformedNor = normal_matrix * (rot * vert_nor); + let newNor = normalize(transformedNor); // set output - out.position = world_pos; - out.pos = world_pos.xyz; - out.nor = normalize(new_nor); + out.position = clipPos; + out.pos = worldPos; + out.nor = normalize(newNor); out.uv = vert_uv; out.tex_id = texture_id; out.used = used; @@ -94,31 +107,20 @@ fn fs_main(in: VertexOut) -> @location(0) vec4f discard; } - // do lambertian shading - let lightDir = normalize(vec3f(-1.0, 1.0, -1.0)); - let diffuse = max(dot(in.nor, lightDir), 0.0); - let texcoord = vec2f(in.uv.x, 1.0 - in.uv.y); - let color = textureSample(ourTexture, ourSampler, texcoord, in.tex_id); - //let color = vec4(in.uv.x, in.uv.y, 0.0, 1.0); + let diffuse = textureSample(ourTexture, ourSampler, texcoord, in.tex_id); - if (color.a < 0.5) { + if (diffuse.a < 0.5) { discard; } - return color; - - // var color = vec3f(0.0, 0.0, 0.0); - - // if (diffuse > 0.75) { - // color = vec3f(0.58, 1.0, 0.235); - // } else if (diffuse > 0.5) { - // color = vec3f(0.447, 0.749, 0.313); - // } else if (diffuse > 0.25) { - // color = vec3f(0.309, 0.490, 0.396); - // } else { - // color = vec3f(0.176, 0.235, 0.478); - // } - - // return vec4f(color, 1.0); + // do lambertian shading + let lightDir = normalize(vec3f(0.2, 0.25, 0.1)); + var directionalLightStrength = max(dot(in.nor, lightDir), 0.0); + let directLight = vec3f(1.0, 0.95, 0.8) * directionalLightStrength; + + let ambientLight = vec3f(0.1, 0.1, 0.1); + + var color = diffuse.xyz * (directLight + ambientLight); + return vec4f(color, 1.0); }