shaders
This commit is contained in:
@@ -61,9 +61,9 @@ var base_pipeline = {
|
||||
primitive: "triangle", // point, line, linestrip, triangle, trianglestrip
|
||||
fill: true, // false for lines
|
||||
depth: {
|
||||
compare: "always", // never/less/equal/less_equal/greater/not_equal/greater_equal/always
|
||||
compare: "greater_equal", // never/less/equal/less_equal/greater/not_equal/greater_equal/always
|
||||
test: true,
|
||||
write: false,
|
||||
write: true,
|
||||
bias: 0,
|
||||
bias_slope_scale: 0,
|
||||
bias_clamp: 0
|
||||
@@ -106,13 +106,68 @@ var base_pipeline = {
|
||||
label: "scripted pipeline"
|
||||
}
|
||||
|
||||
var pipeline_3d = Object.create(base_pipeline);
|
||||
/* rendering modes
|
||||
ps1
|
||||
gouraud
|
||||
diffuse // 16 bit color, 5-5-5
|
||||
7 dynamic lights, 1 ambient
|
||||
textures are affine
|
||||
no vertex skinning
|
||||
256x256 texture max (generally 128x128)
|
||||
320x240, variable up to 640x480
|
||||
|
||||
function use_pipeline(pipeline) {
|
||||
if (!pipeline.gpu)
|
||||
pipeline.gpu = gpu.make_pipeline(pipeline);
|
||||
render._main.set_pipeline(pipeline);
|
||||
}
|
||||
n64
|
||||
gouraud
|
||||
diffuse
|
||||
combiner // a secondary texture sometimes used to combine
|
||||
7 dynamic lights, 1 ambient
|
||||
320x240, or 640x480
|
||||
|
||||
sega saturn
|
||||
gouraud
|
||||
diffuse
|
||||
320x240 or 640x480
|
||||
|
||||
ps2
|
||||
phong
|
||||
diffuse
|
||||
combiner // second texture for modulation of diffuse
|
||||
combine_mode // int for how to combine
|
||||
|
||||
dreamcast
|
||||
phong
|
||||
diffuse
|
||||
combiner // second texture; could be an environment map, or emboss bump mapping
|
||||
fog
|
||||
640x480
|
||||
640x448, special mode to 1280x1024
|
||||
|
||||
gamecube
|
||||
phong
|
||||
diffuse
|
||||
+7 textures // wow!
|
||||
8 dynamic lights
|
||||
640x480
|
||||
|
||||
*/
|
||||
|
||||
/* meshes
|
||||
position (float3)
|
||||
color (rgba)
|
||||
uv
|
||||
*/
|
||||
|
||||
/* materials, modern pbr
|
||||
any object can act as a "material". The engine expects some standardized things:
|
||||
diffuse - base color texture
|
||||
bump - a normal map for dot3 bump maping used in phong shading
|
||||
height - a grayscale heightmap
|
||||
occlusion - ambient occlusion texture
|
||||
emission - texture for where model emits light
|
||||
bump2 - a second normal map for detail
|
||||
metallic - a metal/smoothness map
|
||||
specular - specular map, alternative for the metallic workflow
|
||||
*/
|
||||
|
||||
render.poly_prim = function poly_prim(verts) {
|
||||
var index = [];
|
||||
@@ -155,100 +210,92 @@ render.hotreload = function shader_hotreload() {
|
||||
}
|
||||
};
|
||||
|
||||
function make_shader(shader, ...args) {
|
||||
var file = `shaders/spirv/${shader}.spv`;
|
||||
if (shader_cache[file]) return shader_cache[file];
|
||||
shader = io.slurpbytes(file);
|
||||
shader = render._main.make_shader(shader, ...args);
|
||||
shader_cache[file] = shader;
|
||||
return shader;
|
||||
}
|
||||
function make_pipeline(pipeline) {
|
||||
// 1) Reflection data for vertex shader
|
||||
var refl = pipeline.vertex.reflection
|
||||
if (!refl || !refl.inputs || !Array.isArray(refl.inputs)) {
|
||||
// If there's no reflection data, just pass pipeline along
|
||||
// or throw an error if reflection is mandatory
|
||||
render._main.make_pipeline(pipeline)
|
||||
return
|
||||
}
|
||||
|
||||
function shader_apply_material(shader, material = {}, old = {}) {
|
||||
render.setpipeline(cur.pipeline);
|
||||
for (var p in shader.vs.unimap) {
|
||||
if (!(p in material)) continue;
|
||||
if (material[p] === old[p]) continue;
|
||||
assert(p in material, `shader ${shader.name} has no uniform for ${p}`);
|
||||
var s = shader.vs.unimap[p];
|
||||
var inputs = refl.inputs
|
||||
var buffer_descriptions = []
|
||||
var attributes = []
|
||||
|
||||
if (p === "bones") {
|
||||
render.setunibones(0, s.slot, material[p]);
|
||||
continue;
|
||||
// 2) For each input in the reflection, build one buffer + attribute
|
||||
// (Simplest approach: each input is stored in its own slot, offset=0)
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
var inp = inputs[i]
|
||||
var typeStr = inp.type
|
||||
var nameStr = (inp.name || "").toUpperCase()
|
||||
var pitch = 4 // fallback if unknown
|
||||
var fmt = "float1"
|
||||
|
||||
// Decide pitch & format based on 'type'
|
||||
if (typeStr == "vec2") {
|
||||
pitch = 8
|
||||
fmt = "float2"
|
||||
} else if (typeStr == "vec3") {
|
||||
pitch = 12
|
||||
fmt = "float3"
|
||||
} else if (typeStr == "vec4") {
|
||||
// Special case: if "COLOR" is in the name, treat it as packed bytes
|
||||
if (nameStr.indexOf("COLOR") >= 0) {
|
||||
pitch = 4
|
||||
fmt = "color" // signals engine to use SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4NORM
|
||||
} else {
|
||||
pitch = 16
|
||||
fmt = "float4"
|
||||
}
|
||||
}
|
||||
|
||||
shader_unisize[s.size](0, s.slot, material[p]);
|
||||
// Create a buffer description for this input
|
||||
buffer_descriptions.push({
|
||||
slot: i,
|
||||
pitch: pitch,
|
||||
input_rate: "vertex",
|
||||
instance_step_rate: 0,
|
||||
name:inp.name.split(".").pop()
|
||||
})
|
||||
|
||||
// Create a matching vertex attribute
|
||||
attributes.push({
|
||||
location: inp.location,
|
||||
buffer_slot: i,
|
||||
format: fmt,
|
||||
offset: 0
|
||||
})
|
||||
}
|
||||
|
||||
for (var p in shader.fs.unimap) {
|
||||
if (!(p in material)) continue;
|
||||
if (material[p] === old[p]) continue;
|
||||
assert(p in material, `shader ${shader.name} has no uniform for ${p}`);
|
||||
var s = shader.fs.unimap[p];
|
||||
shader_unisize[s.size](1, s.slot, material[p]);
|
||||
}
|
||||
// 3) Attach these arrays onto the pipeline object
|
||||
pipeline.vertex_buffer_descriptions = buffer_descriptions
|
||||
pipeline.vertex_attributes = attributes
|
||||
|
||||
if (!material.diffuse) return;
|
||||
if (material.diffuse === old.diffuse) return;
|
||||
|
||||
if ("diffuse_texel" in shader.fs.unimap) render.setuniv2(1, shader.fs.unimap.diffuse_texel.slot, [1,1].div([material.diffuse.width, material.diffuse.height]));
|
||||
|
||||
if ("diffuse_size" in shader.fs.unimap) render.setuniv2(1, shader.fs.unimap.diffuse_size.slot, [material.diffuse.width, material.diffuse.height]);
|
||||
|
||||
if ("diffuse_size" in shader.vs.unimap) render.setuniv2(0, shader.vs.unimap.diffuse_size.slot, [material.diffuse.width, material.diffuse.height]);
|
||||
// 4) Hand off the pipeline to native code
|
||||
console.log(`depth: ${json.encode(pipeline.depth)}`);
|
||||
return render._main.make_pipeline(pipeline)
|
||||
}
|
||||
|
||||
// Creates a binding object for a given mesh and shader
|
||||
var bcache = new WeakMap();
|
||||
function sg_bind(mesh, ssbo) {
|
||||
if (cur.bind && cur.mesh === mesh && cur.ssbo === ssbo) {
|
||||
if (ssbo)
|
||||
cur.bind.ssbo = [ssbo];
|
||||
else
|
||||
cur.bind.ssbo = undefined;
|
||||
cur.bind.images = cur.images;
|
||||
cur.bind.samplers = cur.samplers;
|
||||
render.setbind(cur.bind);
|
||||
return;
|
||||
function make_shader(sh_file) {
|
||||
var file = `shaders/spirv/${sh_file}.spv`
|
||||
var refl = json.decode(io.slurp(`shaders/reflection/${sh_file}.json`))
|
||||
if (shader_cache[file]) return shader_cache[file]
|
||||
|
||||
var shader = {
|
||||
code: io.slurpbytes(file),
|
||||
stage: sh_file.endsWith("vert") ? "vertex" : "fragment",
|
||||
num_samplers: refl.separate_samplers ? refl.separate_samplers.length : 0,
|
||||
num_textures: 0,
|
||||
num_storage_buffers: refl.separate_storage_buffers ? refl.separate_storage_buffers.length : 0,
|
||||
num_uniform_buffers: refl.ubos ? refl.ubos.length : 0
|
||||
}
|
||||
|
||||
/* if (bcache.has(cur.shader) && bcache.get(cur.shader).has(mesh)) {
|
||||
cur.bind = bcache.get(cur.shader).get(mesh);
|
||||
cur.bind.images = cur.images;
|
||||
cur.bind.samplers = cur.samplers;
|
||||
if (ssbo)
|
||||
cur.bind.ssbo = [ssbo];
|
||||
render.setbind(cur.bind);
|
||||
return;
|
||||
}*/
|
||||
var bind = {};/* if (!bcache.has(cur.shader)) bcache.set(cur.shader, new WeakMap());
|
||||
if (!bcache.get(cur.shader).has(mesh)) bcache.get(cur.shader).set(mesh, bind);*/
|
||||
cur.mesh = mesh;
|
||||
cur.ssbo = ssbo;
|
||||
cur.bind = bind;
|
||||
bind.attrib = [];
|
||||
if (cur.shader.vs.inputs)
|
||||
for (var a of cur.shader.vs.inputs) {
|
||||
if (!(a.name in mesh)) {
|
||||
console.error(`cannot draw shader ${cur.shader.name}; there is no attrib ${a.name} in the given mesh. ${json.encode(mesh)}`);
|
||||
return undefined;
|
||||
} else bind.attrib.push(mesh[a.name]);
|
||||
}
|
||||
|
||||
if (cur.shader.indexed) {
|
||||
bind.index = mesh.index;
|
||||
bind.count = mesh.count;
|
||||
} else bind.count = mesh.verts;
|
||||
|
||||
bind.ssbo = [];
|
||||
if (cur.shader.vs.storage_buffers) for (var b of cur.shader.vs.storage_buffers) bind.ssbo.push(ssbo);
|
||||
|
||||
bind.images = cur.images;
|
||||
bind.samplers = cur.samplers;
|
||||
|
||||
render.setbind(cur.bind);
|
||||
|
||||
return bind;
|
||||
shader.gpu = render._main.make_shader(shader)
|
||||
shader.reflection = refl;
|
||||
shader_cache[file] = shader
|
||||
return shader
|
||||
}
|
||||
|
||||
render.device = {
|
||||
@@ -290,7 +337,9 @@ var sprite_stack = [];
|
||||
render.device.doc = `Device resolutions given as [x,y,inches diagonal].`;
|
||||
var std_sampler;
|
||||
|
||||
function upload_model(model)
|
||||
var tbuffer;
|
||||
var spritemesh;
|
||||
function upload_model(cmds, model)
|
||||
{
|
||||
var bufs = [];
|
||||
for (var i in model) {
|
||||
@@ -298,26 +347,58 @@ function upload_model(model)
|
||||
if (i === 'indices') model[i].index = true;
|
||||
bufs.push(model[i]);
|
||||
}
|
||||
render._main.upload(bufs);
|
||||
tbuffer = render._main.upload(cmds, bufs, tbuffer);
|
||||
}
|
||||
|
||||
var campos = [0,0,500];
|
||||
|
||||
function bind_model(pass, model, pipeline)
|
||||
{
|
||||
var buffers = pipeline.vertex_buffer_descriptions;
|
||||
var bufs = [];
|
||||
for (var b of buffers) {
|
||||
if (b.name in model)
|
||||
bufs.push(model[b.name])
|
||||
else
|
||||
throw Error (`could not find buffer ${b.name} on model`);
|
||||
}
|
||||
pass.bind_buffers(0,bufs);
|
||||
pass.bind_index_buffer(model.indices);
|
||||
}
|
||||
|
||||
function bind_mat(pass, mat, pipeline)
|
||||
{
|
||||
var imgs = [];
|
||||
var refl = pipeline.fragment.reflection;
|
||||
if (refl.separate_images) {
|
||||
for (var i of pipeline.fragment.reflection.separate_images) {
|
||||
if (i.name in mat) {
|
||||
var tex = mat[i.name];
|
||||
imgs.push({texture:tex.texture, sampler:tex.sampler});
|
||||
} else
|
||||
throw Error (`could not find all necessary images: ${i.name}`)
|
||||
}
|
||||
pass.bind_samplers(false, 0,imgs);
|
||||
}
|
||||
}
|
||||
|
||||
function gpupresent()
|
||||
{
|
||||
var cmds = render._main.acquire_cmd_buffer();
|
||||
var myimg = game.texture("pockle");
|
||||
myimg.sampler = std_sampler;
|
||||
var spritemesh = render._main.make_sprite_mesh(sprite_stack);
|
||||
upload_model(spritemesh);
|
||||
|
||||
spritemesh = render._main.make_sprite_mesh(sprite_stack, spritemesh);
|
||||
upload_model(cmds, spritemesh);
|
||||
cmds.submit();
|
||||
sprite_stack.length = 0;
|
||||
|
||||
var cmds = render._main.acquire_cmd_buffer();
|
||||
cmds = render._main.acquire_cmd_buffer();
|
||||
|
||||
var pass = cmds.render_pass();
|
||||
try{
|
||||
pass.bind_pipeline(base_pipeline.gpu);
|
||||
pass.bind_model(spritemesh);
|
||||
pass.bind_mat({diffuse:myimg});
|
||||
bind_model(pass,spritemesh,base_pipeline);
|
||||
bind_mat(pass,{diffuse:myimg}, base_pipeline);
|
||||
cmds.camera(prosperon.camera.transform);
|
||||
pass.draw(spritemesh.count,1,0,0,0);
|
||||
prosperon.camera.transform.pos = campos;
|
||||
@@ -328,12 +409,14 @@ try{
|
||||
prosperon.camera.far = 100000;
|
||||
cmds.camera_perspective(prosperon.camera);
|
||||
pass.bind_pipeline(pipeline_model.gpu);
|
||||
pass.bind_model(ducky);
|
||||
pass.draw(ducky.count,1,0,0,0);
|
||||
cmds.camera(prosperon.camera.transform, true);
|
||||
pass.bind_pipeline(base_pipeline.gpu);
|
||||
pass.draw(spritemesh.count,1,0,0,0);
|
||||
} catch(e) { console.log(e); } finally {
|
||||
bind_model(pass,ducky.mesh,pipeline_model);
|
||||
bind_mat(pass,ducky.material,pipeline_model);
|
||||
pass.draw(ducky.mesh.count,1,0,0,0);
|
||||
|
||||
// cmds.camera(prosperon.camera.transform, true);
|
||||
// pass.bind_pipeline(base_pipeline.gpu);
|
||||
// pass.draw(spritemesh.count,1,0,0,0);
|
||||
} catch(e) { console.error(e); } finally {
|
||||
pass.end();
|
||||
cmds.submit();
|
||||
}
|
||||
@@ -344,24 +427,6 @@ var ducky;
|
||||
var pipeline_model;
|
||||
|
||||
render.init = function () {
|
||||
io.mount("core");
|
||||
render._main.present = gpupresent;
|
||||
ducky = os.model_buffer("Duck.glb");
|
||||
upload_model(ducky);
|
||||
for (var i in ducky) console.log(`ducky has ${i}`)
|
||||
console.log(ducky.count)
|
||||
var sprite_vert = make_shader("sprite.vert", true,0,0,0,1);
|
||||
var sprite_frag = make_shader("sprite.frag", false,1,0,0,0);
|
||||
base_pipeline.vertex = sprite_vert;
|
||||
base_pipeline.fragment = sprite_frag;
|
||||
base_pipeline.gpu = render._main.make_pipeline(base_pipeline);
|
||||
var model_vert = make_shader("model.vert", true, 0,0,0,1);
|
||||
var model_frag = make_shader("model.frag", false, 0,0,0,0);
|
||||
pipeline_model = Object.create(base_pipeline);
|
||||
pipeline_model.vertex = model_vert;
|
||||
pipeline_model.fragment = model_frag;
|
||||
pipeline_model.gpu = render._main.make_pipeline(pipeline_model);
|
||||
|
||||
std_sampler = render._main.make_sampler({
|
||||
min_filter: "nearest",
|
||||
mag_filter: "nearest",
|
||||
@@ -371,6 +436,39 @@ render.init = function () {
|
||||
address_mode_w: "clamp_edge"
|
||||
});
|
||||
|
||||
io.mount("core");
|
||||
render._main.present = gpupresent;
|
||||
ducky = os.model_buffer("Duck.glb");
|
||||
for (var mesh of ducky) {
|
||||
var mat = mesh.material;
|
||||
for (var i in mat) {
|
||||
var img = {};
|
||||
img.surface = os.make_texture(mat[i]);
|
||||
img.texture = render._main.load_texture(img.surface);
|
||||
img.texture.mode(0);
|
||||
img.sampler = std_sampler;
|
||||
mat[i] = img;
|
||||
}
|
||||
}
|
||||
|
||||
ducky = ducky[0];
|
||||
|
||||
var cmds = render._main.acquire_cmd_buffer();
|
||||
upload_model(cmds,ducky.mesh);
|
||||
cmds.submit();
|
||||
var sprite_vert = make_shader("sprite.vert");
|
||||
var sprite_frag = make_shader("sprite.frag");
|
||||
base_pipeline.vertex = sprite_vert;
|
||||
base_pipeline.fragment = sprite_frag;
|
||||
base_pipeline.gpu = make_pipeline(base_pipeline);
|
||||
|
||||
var model_vert = make_shader("model.vert");
|
||||
var model_frag = make_shader("model.frag");
|
||||
pipeline_model = Object.create(base_pipeline);
|
||||
pipeline_model.vertex = model_vert;
|
||||
pipeline_model.fragment = model_frag;
|
||||
pipeline_model.gpu = make_pipeline(pipeline_model);
|
||||
|
||||
/* os.make_circle2d().draw = function () {
|
||||
render.circle(this.body().transform().pos, this.radius, [1, 1, 0, 1]);
|
||||
};
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
// Constant Buffer for Transformation Matrices
|
||||
cbuffer TransformBuffer : register(b0, space1)
|
||||
{
|
||||
float4x4 vp;
|
||||
float4x4 view;
|
||||
float time; // time in seconds since app start
|
||||
}
|
||||
|
||||
struct VSInput
|
||||
{
|
||||
float3 pos : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 color : COLOR0;
|
||||
float3 normal : NORMAL;
|
||||
};
|
||||
16
shaders/common/common.hlsl
Normal file
16
shaders/common/common.hlsl
Normal file
@@ -0,0 +1,16 @@
|
||||
// Constant Buffer for Transformation Matrices
|
||||
cbuffer TransformBuffer : register(b0, space1)
|
||||
{
|
||||
float4x4 world_to_projection;
|
||||
float4x4 projection_to_world;
|
||||
float4x4 world_to_view;
|
||||
float4x4 view_to_projection;
|
||||
float3 camera_pos_world;
|
||||
float viewport_min_z;
|
||||
float3 camera_dir_world;
|
||||
float viewport_max_z;
|
||||
float2 viewport_size;
|
||||
float2 viewport_offset;
|
||||
float2 render_size;
|
||||
float time; // time in seconds since app start
|
||||
}
|
||||
10
shaders/common/model_pixel.hlsl
Normal file
10
shaders/common/model_pixel.hlsl
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 color : COLOR0;
|
||||
float3 normal : NORMAL;
|
||||
float3 gouraud : COLOR1;
|
||||
};
|
||||
|
||||
42
shaders/common/model_vertex.hlsl
Normal file
42
shaders/common/model_vertex.hlsl
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "common.hlsl"
|
||||
|
||||
struct input
|
||||
{
|
||||
float3 pos : pos;
|
||||
float2 uv : uv;
|
||||
float4 color : color;
|
||||
float3 normal : norm;
|
||||
};
|
||||
|
||||
struct output
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv: TEXCOORD0;
|
||||
float4 color : COLOR0;
|
||||
float3 normal : NORMAL;
|
||||
float3 gouraud : COLOR1;
|
||||
};
|
||||
|
||||
float3 ps1_directional_light(float3 normal, float3 direction, float3 ambient, float3 lightcolor)
|
||||
{
|
||||
float NdotL = dot(normal, normalize(-direction));
|
||||
NdotL = max(NdotL, 0.0f);
|
||||
float3 color = ambient + lightcolor*NdotL;
|
||||
return color;
|
||||
}
|
||||
|
||||
output main(input i)
|
||||
{
|
||||
output o;
|
||||
o.pos = mul(world_to_projection, float4(i.pos,1.0));
|
||||
o.uv = i.uv;
|
||||
o.color = i.color;
|
||||
o.normal = i.normal;
|
||||
|
||||
float3 ambient = float3(0.2,0.2,0.2);
|
||||
float3 lightdir = normalize(float3(1,1,1));
|
||||
o.gouraud = ps1_directional_light(i.normal, lightdir, ambient, float3(1,1,1));
|
||||
|
||||
|
||||
return o;
|
||||
}
|
||||
8
shaders/common/pixel.hlsl
Normal file
8
shaders/common/pixel.hlsl
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "common.hlsl"
|
||||
|
||||
// Structure for pixel shader input (from vertex shader output).
|
||||
struct PSInput
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 color : COLOR0;
|
||||
};
|
||||
25
shaders/common/vertex.hlsl
Normal file
25
shaders/common/vertex.hlsl
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "common.hlsl"
|
||||
|
||||
struct input
|
||||
{
|
||||
float2 pos : pos; // given as world
|
||||
float2 uv : uv; // always a quad
|
||||
float4 color : color;
|
||||
};
|
||||
|
||||
// Output structure from the vertex shader to the pixel shader
|
||||
struct output
|
||||
{
|
||||
float4 pos : SV_Position; // Clip-space position
|
||||
float2 uv : TEXCOORD0; // Texture coordinates
|
||||
float4 color : COLOR0; // Interpolated vertex color
|
||||
};
|
||||
|
||||
output main(input i)
|
||||
{
|
||||
output o;
|
||||
o.pos = mul(world_to_projection, float4(i.pos,0,1));
|
||||
o.uv = i.uv;
|
||||
o.color = i.color;
|
||||
return o;
|
||||
}
|
||||
@@ -1,27 +1,46 @@
|
||||
# Requires shadercross CLI installed from SDL_shadercross
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Ensure directories exist
|
||||
mkdir -p spirv
|
||||
mkdir -p msl
|
||||
mkdir -p dxil
|
||||
mkdir -p reflection
|
||||
|
||||
# Vertex shaders
|
||||
for filename in *.vert.hlsl; do
|
||||
if [ -f "$filename" ]; then
|
||||
echo "compiling ${filename}"
|
||||
shadercross "$filename" -o "spirv/${filename/.hlsl/.spv}"
|
||||
shadercross "$filename" -o "msl/${filename/.hlsl/.msl}"
|
||||
shadercross "$filename" -o "dxil/${filename/.hlsl/.dxil}"
|
||||
|
||||
# Generate reflection JSON
|
||||
spirv-cross "spirv/${filename/.hlsl/.spv}" --reflect > "reflection/${filename/.hlsl/.json}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Fragment shaders
|
||||
for filename in *.frag.hlsl; do
|
||||
if [ -f "$filename" ]; then
|
||||
echo "compiling ${filename}"
|
||||
shadercross "$filename" -o "spirv/${filename/.hlsl/.spv}"
|
||||
shadercross "$filename" -o "msl/${filename/.hlsl/.msl}"
|
||||
shadercross "$filename" -o "dxil/${filename/.hlsl/.dxil}"
|
||||
|
||||
# Generate reflection JSON
|
||||
spirv-cross "spirv/${filename/.hlsl/.spv}" --reflect > "reflection/${filename/.hlsl/.json}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Compute shaders
|
||||
for filename in *.comp.hlsl; do
|
||||
if [ -f "$filename" ]; then
|
||||
echo "compiling ${filename}"
|
||||
shadercross "$filename" -o "spirv/${filename/.hlsl/.spv}"
|
||||
shadercross "$filename" -o "msl/${filename/.hlsl/.msl}"
|
||||
shadercross "$filename" -o "dxil/${filename/.hlsl/.dxil}"
|
||||
|
||||
# Generate reflection JSON
|
||||
spirv-cross "spirv/${filename/.hlsl/.spv}" --reflect > "reflection/${filename/.hlsl/.json}"
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
// If using a texture instead, define:
|
||||
#include "common/model_pixel.hlsl"
|
||||
Texture2D diffuse : register(t0, space2);
|
||||
SamplerState smp : register(s0, space2);
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 normal : NORMAL;
|
||||
};
|
||||
|
||||
float4 main(PSInput input) : SV_TARGET
|
||||
{
|
||||
return float4(input.uv,1,1);
|
||||
float4 color = diffuse.Sample(smp, input.uv);
|
||||
|
||||
return float4(color.rgb*input.gouraud, 1.0);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
#include "common.hlsl"
|
||||
#include "common/model_vertex.hlsl"
|
||||
|
||||
struct VSOutput
|
||||
output vertex(output o)
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float3 normal : NORMAL; // Might be unused in no-light case, but we'll pass it anyway.
|
||||
};
|
||||
|
||||
VSOutput main(VSInput input)
|
||||
{
|
||||
VSOutput output;
|
||||
output.pos = mul(vp, float4(input.pos, 1.0));
|
||||
output.uv = input.uv;
|
||||
output.normal = input.normal; // World space normal if needed
|
||||
return output;
|
||||
return o;
|
||||
}
|
||||
|
||||
@@ -1,21 +1,12 @@
|
||||
#include "common/pixel.hlsl"
|
||||
|
||||
Texture2D diffuse : register(t0, space2);
|
||||
SamplerState smp : register(s0, space2);
|
||||
|
||||
// Structure for pixel shader input (from vertex shader output).
|
||||
struct PSInput
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 color : COLOR0;
|
||||
};
|
||||
|
||||
// Pixel shader main function
|
||||
float4 main(PSInput input) : SV_TARGET
|
||||
{
|
||||
float4 color = diffuse.Sample(smp, input.uv);
|
||||
color *= input.color;
|
||||
|
||||
if (color.a == 0.0f)
|
||||
clip(-1);
|
||||
|
||||
return color;
|
||||
}
|
||||
@@ -1,21 +1,8 @@
|
||||
#include "common.hlsl"
|
||||
|
||||
// Output structure from the vertex shader to the pixel shader
|
||||
struct VertexOutput
|
||||
{
|
||||
float4 pos : SV_Position; // Clip-space position
|
||||
float2 uv : TEXCOORD0; // Texture coordinates
|
||||
float4 color : COLOR0; // Interpolated vertex color
|
||||
};
|
||||
#include "common/vertex.hlsl"
|
||||
|
||||
// Vertex shader
|
||||
VertexOutput main(VSInput input)
|
||||
output vertex(output i)
|
||||
{
|
||||
VertexOutput output;
|
||||
output.pos = mul(vp, float4(input.pos,1.0));
|
||||
output.uv = input.uv;
|
||||
output.color = input.color;
|
||||
|
||||
return output;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
1321
source/jsffi.c
1321
source/jsffi.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user