Codice c++ di una tecnica HSR scritto da ChatGPT!

Aperto da mikepedo, 20 Giugno 2023, 22:35:52

Discussione precedente - Discussione successiva

0 Utenti e 1 Visitatore stanno visualizzando questa discussione.

mikepedo

Ciao a tutti, oggi mi sono un pò divertito a chiedere a chatGPT di scrivermi un codice di HSR software, gestito dalla cpu. In buona sostanza, gli ho chiesto una cosa semplice, ovvero che la cpu, durante la fase di trasform, clipping and lighting, determini quali siano i triangoli visibili e quali quelli nascosti, tenendo presente che alcuni di essi possano essere trasparenti. Inoltre, per non creare troppa attesa alla scheda video (altrimenti solo al termine di tutti i test avrebbe inviato i soli triangoli visibili alla scheda), gli ho detto che ogni qualvolta un triangolo risulta visibile dal test di profondità lo deve anche immediatamente inviare alla scheda video, mentre solo quelli sicuramente nascosti li dovrà scartare. Chiaramente è un metodo semplice che non azzera l'overdraw, ma penso possa venire incontro alle cpu meno potenti, e inoltre, se non ricordo male, i giochi venivano programmati con delle tecniche front to back, ovvero iniziare l'elaborazione geometrica dai triangoli più prossimi al soggetto: così si avrebbero alte probabilità di inviare alla scheda video i soli triangoli realmente visibili...
Si tratta pertanto di una tecnica di HSR applicata ai triangoli, senza andare a lavorare sui singoli pixel. Tradotto: soltanto i triangoli completamente nascosti vengono scartati, mentre se anche un solo pixel di un triangolo sarà visibile, l'intero triangolo sarà elaborato.
In ogni caso, ecco il risultato! Qualcuno che abbia voglia di ragionarci su???  :o

#include <iostream>
#include <vector>

struct Triangle {
    float x1, y1, z1; // Coordinate del primo vertice
    float x2, y2, z2; // Coordinate del secondo vertice
    float x3, y3, z3; // Coordinate del terzo vertice
    float transparency; // Trasparenza del triangolo (0.0 - 1.0)
};

// Dimensioni del frame buffer
const int framebufferWidth = 800;
const int framebufferHeight = 600;

// Buffer di profondità
float depthBuffer[framebufferWidth][framebufferHeight];

// Funzione per il calcolo dell'area di un triangolo
float CalculateTriangleArea(float x1, float y1, float x2, float y2, float x3, float y3) {
    return std::abs((x1*(y2-y3) + x2*(y3-y1) + x3*(y1-y2)) / 2);
}

// Funzione per determinare la visibilità di un triangolo e inviarlo immediatamente alla scheda video se visibile
bool CheckAndRenderTriangle(const Triangle& triangle) {
    // Calcolo dell'area del triangolo
    float area = CalculateTriangleArea(triangle.x1, triangle.y1, triangle.x2, triangle.y2, triangle.x3, triangle.y3);
   
    // Iterazione sui pixel all'interno del bounding box del triangolo
    int minX = std::min({triangle.x1, triangle.x2, triangle.x3});
    int maxX = std::max({triangle.x1, triangle.x2, triangle.x3});
    int minY = std::min({triangle.y1, triangle.y2, triangle.y3});
    int maxY = std::max({triangle.y1, triangle.y2, triangle.y3});
   
    bool visibleTriangleFound = false; // Flag per indicare se è stato trovato un triangolo visibile
   
    for (int y = minY; y <= maxY; y++) {
        for (int x = minX; x <= maxX; x++) {
            // Calcolo delle coordinate baricentriche del punto
            float alpha = CalculateTriangleArea(x, y, triangle.x2, triangle.y2, triangle.x3, triangle.y3) / area;
            float beta = CalculateTriangleArea(triangle.x1, triangle.y1, x, y, triangle.x3, triangle.y3) / area;
            float gamma = CalculateTriangleArea(triangle.x1, triangle.y1, triangle.x2, triangle.y2, x, y) / area;
           
            // Verifica se il punto è all'interno del triangolo
            if (alpha >= 0 && beta >= 0 && gamma >= 0) {
                // Calcolo del valore Z interpolato
                float interpolatedZ = alpha * triangle.z1 + beta * triangle.z2 + gamma * triangle.z3;
               
                // Verifica la visibilità del punto tramite il buffer di profondità
                if (interpolatedZ < depthBuffer
  • [y]) {
                    depthBuffer
  • [y] = interpolatedZ;
                   
                    // Invio del triangolo alla scheda video per il rendering
                    // ...
                   
                    visibleTriangleFound = true; // Indica che è stato trovato un triangolo visibile
                   
                    // Esci dalla funzione, inviando solo il primo triangolo visibile
                    return true;
                }
            }
        }
    }
   
    return visibleTriangleFound; // Restituisce true se è stato trovato almeno un triangolo visibile
}

int main() {
    // Inizializzazione del buffer di profondità
    for (int y = 0; y < framebufferHeight; y++) {
        for (int x = 0; x < framebufferWidth; x++) {
            depthBuffer
  • [y] = std::numeric_limits<float>::max(); // Valore iniziale massimo
        }
    }
   
    // Esempio di utilizzo
    std::vector<Triangle> triangles; // Vettore dei triangoli della scena
   
    // Aggiungi i triangoli della scena al vettore 'triangles'
    // ...
   
    // Itera sui triangoli e invia i triangoli visibili alla scheda video
    for (const Triangle& triangle : triangles) {
        if (CheckAndRenderTriangle(triangle)) {
            // Se è stato trovato un triangolo visibile, passa al triangolo successivo
            continue;
        }
       
        // Se nessun triangolo visibile è stato trovato, determina i restanti triangoli
        // ...
    }
   
    return 0;
}
Since December 15, 2000 without 3dfx.
gone but never forgotten

