From 5c2be2e14798dc32b71b7bd1985681ceeb3c2ee2 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Sat, 25 May 2024 04:22:24 +0300 Subject: [PATCH] add textures, colors Co-authored-by: Ilya --- prismarine-viewer/examples/Cube.frag.wgsl | 5 +-- prismarine-viewer/examples/Cube.vert.wgsl | 7 ++-- prismarine-viewer/examples/playground.ts | 5 ++- prismarine-viewer/examples/shared.ts | 4 +-- .../examples/webgpuRendererWorker.ts | 36 ++++++++++++++++--- prismarine-viewer/viewer/lib/mesher/models.ts | 26 +++++++++++--- 6 files changed, 65 insertions(+), 18 deletions(-) diff --git a/prismarine-viewer/examples/Cube.frag.wgsl b/prismarine-viewer/examples/Cube.frag.wgsl index 1974feca..211ad077 100644 --- a/prismarine-viewer/examples/Cube.frag.wgsl +++ b/prismarine-viewer/examples/Cube.frag.wgsl @@ -4,7 +4,8 @@ @fragment fn main( @location(0) fragUV: vec2f, - @location(1) TextueIndex: f32 + @location(1) @interpolate(flat) TextueIndex: f32, + @location(2) @interpolate(flat) ColorBlend : vec3f ) -> @location(0) vec4f { - return textureSample(myTexture, mySampler, fragUV/64.0 + vec2f(TextueIndex%32,TextueIndex/32.0 )/32.0); + return textureSample(myTexture, mySampler, fragUV/64.0 + vec2f(trunc(TextueIndex/32.0),trunc(TextueIndex%32) )/32.0) * vec4f(ColorBlend,1.0); } diff --git a/prismarine-viewer/examples/Cube.vert.wgsl b/prismarine-viewer/examples/Cube.vert.wgsl index 7898c88f..97d73330 100644 --- a/prismarine-viewer/examples/Cube.vert.wgsl +++ b/prismarine-viewer/examples/Cube.vert.wgsl @@ -6,7 +6,8 @@ struct Uniforms { struct VertexOutput { @builtin(position) Position : vec4f, @location(0) fragUV : vec2f, - @location(1) TextueIndex: f32 + @location(1) @interpolate(flat) TextueIndex: f32, + @location(2) @interpolate(flat) ColorBlend : vec3f } @vertex @@ -14,11 +15,13 @@ fn main( @location(0) position : vec4f, @location(1) uv : vec2f, @location(2) ModelMatrix : vec3f, - @location(3) TextureIndex : f32 + @location(3) TextureIndex : f32, + @location(4) ColorBlend : vec3f ) -> VertexOutput { var output : VertexOutput; output.Position = uniforms.ViewProjectionMatrix * (position +vec4f(ModelMatrix, 0.0)); output.fragUV = uv; output.TextueIndex = TextureIndex; + output.ColorBlend = ColorBlend; return output; } diff --git a/prismarine-viewer/examples/playground.ts b/prismarine-viewer/examples/playground.ts index fb82342e..43e4e079 100644 --- a/prismarine-viewer/examples/playground.ts +++ b/prismarine-viewer/examples/playground.ts @@ -12,7 +12,6 @@ import JSZip from 'jszip' import { TWEEN_DURATION } from '../viewer/lib/entities' import { EntityMesh } from '../viewer/lib/entity/EntityMesh' // import * as Mathgl from 'math.gl' -import { findTextureInBlockStates } from '../../src/playerWindows' import { initWebgpuRenderer, loadFixtureSides, setAnimationTick, webgpuChannel } from './webgpuRendererMain' import { renderToDom } from '@zardoy/react-util' @@ -261,12 +260,12 @@ async function main () { const pos = new Vec3(Math.floor(Math.random() * max), Math.floor(Math.random() * max), Math.floor(Math.random() * max)) const getFace = (face: number) => { return { - face, + side: face, textureIndex: Math.floor(Math.random() * 512) } } blocks[`${pos.x},${pos.y},${pos.z}`] = { - sides: [ + faces: [ getFace(0), getFace(1), getFace(2), diff --git a/prismarine-viewer/examples/shared.ts b/prismarine-viewer/examples/shared.ts index 318396fa..4ef9b417 100644 --- a/prismarine-viewer/examples/shared.ts +++ b/prismarine-viewer/examples/shared.ts @@ -1,5 +1,5 @@ export type BlockFaceType = { - face: number + side: number textureIndex: number textureName?: string tint?: [number, number, number] @@ -7,5 +7,5 @@ export type BlockFaceType = { } export type BlockType = { - sides: BlockFaceType[] + faces: BlockFaceType[] } diff --git a/prismarine-viewer/examples/webgpuRendererWorker.ts b/prismarine-viewer/examples/webgpuRendererWorker.ts index f066cbb9..fb244370 100644 --- a/prismarine-viewer/examples/webgpuRendererWorker.ts +++ b/prismarine-viewer/examples/webgpuRendererWorker.ts @@ -53,6 +53,7 @@ class WebgpuRendererWorker { InstancedModelBuffer: GPUBuffer pipeline: GPURenderPipeline InstancedTextureIndexBuffer: GPUBuffer + InstancedColorBuffer: GPUBuffer constructor(public canvas: HTMLCanvasElement, public imageBlob: ImageBitmapSource, public isPlayground: boolean, public FragShaderOverride?) { this.init() @@ -108,6 +109,12 @@ class WebgpuRendererWorker { mappedAtCreation: true, }) + this.InstancedColorBuffer = device.createBuffer({ + size: this.NUMBER_OF_CUBES * 4 * 3, + usage: GPUBufferUsage.VERTEX || GPUBufferUsage.MAP_WRITE, + mappedAtCreation: true, + }) + //device.StepM const vertexCode = VertShader @@ -160,6 +167,18 @@ class WebgpuRendererWorker { } ], stepMode: 'instance', + }, + { + arrayStride: 3 * 4, + attributes: [ + { + // ModelMatrix + shaderLocation: 4, + offset: 0, + format: 'float32x3', + } + ], + stepMode: 'instance', } ], @@ -217,7 +236,8 @@ class WebgpuRendererWorker { { cubeTexture = device.createTexture({ size: [textureBitmap.width, textureBitmap.height, 1], - format: 'rgba8unorm', + //format: 'rgba8unorm', + format: 'rgb10a2unorm', usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | @@ -259,7 +279,7 @@ class WebgpuRendererWorker { colorAttachments: [ { view: undefined as any, // Assigned later - clearValue: [0.5, 0.5, 0.5, 1.0], + clearValue: [0.6784313725490196, 0.8470588235294118, 0.9019607843137255, 1.0], loadOp: 'clear', storeOp: 'store', }, @@ -285,10 +305,12 @@ class WebgpuRendererWorker { rendering = true const positions = [] as number[] let textureIndexes = [] as number[] + let colors = [] as number[] for (let i = 0; i < allSides.length / 6; i++) { const side = allSides[i * 6]! positions.push(...[side[0], side[1], side[2]]) textureIndexes.push(side[3].textureIndex) + colors.push(1, 1, 1) } //Todo: make this dynamic @@ -303,6 +325,9 @@ class WebgpuRendererWorker { new Float32Array(this.InstancedTextureIndexBuffer.getMappedRange()).set(new Float32Array(textureIndexes)) this.InstancedTextureIndexBuffer.unmap() + new Float32Array(this.InstancedColorBuffer.getMappedRange()).set(new Float32Array(colors)) + this.InstancedColorBuffer.unmap() + // this.NUMBER_OF_CUBES = positions.length } @@ -347,6 +372,7 @@ class WebgpuRendererWorker { passEncoder.setVertexBuffer(0, verticesBuffer) passEncoder.setVertexBuffer(1, this.InstancedModelBuffer) passEncoder.setVertexBuffer(2, this.InstancedTextureIndexBuffer) + passEncoder.setVertexBuffer(3, this.InstancedColorBuffer) passEncoder.draw(cubeVertexCount, this.NUMBER_OF_CUBES) @@ -399,7 +425,7 @@ export const workerProxyType = createWorkerProxy({ const newData = Object.entries(data.blocks).flatMap(([key, value]) => { const [x, y, z] = key.split(',').map(Number) const block = value as BlockType - return block.sides.map((side) => { + return block.faces.map((side) => { return [x, y, z, side] as [number, number, number, BlockFaceType] }) }) @@ -482,7 +508,7 @@ export const workerProxyType = createWorkerProxy({ // }) const dataSize = json.length / 5 for (let i = 0; i < json.length; i += 5) { - allSides.push([json[i], json[i + 1], json[i + 2], { face: json[i + 3], textureIndex: json[i + 4] }]) + allSides.push([json[i], json[i + 1], json[i + 2], { side: json[i + 3], textureIndex: json[i + 4] }]) } updateCubesWhenAvailable(0) }, @@ -505,7 +531,7 @@ const exportData = () => { const sideData = allSides[i] if (!sideData) continue const [x, y, z, side] = sideData - flatData.set([x, y, z, side.face, side.textureIndex], i * 5) + flatData.set([x, y, z, side.side, side.textureIndex], i * 5) } return { sides: flatData } diff --git a/prismarine-viewer/viewer/lib/mesher/models.ts b/prismarine-viewer/viewer/lib/mesher/models.ts index bfb96d11..16fe7d41 100644 --- a/prismarine-viewer/viewer/lib/mesher/models.ts +++ b/prismarine-viewer/viewer/lib/mesher/models.ts @@ -2,6 +2,7 @@ import { Vec3 } from 'vec3' import type { BlockStatesOutput } from '../../prepare/modelsBuilder' import { World } from './world' import { Block } from 'prismarine-block' +import { BlockType } from '../../../examples/shared' const tints: any = {} let blockStates: BlockStatesOutput @@ -17,6 +18,19 @@ for (const key of Object.keys(tintsData)) { tints[key] = prepareTints(tintsData[key]) } +type TestTileData = { + block: string + faces: { + face: string + neighbor: string + light?: number + }[] +} + +type Tiles = { + [blockPos: string]: BlockType & TestTileData +} + function prepareTints (tints) { const map = new Map() const defaultValue = tintToGl(tints.default) @@ -171,11 +185,12 @@ function renderLiquid (world, cursor, texture, type, biome, water, attr) { } if (needTiles) { - attr.tiles[`${cursor.x},${cursor.y},${cursor.z}`] ??= { + const tiles = attr.tiles as Tiles + tiles[`${cursor.x},${cursor.y},${cursor.z}`] ??= { block: 'water', faces: [], } - attr.tiles[`${cursor.x},${cursor.y},${cursor.z}`].faces.push({ + tiles[`${cursor.x},${cursor.y},${cursor.z}`].faces.push({ face, neighbor: `${neighborPos.x},${neighborPos.y},${neighborPos.z}`, // texture: eFace.texture.name, @@ -410,12 +425,15 @@ function renderElement (world: World, cursor: Vec3, element, doAO: boolean, attr } if (needTiles) { - attr.tiles[`${cursor.x},${cursor.y},${cursor.z}`] ??= { + const tiles = attr.tiles as Tiles + tiles[`${cursor.x},${cursor.y},${cursor.z}`] ??= { block: block.name, faces: [], } - attr.tiles[`${cursor.x},${cursor.y},${cursor.z}`].faces.push({ + tiles[`${cursor.x},${cursor.y},${cursor.z}`].faces.push({ face, + side: eFace.texture.side, + textureIndex: 0, neighbor: `${neighborPos.x},${neighborPos.y},${neighborPos.z}`, light: baseLight // texture: eFace.texture.name,