حالا سوالی که مطرح می شه در بین زبان هایی که برای نوشتن شیدر های گرافیکی توسعه داده شدن چندتاش را می شه در vulkan استفاده کرد ؟
GLSL (OpenGL Shading Language) - used for shaders in OpenGL and WebGL
HLSL (High-Level Shading Language) - used for shaders in Microsoft DirectX
SPIR-V (Standard Portable Intermediate Representation) - a binary format that can be used for shaders in Vulkan, OpenGL, and OpenCL
Metal Shading Language - used for shaders in Apple's Metal graphics API
Cg (C for Graphics) - a shading language developed by Nvidia for use with their graphics hardware
RenderScript - a shading language used for compute kernels in Android's RenderScript API
Sh - a shading language used for ray tracing in the Nvidia OptiX ray tracing engine
و حالا در vulkan
Shaders in Vulkan are written in the SPIR-V language, which is a binary format that can be generated by a variety of shader compilers. You can write shaders directly in SPIR-V, or you can write them in another language such as GLSL or HLSL and then compile them to SPIR-V.
To use shaders in Vulkan, you will need to create a pipeline that specifies the shader stages (vertex shader, tessellation control shader, tessellation evaluation shader, geometry shader, fragment shader, compute shader) and the input and output data for each stage. The pipeline can then be bound to a command buffer and executed on the GPU.
Vulkan provides a number of tools and libraries for working with shaders, including the Vulkan SDK, the SPIR-V Tools library, and the glslang compiler.
حالا بیایید یک نگاهی به کدهای شیدرهای مختلف در زبان های مختلف داشته باشیم
#version 330 core
uniform float time;
uniform vec2 resolution;
void main()
{
vec2 uv = (gl_FragCoord.xy / resolution.xy) * 2.0 - 1.0;
float t = time * 0.5;
float wave1 = sin(uv.x * 20.0 + t) * 0.2;
float wave2 = sin(uv.y * 20.0 + t) * 0.2;
gl_FragColor = vec4(0.5 + wave1 + wave2, 0.5 + wave1, 0.5 + wave2, 1.0);
}
HLSL:
float2 main(float2 uv : TEXCOORD) : SV_Target
{
float t = _Time.y * 0.5;
float wave1 = sin(uv.x * 20.0 + t) * 0.2;
float wave2 = sin(uv.y * 20.0 + t) * 0.2;
return float4(0.5 + wave1 + wave2, 0.5 + wave1, 0.5 + wave2, 1.0);
}
Metal Shading Language:
#include <metal_stdlib>
using namespace metal;
struct VertexIn {
float2 position [[attribute(0)]];
};
struct VertexOut {
float2 texCoord [[user(locn0)]];
};
vertex VertexOut vertexShader(VertexIn vertexIn [[stage_in]]) {
VertexOut vertexOut;
vertexOut.texCoord = vertexIn.position;
return vertexOut;
}
fragment float4 fragmentShader(VertexOut vertexOut [[stage_in]],
constant float& time [[buffer(0)]],
constant float2& resolution [[buffer(1)]]) {
float2 uv = (vertexOut.texCoord / resolution) * 2.0 - 1.0;
float t = time * 0.5;
float wave1 = sin(uv.x * 20.0 + t) * 0.2;
float wave2 = sin(uv.y * 20.0 + t) * 0.2;
return float4(0.5 + wave1 + wave2, 0
.5 + wave1, 0.5 + wave2, 1.0);
}
Cg:
struct VertexInput {
float2 position : POSITION;
};
struct VertexOutput {
float2 texCoord : TEXCOORD0;
};
VertexOutput vertexShader(VertexInput input) {
VertexOutput output;
output.texCoord = input.position;
return output;
}
float4 fragmentShader(VertexOutput input,
uniform float time,
uniform float2 resolution) : COLOR {
float2 uv = (input.texCoord / resolution) * 2.0 - 1.0;
float t = time * 0.5;
float wave1 = sin(uv.x * 20.0 + t) * 0.2;
float wave2 = sin(uv.y * 20.0 + t) * 0.2;
return float4(0.5 + wave1 + wave2, 0.5 + wave1, 0.5 + wave2, 1.0);
}
RenderScript:
#pragma version(1)
#pragma rs_fp_relaxed
float2 __attribute__((kernel)) wave(float2 in, uint32_t x, uint32_t y) {
float2 uv = in * 2.0 - 1.0;
float t = rsGetElementAt_float(g_time, 1) * 0.5;
float wave1 = sin(uv.x * 20.0 + t) * 0.2;
float wave2 = sin(uv.y * 20.0 + t) * 0.2;
return float2(0.5 + wave1 + wave2, 0.5 + wave1);
}
خوب این سری ویدئو ها هم برای vulkan جالبه
https://www.youtube.com/watch?v=Y9U9IE0gVHA&list=PL8327DO66nu9qYVKLDmdLW_8 4-yE4auCR
اگر به این خط تولید هم یک نگاهی بندازید اول پردازنده میاد رئوس و فضای کلی را می سازه و شما اول شیدر های ورتکستون اعمال می شه و در آخر روی پیکسل های نهای شیدر فرگمنت (یا پیکسل در HLSL دایرکس)