Glide

Ciao mikepedo,

è sempre un piacere rileggere un tuo thread :). L'idea è interessante, se ho compreso bene il tuo fine: utilizzare i sistemi assemblati ad hoc per utilizzare oggi schede 3dfx e, nello stesso tempo, dotati di CPU performanti (Athlon o Core), spostando su queste ultime il carico di lavoro legato a funzionalità grafiche che i chip 3dfx non supportano. Questo vuol dire ampliare il bacino dei giochi supportati...

Ciao ciao

mikepedo

Citazione di: Glide il 21 Giugno 2023, 20:13:36Ciao mikepedo,

è sempre un piacere rileggere un tuo thread :). L'idea è interessante, se ho compreso bene il tuo fine: utilizzare i sistemi assemblati ad hoc per utilizzare oggi schede 3dfx e, nello stesso tempo, dotati di CPU performanti (Athlon o Core), spostando su queste ultime il carico di lavoro legato a funzionalità grafiche che i chip 3dfx non supportano. Questo vuol dire ampliare il bacino dei giochi supportati...

Ciao ciao

Piacere mio! In realtà lo scopo non è aumentare il bacino dei giochi supportati, ma aumentare le prestazioni in-game, allo scopo di permettere una buona giocabilità anche dei giochi più recenti, ma già "compatibili" diciamo.
Sostanzialmente l'algoritmo dovrebbe permettere di inviare alla scheda video soltanto i triangoli visibili (e per semplicità, anche i parzialmente visibili) scartando quelli totalmente nascosti. Non è una tecnica TBR per interderci come aveva PowerVR, che di fatto lavorava nella fase di rendering: questo è un codice che lavora nella fase geometrica e quindi totalmente software, dal momento che le schede 3dfx non supportato il T&L in hw.

I vantaggi sono molteplici:
-minor numeri di triangoli inviati alla scheda video, quindi minor banda passante necessaria (ne giovano soprattutto le schede PCI33)
-risparmio di fill rate (meno triangoli da renderizzare)
-risparmio di bandwidth (minor scritture del frame buffer)

La cosa bella di questo approccio è che le modifiche lato driver interessano solo la gestione geometrica della scena, mentre tutto quello che viene a valle può restare così com'è.
Ora, sulla fattibilità dell'idea alzo le mani, servirebbe qualcuno che abbia idea di come implementarlo.
Since December 15, 2000 without 3dfx.
gone but never forgotten

mikepedo

#3
Aggiungo: questo algoritmo potrebbe anche essere migliorato, effettuando un "cutting" dei triangoli parzialmente visibili, così da inviare solo la parte visibile di esso... e per fare questo si potrebbe ragionare su una tecnica a tiles applicata alla geometria... ma un passo alla volta! Se qualcuno avesse la capacità ed il tempo di provarci...
Sta di fatto che sarebbe un bel beneficio per chi ha installato una 3dfx in un sistema potente: sfruttare questa potenza per alleggerire la vecchietta!
Since December 15, 2000 without 3dfx.
gone but never forgotten

Glide

Ciao mikepedo, scusami innanzitutto se ti rispondo soltanto ora, nonostante il tuo thread meriti ben altri tempi di reazione, e grazie mille per il chiarimento.

L'obiettivo è quindi molto interessante, si tratterebbe di un bel boost prestazionale che potrebbero ottenere piacevolmente, e come sempre a costo zero - trattandosi di una modifica non a livello hardware ma software che, se effettivamente realizzata, non verrebbe distribuita a pagamento, o almeno non da 3dfxzone - le nostre gaming build :) costruite per far lavorare nelle migliori condizioni possibili le schede grafiche e gli acceleratori grafici di 3dfx.

Per idee, considerazioni, e tutto il resto, da parte di chi legge ed è interessato, ovviamente siamo qui.

@mikepedo Vado infine un pò off topic, ma non resisto (avrei voluto dirtelo anche nel corso del mio primo reply): ho avuto la fortuna di conoscerti e interagire con te attraverso questa Community "diversi" anni fa. E' sempre stata evidente la tua grande conoscenza dei temi legati alla computer graphics, accanto alla passione per 3dfx, ovvio. Direi però che nel 2023 ti trovo ancora più padrone di certi argomenti, e la cosa mi fa molto piacere.

Grazie ancora mitico MOD.

Ciao ciao

mikepedo

Grazie! Ma si tratta di un concetto che poi andrebbe applicato da chi realmente conosce la programmazione e l'hw 3D.
Non saprei, questa idea di lavorare sulla geometria ce l'ho da anni, ma chiaramente servirebbe qualcuno che abbia realmente la capacità di fare un tentativo.
Di fatto una scheda 3dfx la puoi vedere come un renderizzatore che elabora qualsiasi cosa gli viene inviata, perchè non ha complessi sistemi per ridurre l'overdraw. Lo scopo è inviarle soltanto quello che è realmente visibile e necessario.
Since December 15, 2000 without 3dfx.
gone but never forgotten

Glide

Ogni idea è benvenuta, poi se arriva da una fonte autorevole e affidabile - non lo dico io ma la storia di questo forum, basta fare un giro tra i thread per averne contezza - ancora meglio. La tua esposizione credo sia chiara, e la discussione è aperta a tutti.

Ciao ciao